aboutsummaryrefslogtreecommitdiff
path: root/nxcomp/ServerChannel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxcomp/ServerChannel.cpp')
-rw-r--r--nxcomp/ServerChannel.cpp7942
1 files changed, 0 insertions, 7942 deletions
diff --git a/nxcomp/ServerChannel.cpp b/nxcomp/ServerChannel.cpp
deleted file mode 100644
index eff24e90e..000000000
--- a/nxcomp/ServerChannel.cpp
+++ /dev/null
@@ -1,7942 +0,0 @@
-/**************************************************************************/
-/* */
-/* 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. */
-/* */
-/**************************************************************************/
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#ifndef ANDROID
-#include <sys/shm.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xatom.h>
-
-#include "NXproto.h"
-#include "NXalert.h"
-#include "NXpack.h"
-#include "NXmitshm.h"
-
-#include "ServerChannel.h"
-
-#include "EncodeBuffer.h"
-#include "DecodeBuffer.h"
-
-#include "StaticCompressor.h"
-
-#include "Statistics.h"
-#include "Proxy.h"
-
-#include "Auth.h"
-#include "Unpack.h"
-
-//
-// Available unpack methods.
-//
-
-#include "Alpha.h"
-#include "Colormap.h"
-#include "Bitmap.h"
-#include "Jpeg.h"
-#include "Pgn.h"
-#include "Rgb.h"
-#include "Rle.h"
-
-extern Proxy *proxy;
-
-//
-// Set the verbosity level. You also
-// need to define OPCODES in Misc.cpp
-// if you want literals instead of
-// opcodes' numbers.
-//
-
-#define PANIC
-#define WARNING
-#undef OPCODES
-#undef TEST
-#undef DEBUG
-#undef DUMP
-
-//
-// Log the important tracepoints related
-// to writing packets to the peer proxy.
-//
-
-#undef FLUSH
-
-//
-// Log the operations related to splits.
-//
-
-#undef SPLIT
-
-//
-// Define this to log when a channel
-// is created or destroyed.
-//
-
-#undef REFERENCES
-
-//
-// Define this to exit and suspend the
-// session after a given number of X
-// messages decoded by the proxy.
-//
-
-#undef SUSPEND
-
-//
-// Define these to hide the server extensions.
-//
-
-#define HIDE_MIT_SHM_EXTENSION
-#define HIDE_BIG_REQUESTS_EXTENSION
-#define HIDE_XFree86_Bigfont_EXTENSION
-#undef HIDE_SHAPE_EXTENSION
-#undef HIDE_XKEYBOARD_EXTENSION
-
-//
-// Known reasons of connection failures.
-//
-
-#define INVALID_COOKIE_DATA "Invalid MIT-MAGIC-COOKIE-1 key"
-#define INVALID_COOKIE_SIZE ((int) sizeof(INVALID_COOKIE_DATA) - 1)
-
-#define NO_AUTH_PROTO_DATA "No protocol specified"
-#define NO_AUTH_PROTO_SIZE ((int) sizeof(NO_AUTH_PROTO_DATA) - 1)
-
-//
-// Here are the static members.
-//
-
-#ifdef REFERENCES
-
-int ServerChannel::references_ = 0;
-
-#endif
-
-ServerChannel::ServerChannel(Transport *transport, StaticCompressor *compressor)
-
- : Channel(transport, compressor), readBuffer_(transport_, this)
-{
- //
- // Sequence number of the next message
- // being encoded or decoded.
- //
-
- clientSequence_ = 0;
- serverSequence_ = 0;
-
- //
- // Save the last motion event and flush
- // it only when the timeout expires.
- //
-
- lastMotion_[0] = '\0';
-
- //
- // Clear the queue of sequence numbers
- // of split commits. Used to mask the
- // errors.
- //
-
- initCommitQueue();
-
- //
- // Do we enable or not sending of expose
- // events to the X client.
- //
-
- enableExpose_ = 1;
- enableGraphicsExpose_ = 1;
- enableNoExpose_ = 1;
-
- //
- // Track data of image currently being
- // decompressed.
- //
-
- imageState_ = NULL;
-
- //
- // Track MIT-SHM resources.
- //
-
- shmemState_ = NULL;
-
- //
- // Store the unpack state for each agent
- // resource.
- //
-
- for (int i = 0; i < CONNECTIONS_LIMIT; i++)
- {
- unpackState_[i] = NULL;
- }
-
- //
- // Data about the split parameters requested
- // by the encoding side.
- //
-
- splitState_.resource = nothing;
- splitState_.current = 0;
- splitState_.save = 1;
- splitState_.load = 1;
- splitState_.commit = 0;
-
- //
- // It will be eventually set by
- // the server proxy.
- //
-
- fontPort_ = -1;
-
- #ifdef REFERENCES
- *logofs << "ServerChannel: Created new object at "
- << this << " for FD#" << fd_ << " out of "
- << ++references_ << " allocated channels.\n"
- << logofs_flush;
- #endif
-}
-
-ServerChannel::~ServerChannel()
-{
- #ifdef TEST
- *logofs << "ServerChannel: Freeing image state information.\n"
- << logofs_flush;
- #endif
-
- handleImageStateRemove();
-
- #ifdef TEST
- *logofs << "ServerChannel: Freeing shared memory information.\n"
- << logofs_flush;
- #endif
-
- handleShmemStateRemove();
-
- #ifdef TEST
- *logofs << "ServerChannel: Freeing unpack state information.\n"
- << logofs_flush;
- #endif
-
- for (int i = 0; i < CONNECTIONS_LIMIT; i++)
- {
- handleUnpackStateRemove(i);
- }
-
- #ifdef TEST
- *logofs << "ServerChannel: Freeing channel caches.\n"
- << logofs_flush;
- #endif
-
- #ifdef REFERENCES
- *logofs << "ServerChannel: Deleted object at "
- << this << " for FD#" << fd_ << " out of "
- << --references_ << " allocated channels.\n"
- << logofs_flush;
- #endif
-}
-
-//
-// Beginning of handleRead().
-//
-
-int ServerChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message,
- unsigned int length)
-{
- #ifdef DEBUG
- *logofs << "handleRead: Called for FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- //
- // Pointer to located message and
- // its size in bytes.
- //
-
- const unsigned char *inputMessage;
- unsigned int inputLength;
-
- //
- // Set when message is found in
- // cache.
- //
-
- int hit;
-
- #if defined(TEST) || defined(INFO)
- *logofs << "handleRead: Trying to read from FD#"
- << fd_ << " at " << strMsTimestamp() << ".\n"
- << logofs_flush;
- #endif
-
- int result = readBuffer_.readMessage();
-
- #if defined(DEBUG) || defined(INFO)
- *logofs << "handleRead: Read result on FD#" << fd_
- << " is " << result << ".\n"
- << logofs_flush;
- #endif
-
- if (result < 0)
- {
- //
- // Let the proxy close the channel.
- //
-
- return -1;
- }
- else if (result == 0)
- {
- #if defined(TEST) || defined(INFO)
-
- //
- // This can happen because we have the descriptor
- // selected in the read set but we already read
- // the data asynchronously, while decoding data
- // read from the proxy.
- //
-
- *logofs << "handleRead: WARNING! No data read from FD#"
- << fd_ << " while encoding messages.\n"
- << logofs_flush;
-
- #endif
-
- return 0;
- }
-
- #if defined(TEST) || defined(INFO) || defined(FLUSH)
- *logofs << "handleRead: Encoding messages for FD#" << fd_
- << " with " << readBuffer_.getLength() << " bytes "
- << "in the buffer.\n" << logofs_flush;
- #endif
-
- //
- // Extract any complete message which
- // is available in the buffer.
- //
-
- if (proxy -> handleAsyncSwitch(fd_) < 0)
- {
- return -1;
- }
-
- while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL)
- {
- hit = 0;
-
- if (firstReply_)
- {
- //
- // Handle the X server's authorization reply.
- //
-
- if (handleAuthorization(inputMessage, inputLength) < 0)
- {
- return -1;
- }
-
- imageByteOrder_ = inputMessage[30];
- bitmapBitOrder_ = inputMessage[31];
- scanlineUnit_ = inputMessage[32];
- scanlinePad_ = inputMessage[33];
-
- encodeBuffer.encodeValue((unsigned int) inputMessage[0], 8);
- encodeBuffer.encodeValue((unsigned int) inputMessage[1], 8);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 2, bigEndian_), 16);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 4, bigEndian_), 16);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 6, bigEndian_), 16);
-
- if (ServerCache::lastInitReply.compare(inputLength - 8, inputMessage + 8))
- {
- encodeBuffer.encodeBoolValue(1);
- }
- else
- {
- encodeBuffer.encodeBoolValue(0);
-
- for (unsigned int i = 8; i < inputLength; i++)
- {
- encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8);
- }
- }
-
- firstReply_ = 0;
-
- #if defined(TEST) || defined(OPCODES)
-
- int bits = encodeBuffer.diffBits();
-
- *logofs << "handleRead: Handled first reply. " << inputLength
- << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
-
- #endif
-
- priority_++;
-
- }
- else
- {
- //
- // NX client needs this line to consider
- // the initialization phase successfully
- // completed.
- //
-
- if (firstClient_ == -1)
- {
- cerr << "Info" << ": Established X server connection.\n" ;
-
- firstClient_ = fd_;
- }
-
- //
- // Check if this is a reply.
- //
-
- if (*inputMessage == X_Reply)
- {
- int bits = 0;
-
- unsigned char inputOpcode = *inputMessage;
-
- unsigned short int requestSequenceNum;
- unsigned char requestOpcode;
- unsigned int requestData[3];
-
- unsigned int sequenceNum = GetUINT(inputMessage + 2, bigEndian_);
-
- #ifdef SUSPEND
-
- if (sequenceNum >= 1000)
- {
- cerr << "Warning" << ": Exiting to test the resilience of the agent.\n";
-
- sleep(2);
-
- HandleAbort();
- }
-
- #endif
-
- //
- // We managed all the events and errors caused
- // by the previous requests. We can now reset
- // the queue of split commits.
- //
-
- clearCommitQueue();
-
- //
- // Encode opcode and difference between
- // current sequence and the last one.
- //
-
- encodeBuffer.encodeOpcodeValue(inputOpcode, serverCache_ -> opcodeCache);
-
- unsigned int sequenceDiff = sequenceNum - serverSequence_;
-
- serverSequence_ = sequenceNum;
-
- #ifdef DEBUG
- *logofs << "handleRead: Last server sequence number for FD#"
- << fd_ << " is " << serverSequence_ << " with "
- << "difference " << sequenceDiff << ".\n"
- << logofs_flush;
- #endif
-
- encodeBuffer.encodeCachedValue(sequenceDiff, 16,
- serverCache_ -> replySequenceCache, 7);
-
- //
- // Now handle the data part.
- //
-
- if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) &&
- requestSequenceNum == sequenceNum)
- {
- //
- // We've found the request that generated this reply.
- // It is possible to compress the reply based on the
- // specific request type.
- //
-
- sequenceQueue_.pop(requestSequenceNum, requestOpcode,
- requestData[0], requestData[1], requestData[2]);
-
- //
- // If differential compression is disabled
- // then use the most simple encoding.
- //
-
- if (control -> LocalDeltaCompression == 0)
- {
- int result = handleFastReadReply(encodeBuffer, requestOpcode,
- inputMessage, inputLength);
- if (result < 0)
- {
- return -1;
- }
- else if (result > 0)
- {
- continue;
- }
- }
-
- switch (requestOpcode)
- {
- case X_AllocColor:
- {
- const unsigned char *nextSrc = inputMessage + 8;
- for (unsigned int i = 0; i < 3; i++)
- {
- unsigned int colorValue = GetUINT(nextSrc, bigEndian_);
- nextSrc += 2;
- if (colorValue == requestData[i])
- encodeBuffer.encodeBoolValue(1);
- else
- {
- encodeBuffer.encodeBoolValue(0);
- encodeBuffer.encodeValue(colorValue - colorValue, 16, 6);
- }
- }
- unsigned int pixel = GetULONG(inputMessage + 16, bigEndian_);
- encodeBuffer.encodeValue(pixel, 32, 9);
-
- priority_++;
- }
- break;
- case X_GetAtomName:
- {
- unsigned int nameLength = GetUINT(inputMessage + 8, bigEndian_);
- encodeBuffer.encodeValue(nameLength, 16, 6);
- const unsigned char *nextSrc = inputMessage + 32;
-
- // Since ProtoStep7 (#issue 108)
- encodeBuffer.encodeTextData(nextSrc, nameLength);
-
- priority_++;
- }
- break;
- case X_GetGeometry:
- {
- //
- // TODO: This obtains a satisfactory 10:1, but
- // could be cached to leverage the big amount
- // of such requests issued by QT clients.
- //
-
- encodeBuffer.encodeCachedValue(inputMessage[1], 8,
- serverCache_ -> depthCache);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> getGeometryRootCache, 9);
- const unsigned char *nextSrc = inputMessage + 12;
- for (unsigned int i = 0; i < 5; i++)
- {
- encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16,
- *serverCache_ -> getGeometryGeomCache[i], 8);
- nextSrc += 2;
- }
-
- priority_++;
- }
- break;
- case X_GetInputFocus:
- {
- //
- // Is it a real X_GetInputFocus or a
- // masqueraded reply?
- //
-
- if (requestData[0] == X_GetInputFocus)
- {
- encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> getInputFocusWindowCache);
-
- priority_++;
- }
- else
- {
- //
- // TODO: We are not setting priority in case
- // of replies other than real X_GetInputFocus
- // or X_NXGetUnpackParameters. We should check
- // once again that this is OK.
- //
-
- #ifdef TEST
- *logofs << "handleRead: Received tainted X_GetInputFocus reply "
- << "for request OPCODE#" << requestData[0] << " with "
- << "sequence " << sequenceNum << ".\n"
- << logofs_flush;
- #endif
-
- //
- // Don't encode any data in case of sync
- // messages or any other reply for which
- // opcode is enough.
- //
-
- if (requestData[0] == opcodeStore_ -> getUnpackParameters)
- {
- for (int i = 0; i < PACK_METHOD_LIMIT; i++)
- {
- encodeBuffer.encodeBoolValue(control -> LocalUnpackMethods[i]);
- }
-
- priority_++;
- }
- else if (requestData[0] == opcodeStore_ -> getShmemParameters)
- {
- if (handleShmemReply(encodeBuffer, requestOpcode, requestData[1],
- inputMessage, inputLength) < 0)
- {
- return -1;
- }
-
- priority_++;
- }
- else if (requestData[0] == opcodeStore_ -> getFontParameters)
- {
- if (handleFontReply(encodeBuffer, requestOpcode,
- inputMessage, inputLength) < 0)
- {
- return -1;
- }
- }
-
- //
- // Account this data to the original opcode.
- //
-
- requestOpcode = requestData[0];
- }
- }
- break;
- case X_GetKeyboardMapping:
- {
- unsigned int keysymsPerKeycode = (unsigned int) inputMessage[1];
- if (ServerCache::getKeyboardMappingLastMap.compare(inputLength - 32,
- inputMessage + 32) && (keysymsPerKeycode ==
- ServerCache::getKeyboardMappingLastKeysymsPerKeycode))
- {
- encodeBuffer.encodeBoolValue(1);
-
- priority_++;
-
- break;
- }
- ServerCache::getKeyboardMappingLastKeysymsPerKeycode = keysymsPerKeycode;
- encodeBuffer.encodeBoolValue(0);
- unsigned int numKeycodes =
- (((inputLength - 32) / keysymsPerKeycode) >> 2);
- encodeBuffer.encodeValue(numKeycodes, 8);
- encodeBuffer.encodeValue(keysymsPerKeycode, 8, 4);
- const unsigned char *nextSrc = inputMessage + 32;
- unsigned char previous = 0;
- for (unsigned int count = numKeycodes * keysymsPerKeycode;
- count; --count)
- {
- unsigned int keysym = GetULONG(nextSrc, bigEndian_);
- nextSrc += 4;
- if (keysym == NoSymbol)
- encodeBuffer.encodeBoolValue(1);
- else
- {
- encodeBuffer.encodeBoolValue(0);
- unsigned int first3Bytes = (keysym >> 8);
- encodeBuffer.encodeCachedValue(first3Bytes, 24,
- serverCache_ -> getKeyboardMappingKeysymCache, 9);
- unsigned char lastByte = (unsigned char) (keysym & 0xff);
- encodeBuffer.encodeCachedValue(lastByte - previous, 8,
- serverCache_ -> getKeyboardMappingLastByteCache, 5);
- previous = lastByte;
- }
- }
-
- priority_++;
- }
- break;
- case X_GetModifierMapping:
- {
- encodeBuffer.encodeValue((unsigned int) inputMessage[1], 8);
- const unsigned char *nextDest = inputMessage + 32;
- if (ServerCache::getModifierMappingLastMap.compare(inputLength - 32,
- nextDest))
- {
- encodeBuffer.encodeBoolValue(1);
-
- priority_++;
-
- break;
- }
- encodeBuffer.encodeBoolValue(0);
- for (unsigned int count = inputLength - 32; count; count--)
- {
- unsigned char next = *nextDest++;
- if (next == 0)
- encodeBuffer.encodeBoolValue(1);
- else
- {
- encodeBuffer.encodeBoolValue(0);
- encodeBuffer.encodeValue(next, 8);
- }
- }
-
- priority_++;
- }
- break;
- case X_GetProperty:
- {
- MessageStore *messageStore = serverStore_ ->
- getReplyStore(X_GetProperty);
-
- hit = handleEncode(encodeBuffer, serverCache_, messageStore,
- requestOpcode, inputMessage, inputLength);
-
- priority_++;
- }
- break;
- case X_GetSelectionOwner:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> getSelectionOwnerCache, 9);
- priority_++;
- }
- break;
- case X_GetWindowAttributes:
- {
- encodeBuffer.encodeValue((unsigned int) inputMessage[1], 2);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> visualCache);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_),
- 16, serverCache_ -> getWindowAttributesClassCache, 3);
- encodeBuffer.encodeCachedValue(inputMessage[14], 8,
- serverCache_ -> getWindowAttributesBitGravityCache);
- encodeBuffer.encodeCachedValue(inputMessage[15], 8,
- serverCache_ -> getWindowAttributesWinGravityCache);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_),
- 32, serverCache_ -> getWindowAttributesPlanesCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 20, bigEndian_),
- 32, serverCache_ -> getWindowAttributesPixelCache, 9);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[24]);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[25]);
- encodeBuffer.encodeValue((unsigned int) inputMessage[26], 2);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[27]);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 28, bigEndian_),
- 29, serverCache_ -> colormapCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 32, bigEndian_),
- 32, serverCache_ -> getWindowAttributesAllEventsCache);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 36, bigEndian_),
- 32, serverCache_ -> getWindowAttributesYourEventsCache);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 40, bigEndian_),
- 16, serverCache_ -> getWindowAttributesDontPropagateCache);
-
- priority_++;
- }
- break;
- case X_GrabKeyboard:
- case X_GrabPointer:
- {
- encodeBuffer.encodeValue((unsigned int) inputMessage[1], 3);
-
- priority_++;
- }
- break;
- case X_InternAtom:
- {
- encodeBuffer.encodeValue(GetULONG(inputMessage + 8, bigEndian_), 29, 9);
-
- priority_++;
- }
- break;
- case X_ListExtensions:
- {
- encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8);
- unsigned int numExtensions = (unsigned int) inputMessage[1];
- encodeBuffer.encodeValue(numExtensions, 8);
- const unsigned char *nextSrc = inputMessage + 32;
-
- for (; numExtensions; numExtensions--)
- {
- unsigned int length = (unsigned int) (*nextSrc++);
-
- encodeBuffer.encodeValue(length, 8);
-
- #ifdef HIDE_MIT_SHM_EXTENSION
-
- if (!strncmp((char *) nextSrc, "MIT-SHM", 7))
- {
- #ifdef TEST
- *logofs << "handleRead: Hiding MIT-SHM extension in reply.\n"
- << logofs_flush;
- #endif
-
- memcpy((unsigned char *) nextSrc, "NO-MIT-", 7);
- }
-
- #endif
-
- #ifdef HIDE_BIG_REQUESTS_EXTENSION
-
- if (!strncmp((char *) nextSrc, "BIG-REQUESTS", 12))
- {
- #ifdef TEST
- *logofs << "handleRead: Hiding BIG-REQUESTS extension in reply.\n"
- << logofs_flush;
- #endif
-
- memcpy((unsigned char *) nextSrc, "NO-BIG-REQUE", 12);
- }
-
- #endif
-
- #ifdef HIDE_XKEYBOARD_EXTENSION
-
- if (!strncmp((char *) nextSrc, "XKEYBOARD", 9))
- {
- #ifdef TEST
- *logofs << "handleRead: Hiding XKEYBOARD extension in reply.\n"
- << logofs_flush;
- #endif
-
- memcpy((unsigned char *) nextSrc, "NO-XKEYBO", 9);
- }
-
- #endif
-
- #ifdef HIDE_XFree86_Bigfont_EXTENSION
-
- if (!strncmp((char *) nextSrc, "XFree86-Bigfont", 15))
- {
- #ifdef TEST
- *logofs << "handleRead: Hiding XFree86-Bigfont extension in reply.\n"
- << logofs_flush;
- #endif
-
- memcpy((unsigned char *) nextSrc, "NO-XFree86-Bigf", 15);
- }
-
- #endif
-
- #ifdef HIDE_SHAPE_EXTENSION
-
- if (!strncmp((char *) nextSrc, "SHAPE", 5))
- {
- #ifdef TEST
- *logofs << "handleRead: Hiding SHAPE extension in reply.\n"
- << logofs_flush;
- #endif
-
- memcpy((unsigned char *) nextSrc, "NO-SH", 5);
- }
-
- #endif
-
- //
- // Check if user disabled RENDER extension.
- //
-
- if (control -> HideRender == 1 &&
- !strncmp((char *) nextSrc, "RENDER", 6))
- {
- #ifdef TEST
- *logofs << "handleRead: Hiding RENDER extension in reply.\n"
- << logofs_flush;
- #endif
-
- memcpy((unsigned char *) nextSrc, "NO-REN", 6);
- }
-
- for (; length; length--)
- {
- encodeBuffer.encodeValue((unsigned int) (*nextSrc++), 8);
- }
- }
-
- priority_++;
- }
- break;
- case X_ListFonts:
- {
- MessageStore *messageStore = serverStore_ ->
- getReplyStore(X_ListFonts);
-
- if (handleEncodeCached(encodeBuffer, serverCache_, messageStore,
- inputMessage, inputLength))
- {
- priority_++;
-
- hit = 1;
-
- break;
- }
-
- encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8);
- unsigned int numFonts = GetUINT(inputMessage + 8, bigEndian_);
- encodeBuffer.encodeValue(numFonts, 16, 6);
-
- // Differential encoding.
- encodeBuffer.encodeBoolValue(1);
-
- const unsigned char* nextSrc = inputMessage + 32;
- for (; numFonts; numFonts--)
- {
- unsigned int length = (unsigned int) (*nextSrc++);
- encodeBuffer.encodeValue(length, 8);
-
- // Since ProtoStep7 (#issue 108)
- encodeBuffer.encodeTextData(nextSrc, length);
-
- nextSrc += length;
- }
-
- priority_++;
- }
- break;
- case X_LookupColor:
- case X_AllocNamedColor:
- {
- const unsigned char *nextSrc = inputMessage + 8;
- if (requestOpcode == X_AllocNamedColor)
- {
- encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 9);
- nextSrc += 4;
- }
- unsigned int count = 3;
- do
- {
- unsigned int exactColor = GetUINT(nextSrc, bigEndian_);
- encodeBuffer.encodeValue(exactColor, 16, 9);
- unsigned int visualColor = GetUINT(nextSrc + 6, bigEndian_) -
- exactColor;
- encodeBuffer.encodeValue(visualColor, 16, 5);
- nextSrc += 2;
- }
- while (--count);
-
- priority_++;
- }
- break;
- case X_QueryBestSize:
- {
- encodeBuffer.encodeValue(GetUINT(inputMessage + 8, bigEndian_), 16, 8);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 10, bigEndian_), 16, 8);
-
- priority_++;
- }
- break;
- case X_QueryColors:
- {
- // Differential encoding.
- encodeBuffer.encodeBoolValue(1);
-
- unsigned int numColors = ((inputLength - 32) >> 3);
- const unsigned char *nextSrc = inputMessage + 40;
- unsigned char *nextDest = (unsigned char *) inputMessage + 38;
- for (unsigned int c = 1; c < numColors; c++)
- {
- for (unsigned int i = 0; i < 6; i++)
- *nextDest++ = *nextSrc++;
- nextSrc += 2;
- }
- unsigned int colorsLength = numColors * 6;
- if (serverCache_ -> queryColorsLastReply.compare(colorsLength,
- inputMessage + 32))
- encodeBuffer.encodeBoolValue(1);
- else
- {
- const unsigned char *nextSrc = inputMessage + 32;
- encodeBuffer.encodeBoolValue(0);
- encodeBuffer.encodeValue(numColors, 16, 5);
- for (numColors *= 3; numColors; numColors--)
- {
- encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16);
- nextSrc += 2;
- }
- }
-
- priority_++;
- }
- break;
- case X_QueryExtension:
- {
- if (requestData[0] == X_QueryExtension)
- {
- //
- // Value in requestData[0] will be nonzero
- // if the request is for an extension that
- // we should hide to the X client.
- //
-
- if (requestData[1])
- {
- encodeBuffer.encodeBoolValue(0);
- encodeBuffer.encodeValue(0, 8);
- }
- else
- {
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[8]);
- encodeBuffer.encodeValue((unsigned int) inputMessage[9], 8);
- }
-
- encodeBuffer.encodeValue((unsigned int) inputMessage[10], 8);
- encodeBuffer.encodeValue((unsigned int) inputMessage[11], 8);
-
- if (requestData[2] == X_NXInternalShapeExtension)
- {
- opcodeStore_ -> shapeExtension = inputMessage[9];
-
- #ifdef TEST
- *logofs << "handleRead: Shape extension opcode for FD#" << fd_
- << " is " << (unsigned int) opcodeStore_ -> shapeExtension
- << ".\n" << logofs_flush;
- #endif
- }
- else if (requestData[2] == X_NXInternalRenderExtension)
- {
- opcodeStore_ -> renderExtension = inputMessage[9];
-
- #ifdef TEST
- *logofs << "handleRead: Render extension opcode for FD#" << fd_
- << " is " << (unsigned int) opcodeStore_ -> renderExtension
- << ".\n" << logofs_flush;
- #endif
- }
-
- priority_++;
- }
- else
- {
- #ifdef TEST
- *logofs << "handleRead: Received tainted X_QueryExtension reply "
- << "for request OPCODE#" << requestData[0] << " with "
- << "sequence " << sequenceNum << ".\n"
- << logofs_flush;
- #endif
-
- if (requestData[0] == opcodeStore_ -> getShmemParameters)
- {
- if (handleShmemReply(encodeBuffer, requestOpcode, requestData[1],
- inputMessage, inputLength) < 0)
- {
- return -1;
- }
-
- priority_++;
- }
- //
- // Account this data to the original opcode.
- //
-
- requestOpcode = requestData[0];
- }
- }
- break;
- case X_QueryFont:
- {
- MessageStore *messageStore = serverStore_ ->
- getReplyStore(X_QueryFont);
-
- if (handleEncodeCached(encodeBuffer, serverCache_, messageStore,
- inputMessage, inputLength))
- {
- priority_++;
-
- hit = 1;
-
- break;
- }
-
- // Differential encoding.
- encodeBuffer.encodeBoolValue(1);
-
- unsigned int numProperties = GetUINT(inputMessage + 46, bigEndian_);
- unsigned int numCharInfos = GetULONG(inputMessage + 56, bigEndian_);
- encodeBuffer.encodeValue(numProperties, 16, 8);
- encodeBuffer.encodeValue(numCharInfos, 32, 10);
- handleEncodeCharInfo(inputMessage + 8, encodeBuffer);
- handleEncodeCharInfo(inputMessage + 24, encodeBuffer);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 40, bigEndian_), 16, 9);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 42, bigEndian_), 16, 9);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 44, bigEndian_), 16, 9);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[48]);
- encodeBuffer.encodeValue((unsigned int) inputMessage[49], 8);
- encodeBuffer.encodeValue((unsigned int) inputMessage[50], 8);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[51]);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 52, bigEndian_), 16, 9);
- encodeBuffer.encodeValue(GetUINT(inputMessage + 54, bigEndian_), 16, 9);
- const unsigned char *nextSrc = inputMessage + 60;
- unsigned int index;
-
- int end = 0;
-
- if (ServerCache::queryFontFontCache.lookup(numProperties * 8 +
- numCharInfos * 12, nextSrc, index))
- {
- encodeBuffer.encodeBoolValue(1);
- encodeBuffer.encodeValue(index, 4);
-
- end = 1;
- }
-
- if (end == 0)
- {
- encodeBuffer.encodeBoolValue(0);
- for (; numProperties; numProperties--)
- {
- encodeBuffer.encodeValue(GetULONG(nextSrc, bigEndian_), 32, 9);
- encodeBuffer.encodeValue(GetULONG(nextSrc + 4, bigEndian_), 32, 9);
- nextSrc += 8;
- }
- for (; numCharInfos; numCharInfos--)
- {
- handleEncodeCharInfo(nextSrc, encodeBuffer);
-
- nextSrc += 12;
- }
- }
-
- priority_++;
- }
- break;
- case X_QueryPointer:
- {
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> queryPointerRootCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_),
- 29, serverCache_ -> queryPointerChildCache, 9);
- unsigned int rootX = GetUINT(inputMessage + 16, bigEndian_);
- unsigned int rootY = GetUINT(inputMessage + 18, bigEndian_);
- unsigned int eventX = GetUINT(inputMessage + 20, bigEndian_);
- unsigned int eventY = GetUINT(inputMessage + 22, bigEndian_);
- eventX -= rootX;
- eventY -= rootY;
- encodeBuffer.encodeCachedValue(
- rootX - serverCache_ -> motionNotifyLastRootX, 16,
- serverCache_ -> motionNotifyRootXCache, 8);
- serverCache_ -> motionNotifyLastRootX = rootX;
- encodeBuffer.encodeCachedValue(
- rootY - serverCache_ -> motionNotifyLastRootY, 16,
- serverCache_ -> motionNotifyRootYCache, 8);
- serverCache_ -> motionNotifyLastRootY = rootY;
- encodeBuffer.encodeCachedValue(eventX, 16,
- serverCache_ -> motionNotifyEventXCache, 8);
- encodeBuffer.encodeCachedValue(eventY, 16,
- serverCache_ -> motionNotifyEventYCache, 8);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 24, bigEndian_),
- 16, serverCache_ -> motionNotifyStateCache);
- priority_++;
- }
- break;
- case X_QueryTree:
- {
- //
- // This was very inefficient. In practice
- // it just copied data on the output. Now
- // it obtains an average 7:1 compression
- // and could optionally be cached.
- //
-
- unsigned int children = GetUINT(inputMessage + 16, bigEndian_);
-
- encodeBuffer.encodeValue(children, 16, 8);
-
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29,
- serverCache_ -> queryTreeWindowCache);
-
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_), 29,
- serverCache_ -> queryTreeWindowCache);
-
- const unsigned char *next = inputMessage + 32;
-
- for (unsigned int i = 0; i < children; i++)
- {
- encodeBuffer.encodeCachedValue(GetULONG(next + (i * 4), bigEndian_), 29,
- serverCache_ -> queryTreeWindowCache);
- }
-
- priority_++;
- }
- break;
- case X_TranslateCoords:
- {
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[1]);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> translateCoordsChildCache, 9);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 12, bigEndian_),
- 16, serverCache_ -> translateCoordsXCache, 8);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 14, bigEndian_),
- 16, serverCache_ -> translateCoordsYCache, 8);
- priority_++;
- }
- break;
- case X_GetImage:
- {
- MessageStore *messageStore = serverStore_ ->
- getReplyStore(X_GetImage);
-
- if (handleEncodeCached(encodeBuffer, serverCache_, messageStore,
- inputMessage, inputLength))
- {
- priority_++;
-
- hit = 1;
-
- break;
- }
-
- // Depth.
- encodeBuffer.encodeCachedValue(inputMessage[1], 8,
- serverCache_ -> depthCache);
- // Reply length.
- encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 9);
-
- // Visual.
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_), 29,
- serverCache_ -> visualCache);
-
- // Since ProtoStep8 (#issue 108)
- handleCopy(encodeBuffer, requestOpcode, messageStore ->
- dataOffset, inputMessage, inputLength);
-
- priority_++;
- }
- break;
- case X_GetPointerMapping:
- {
- encodeBuffer.encodeValue(inputMessage[1], 8, 4);
- encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 4);
- for (unsigned int i = 32; i < inputLength; i++)
- encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8, 4);
-
- priority_++;
- }
- break;
- case X_GetKeyboardControl:
- {
- encodeBuffer.encodeValue(inputMessage[1], 8, 2);
- encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 8);
- for (unsigned int i = 8; i < inputLength; i++)
- encodeBuffer.encodeValue((unsigned int) inputMessage[i], 8, 4);
-
- priority_++;
- }
- break;
- default:
- {
- #ifdef PANIC
- *logofs << "ServerChannel: PANIC! No matching request with "
- << "OPCODE#" << (unsigned int) requestOpcode
- << " for reply with sequence number "
- << requestSequenceNum << ".\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": No matching request with OPCODE#"
- << (unsigned int) requestOpcode << " for reply with "
- << "sequence number " << requestSequenceNum << ".\n";
-
- return -1;
- }
- }
-
- bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES)
-
- const char *cacheString = (hit ? "cached " : "");
-
- *logofs << "handleRead: Handled " << cacheString << "reply to OPCODE#"
- << (unsigned int) requestOpcode << " (" << DumpOpcode(requestOpcode)
- << ") for FD#" << fd_ << " sequence " << serverSequence_
- << ". " << inputLength << " bytes in, " << bits << " bits ("
- << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush;
-
- #endif
-
- } // End of if (sequenceQueue_.peek(requestSequenceNum, requestOpcode) && ...
- else
- {
- //
- // We didn't push the request opcode.
- // Check if fast encoding is required.
- //
-
- requestOpcode = X_Reply;
-
- if (control -> LocalDeltaCompression == 0)
- {
- int result = handleFastReadReply(encodeBuffer, requestOpcode,
- inputMessage, inputLength);
- if (result < 0)
- {
- return -1;
- }
- else if (result > 0)
- {
- continue;
- }
- }
-
- //
- // Group all replies whose opcode was not
- // pushed in sequence number queue under
- // the category 'generic reply'.
- //
-
- #ifdef DEBUG
- *logofs << "handleRead: Identified generic reply.\n"
- << logofs_flush;
- #endif
-
- MessageStore *messageStore = serverStore_ ->
- getReplyStore(X_NXInternalGenericReply);
-
- hit = handleEncode(encodeBuffer, serverCache_, messageStore,
- requestOpcode, inputMessage, inputLength);
-
- priority_++;
-
- bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES)
-
- const char *cacheString = (hit ? "cached " : "");
-
- *logofs << "handleRead: Handled " << cacheString << "generic reply "
- << "OPCODE#" << X_NXInternalGenericReply << " for FD#" << fd_
- << " sequence " << serverSequence_ << ". " << inputLength
- << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
-
- #endif
- }
-
- if (hit)
- {
- statistics -> addCachedReply(requestOpcode);
- }
-
- statistics -> addReplyBits(requestOpcode, inputLength << 3, bits);
-
- } // End of if (inputMessage[0] == 1) ...
- else
- {
- //
- // Event or error.
- //
-
- unsigned char inputOpcode = *inputMessage;
-
- unsigned int inputSequence = GetUINT(inputMessage + 2, bigEndian_);
-
- //
- // Check if this is an event which we can discard.
- //
-
- if ((inputOpcode == Expose && enableExpose_ == 0) ||
- (inputOpcode == GraphicsExpose && enableGraphicsExpose_ == 0) ||
- (inputOpcode == NoExpose && enableNoExpose_ == 0))
- {
- continue;
- }
- else if (shmemState_ != NULL && shmemState_ -> enabled == 1 &&
- inputOpcode == shmemState_ -> event &&
- checkShmemEvent(inputOpcode, inputSequence,
- inputMessage) > 0)
- {
- continue;
- }
- else if (inputOpcode == MotionNotify)
- {
- //
- // Save the motion event and send when another
- // event or error is received or the motion ti-
- // meout is elapsed. If a previous motion event
- // was already saved, we replace it with the
- // new one and don't reset the timeout, so we
- // still have a motion event every given ms.
- //
-
- memcpy(lastMotion_, inputMessage, 32);
-
- #ifdef TEST
- *logofs << "handleRead: Saved suppressed motion event for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- continue;
- }
- else if (inputOpcode == X_Error)
- {
- //
- // Check if this is an error that matches a
- // sequence number for which we are expecting
- // a reply.
- //
-
- unsigned short int errorSequenceNum;
- unsigned char errorOpcode;
-
- if (sequenceQueue_.peek(errorSequenceNum, errorOpcode) &&
- ((unsigned int) errorSequenceNum == inputSequence))
- {
- sequenceQueue_.pop(errorSequenceNum, errorOpcode);
- }
-
- //
- // Check if error is due to an image commit
- // generated at the end of a split.
- //
-
- if (checkCommitError(*(inputMessage + 1), inputSequence, inputMessage) > 0)
- {
- #ifdef TEST
- *logofs << "handleRead: Skipping error on image commit for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- continue;
- }
-
- //
- // Check if it's an error generated by a request
- // concerning shared memory support.
- //
-
- else if (shmemState_ != NULL && (shmemState_ -> sequence ==
- inputSequence || (shmemState_ -> enabled == 1 &&
- (shmemState_ -> opcode == *(inputMessage + 10) ||
- shmemState_ -> error == *(inputMessage + 1)))) &&
- checkShmemError(*(inputMessage + 1), inputSequence,
- inputMessage) > 0)
- {
- #ifdef TEST
- *logofs << "handleRead: Skipping error on shmem operation for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- continue;
- }
- }
- //
- // Check if user pressed the CTRL+ALT+SHIFT+ESC key
- // sequence because was unable to kill the session
- // through the normal procedure.
- //
-
- if (inputOpcode == KeyPress)
- {
- if (checkKeyboardEvent(inputOpcode, inputSequence, inputMessage) == 1)
- {
- #ifdef TEST
- *logofs << "handleRead: Removing the key sequence from the "
- << "event stream for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- continue;
- }
- }
-
- //
- // We are going to handle an event or error
- // that's not a mouse motion. Prepend any
- // saved motion to it.
- //
-
- if (lastMotion_[0] != '\0')
- {
- if (handleMotion(encodeBuffer) < 0)
- {
- #ifdef PANIC
- *logofs << "handleRead: PANIC! Can't encode motion event for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't encode motion event for FD#"
- << fd_ << ".\n";
-
- return -1;
- }
- }
-
- //
- // Encode opcode and difference between
- // current sequence and the last one.
- //
-
- encodeBuffer.encodeOpcodeValue(inputOpcode, serverCache_ -> opcodeCache);
-
- unsigned int sequenceDiff = inputSequence - serverSequence_;
-
- serverSequence_ = inputSequence;
-
- #ifdef DEBUG
- *logofs << "handleRead: Last server sequence number for FD#"
- << fd_ << " is " << serverSequence_ << " with "
- << "difference " << sequenceDiff << ".\n"
- << logofs_flush;
- #endif
-
- encodeBuffer.encodeCachedValue(sequenceDiff, 16,
- serverCache_ -> eventSequenceCache, 7);
-
- //
- // If differential compression is disabled
- // then use the most simple encoding.
- //
-
- if (control -> LocalDeltaCompression == 0)
- {
- int result = handleFastReadEvent(encodeBuffer, inputOpcode,
- inputMessage, inputLength);
- if (result < 0)
- {
- return -1;
- }
- else if (result > 0)
- {
- continue;
- }
- }
-
- switch (inputOpcode)
- {
- case X_Error:
- {
- //
- // Set the priority flag in the case of
- // a X protocol error. This may restart
- // the client if it was waiting for the
- // reply.
- //
-
- priority_++;
-
- unsigned char errorCode = *(inputMessage + 1);
-
- encodeBuffer.encodeCachedValue(errorCode, 8,
- serverCache_ -> errorCodeCache);
-
- if (errorCode != 11 && errorCode != 8 &&
- errorCode != 15 && errorCode != 1)
- {
- encodeBuffer.encodeValue(GetULONG(inputMessage + 4, bigEndian_), 32, 16);
- }
-
- if (errorCode >= 18)
- {
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16,
- serverCache_ -> errorMinorCache);
- }
-
- encodeBuffer.encodeCachedValue(inputMessage[10], 8,
- serverCache_ -> errorMajorCache);
-
- if (errorCode >= 18)
- {
- const unsigned char *nextSrc = inputMessage + 11;
- for (unsigned int i = 11; i < 32; i++)
- encodeBuffer.encodeValue(*nextSrc++, 8);
- }
- }
- break;
- case ButtonPress:
- case ButtonRelease:
- case KeyPress:
- case KeyRelease:
- case MotionNotify:
- case EnterNotify:
- case LeaveNotify:
- {
- //
- // Set the priority in the case this is
- // an event that the remote side may
- // care to receive as soon as possible.
- //
-
- switch (inputOpcode)
- {
- case ButtonPress:
- case ButtonRelease:
- case KeyPress:
- case KeyRelease:
- {
- priority_++;
- }
- }
-
- unsigned char detail = inputMessage[1];
- if (*inputMessage == MotionNotify)
- encodeBuffer.encodeBoolValue((unsigned int) detail);
- else if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify))
- encodeBuffer.encodeValue((unsigned int) detail, 3);
- else if (*inputMessage == KeyRelease)
- {
- if (detail == serverCache_ -> keyPressLastKey)
- encodeBuffer.encodeBoolValue(1);
- else
- {
- encodeBuffer.encodeBoolValue(0);
- encodeBuffer.encodeValue((unsigned int) detail, 8);
- }
- }
- else if ((*inputMessage == ButtonPress) || (*inputMessage == ButtonRelease))
- encodeBuffer.encodeCachedValue(detail, 8,
- serverCache_ -> buttonCache);
- else
- encodeBuffer.encodeValue((unsigned int) detail, 8);
- unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_);
- unsigned int timestampDiff =
- timestamp - serverCache_ -> lastTimestamp;
- serverCache_ -> lastTimestamp = timestamp;
- encodeBuffer.encodeCachedValue(timestampDiff, 32,
- serverCache_ -> motionNotifyTimestampCache, 9);
- int skipRest = 0;
- if (*inputMessage == KeyRelease)
- {
- skipRest = 1;
- for (unsigned int i = 8; i < 31; i++)
- {
- if (inputMessage[i] != serverCache_ -> keyPressCache[i - 8])
- {
- skipRest = 0;
- break;
- }
- }
- encodeBuffer.encodeBoolValue(skipRest);
- }
-
- if (!skipRest)
- {
- const unsigned char *nextSrc = inputMessage + 8;
- for (unsigned int i = 0; i < 3; i++)
- {
- encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29,
- *serverCache_ -> motionNotifyWindowCache[i], 6);
- nextSrc += 4;
- }
- unsigned int rootX = GetUINT(inputMessage + 20, bigEndian_);
- unsigned int rootY = GetUINT(inputMessage + 22, bigEndian_);
- unsigned int eventX = GetUINT(inputMessage + 24, bigEndian_);
- unsigned int eventY = GetUINT(inputMessage + 26, bigEndian_);
- eventX -= rootX;
- eventY -= rootY;
- encodeBuffer.encodeCachedValue(rootX -
- serverCache_ -> motionNotifyLastRootX, 16,
- serverCache_ -> motionNotifyRootXCache, 6);
- serverCache_ -> motionNotifyLastRootX = rootX;
- encodeBuffer.encodeCachedValue(rootY -
- serverCache_ -> motionNotifyLastRootY, 16,
- serverCache_ -> motionNotifyRootYCache, 6);
- serverCache_ -> motionNotifyLastRootY = rootY;
- encodeBuffer.encodeCachedValue(eventX, 16,
- serverCache_ -> motionNotifyEventXCache, 6);
- encodeBuffer.encodeCachedValue(eventY, 16,
- serverCache_ -> motionNotifyEventYCache, 6);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 28, bigEndian_),
- 16, serverCache_ -> motionNotifyStateCache);
- if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify))
- encodeBuffer.encodeValue((unsigned int) inputMessage[30], 2);
- else
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[30]);
- if ((*inputMessage == EnterNotify) || (*inputMessage == LeaveNotify))
- encodeBuffer.encodeValue((unsigned int) inputMessage[31], 2);
- else if (*inputMessage == KeyPress)
- {
- serverCache_ -> keyPressLastKey = detail;
- for (unsigned int i = 8; i < 31; i++)
- {
- serverCache_ -> keyPressCache[i - 8] = inputMessage[i];
- }
- }
- }
- }
- break;
- case ColormapNotify:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> colormapNotifyWindowCache, 8);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> colormapNotifyColormapCache, 8);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[13]);
- }
- break;
- case ConfigureNotify:
- {
- const unsigned char *nextSrc = inputMessage + 4;
- for (unsigned int i = 0; i < 3; i++)
- {
- encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29,
- *serverCache_ -> configureNotifyWindowCache[i], 9);
- nextSrc += 4;
- }
- for (unsigned int j = 0; j < 5; j++)
- {
- encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16,
- *serverCache_ -> configureNotifyGeomCache[j], 8);
- nextSrc += 2;
- }
- encodeBuffer.encodeBoolValue(*nextSrc);
- }
- break;
- case CreateNotify:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> createNotifyWindowCache, 9);
- unsigned int window = GetULONG(inputMessage + 8, bigEndian_);
- encodeBuffer.encodeValue(window -
- serverCache_ -> createNotifyLastWindow, 29, 5);
- serverCache_ -> createNotifyLastWindow = window;
- const unsigned char* nextSrc = inputMessage + 12;
- for (unsigned int i = 0; i < 5; i++)
- {
- encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16, 9);
- nextSrc += 2;
- }
- encodeBuffer.encodeBoolValue(*nextSrc);
- }
- break;
- case Expose:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_), 29,
- serverCache_ -> exposeWindowCache, 9);
- const unsigned char *nextSrc = inputMessage + 8;
- for (unsigned int i = 0; i < 5; i++)
- {
- encodeBuffer.encodeCachedValue(GetUINT(nextSrc, bigEndian_), 16,
- *serverCache_ -> exposeGeomCache[i], 6);
- nextSrc += 2;
- }
- }
- break;
- case FocusIn:
- case FocusOut:
- {
- encodeBuffer.encodeValue((unsigned int) inputMessage[1], 3);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> focusInWindowCache, 9);
- encodeBuffer.encodeValue((unsigned int) inputMessage[8], 2);
- }
- break;
- case KeymapNotify:
- {
- if (ServerCache::lastKeymap.compare(31, inputMessage + 1))
- encodeBuffer.encodeBoolValue(1);
- else
- {
- encodeBuffer.encodeBoolValue(0);
- const unsigned char *nextSrc = inputMessage + 1;
- for (unsigned int i = 1; i < 32; i++)
- encodeBuffer.encodeValue((unsigned int) *nextSrc++, 8);
- }
- }
- break;
- case MapNotify:
- case UnmapNotify:
- case DestroyNotify:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> mapNotifyEventCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> mapNotifyWindowCache, 9);
- if ((*inputMessage == MapNotify) || (*inputMessage == UnmapNotify))
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[12]);
- }
- break;
- case NoExpose:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> noExposeDrawableCache, 9);
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + 8, bigEndian_), 16,
- serverCache_ -> noExposeMinorCache);
- encodeBuffer.encodeCachedValue(inputMessage[10], 8,
- serverCache_ -> noExposeMajorCache);
- }
- break;
- case PropertyNotify:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> propertyNotifyWindowCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> propertyNotifyAtomCache, 9);
- unsigned int timestamp = GetULONG(inputMessage + 12, bigEndian_);
- unsigned int timestampDiff =
- timestamp - serverCache_ -> lastTimestamp;
- serverCache_ -> lastTimestamp = timestamp;
- encodeBuffer.encodeValue(timestampDiff, 32, 9);
- encodeBuffer.encodeBoolValue((unsigned int) inputMessage[16]);
- }
- break;
- case ReparentNotify:
- {
- const unsigned char* nextSrc = inputMessage + 4;
- for (unsigned int i = 0; i < 3; i++)
- {
- encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_),
- 29, serverCache_ -> reparentNotifyWindowCache, 9);
- nextSrc += 4;
- }
- encodeBuffer.encodeValue(GetUINT(nextSrc, bigEndian_), 16, 6);
- encodeBuffer.encodeValue(GetUINT(nextSrc + 2, bigEndian_), 16, 6);
- encodeBuffer.encodeBoolValue((unsigned int)inputMessage[20]);
- }
- break;
- case SelectionClear:
- {
- unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_);
- unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp;
- serverCache_ -> lastTimestamp = timestamp;
- encodeBuffer.encodeValue(timestampDiff, 32, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> selectionClearWindowCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_),
- 29, serverCache_ -> selectionClearAtomCache, 9);
- }
- break;
- case SelectionRequest:
- {
- unsigned int timestamp = GetULONG(inputMessage + 4, bigEndian_);
- unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp;
- serverCache_ -> lastTimestamp = timestamp;
- encodeBuffer.encodeValue(timestampDiff, 32, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 8, bigEndian_),
- 29, serverCache_ -> selectionClearWindowCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 12, bigEndian_),
- 29, serverCache_ -> selectionClearWindowCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 16, bigEndian_),
- 29, serverCache_ -> selectionClearAtomCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 20, bigEndian_),
- 29, serverCache_ -> selectionClearAtomCache, 9);
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 24, bigEndian_),
- 29, serverCache_ -> selectionClearAtomCache, 9);
- }
- break;
- case VisibilityNotify:
- {
- encodeBuffer.encodeCachedValue(GetULONG(inputMessage + 4, bigEndian_),
- 29, serverCache_ -> visibilityNotifyWindowCache, 9);
- encodeBuffer.encodeValue((unsigned int) inputMessage[8], 2);
- }
- break;
- default:
- {
- #ifdef TEST
- *logofs << "handleRead: Using generic event compression "
- << "for OPCODE#" << (unsigned int) inputOpcode
- << ".\n" << logofs_flush;
- #endif
-
- encodeBuffer.encodeCachedValue(*(inputMessage + 1), 8,
- serverCache_ -> genericEventCharCache);
-
- for (unsigned int i = 0; i < 14; i++)
- {
- encodeBuffer.encodeCachedValue(GetUINT(inputMessage + i * 2 + 4, bigEndian_),
- 16, *serverCache_ -> genericEventIntCache[i]);
- }
- }
-
- } // switch (inputOpcode)...
-
- int bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES)
-
- if (*inputMessage == X_Error)
- {
- unsigned char code = *(inputMessage + 1);
-
- *logofs << "handleRead: Handled error ERR_CODE#"
- << (unsigned int) code << " for FD#" << fd_;
-
- *logofs << " RES_ID#" << GetULONG(inputMessage + 4, bigEndian_);
-
- *logofs << " MIN_OP#" << GetUINT(inputMessage + 8, bigEndian_);
-
- *logofs << " MAJ_OP#" << (unsigned int) *(inputMessage + 10);
-
- *logofs << " sequence " << inputSequence << ". " << inputLength
- << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
- }
- else
- {
- *logofs << "handleRead: Handled event OPCODE#"
- << (unsigned int) *inputMessage << " for FD#" << fd_
- << " sequence " << inputSequence << ". " << inputLength
- << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
- }
-
- #endif
-
- statistics -> addEventBits(*inputMessage, inputLength << 3, bits);
-
- } // End of if (inputMessage[0] == X_Reply) ... else ...
-
- } // End of if (firstReply_) ... else ...
-
- } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != 0) ...
-
- //
- // Check if we need to flush because of
- // prioritized data.
- //
-
- if (priority_ > 0)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleRead: WARNING! Requesting flush "
- << "because of " << priority_ << " prioritized "
- << "messages for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- if (proxy -> handleAsyncPriority() < 0)
- {
- return -1;
- }
-
- //
- // Reset the priority flag.
- //
-
- priority_ = 0;
- }
-
- //
- // Flush if we produced enough data.
- //
-
- if (proxy -> canAsyncFlush() == 1)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleRead: WARNING! Requesting flush "
- << "because of token length exceeded.\n"
- << logofs_flush;
- #endif
-
- if (proxy -> handleAsyncFlush() < 0)
- {
- return -1;
- }
- }
-
- #if defined(TEST) || defined(INFO)
-
- if (transport_ -> pending() != 0 ||
- readBuffer_.checkMessage() != 0)
- {
- *logofs << "handleRead: PANIC! Buffer for X descriptor FD#"
- << fd_ << " has " << transport_ -> pending()
- << " bytes to read.\n" << logofs_flush;
-
- HandleCleanup();
- }
-
- #endif
-
- //
- // Reset the read buffer.
- //
-
- readBuffer_.fullReset();
-
- return 1;
-}
-
-//
-// End of handleRead().
-//
-
-//
-// Beginning of handleWrite().
-//
-
-int ServerChannel::handleWrite(const unsigned char *message, unsigned int length)
-{
- #ifdef TEST
- *logofs << "handleWrite: Called for FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- //
- // Create the buffer from which to
- // decode messages.
- //
-
- DecodeBuffer decodeBuffer(message, length);
-
- #if defined(TEST) || defined(INFO) || defined(FLUSH)
- *logofs << "handleWrite: Decoding messages for FD#" << fd_
- << " with " << length << " bytes in the buffer.\n"
- << logofs_flush;
- #endif
-
- if (firstRequest_)
- {
- //
- // Need to add the length of the first request
- // because it was not present in the previous
- // versions. Length of the first request was
- // assumed to be the same as the encode buffer
- // but this may be not the case if a different
- // encoding is used.
- //
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeValue(length, 8);
-
- unsigned int nextByte;
- unsigned char *outputMessage = writeBuffer_.addMessage(length);
- unsigned char *nextDest = outputMessage;
-
- for (unsigned int i = 0; i < length; i++)
- {
- decodeBuffer.decodeValue(nextByte, 8);
-
- *nextDest++ = (unsigned char) nextByte;
- }
-
- if (*outputMessage == 0x42)
- {
- setBigEndian(1);
- }
- else
- {
- setBigEndian(0);
- }
-
- #ifdef TEST
- *logofs << "handleWrite: First request detected.\n" << logofs_flush;
- #endif
-
- //
- // Handle the fake authorization cookie.
- //
-
- if (handleAuthorization(outputMessage) < 0)
- {
- return -1;
- }
-
- firstRequest_ = 0;
-
- } // End of if (firstRequest_)
-
- //
- // This was previously in a 'else' block.
- // Due to the way the first request was
- // handled, we could not decode multiple
- // messages in the first frame.
- //
-
- { // Start of the decoding block.
-
- unsigned char outputOpcode;
-
- unsigned char *outputMessage;
- unsigned int outputLength;
-
- //
- // Set when message is found in cache.
- //
-
- int hit;
-
- while (decodeBuffer.decodeOpcodeValue(outputOpcode, clientCache_ -> opcodeCache, 1))
- {
- hit = 0;
-
- //
- // Splits are sent by client proxy outside the
- // normal read loop. As we 'insert' splits in
- // the real client-server X protocol, we must
- // avoid to increment the sequence number or
- // our clients would get confused.
- //
-
- if (outputOpcode != opcodeStore_ -> splitData)
- {
- clientSequence_++;
- clientSequence_ &= 0xffff;
-
- #ifdef DEBUG
- *logofs << "handleWrite: Last client sequence number for FD#"
- << fd_ << " is " << clientSequence_ << ".\n"
- << logofs_flush;
- #endif
- }
- else
- {
- //
- // It's a split, not a normal
- // burst of proxy data.
- //
-
- handleSplit(decodeBuffer);
-
- continue;
- }
-
- #ifdef SUSPEND
-
- if (clientSequence_ == 1000)
- {
- cerr << "Warning" << ": Exiting to test the resilience of the agent.\n";
-
- sleep(2);
-
- HandleAbort();
- }
-
- #endif
-
- //
- // Is differential encoding disabled?
- //
-
- if (control -> RemoteDeltaCompression == 0)
- {
- int result = handleFastWriteRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength);
- if (result < 0)
- {
- return -1;
- }
- else if (result > 0)
- {
- continue;
- }
- }
-
- //
- // General-purpose temp variables for
- // decoding ints and chars.
- //
-
- unsigned int value;
- unsigned char cValue;
-
- #ifdef DEBUG
- *logofs << "handleWrite: Going to handle request OPCODE#"
- << (unsigned int) outputOpcode << " (" << DumpOpcode(outputOpcode)
- << ") for FD#" << fd_ << " sequence " << clientSequence_
- << ".\n" << logofs_flush;
- #endif
-
- switch (outputOpcode)
- {
- case X_AllocColor:
- {
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> colormapCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned char *nextDest = outputMessage + 8;
- unsigned int colorData[3];
-
- for (unsigned int i = 0; i < 3; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *(clientCache_ -> allocColorRGBCache[i]), 4);
- PutUINT(value, nextDest, bigEndian_);
- colorData[i] = value;
- nextDest += 2;
- }
-
- sequenceQueue_.push(clientSequence_, outputOpcode,
- colorData[0], colorData[1], colorData[2]);
- }
- break;
- case X_ReparentWindow:
- {
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeValue(value, 16, 11);
- PutUINT(value, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeValue(value, 16, 11);
- PutUINT(value, outputMessage + 14, bigEndian_);
- }
- break;
- case X_ChangeProperty:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_ChangeProperty);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned char format;
- decodeBuffer.decodeCachedValue(format, 8,
- clientCache_ -> changePropertyFormatCache);
- unsigned int dataLength;
- decodeBuffer.decodeValue(dataLength, 32, 6);
- outputLength = 24 + RoundUp4(dataLength * (format >> 3));
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 2);
- outputMessage[1] = (unsigned char) value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> changePropertyPropertyCache, 9);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> changePropertyTypeCache, 9);
- PutULONG(value, outputMessage + 12, bigEndian_);
- outputMessage[16] = format;
- PutULONG(dataLength, outputMessage + 20, bigEndian_);
- unsigned char *nextDest = outputMessage + 24;
-
- if (format == 8)
- {
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, dataLength);
- }
- else if (format == 32)
- {
- for (unsigned int i = 0; i < dataLength; i++)
- {
- decodeBuffer.decodeCachedValue(value, 32,
- clientCache_ -> changePropertyData32Cache);
-
- PutULONG(value, nextDest, bigEndian_);
-
- nextDest += 4;
- }
- }
- else
- {
- for (unsigned int i = 0; i < dataLength; i++)
- {
- decodeBuffer.decodeValue(value, 16);
-
- PutUINT(value, nextDest, bigEndian_);
-
- nextDest += 2;
- }
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_SendEvent:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_SendEvent);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 44;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeBoolValue(value);
- *(outputMessage + 1) = value;
- decodeBuffer.decodeBoolValue(value);
- if (value)
- {
- decodeBuffer.decodeBoolValue(value);
- }
- else
- {
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- }
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 32,
- clientCache_ -> sendEventMaskCache, 9);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(*(outputMessage + 12), 8,
- clientCache_ -> sendEventCodeCache);
- decodeBuffer.decodeCachedValue(*(outputMessage + 13), 8,
- clientCache_ -> sendEventByteDataCache);
- decodeBuffer.decodeValue(value, 16, 4);
- clientCache_ -> sendEventLastSequence += value;
- clientCache_ -> sendEventLastSequence &= 0xffff;
- PutUINT(clientCache_ -> sendEventLastSequence, outputMessage + 14, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 32,
- clientCache_ -> sendEventIntDataCache);
- PutULONG(value, outputMessage + 16, bigEndian_);
-
- for (unsigned int i = 20; i < 44; i++)
- {
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> sendEventEventCache);
- *(outputMessage + i) = cValue;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_ChangeWindowAttributes:
- {
- unsigned int numAttrs;
- decodeBuffer.decodeValue(numAttrs, 4);
- outputLength = 12 + (numAttrs << 2);
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned int bitmask;
- decodeBuffer.decodeCachedValue(bitmask, 15,
- clientCache_ -> createWindowBitmaskCache);
- PutULONG(bitmask, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
- unsigned int mask = 0x1;
- for (unsigned int i = 0; i < 15; i++)
- {
- if (bitmask & mask)
- {
- decodeBuffer.decodeCachedValue(value, 32,
- *clientCache_ -> createWindowAttrCache[i]);
- PutULONG(value, nextDest, bigEndian_);
- nextDest += 4;
- }
- mask <<= 1;
- }
- }
- break;
- case X_ClearArea:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_ClearArea);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[1] = (unsigned char) value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned char *nextDest = outputMessage + 8;
- for (unsigned int i = 0; i < 4; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> clearAreaGeomCache[i], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_CloseFont:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 29, 5);
- clientCache_ -> lastFont += value;
- clientCache_ -> lastFont &= 0x1fffffff;
- PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_);
- }
- break;
- case X_ConfigureWindow:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_ConfigureWindow);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned int bitmask;
- decodeBuffer.decodeCachedValue(bitmask, 7,
- clientCache_ -> configureWindowBitmaskCache);
- PutUINT(bitmask, outputMessage + 8, bigEndian_);
- unsigned int mask = 0x1;
- for (unsigned int i = 0; i < 7; i++)
- {
- if (bitmask & mask)
- {
- unsigned char* nextDest = writeBuffer_.addMessage(4);
- outputLength += 4;
- decodeBuffer.decodeCachedValue(value, CONFIGUREWINDOW_FIELD_WIDTH[i],
- *clientCache_ -> configureWindowAttrCache[i], 8);
- PutULONG(value, nextDest, bigEndian_);
- nextDest += 4;
- }
- mask <<= 1;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_ConvertSelection:
- {
- outputLength = 24;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> convertSelectionRequestorCache, 9);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned char* nextDest = outputMessage + 8;
- for (unsigned int i = 0; i < 3; i++)
- {
- decodeBuffer.decodeCachedValue(value, 29,
- *(clientCache_ -> convertSelectionAtomCache[i]), 9);
- PutULONG(value, nextDest, bigEndian_);
- nextDest += 4;
- }
- decodeBuffer.decodeValue(value, 32, 4);
- clientCache_ -> convertSelectionLastTimestamp += value;
- PutULONG(clientCache_ -> convertSelectionLastTimestamp,
- nextDest, bigEndian_);
- }
- break;
- case X_CopyArea:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_CopyArea);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 28;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 12, bigEndian_);
- unsigned char *nextDest = outputMessage + 16;
- for (unsigned int i = 0; i < 6; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> copyAreaGeomCache[i], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_CopyGC:
- {
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 23,
- clientCache_ -> createGCBitmaskCache);
- PutULONG(value, outputMessage + 12, bigEndian_);
- }
- break;
- case X_CopyPlane:
- {
- outputLength = 32;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 12, bigEndian_);
- unsigned char *nextDest = outputMessage + 16;
- for (unsigned int i = 0; i < 6; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> copyPlaneGeomCache[i], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
- decodeBuffer.decodeCachedValue(value, 32,
- clientCache_ -> copyPlaneBitPlaneCache, 10);
- PutULONG(value, outputMessage + 28, bigEndian_);
- }
- break;
- case X_CreateGC:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_CreateGC);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeNewXidValue(value, clientCache_ -> lastId,
- clientCache_ -> lastIdCache, clientCache_ -> gcCache,
- clientCache_ -> freeGCCache);
-
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned int offset = 8;
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + offset, bigEndian_);
- offset += 4;
- unsigned int bitmask;
- decodeBuffer.decodeCachedValue(bitmask, 23,
- clientCache_ -> createGCBitmaskCache);
- PutULONG(bitmask, outputMessage + offset, bigEndian_);
- unsigned int mask = 0x1;
- for (unsigned int i = 0; i < 23; i++)
- {
- if (bitmask & mask)
- {
- unsigned char* nextDest = writeBuffer_.addMessage(4);
- outputLength += 4;
- unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i];
- if (fieldWidth <= 4)
- decodeBuffer.decodeValue(value, fieldWidth);
- else
- decodeBuffer.decodeCachedValue(value, fieldWidth,
- *clientCache_ -> createGCAttrCache[i]);
- PutULONG(value, nextDest, bigEndian_);
- }
- mask <<= 1;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_ChangeGC:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_ChangeGC);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned int offset = 8;
- unsigned int bitmask;
- decodeBuffer.decodeCachedValue(bitmask, 23,
- clientCache_ -> createGCBitmaskCache);
- PutULONG(bitmask, outputMessage + offset, bigEndian_);
- unsigned int mask = 0x1;
- for (unsigned int i = 0; i < 23; i++)
- {
- if (bitmask & mask)
- {
- unsigned char* nextDest = writeBuffer_.addMessage(4);
- outputLength += 4;
- unsigned int fieldWidth = CREATEGC_FIELD_WIDTH[i];
- if (fieldWidth <= 4)
- decodeBuffer.decodeValue(value, fieldWidth);
- else
- decodeBuffer.decodeCachedValue(value, fieldWidth,
- *clientCache_ -> createGCAttrCache[i]);
- PutULONG(value, nextDest, bigEndian_);
- }
- mask <<= 1;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_CreatePixmap:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_CreatePixmap);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
- }
- break;
- case X_CreateWindow:
- {
- outputLength = 32;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
- decodeBuffer.decodeCachedValue(cValue, 8, clientCache_ -> depthCache);
- outputMessage[1] = cValue;
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeNewXidValue(value, clientCache_ -> lastId,
- clientCache_ -> lastIdCache, clientCache_ -> windowCache,
- clientCache_ -> freeWindowCache);
-
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
- unsigned int i;
- for (i = 0; i < 6; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> createWindowGeomCache[i], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
- decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> visualCache);
- PutULONG(value, outputMessage + 24, bigEndian_);
- unsigned int bitmask;
- decodeBuffer.decodeCachedValue(bitmask, 15,
- clientCache_ -> createWindowBitmaskCache);
- PutULONG(bitmask, outputMessage + 28, bigEndian_);
- unsigned int mask = 0x1;
- for (i = 0; i < 15; i++)
- {
- if (bitmask & mask)
- {
- nextDest = writeBuffer_.addMessage(4);
- outputLength += 4;
- decodeBuffer.decodeCachedValue(value, 32,
- *clientCache_ -> createWindowAttrCache[i]);
- PutULONG(value, nextDest, bigEndian_);
- }
- mask <<= 1;
- }
- writeBuffer_.unregisterPointer();
- }
- break;
- case X_DeleteProperty:
- {
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeValue(value, 29, 9);
- PutULONG(value, outputMessage + 8, bigEndian_);
- }
- break;
- case X_FillPoly:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_FillPoly);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int numPoints;
-
- // Since ProtoStep10 (#issue 108)
- decodeBuffer.decodeCachedValue(numPoints, 16,
- clientCache_ -> fillPolyNumPointsCache, 4);
-
- outputLength = 16 + (numPoints << 2);
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeValue(value, 2);
- outputMessage[12] = (unsigned char) value;
- unsigned int relativeCoordMode;
- decodeBuffer.decodeBoolValue(relativeCoordMode);
- outputMessage[13] = (unsigned char) relativeCoordMode;
- unsigned char *nextDest = outputMessage + 16;
- unsigned int pointIndex = 0;
- for (unsigned int i = 0; i < numPoints; i++)
- {
- if (relativeCoordMode)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> fillPolyXRelCache[pointIndex], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> fillPolyYRelCache[pointIndex], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
- else
- {
- unsigned int x, y;
- decodeBuffer.decodeBoolValue(value);
- if (value)
- {
- decodeBuffer.decodeValue(value, 3);
- x = clientCache_ -> fillPolyRecentX[value];
- y = clientCache_ -> fillPolyRecentY[value];
- }
- else
- {
- decodeBuffer.decodeCachedValue(x, 16,
- *clientCache_ -> fillPolyXAbsCache[pointIndex], 8);
- decodeBuffer.decodeCachedValue(y, 16,
- *clientCache_ -> fillPolyYAbsCache[pointIndex], 8);
- clientCache_ -> fillPolyRecentX[clientCache_ -> fillPolyIndex] = x;
- clientCache_ -> fillPolyRecentY[clientCache_ -> fillPolyIndex] = y;
- clientCache_ -> fillPolyIndex++;
- if (clientCache_ -> fillPolyIndex == 8)
- clientCache_ -> fillPolyIndex = 0;
- }
- PutUINT(x, nextDest, bigEndian_);
- nextDest += 2;
- PutUINT(y, nextDest, bigEndian_);
- nextDest += 2;
- }
-
- if (++pointIndex == 10) pointIndex = 0;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_FreeColors:
- {
- unsigned int numPixels;
- decodeBuffer.decodeValue(numPixels, 16, 4);
- outputLength = 12 + (numPixels << 2);
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> colormapCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeValue(value, 32, 4);
- PutULONG(value, outputMessage + 8, bigEndian_);
- unsigned char* nextDest = outputMessage + 12;
- while (numPixels)
- {
- decodeBuffer.decodeValue(value, 32, 8);
- PutULONG(value, nextDest, bigEndian_);
- nextDest += 4;
- numPixels--;
- }
- }
- break;
- case X_FreeCursor:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> cursorCache, 9);
- PutULONG(value, outputMessage + 4, bigEndian_);
- }
- break;
- case X_FreeGC:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeGCCache);
-
- PutULONG(value, outputMessage + 4, bigEndian_);
- }
- break;
- case X_FreePixmap:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeDrawableCache);
-
- PutULONG(value, outputMessage + 4, bigEndian_);
- }
- break;
- case X_GetAtomName:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 29, 9);
- PutULONG(value, outputMessage + 4, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GetGeometry:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GetInputFocus:
- {
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode, outputOpcode);
- }
- break;
- case X_GetModifierMapping:
- {
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GetKeyboardMapping:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 8);
- outputMessage[4] = value;
- decodeBuffer.decodeValue(value, 8);
- outputMessage[5] = value;
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GetProperty:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_GetProperty);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- //
- // Save a reference to identify the reply.
- //
-
- unsigned int property = GetULONG(outputMessage + 8, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode, property);
-
- break;
- }
-
- outputLength = 24;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[1] = (unsigned char) value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned int property;
- decodeBuffer.decodeValue(property, 29, 9);
- PutULONG(property, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeValue(value, 29, 9);
- PutULONG(value, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeValue(value, 32, 2);
- PutULONG(value, outputMessage + 16, bigEndian_);
- decodeBuffer.decodeValue(value, 32, 8);
- PutULONG(value, outputMessage + 20, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode, property);
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_GetSelectionOwner:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> getSelectionOwnerSelectionCache, 9);
- PutULONG(value, outputMessage + 4, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GrabButton:
- case X_GrabPointer:
- {
- outputLength = 24;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[1] = (unsigned char) value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> grabButtonEventMaskCache);
- PutUINT(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[10] = (unsigned char) value;
- decodeBuffer.decodeBoolValue(value);
- outputMessage[11] = (unsigned char) value;
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> grabButtonConfineCache, 9);
- PutULONG(value, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> cursorCache, 9);
- PutULONG(value, outputMessage + 16, bigEndian_);
- if (outputOpcode == X_GrabButton)
- {
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> grabButtonButtonCache);
- outputMessage[20] = cValue;
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> grabButtonModifierCache);
- PutUINT(value, outputMessage + 22, bigEndian_);
- }
- else
- {
- decodeBuffer.decodeValue(value, 32, 4);
- clientCache_ -> grabKeyboardLastTimestamp += value;
- PutULONG(clientCache_ -> grabKeyboardLastTimestamp,
- outputMessage + 20, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- }
- break;
- case X_GrabKeyboard:
- {
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[1] = (unsigned char) value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeValue(value, 32, 4);
- clientCache_ -> grabKeyboardLastTimestamp += value;
- PutULONG(clientCache_ -> grabKeyboardLastTimestamp, outputMessage + 8,
- bigEndian_);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[12] = (unsigned char) value;
- decodeBuffer.decodeBoolValue(value);
- outputMessage[13] = (unsigned char) value;
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GrabServer:
- case X_UngrabServer:
- case X_NoOperation:
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Managing (probably tainted) X_NoOperation request for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
- }
- break;
- case X_PolyText8:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyText8);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> polyTextCacheX);
- clientCache_ -> polyTextLastX += value;
- clientCache_ -> polyTextLastX &= 0xffff;
- PutUINT(clientCache_ -> polyTextLastX, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> polyTextCacheY);
- clientCache_ -> polyTextLastY += value;
- clientCache_ -> polyTextLastY &= 0xffff;
- PutUINT(clientCache_ -> polyTextLastY, outputMessage + 14, bigEndian_);
- unsigned int addedLength = 0;
- writeBuffer_.registerPointer(&outputMessage);
- for (;;)
- {
- decodeBuffer.decodeBoolValue(value);
- if (!value)
- break;
- unsigned int textLength;
- decodeBuffer.decodeValue(textLength, 8);
- if (textLength == 255)
- {
- addedLength += 5;
- unsigned char *nextSegment = writeBuffer_.addMessage(5);
- *nextSegment = (unsigned char) textLength;
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> polyTextFontCache);
- PutULONG(value, nextSegment + 1, 1);
- }
- else
- {
- addedLength += (textLength + 2);
- unsigned char *nextSegment =
- writeBuffer_.addMessage(textLength + 2);
- *nextSegment = (unsigned char) textLength;
- unsigned char *nextDest = nextSegment + 1;
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> polyTextDeltaCache);
- *nextDest++ = cValue;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, textLength);
-
- nextDest += textLength;
- }
- }
- outputLength += addedLength;
- unsigned int mod4 = (addedLength & 0x3);
- if (mod4)
- {
- unsigned int extra = 4 - mod4;
- unsigned char *nextDest = writeBuffer_.addMessage(extra);
- for (unsigned int i = 0; i < extra; i++)
- *nextDest++ = 0;
- outputLength += extra;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PolyText16:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyText16);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> polyTextCacheX);
- clientCache_ -> polyTextLastX += value;
- clientCache_ -> polyTextLastX &= 0xffff;
- PutUINT(clientCache_ -> polyTextLastX, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> polyTextCacheY);
- clientCache_ -> polyTextLastY += value;
- clientCache_ -> polyTextLastY &= 0xffff;
- PutUINT(clientCache_ -> polyTextLastY, outputMessage + 14, bigEndian_);
- unsigned int addedLength = 0;
- writeBuffer_.registerPointer(&outputMessage);
- for (;;)
- {
- decodeBuffer.decodeBoolValue(value);
- if (!value)
- break;
- unsigned int textLength;
- decodeBuffer.decodeValue(textLength, 8);
- if (textLength == 255)
- {
- addedLength += 5;
- unsigned char *nextSegment = writeBuffer_.addMessage(5);
- *nextSegment = (unsigned char) textLength;
- decodeBuffer.decodeCachedValue(value, 29, clientCache_ -> polyTextFontCache);
- PutULONG(value, nextSegment + 1, 1);
- }
- else
- {
- addedLength += (textLength * 2 + 2);
- unsigned char *nextSegment =
- writeBuffer_.addMessage(textLength * 2 + 2);
- *nextSegment = (unsigned char) textLength;
- unsigned char *nextDest = nextSegment + 1;
- decodeBuffer.decodeCachedValue(cValue, 8, clientCache_ -> polyTextDeltaCache);
- *nextDest++ = cValue;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, textLength * 2);
-
- nextDest += textLength * 2;
- }
- }
- outputLength += addedLength;
-
- unsigned int mod4 = (addedLength & 0x3);
- if (mod4)
- {
- unsigned int extra = 4 - mod4;
- unsigned char *nextDest = writeBuffer_.addMessage(extra);
- for (unsigned int i = 0; i < extra; i++)
- *nextDest++ = 0;
- outputLength += extra;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_ImageText8:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_ImageText8);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int textLength;
- decodeBuffer.decodeCachedValue(textLength, 8,
- clientCache_ -> imageTextLengthCache, 4);
- outputLength = 16 + RoundUp4(textLength);
- outputMessage = writeBuffer_.addMessage(outputLength);
- outputMessage[1] = (unsigned char) textLength;
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> imageTextCacheX);
- clientCache_ -> imageTextLastX += value;
- clientCache_ -> imageTextLastX &= 0xffff;
- PutUINT(clientCache_ -> imageTextLastX, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> imageTextCacheY);
- clientCache_ -> imageTextLastY += value;
- clientCache_ -> imageTextLastY &= 0xffff;
- PutUINT(clientCache_ -> imageTextLastY, outputMessage + 14, bigEndian_);
- unsigned char *nextDest = outputMessage + 16;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, textLength);
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_ImageText16:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_ImageText16);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int textLength;
- decodeBuffer.decodeCachedValue(textLength, 8,
- clientCache_ -> imageTextLengthCache, 4);
- outputLength = 16 + RoundUp4(textLength * 2);
- outputMessage = writeBuffer_.addMessage(outputLength);
- outputMessage[1] = (unsigned char) textLength;
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> imageTextCacheX);
- clientCache_ -> imageTextLastX += value;
- clientCache_ -> imageTextLastX &= 0xffff;
- PutUINT(clientCache_ -> imageTextLastX, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> imageTextCacheY);
- clientCache_ -> imageTextLastY += value;
- clientCache_ -> imageTextLastY &= 0xffff;
- PutUINT(clientCache_ -> imageTextLastY, outputMessage + 14, bigEndian_);
- unsigned char *nextDest = outputMessage + 16;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, textLength * 2);
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_InternAtom:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_InternAtom);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- sequenceQueue_.push(clientSequence_, outputOpcode);
-
- break;
- }
-
- unsigned int nameLength;
- decodeBuffer.decodeValue(nameLength, 16, 6);
- outputLength = RoundUp4(nameLength) + 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- PutUINT(nameLength, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeBoolValue(value);
- outputMessage[1] = (unsigned char) value;
- unsigned char *nextDest = outputMessage + 8;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, nameLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_ListExtensions:
- {
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_ListFonts:
- {
- unsigned int textLength;
- decodeBuffer.decodeValue(textLength, 16, 6);
- outputLength = 8 + RoundUp4(textLength);
- outputMessage = writeBuffer_.addMessage(outputLength);
- PutUINT(textLength, outputMessage + 6, bigEndian_);
- decodeBuffer.decodeValue(value, 16, 6);
- PutUINT(value, outputMessage + 4, bigEndian_);
- unsigned char* nextDest = outputMessage + 8;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, textLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_LookupColor:
- case X_AllocNamedColor:
- {
- unsigned int textLength;
- decodeBuffer.decodeValue(textLength, 16, 6);
- outputLength = 12 + RoundUp4(textLength);
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> colormapCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- PutUINT(textLength, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, textLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_MapWindow:
- case X_UnmapWindow:
- case X_MapSubwindows:
- case X_GetWindowAttributes:
- case X_DestroyWindow:
- case X_DestroySubwindows:
- case X_QueryPointer:
- case X_QueryTree:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- if (outputOpcode == X_DestroyWindow) // Since ProtoStep7 (#issue 108)
- {
- decodeBuffer.decodeFreeXidValue(value, clientCache_ -> freeWindowCache);
- }
- else
- {
- decodeBuffer.decodeXidValue(value, clientCache_ -> windowCache);
- }
-
- PutULONG(value, outputMessage + 4, bigEndian_);
- if (outputOpcode == X_QueryPointer ||
- outputOpcode == X_GetWindowAttributes ||
- outputOpcode == X_QueryTree)
- {
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- }
- break;
- case X_OpenFont:
- {
- unsigned int nameLength;
- decodeBuffer.decodeValue(nameLength, 16, 7);
- outputLength = RoundUp4(12 + nameLength);
- outputMessage = writeBuffer_.addMessage(outputLength);
- PutUINT(nameLength, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeValue(value, 29, 5);
- clientCache_ -> lastFont += value;
- clientCache_ -> lastFont &= 0x1fffffff;
- PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeTextData(nextDest, nameLength);
- }
- break;
- case X_PolyFillRectangle:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyFillRectangle);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
-
- unsigned int index = 0;
- unsigned int lastX = 0, lastY = 0, lastWidth = 0, lastHeight = 0;
- unsigned int numRectangles = 0;
-
- for (;;)
- {
- outputLength += 8;
- writeBuffer_.addMessage(8);
- unsigned char *nextDest = outputMessage + 12 +
- (numRectangles << 3);
- numRectangles++;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillRectangleCacheX[index], 8);
- value += lastX;
- PutUINT(value, nextDest, bigEndian_);
- lastX = value;
- nextDest += 2;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillRectangleCacheY[index], 8);
- value += lastY;
- PutUINT(value, nextDest, bigEndian_);
- lastY = value;
- nextDest += 2;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillRectangleCacheWidth[index], 8);
- value += lastWidth;
- PutUINT(value, nextDest, bigEndian_);
- lastWidth = value;
- nextDest += 2;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillRectangleCacheHeight[index], 8);
- value += lastHeight;
- PutUINT(value, nextDest, bigEndian_);
- lastHeight = value;
- nextDest += 2;
-
- if (++index == 4) index = 0;
-
- decodeBuffer.decodeBoolValue(value);
-
- if (!value) break;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PolyFillArc:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyFillArc);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
-
- unsigned int index = 0;
- unsigned int lastX = 0, lastY = 0,
- lastWidth = 0, lastHeight = 0,
- lastAngle1 = 0, lastAngle2 = 0;
-
- unsigned int numArcs = 0;
-
- for (;;)
- {
- outputLength += 12;
- writeBuffer_.addMessage(12);
-
- unsigned char *nextDest = outputMessage + 12 +
- (numArcs * 12);
- numArcs++;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillArcCacheX[index], 8);
- value += lastX;
- PutUINT(value, nextDest, bigEndian_);
- lastX = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillArcCacheY[index], 8);
- value += lastY;
- PutUINT(value, nextDest, bigEndian_);
- lastY = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillArcCacheWidth[index], 8);
- value += lastWidth;
- PutUINT(value, nextDest, bigEndian_);
- lastWidth = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillArcCacheHeight[index], 8);
- value += lastHeight;
- PutUINT(value, nextDest, bigEndian_);
- lastHeight = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillArcCacheAngle1[index], 8);
- value += lastAngle1;
- PutUINT(value, nextDest, bigEndian_);
- lastAngle1 = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyFillArcCacheAngle2[index], 8);
- value += lastAngle2;
- PutUINT(value, nextDest, bigEndian_);
- lastAngle2 = value;
- nextDest += 2;
-
- if (++index == 2) index = 0;
-
- decodeBuffer.decodeBoolValue(value);
-
- if (!value) break;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PolyArc:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyArc);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- writeBuffer_.registerPointer(&outputMessage);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
-
- unsigned int index = 0;
- unsigned int lastX = 0, lastY = 0,
- lastWidth = 0, lastHeight = 0,
- lastAngle1 = 0, lastAngle2 = 0;
-
- unsigned int numArcs = 0;
-
- for (;;)
- {
- outputLength += 12;
- writeBuffer_.addMessage(12);
-
- unsigned char *nextDest = outputMessage + 12 +
- (numArcs * 12);
- numArcs++;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyArcCacheX[index], 8);
- value += lastX;
- PutUINT(value, nextDest, bigEndian_);
- lastX = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyArcCacheY[index], 8);
- value += lastY;
- PutUINT(value, nextDest, bigEndian_);
- lastY = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyArcCacheWidth[index], 8);
- value += lastWidth;
- PutUINT(value, nextDest, bigEndian_);
- lastWidth = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyArcCacheHeight[index], 8);
- value += lastHeight;
- PutUINT(value, nextDest, bigEndian_);
- lastHeight = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyArcCacheAngle1[index], 8);
- value += lastAngle1;
- PutUINT(value, nextDest, bigEndian_);
- lastAngle1 = value;
- nextDest += 2;
-
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyArcCacheAngle2[index], 8);
- value += lastAngle2;
- PutUINT(value, nextDest, bigEndian_);
- lastAngle2 = value;
- nextDest += 2;
-
- if (++index == 2) index = 0;
-
- decodeBuffer.decodeBoolValue(value);
-
- if (!value) break;
- }
- writeBuffer_.unregisterPointer();
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PolyPoint:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyPoint);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int numPoints;
- decodeBuffer.decodeValue(numPoints, 16, 4);
- outputLength = (numPoints << 2) + 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- unsigned int relativeCoordMode;
- decodeBuffer.decodeBoolValue(relativeCoordMode);
- outputMessage[1] = (unsigned char) relativeCoordMode;
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
-
- unsigned int index = 0;
- unsigned int lastX = 0, lastY = 0;
-
- for (unsigned int i = 0; i < numPoints; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyPointCacheX[index], 8);
- lastX += value;
- PutUINT(lastX, nextDest, bigEndian_);
- nextDest += 2;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyPointCacheY[index], 8);
- lastY += value;
- PutUINT(lastY, nextDest, bigEndian_);
- nextDest += 2;
-
- if (++index == 2) index = 0;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PolyLine:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolyLine);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int numPoints;
- decodeBuffer.decodeValue(numPoints, 16, 4);
- outputLength = (numPoints << 2) + 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- unsigned int relativeCoordMode;
- decodeBuffer.decodeBoolValue(relativeCoordMode);
- outputMessage[1] = (unsigned char) relativeCoordMode;
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
-
- unsigned int index = 0;
- unsigned int lastX = 0, lastY = 0;
-
- for (unsigned int i = 0; i < numPoints; i++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyLineCacheX[index], 8);
- lastX += value;
- PutUINT(lastX, nextDest, bigEndian_);
- nextDest += 2;
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyLineCacheY[index], 8);
- lastY += value;
- PutUINT(lastY, nextDest, bigEndian_);
- nextDest += 2;
-
- if (++index == 2) index = 0;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PolyRectangle:
- {
- unsigned int numRectangles;
- decodeBuffer.decodeValue(numRectangles, 16, 3);
- outputLength = (numRectangles << 3) + 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
- for (unsigned int i = 0; i < numRectangles; i++)
- for (unsigned int k = 0; k < 4; k++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> polyRectangleGeomCache[k], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
- }
- break;
- case X_PolySegment:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PolySegment);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int numSegments;
- decodeBuffer.decodeValue(numSegments, 16, 4);
- outputLength = (numSegments << 3) + 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
-
- for (numSegments *= 2; numSegments; numSegments--)
- {
- unsigned int index;
- decodeBuffer.decodeBoolValue(index);
- unsigned int x;
- decodeBuffer.decodeCachedValue(x, 16,
- clientCache_ -> polySegmentCacheX, 6);
- x += clientCache_ -> polySegmentLastX[index];
- PutUINT(x, nextDest, bigEndian_);
- nextDest += 2;
-
- unsigned int y;
- decodeBuffer.decodeCachedValue(y, 16,
- clientCache_ -> polySegmentCacheY, 6);
- y += clientCache_ -> polySegmentLastY[index];
- PutUINT(y, nextDest, bigEndian_);
- nextDest += 2;
-
- clientCache_ -> polySegmentLastX[clientCache_ -> polySegmentCacheIndex] = x;
- clientCache_ -> polySegmentLastY[clientCache_ -> polySegmentCacheIndex] = y;
-
- if (clientCache_ -> polySegmentCacheIndex == 1)
- clientCache_ -> polySegmentCacheIndex = 0;
- else
- clientCache_ -> polySegmentCacheIndex = 1;
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_PutImage:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_PutImage);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
-
- if (outputOpcode == X_PutImage)
- {
- handleImage(outputOpcode, outputMessage, outputLength);
- }
- }
- break;
- case X_QueryBestSize:
- {
- outputLength = 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 2);
- outputMessage[1] = (unsigned char)value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeValue(value, 16, 8);
- PutUINT(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeValue(value, 16, 8);
- PutUINT(value, outputMessage + 10, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_QueryColors:
- {
- // Differential or plain data compression?
- decodeBuffer.decodeBoolValue(value);
-
- if (value)
- {
- unsigned int numColors;
- decodeBuffer.decodeValue(numColors, 16, 5);
- outputLength = (numColors << 2) + 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> colormapCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- unsigned char *nextDest = outputMessage + 8;
- unsigned int predictedPixel = clientCache_ -> queryColorsLastPixel;
- for (unsigned int i = 0; i < numColors; i++)
- {
- unsigned int pixel;
- decodeBuffer.decodeBoolValue(value);
- if (value)
- pixel = predictedPixel;
- else
- decodeBuffer.decodeValue(pixel, 32, 9);
- PutULONG(pixel, nextDest, bigEndian_);
- if (i == 0)
- clientCache_ -> queryColorsLastPixel = pixel;
- predictedPixel = pixel + 1;
- nextDest += 4;
- }
- }
- else
- {
- // Request length.
- unsigned int requestLength;
- decodeBuffer.decodeValue(requestLength, 16, 10);
- outputLength = (requestLength << 2);
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- const unsigned char *compressedData = NULL;
- unsigned int compressedDataSize = 0;
-
- int decompressed = handleDecompress(decodeBuffer, outputOpcode, 4,
- outputMessage, outputLength, compressedData,
- compressedDataSize);
- if (decompressed < 0)
- {
- return -1;
- }
- }
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_QueryExtension:
- {
- unsigned int nameLength;
- decodeBuffer.decodeValue(nameLength, 16, 6);
- outputLength = 8 + RoundUp4(nameLength);
- outputMessage = writeBuffer_.addMessage(outputLength);
- PutUINT(nameLength, outputMessage + 4, bigEndian_);
- unsigned char *nextDest = outputMessage + 8;
- for (unsigned int i = 0; i < nameLength; i++)
- {
- decodeBuffer.decodeValue(value, 8);
- *nextDest++ = (unsigned char) value;
- }
-
- unsigned int hide = 0;
-
- #ifdef HIDE_MIT_SHM_EXTENSION
-
- if (!strncmp((char *) outputMessage + 8, "MIT-SHM", 7))
- {
- #ifdef TEST
- *logofs << "handleWrite: Going to hide MIT-SHM extension in reply.\n"
- << logofs_flush;
- #endif
-
- hide = 1;
- }
-
- #endif
-
- #ifdef HIDE_BIG_REQUESTS_EXTENSION
-
- if (!strncmp((char *) outputMessage + 8, "BIG-REQUESTS", 12))
- {
- #ifdef TEST
- *logofs << "handleWrite: Going to hide BIG-REQUESTS extension in reply.\n"
- << logofs_flush;
- #endif
-
- hide = 1;
- }
-
- #endif
-
- #ifdef HIDE_XKEYBOARD_EXTENSION
-
- else if (!strncmp((char *) outputMessage + 8, "XKEYBOARD", 9))
- {
- #ifdef TEST
- *logofs << "handleWrite: Going to hide XKEYBOARD extension in reply.\n"
- << logofs_flush;
- #endif
-
- hide = 1;
- }
-
- #endif
-
- #ifdef HIDE_XFree86_Bigfont_EXTENSION
-
- else if (!strncmp((char *) outputMessage + 8, "XFree86-Bigfont", 15))
- {
- #ifdef TEST
- *logofs << "handleWrite: Going to hide XFree86-Bigfont extension in reply.\n"
- << logofs_flush;
- #endif
-
- hide = 1;
- }
-
- #endif
-
- //
- // This is if you want to experiment disabling SHAPE extensions.
- //
-
- #ifdef HIDE_SHAPE_EXTENSION
-
- if (!strncmp((char *) outputMessage + 8, "SHAPE", 5))
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Going to hide SHAPE extension in reply.\n"
- << logofs_flush;
- #endif
-
- hide = 1;
- }
-
- #endif
-
- //
- // Check if user disabled RENDER extension.
- //
-
- if (control -> HideRender == 1 &&
- strncmp((char *) outputMessage + 8, "RENDER", 6) == 0)
- {
- #ifdef TEST
- *logofs << "handleWrite: Going to hide RENDER extension in reply.\n"
- << logofs_flush;
- #endif
-
- hide = 1;
- }
-
- unsigned int extension = 0;
-
- if (strncmp((char *) outputMessage + 8, "SHAPE", 5) == 0)
- {
- extension = X_NXInternalShapeExtension;
- }
- else if (strncmp((char *) outputMessage + 8, "RENDER", 6) == 0)
- {
- extension = X_NXInternalRenderExtension;
- }
-
- sequenceQueue_.push(clientSequence_, outputOpcode,
- outputOpcode, hide, extension);
- }
- break;
- case X_QueryFont:
- {
- outputLength = 8;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 29, 5);
- clientCache_ -> lastFont += value;
- clientCache_ -> lastFont &= 0x1fffffff;
- PutULONG(clientCache_ -> lastFont, outputMessage + 4, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_SetClipRectangles:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_SetClipRectangles);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- break;
- }
-
- unsigned int numRectangles;
-
- // Since ProtoStep9 (#issue 108)
- decodeBuffer.decodeValue(numRectangles, 15, 4);
-
- outputLength = (numRectangles << 3) + 12;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeValue(value, 2);
- outputMessage[1] = (unsigned char) value;
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> setClipRectanglesXCache, 8);
- PutUINT(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> setClipRectanglesYCache, 8);
- PutUINT(value, outputMessage + 10, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
- for (unsigned int i = 0; i < numRectangles; i++)
- {
- for (unsigned int k = 0; k < 4; k++)
- {
- decodeBuffer.decodeCachedValue(value, 16,
- *clientCache_ -> setClipRectanglesGeomCache[k], 8);
- PutUINT(value, nextDest, bigEndian_);
- nextDest += 2;
- }
- }
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_SetDashes:
- {
- unsigned int numDashes;
- decodeBuffer.decodeCachedValue(numDashes, 16,
- clientCache_ -> setDashesLengthCache, 5);
- outputLength = 12 + RoundUp4(numDashes);
- outputMessage = writeBuffer_.addMessage(outputLength);
- PutUINT(numDashes, outputMessage + 10, bigEndian_);
- decodeBuffer.decodeXidValue(value, clientCache_ -> gcCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> setDashesOffsetCache, 5);
- PutUINT(value, outputMessage + 8, bigEndian_);
- unsigned char *nextDest = outputMessage + 12;
- for (unsigned int i = 0; i < numDashes; i++)
- {
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> setDashesDashCache_[i & 1], 5);
- *nextDest++ = cValue;
- }
- }
- break;
- case X_SetSelectionOwner:
- {
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> setSelectionOwnerCache, 9);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> getSelectionOwnerSelectionCache, 9);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 32,
- clientCache_ -> setSelectionOwnerTimestampCache, 9);
- PutULONG(value, outputMessage + 12, bigEndian_);
- }
- break;
- case X_TranslateCoords:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_TranslateCoords);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- sequenceQueue_.push(clientSequence_, outputOpcode);
-
- break;
- }
-
- outputLength = 16;
- outputMessage = writeBuffer_.addMessage(outputLength);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> translateCoordsSrcCache, 9);
- PutULONG(value, outputMessage + 4, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 29,
- clientCache_ -> translateCoordsDstCache, 9);
- PutULONG(value, outputMessage + 8, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> translateCoordsXCache, 8);
- PutUINT(value, outputMessage + 12, bigEndian_);
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> translateCoordsYCache, 8);
- PutUINT(value, outputMessage + 14, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_GetImage:
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_GetImage);
-
- if (handleDecodeCached(decodeBuffer, clientCache_, messageStore,
- outputMessage, outputLength))
- {
- sequenceQueue_.push(clientSequence_, outputOpcode);
-
- break;
- }
-
- outputLength = 20;
- outputMessage = writeBuffer_.addMessage(outputLength);
- // Format.
- unsigned int format;
- decodeBuffer.decodeValue(format, 2);
- outputMessage[1] = (unsigned char) format;
- // Drawable.
- decodeBuffer.decodeXidValue(value, clientCache_ -> drawableCache);
- PutULONG(value, outputMessage + 4, bigEndian_);
- // X.
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> putImageXCache, 8);
- clientCache_ -> putImageLastX += value;
- clientCache_ -> putImageLastX &= 0xffff;
- PutUINT(clientCache_ -> putImageLastX, outputMessage + 8, bigEndian_);
- // Y.
- decodeBuffer.decodeCachedValue(value, 16,
- clientCache_ -> putImageYCache, 8);
- clientCache_ -> putImageLastY += value;
- clientCache_ -> putImageLastY &= 0xffff;
- PutUINT(clientCache_ -> putImageLastY, outputMessage + 10, bigEndian_);
- // Width.
- unsigned int width;
- decodeBuffer.decodeCachedValue(width, 16,
- clientCache_ -> putImageWidthCache, 8);
- PutUINT(width, outputMessage + 12, bigEndian_);
- // Height.
- unsigned int height;
- decodeBuffer.decodeCachedValue(height, 16,
- clientCache_ -> putImageHeightCache, 8);
- PutUINT(height, outputMessage + 14, bigEndian_);
- // Plane mask.
- decodeBuffer.decodeCachedValue(value, 32,
- clientCache_ -> getImagePlaneMaskCache, 5);
- PutULONG(value, outputMessage + 16, bigEndian_);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
-
- handleSave(messageStore, outputMessage, outputLength);
- }
- break;
- case X_GetPointerMapping:
- {
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- case X_GetKeyboardControl:
- {
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode);
- }
- break;
- default:
- {
- if (outputOpcode == opcodeStore_ -> renderExtension)
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXInternalRenderExtension);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> shapeExtension)
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXInternalShapeExtension);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> putPackedImage)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding packed image request for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXPutPackedImage);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
-
- if (outputOpcode == opcodeStore_ -> putPackedImage)
- {
- handleImage(outputOpcode, outputMessage, outputLength);
- }
- }
- else if (outputOpcode == opcodeStore_ -> setUnpackColormap)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding set unpack colormap request "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXSetUnpackColormap);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
- //
- // Message could have been split.
- //
-
- if (outputOpcode == opcodeStore_ -> setUnpackColormap)
- {
- handleColormap(outputOpcode, outputMessage, outputLength);
- }
- }
- else if (outputOpcode == opcodeStore_ -> setUnpackAlpha)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding unpack alpha request for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXSetUnpackAlpha);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
- //
- // Message could have been split.
- //
-
- if (outputOpcode == opcodeStore_ -> setUnpackAlpha)
- {
- handleAlpha(outputOpcode, outputMessage, outputLength);
- }
- }
- else if (outputOpcode == opcodeStore_ -> setUnpackGeometry)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding set unpack geometry request "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXSetUnpackGeometry);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
-
- handleGeometry(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> startSplit)
- {
- handleStartSplitRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> endSplit)
- {
- handleEndSplitRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> commitSplit)
- {
- int result = handleCommitSplitRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength);
-
- //
- // Check if message has been successfully
- // extracted from the split store. In this
- // case post-process it in the usual way.
- //
-
- if (result > 0)
- {
- if (outputOpcode == opcodeStore_ -> putPackedImage ||
- outputOpcode == X_PutImage)
- {
- handleImage(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> setUnpackColormap)
- {
- handleColormap(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> setUnpackAlpha)
- {
- handleAlpha(outputOpcode, outputMessage, outputLength);
- }
- }
- else if (result < 0)
- {
- return -1;
- }
- }
- else if (outputOpcode == opcodeStore_ -> abortSplit)
- {
- handleAbortSplitRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> finishSplit)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding finish split request "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> resourceCache);
-
- handleNullRequest(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> freeSplit)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding free split request "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> resourceCache);
-
- handleNullRequest(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> freeUnpack)
- {
- #ifdef DEBUG
- *logofs << "handleWrite: Decoding free unpack request "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- decodeBuffer.decodeCachedValue(cValue, 8,
- clientCache_ -> resourceCache);
-
- #ifdef DEBUG
- *logofs << "handleWrite: Freeing unpack state for resource "
- << (unsigned int) cValue << ".\n" << logofs_flush;
- #endif
-
- handleUnpackStateRemove(cValue);
-
- handleNullRequest(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> setExposeParameters)
- {
- //
- // Send expose events according to agent's wish.
- //
-
- decodeBuffer.decodeBoolValue(enableExpose_);
- decodeBuffer.decodeBoolValue(enableGraphicsExpose_);
- decodeBuffer.decodeBoolValue(enableNoExpose_);
-
- handleNullRequest(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> getUnpackParameters)
- {
- //
- // Client proxy needs the list of supported
- // unpack methods. We would need an encode
- // buffer, but this is in proxy, not here in
- // channel.
- //
-
- #ifdef TEST
- *logofs << "handleWrite: Sending X_GetInputFocus request for FD#"
- << fd_ << " due to OPCODE#" << (unsigned int) outputOpcode
- << ".\n" << logofs_flush;
- #endif
-
- outputOpcode = X_GetInputFocus;
-
- outputLength = 4;
- outputMessage = writeBuffer_.addMessage(outputLength);
-
- sequenceQueue_.push(clientSequence_, outputOpcode,
- opcodeStore_ -> getUnpackParameters);
- }
- else if (outputOpcode == opcodeStore_ -> getControlParameters ||
- outputOpcode == opcodeStore_ -> getCleanupParameters ||
- outputOpcode == opcodeStore_ -> getImageParameters)
- {
- handleNullRequest(outputOpcode, outputMessage, outputLength);
- }
- else if (outputOpcode == opcodeStore_ -> getShmemParameters)
- {
- if (handleShmemRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength) < 0)
- {
- return -1;
- }
- }
- else if (outputOpcode == opcodeStore_ -> setCacheParameters)
- {
- if (handleCacheRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength) < 0)
- {
- return -1;
- }
- }
- else if (outputOpcode == opcodeStore_ -> getFontParameters)
- {
- if (handleFontRequest(decodeBuffer, outputOpcode,
- outputMessage, outputLength) < 0)
- {
- return -1;
- }
- }
- else
- {
- MessageStore *messageStore = clientStore_ ->
- getRequestStore(X_NXInternalGenericRequest);
-
- hit = handleDecode(decodeBuffer, clientCache_, messageStore,
- outputOpcode, outputMessage, outputLength);
- }
- }
- } // End of switch on opcode.
-
- //
- // TODO: at the moment the variable hit was being set
- // but not used, so to avoid the corresponding warning
- // this logging block has been added.
- // This code will probably be optimized away when none
- // of the defines is set, but if there is no additional
- // use for the hit variable in the future, then maybe
- // it could be removed completely.
- //
-
- if (hit)
- {
- #if defined(TEST) || defined(OPCODES)
- *logofs << "handleWrite: Cached flag enabled in handled request.\n"
- << logofs_flush;
- #endif
- }
-
- //
- // A packed image request can generate more than just
- // a single X_PutImage. Write buffer is handled inside
- // handleUnpack(). Cannot simply assume that the final
- // opcode and size must be put at the buffer offset as
- // as buffer could have been grown or could have been
- // replaced by a scratch buffer. The same is true in
- // the case of a shared memory image.
- //
-
- if (outputOpcode != 0)
- {
- //
- // Commit opcode and size to the buffer.
- //
-
- *outputMessage = (unsigned char) outputOpcode;
-
- PutUINT(outputLength >> 2, outputMessage + 2, bigEndian_);
-
- #if defined(TEST) || defined(OPCODES)
- *logofs << "handleWrite: Handled request OPCODE#"
- << (unsigned int) outputOpcode << " ("
- << DumpOpcode(outputOpcode) << ") for FD#"
- << fd_ << " sequence " << clientSequence_
- << ". " << outputLength << " bytes out.\n"
- << logofs_flush;
- #endif
- }
- #if defined(TEST) || defined(OPCODES)
- else
- {
- //
- // In case of shared memory images the log doesn't
- // reflect the actual opcode of the request that is
- // going to be written. It would be possible to find
- // the opcode of the original request received from
- // the remote proxy in member imageState_ -> opcode,
- // but we have probably already deleted the struct.
- //
-
- *logofs << "handleWrite: Handled image request for FD#"
- << fd_ << " new sequence " << clientSequence_
- << ". " << outputLength << " bytes out.\n"
- << logofs_flush;
- }
- #endif
-
- //
- // Check if we produced enough data. We need to
- // decode all the proxy messages or the decode
- // buffer will be left in an inconsistent state,
- // so we just update the finish flag in case of
- // failure.
- //
-
- handleFlush(flush_if_needed);
-
- } // End of while (decodeBuffer.decodeOpcodeValue(outputOpcode, 8, ...
-
- } // End of the decoding block.
-
- //
- // Write any remaining data to the X connection.
- //
-
- if (handleFlush(flush_if_any) < 0)
- {
- return -1;
- }
-
- //
- // Reset offset at which we read the
- // last event looking for the shared
- // memory completion.
- //
-
- if (shmemState_ != NULL)
- {
- shmemState_ -> checked = 0;
- }
-
- return 1;
-}
-
-//
-// End of handleWrite().
-//
-
-//
-// Other members.
-//
-
-int ServerChannel::handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store,
- T_store_action action, int position, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- // Since ProtoStep7 (#issue 108)
- splitState_.current = splitState_.resource;
-
- handleSplitStoreAlloc(&splitResources_, splitState_.current);
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! Message OPCODE#"
- << (unsigned int) store -> opcode() << " of size " << size
- << " [split] with resource " << splitState_.current
- << " position " << position << " and action ["
- << DumpAction(action) << "] at " << strMsTimestamp()
- << ".\n" << logofs_flush;
- #endif
-
- //
- // Get the MD5 of the message being
- // split.
- //
-
- T_checksum checksum = NULL;
-
- if (action != IS_HIT)
- {
- handleSplitChecksum(decodeBuffer, checksum);
- }
-
- //
- // The method must abort the connection
- // if it can't allocate the split.
- //
-
- Split *splitMessage = clientStore_ -> getSplitStore(splitState_.current) ->
- add(store, splitState_.current, position,
- action, checksum, buffer, size);
-
- //
- // If the encoding side didn't provide
- // a checksum, then don't send the split
- // report.
- //
-
- if (checksum == NULL)
- {
- if (action == IS_HIT)
- {
- splitMessage -> setState(split_loaded);
- }
- else
- {
- splitMessage -> setState(split_missed);
- }
-
- #if defined(TEST) || defined(SPLIT)
-
- *logofs << "handleSplit: SPLIT! There are " << clientStore_ ->
- getSplitTotalSize() << " messages and " << clientStore_ ->
- getSplitTotalStorageSize() << " bytes to send in "
- << "the split stores.\n" << logofs_flush;
-
- clientStore_ -> dumpSplitStore(splitState_.current);
-
- #endif
-
- return 1;
- }
-
- delete [] checksum;
-
- //
- // Tell the split store if it must use
- // the disk cache to retrieve and save
- // the message.
- //
-
- splitMessage -> setPolicy(splitState_.load, splitState_.save);
-
- //
- // Try to locate the message on disk.
- //
-
- if (clientStore_ -> getSplitStore(splitState_.current) ->
- load(splitMessage) == 1)
- {
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! Loaded the message "
- << "from the image cache.\n" << logofs_flush;
- #endif
-
- splitMessage -> setState(split_loaded);
- }
- else
- {
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: WARNING! SPLIT! Can't find the message "
- << "in the image cache.\n" << logofs_flush;
- #endif
-
- splitMessage -> setState(split_missed);
- }
-
- #if defined(TEST) || defined(SPLIT)
-
- T_timestamp startTs = getTimestamp();
-
- *logofs << "handleSplit: SPLIT! Encoding abort "
- << "split events for FD#" << fd_ << " at "
- << strMsTimestamp() << ".\n" << logofs_flush;
- #endif
-
- if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0)
- {
- return -1;
- }
-
- //
- // Send the encoded data immediately. We
- // want the abort split message to reach
- // the remote proxy as soon as possible.
- //
-
- if (proxy -> handleAsyncFlush() < 0)
- {
- return -1;
- }
-
- #if defined(TEST) || defined(SPLIT)
-
- *logofs << "handleSplit: SPLIT! Spent "
- << diffTimestamp(startTs, getTimestamp()) << " Ms "
- << "handling abort split events for FD#" << fd_
- << ".\n" << logofs_flush;
-
- *logofs << "handleSplit: SPLIT! There are " << clientStore_ ->
- getSplitTotalSize() << " messages and " << clientStore_ ->
- getSplitTotalStorageSize() << " bytes to send in "
- << "the split stores.\n" << logofs_flush;
-
- clientStore_ -> dumpSplitStore(splitState_.current);
-
- #endif
-
- return 1;
-}
-
-int ServerChannel::handleSplit(DecodeBuffer &decodeBuffer)
-{
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! Going to handle splits "
- << "for FD#" << fd_ << " at " << strMsTimestamp()
- << ".\n" << logofs_flush;
- #endif
-
- unsigned char resource;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeCachedValue(resource, 8,
- clientCache_ -> resourceCache);
-
- splitState_.current = resource;
-
- handleSplitStoreAlloc(&splitResources_, splitState_.current);
-
- SplitStore *splitStore = clientStore_ -> getSplitStore(splitState_.current);
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! Handling splits for "
- << "resource [" << splitState_.current << "] with "
- << splitStore -> getSize() << " elements "
- << "in the split store.\n" << logofs_flush;
- #endif
-
- int result = splitStore -> receive(decodeBuffer);
-
- if (result < 0)
- {
- #ifdef PANIC
- *logofs << "handleSplit: PANIC! Receive of split for FD#" << fd_
- << " failed.\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Receive of split for FD#" << fd_
- << " failed.\n";
-
- return -1;
- }
- else if (result == 0)
- {
- //
- // The split is still incomplete. It's time
- // to check if we need to start the house-
- // keeping process to take care of the image
- // cache.
- //
-
- if (proxy -> handleAsyncKeeperCallback() < 0)
- {
- return -1;
- }
- }
- else
- {
- //
- // Note that we don't need the resource id at the
- // X server side and, thus, we don't provide it
- // at the time we add split to the split store.
- //
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! Remote agent should "
- << "now commit a new split for resource ["
- << splitState_.current << "].\n"
- << logofs_flush;
-
- clientStore_ -> dumpCommitStore();
-
- #endif
-
- if (splitStore -> getSize() == 0)
- {
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! Removing split store "
- << "for resource [" << splitState_.current
- << "] at " << strMsTimestamp() << ".\n"
- << logofs_flush;
- #endif
-
- handleSplitStoreRemove(&splitResources_, splitState_.current);
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: SPLIT! There are [" << clientStore_ ->
- getSplitTotalSize() << "] messages and " << clientStore_ ->
- getSplitTotalStorageSize() << " bytes to send in "
- << "the split stores.\n" << logofs_flush;
- #endif
- }
- else
- {
- //
- // If the next split is discarded, it can be
- // that, since the beginning of the split, we
- // have saved the message on the disk, due to
- // a more recent split operation. This is also
- // the case when we had to discard the message
- // because it was locked but, since then, we
- // completed the transferral of the split.
- //
-
- Split *splitMessage = splitStore -> getFirstSplit();
-
- if (splitMessage -> getAction() == is_discarded &&
- splitMessage -> getState() == split_missed &&
- splitStore -> load(splitMessage) == 1)
- {
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplit: WARNING! SPLIT! Asynchronously "
- << "loaded the message from the image cache.\n"
- << logofs_flush;
- #endif
-
- splitMessage -> setState(split_loaded);
-
- #if defined(TEST) || defined(SPLIT)
-
- T_timestamp startTs = getTimestamp();
-
- *logofs << "handleSplit: WARNING! SPLIT! Asynchronously "
- << "encoding abort split events for FD#" << fd_
- << " at " << strMsTimestamp() << ".\n"
- << logofs_flush;
- #endif
-
- if (proxy -> handleAsyncSplit(fd_, splitMessage) < 0)
- {
- return -1;
- }
-
- //
- // Send the encoded data immediately. We
- // want the abort split message to reach
- // the remote proxy as soon as possible.
- //
-
- if (proxy -> handleAsyncFlush() < 0)
- {
- return -1;
- }
-
- #if defined(TEST) || defined(SPLIT)
-
- *logofs << "handleSplit: WARNING! SPLIT! Spent "
- << diffTimestamp(startTs, getTimestamp()) << " Ms "
- << "handling asynchronous abort split events for "
- << "FD#" << fd_ << ".\n" << logofs_flush;
-
- *logofs << "handleSplit: SPLIT! There are " << clientStore_ ->
- getSplitTotalSize() << " messages and " << clientStore_ ->
- getSplitTotalStorageSize() << " bytes to send in "
- << "the split stores.\n" << logofs_flush;
-
- clientStore_ -> dumpSplitStore(splitState_.current);
-
- #endif
- }
- }
- }
-
- return 1;
-}
-
-int ServerChannel::handleSplitEvent(EncodeBuffer &encodeBuffer, Split *splitMessage)
-{
- int resource = splitMessage -> getResource();
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplitEvent: SPLIT! Going to send a "
- << "split report for resource " << resource
- << ".\n" << logofs_flush;
- #endif
-
- //
- // This function is called only after the message
- // has been searched in the disk cache. We need to
- // inform the other side if the data transfer can
- // start or it must be aborted to let the local
- // side use the copy that was found on the disk.
- //
-
- #if defined(TEST) || defined(INFO)
-
- if (splitMessage -> getState() != split_loaded &&
- splitMessage -> getState() != split_missed)
- {
- *logofs << "handleSplitEvent: PANIC! Can't find the split to be aborted.\n"
- << logofs_flush;
-
- HandleCleanup();
- }
-
- #endif
-
- //
- // We need to send a boolean telling if the split
- // was found or not, followed by the checksum of
- // message we are referencing.
- //
-
- T_checksum checksum = splitMessage -> getChecksum();
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplitEvent: SPLIT! Sending split report for "
- << "checksum [" << DumpChecksum(checksum) << "].\n"
- << logofs_flush;
- #endif
-
- if (proxy -> handleAsyncSwitch(fd_) < 0)
- {
- return -1;
- }
-
- encodeBuffer.encodeOpcodeValue(opcodeStore_ -> splitEvent,
- serverCache_ -> opcodeCache);
-
- //
- // The encoding in older protocol versions
- // is different but we will never try to
- // send a split report if the remote does
- // not support our version.
- //
-
- encodeBuffer.encodeCachedValue(resource, 8,
- serverCache_ -> resourceCache);
-
- if (splitMessage -> getState() == split_loaded)
- {
- encodeBuffer.encodeBoolValue(1);
-
- encodeBuffer.encodeOpcodeValue(splitMessage -> getStore() -> opcode(),
- serverCache_ -> abortOpcodeCache);
-
- encodeBuffer.encodeValue(splitMessage -> compressedSize(), 32, 14);
- }
- else
- {
- encodeBuffer.encodeBoolValue(0);
- }
-
- for (unsigned int i = 0; i < MD5_LENGTH; i++)
- {
- encodeBuffer.encodeValue((unsigned int) checksum[i], 8);
- }
-
- //
- // Update statistics for this special opcode.
- //
-
- int bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES) || defined(INFO) || defined(SPLIT)
- *logofs << "handleSplitEvent: SPLIT! Handled event OPCODE#"
- << (unsigned int) opcodeStore_ -> splitEvent << " ("
- << DumpOpcode(opcodeStore_ -> splitEvent) << ")" << " for FD#"
- << fd_ << " sequence none. 0 bytes in, " << bits << " bits ("
- << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush;
- #endif
-
- statistics -> addEventBits(opcodeStore_ -> splitEvent, 0, bits);
-
- return 1;
-}
-
-int ServerChannel::handleAbortSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- unsigned char resource;
-
- decodeBuffer.decodeCachedValue(resource, 8,
- clientCache_ -> resourceCache);
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleAbortSplitRequest: SPLIT! Handling abort split "
- << "request for FD#" << fd_ << " and resource "
- << (unsigned) resource << ".\n"
- << logofs_flush;
- #endif
-
- int splits = 0;
-
- SplitStore *splitStore = clientStore_ -> getSplitStore(resource);
-
- if (splitStore != NULL)
- {
- //
- // Discard from the memory cache the messages
- // that are still incomplete and then get rid
- // of the splits in the store.
- //
-
- #if defined(TEST) || defined(SPLIT)
-
- clientStore_ -> dumpSplitStore(resource);
-
- #endif
-
- Split *splitMessage;
-
- for (;;)
- {
- splitMessage = splitStore -> getFirstSplit();
-
- if (splitMessage == NULL)
- {
- //
- // Check if we had created the store
- // but no message was added yet.
- //
-
- #ifdef WARNING
-
- if (splits == 0)
- {
- *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The "
- << "split store for resource [" << (unsigned int)
- resource << "] is unexpectedly empty.\n"
- << logofs_flush;
- }
-
- #endif
-
- break;
- }
-
- //
- // Splits already aborted can't be in the
- // split store.
- //
-
- #if defined(TEST) || defined(SPLIT)
-
- if (splitMessage -> getState() == split_aborted)
- {
- *logofs << "handleAbortSplitRequest: PANIC! SPLIT! Found an "
- << "aborted split in store [" << (unsigned int) resource
- << "].\n" << logofs_flush;
-
- HandleCleanup();
- }
-
- #endif
-
- if (splitMessage -> getAction() == IS_HIT)
- {
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleAbortSplitRequest: SPLIT! Removing the "
- << "split from the memory cache.\n"
- << logofs_flush;
- #endif
-
- splitMessage -> getStore() -> remove(splitMessage -> getPosition(),
- discard_checksum, use_data);
- }
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleAbortSplitRequest: SPLIT! Removing the "
- << "split from the split store.\n"
- << logofs_flush;
- #endif
-
- splitMessage = splitStore -> pop();
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleAbortSplitRequest: SPLIT! Freeing up the "
- << "aborted split.\n" << logofs_flush;
- #endif
-
- delete splitMessage;
-
- splits++;
- }
- }
- #ifdef WARNING
- else
- {
- *logofs << "handleAbortSplitRequest: WARNING! SPLIT! The "
- << "split store for resource [" << (unsigned int)
- resource << "] is already empty.\n"
- << logofs_flush;
- }
- #endif
-
- handleNullRequest(opcode, buffer, size);
-
- return (splits > 0);
-}
-
-int ServerChannel::handleCommitSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- //
- // Get request type and position of the image
- // to commit.
- //
-
- unsigned char request;
-
- decodeBuffer.decodeOpcodeValue(request, clientCache_ -> opcodeCache);
-
- unsigned int diffCommit;
-
- decodeBuffer.decodeValue(diffCommit, 32, 5);
-
- splitState_.commit += diffCommit;
-
- unsigned char resource = 0;
- unsigned int commit = 1;
-
- //
- // Send the resource id and the commit flag.
- // The resource id is ignored at the moment.
- // The message will be handled based on the
- // resource id that was sent together with
- // the original message.
- //
-
- decodeBuffer.decodeCachedValue(resource, 8,
- clientCache_ -> resourceCache);
-
- decodeBuffer.decodeBoolValue(commit);
-
- Split *split = handleSplitCommitRemove(request, resource, splitState_.commit);
-
- if (split == NULL)
- {
- return -1;
- }
-
- clientStore_ -> getCommitStore() -> update(split);
-
- if (commit == 1)
- {
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleCommitSplitRequest: SPLIT! Handling split commit "
- << "for FD#" << fd_ << " with commit " << commit
- << " request " << (unsigned) request << " resource "
- << (unsigned) resource << " and position "
- << splitState_.commit << ".\n"
- << logofs_flush;
- #endif
-
- //
- // Allocate as many bytes in the write
- // buffer as the final length of the
- // message in uncompressed form.
- //
-
- size = split -> plainSize();
-
- buffer = writeBuffer_.addMessage(size);
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleCommitSplitRequest: SPLIT! Prepared an "
- << "outgoing buffer of " << size << " bytes.\n"
- << logofs_flush;
- #endif
-
- if (clientStore_ -> getCommitStore() -> expand(split, buffer, size) < 0)
- {
- writeBuffer_.removeMessage(size);
-
- commit = 0;
- }
- }
-
- //
- // Free the split.
- //
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleCommitSplitRequest: SPLIT! Freeing up the "
- << "committed split.\n" << logofs_flush;
- #endif
-
- delete split;
-
- //
- // Discard the operation and send a null
- // message.
- //
-
- if (commit == 0)
- {
- handleNullRequest(opcode, buffer, size);
- }
- else
- {
- //
- // Save the sequence number to be able
- // to mask any error generated by the
- // request.
- //
-
- updateCommitQueue(clientSequence_);
-
- //
- // Now in the write buffer there is
- // a copy of this request.
- //
-
- opcode = request;
- }
-
- return commit;
-}
-
-int ServerChannel::handleGeometry(unsigned char &opcode, unsigned char *&buffer,
- unsigned int &size)
-{
- //
- // Replace the old geometry and taint
- // the message into a X_NoOperation.
- //
-
- int resource = *(buffer + 1);
-
- #ifdef TEST
- *logofs << "handleGeometry: Setting new unpack geometry "
- << "for resource " << resource << ".\n"
- << logofs_flush;
- #endif
-
- handleUnpackStateInit(resource);
-
- handleUnpackAllocGeometry(resource);
-
- unpackState_[resource] -> geometry -> depth1_bpp = *(buffer + 4);
- unpackState_[resource] -> geometry -> depth4_bpp = *(buffer + 5);
- unpackState_[resource] -> geometry -> depth8_bpp = *(buffer + 6);
- unpackState_[resource] -> geometry -> depth16_bpp = *(buffer + 7);
- unpackState_[resource] -> geometry -> depth24_bpp = *(buffer + 8);
- unpackState_[resource] -> geometry -> depth32_bpp = *(buffer + 9);
-
- unpackState_[resource] -> geometry -> red_mask = GetULONG(buffer + 12, bigEndian_);
- unpackState_[resource] -> geometry -> green_mask = GetULONG(buffer + 16, bigEndian_);
- unpackState_[resource] -> geometry -> blue_mask = GetULONG(buffer + 20, bigEndian_);
-
- handleCleanAndNullRequest(opcode, buffer, size);
-
- return 1;
-}
-
-int ServerChannel::handleColormap(unsigned char &opcode, unsigned char *&buffer,
- unsigned int &size)
-{
- //
- // Replace the old colormap and taint
- // the message into a X_NoOperation.
- //
-
- int resource = *(buffer + 1);
-
- #ifdef TEST
- *logofs << "handleColormap: Setting new unpack colormap "
- << "for resource " << resource << ".\n"
- << logofs_flush;
- #endif
-
- handleUnpackStateInit(resource);
-
- handleUnpackAllocColormap(resource);
-
- //
- // New protocol versions send the alpha
- // data in compressed form.
- //
-
- //
- // Since ProtoStep7 (#issue 108)
- //
-
- { // An anonymous block is used here to limit the scope of local variables
- unsigned int packed = GetULONG(buffer + 8, bigEndian_);
- unsigned int unpacked = GetULONG(buffer + 12, bigEndian_);
-
- validateSize("colormap", packed, unpacked, 16, size);
-
- if (unpackState_[resource] -> colormap -> entries != unpacked >> 2 &&
- unpackState_[resource] -> colormap -> data != NULL)
- {
- #ifdef TEST
- *logofs << "handleColormap: Freeing previously allocated "
- << "unpack colormap data.\n" << logofs_flush;
- #endif
-
- delete [] unpackState_[resource] -> colormap -> data;
-
- unpackState_[resource] -> colormap -> data = NULL;
- unpackState_[resource] -> colormap -> entries = 0;
- }
-
- #ifdef TEST
- *logofs << "handleColormap: Setting " << unpacked
- << " bytes of unpack colormap data for resource "
- << resource << ".\n" << logofs_flush;
- #endif
-
- if (unpackState_[resource] -> colormap -> data == NULL)
- {
- unpackState_[resource] -> colormap -> data =
- (unsigned int *) new unsigned char[unpacked];
-
- if (unpackState_[resource] -> colormap -> data == NULL)
- {
- #ifdef PANIC
- *logofs << "handleColormap: PANIC! Can't allocate "
- << unpacked << " entries for unpack colormap data "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- goto handleColormapEnd;
- }
-
- #ifdef DEBUG
- *logofs << "handleColormap: Size of new colormap data is "
- << unpacked << ".\n" << logofs_flush;
- #endif
- }
-
- unsigned int method = *(buffer + 4);
-
- if (method == PACK_COLORMAP)
- {
- if (UnpackColormap(method, buffer + 16, packed,
- (unsigned char *) unpackState_[resource] ->
- colormap -> data, unpacked) < 0)
- {
- #ifdef PANIC
- *logofs << "handleColormap: PANIC! Can't unpack " << packed
- << " bytes to " << unpacked << " entries for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- delete [] unpackState_[resource] -> colormap -> data;
-
- unpackState_[resource] -> colormap -> data = NULL;
- unpackState_[resource] -> colormap -> entries = 0;
-
- goto handleColormapEnd;
- }
- }
- else
- {
- memcpy((unsigned char *) unpackState_[resource] ->
- colormap -> data, buffer + 16, unpacked);
- }
-
- unpackState_[resource] -> colormap -> entries = unpacked >> 2;
-
- #if defined(DEBUG) && defined(DUMP)
-
- *logofs << "handleColormap: Dumping colormap entries:\n"
- << logofs_flush;
-
- const unsigned char *p = (const unsigned char *) unpackState_[resource] -> colormap -> data;
-
- for (unsigned int i = 0; i < unpackState_[resource] ->
- colormap -> entries; i++)
- {
- *logofs << "handleColormap: [" << i << "] ["
- << (void *) ((int) p[i]) << "].\n"
- << logofs_flush;
- }
-
- #endif
- } // end anonymous block
-
-handleColormapEnd:
-
- handleCleanAndNullRequest(opcode, buffer, size);
-
- return 1;
-}
-
-int ServerChannel::handleAlpha(unsigned char &opcode, unsigned char *&buffer,
- unsigned int &size)
-{
- int resource = *(buffer + 1);
-
- #ifdef TEST
- *logofs << "handleAlpha: Setting new unpack alpha "
- << "for resource " << resource << ".\n"
- << logofs_flush;
- #endif
-
- handleUnpackStateInit(resource);
-
- handleUnpackAllocAlpha(resource);
-
- //
- // New protocol versions send the alpha
- // data in compressed form.
- //
-
- //
- // Since ProtoStep7 (#issue 108)
- //
-
- { // An anonymous block is used here to limit the scope of local variables
- unsigned int packed = GetULONG(buffer + 8, bigEndian_);
- unsigned int unpacked = GetULONG(buffer + 12, bigEndian_);
-
- validateSize("alpha", packed, unpacked, 16, size);
-
- if (unpackState_[resource] -> alpha -> entries != unpacked &&
- unpackState_[resource] -> alpha -> data != NULL)
- {
- #ifdef TEST
- *logofs << "handleAlpha: Freeing previously allocated "
- << "unpack alpha data.\n" << logofs_flush;
- #endif
-
- delete [] unpackState_[resource] -> alpha -> data;
-
- unpackState_[resource] -> alpha -> data = NULL;
- unpackState_[resource] -> alpha -> entries = 0;
- }
-
- #ifdef TEST
- *logofs << "handleAlpha: Setting " << unpacked
- << " bytes of unpack alpha data for resource "
- << resource << ".\n" << logofs_flush;
- #endif
-
- if (unpackState_[resource] -> alpha -> data == NULL)
- {
- unpackState_[resource] -> alpha -> data = new unsigned char[unpacked];
-
- if (unpackState_[resource] -> alpha -> data == NULL)
- {
- #ifdef PANIC
- *logofs << "handleAlpha: PANIC! Can't allocate "
- << unpacked << " entries for unpack alpha data "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- goto handleAlphaEnd;
- }
-
- #ifdef DEBUG
- *logofs << "handleAlpha: Size of new alpha data is "
- << unpacked << ".\n" << logofs_flush;
- #endif
- }
-
- unsigned int method = *(buffer + 4);
-
- if (method == PACK_ALPHA)
- {
- if (UnpackAlpha(method, buffer + 16, packed,
- unpackState_[resource] -> alpha ->
- data, unpacked) < 0)
- {
- #ifdef PANIC
- *logofs << "handleAlpha: PANIC! Can't unpack " << packed
- << " bytes to " << unpacked << " entries for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- delete [] unpackState_[resource] -> alpha -> data;
-
- unpackState_[resource] -> alpha -> data = NULL;
- unpackState_[resource] -> alpha -> entries = 0;
-
- goto handleAlphaEnd;
- }
- }
- else
- {
- memcpy((unsigned char *) unpackState_[resource] ->
- alpha -> data, buffer + 16, unpacked);
- }
-
- unpackState_[resource] -> alpha -> entries = unpacked;
-
- #if defined(DEBUG) && defined(DUMP)
-
- *logofs << "handleAlpha: Dumping alpha entries:\n"
- << logofs_flush;
-
- const unsigned char *p = unpackState_[resource] -> alpha -> data;
-
- for (unsigned int i = 0; i < unpackState_[resource] ->
- alpha -> entries; i++)
- {
- *logofs << "handleAlpha: [" << i << "] ["
- << (void *) ((int) p[i]) << "].\n"
- << logofs_flush;
- }
-
- #endif
- } //end anonymous block
-
-handleAlphaEnd:
-
- handleCleanAndNullRequest(opcode, buffer, size);
-
- return 1;
-}
-
-int ServerChannel::handleImage(unsigned char &opcode, unsigned char *&buffer,
- unsigned int &size)
-{
- int result = 1;
-
- //
- // Save the original opcode together with
- // the image state so we can later find if
- // this is a plain or a packed image when
- // moving data to the shared memory area.
- //
-
- handleImageStateAlloc(opcode);
-
- if (opcode == opcodeStore_ -> putPackedImage)
- {
- //
- // Unpack the image and put a X_PutImage in a
- // new buffer. Save the expected output size,
- // so, in the case of a decoding error we can
- // still update the statistics.
- //
-
- int length = GetULONG(buffer + 20, bigEndian_);
-
- #ifdef TEST
- *logofs << "handleImage: Sending image for FD#" << fd_
- << " due to OPCODE#" << (unsigned int) opcode << " with "
- << GetULONG(buffer + 16, bigEndian_) << " bytes packed "
- << "and " << GetULONG(buffer + 20, bigEndian_)
- << " bytes unpacked.\n" << logofs_flush;
- #endif
-
- statistics -> addPackedBytesIn(size);
-
- result = handleUnpack(opcode, buffer, size);
-
- if (result < 0)
- {
- //
- // Recover from the error. Send a X_NoOperation
- // to keep the sequence counter in sync with
- // the remote peer.
- //
-
- size = 4;
- buffer = writeBuffer_.addMessage(size);
-
- *buffer = X_NoOperation;
-
- PutUINT(size >> 2, buffer + 2, bigEndian_);
-
- #ifdef PANIC
- *logofs << "handleImage: PANIC! Sending X_NoOperation for FD#"
- << fd_ << " to recover from failed unpack.\n"
- << logofs_flush;
- #endif
-
- //
- // Set the output length to reflect the amount of
- // data that would have been produced by unpacking
- // the image. This is advisable to keep the count-
- // ers in sync with those at remote proxy. Setting
- // the size here doesn't have any effect on the
- // size of data sent to the X server as the actual
- // size will be taken from the content of the write
- // buffer.
- //
-
- size = length;
- }
-
- statistics -> addPackedBytesOut(size);
-
- //
- // Refrain the write loop from putting
- // opcode and size in the output buffer.
- //
-
- opcode = 0;
- }
-
- //
- // Now image is unpacked as a X_PutImage
- // in write buffer. Check if we can send
- // the image using the MIT-SHM extension.
- //
-
- if (result > 0)
- {
- result = handleShmem(opcode, buffer, size);
-
- //
- // We already put opcode and size in
- // the resulting buffer.
- //
-
- if (result > 0)
- {
- opcode = 0;
- }
- }
-
- return 1;
-}
-
-int ServerChannel::handleMotion(EncodeBuffer &encodeBuffer)
-{
- #if defined(TEST) || defined(INFO)
-
- if (lastMotion_[0] == '\0')
- {
- *logofs << "handleMotion: PANIC! No motion events to send "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
-
- HandleCleanup();
- }
-
- #endif
-
- #if defined(TEST) || defined(INFO)
- *logofs << "handleMotion: Sending motion events for FD#"
- << fd_ << " at " << strMsTimestamp() << ".\n"
- << logofs_flush;
- #endif
-
- //
- // Replicate code from read loop. When have
- // time and wish, try to split everything
- // in functions.
- //
-
- if (proxy -> handleAsyncSwitch(fd_) < 0)
- {
- return -1;
- }
-
- const unsigned char *buffer = lastMotion_;
- unsigned char opcode = *lastMotion_;
- unsigned int size = 32;
-
- if (GetUINT(buffer + 2, bigEndian_) < serverSequence_)
- {
- PutUINT(serverSequence_, (unsigned char *) buffer + 2, bigEndian_);
- }
-
- encodeBuffer.encodeOpcodeValue(opcode, serverCache_ -> opcodeCache);
-
- unsigned int sequenceNum = GetUINT(buffer + 2, bigEndian_);
-
- unsigned int sequenceDiff = sequenceNum - serverSequence_;
-
- serverSequence_ = sequenceNum;
-
- #ifdef DEBUG
- *logofs << "handleMotion: Last server sequence number for FD#"
- << fd_ << " is " << serverSequence_ << " with "
- << "difference " << sequenceDiff << ".\n"
- << logofs_flush;
- #endif
-
- encodeBuffer.encodeCachedValue(sequenceDiff, 16,
- serverCache_ -> eventSequenceCache, 7);
-
- //
- // If we fast encoded the message
- // then skip the rest.
- //
-
- if (control -> LocalDeltaCompression == 0)
- {
- int result = handleFastReadEvent(encodeBuffer, opcode,
- buffer, size);
-
- #ifdef DEBUG
- *logofs << "handleMotion: Sent saved motion event for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- lastMotion_[0] = '\0';
-
- #ifdef DEBUG
- *logofs << "handleMotion: Reset last motion event for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- if (result < 0)
- {
- return -1;
- }
- else if (result > 0)
- {
- return 1;
- }
- }
-
- //
- // This should be just the part specific
- // for motion events but is currently a
- // copy-paste of code from the read loop.
- //
-
- unsigned char detail = buffer[1];
- if (*buffer == MotionNotify)
- encodeBuffer.encodeBoolValue((unsigned int) detail);
- else if ((*buffer == EnterNotify) || (*buffer == LeaveNotify))
- encodeBuffer.encodeValue((unsigned int) detail, 3);
- else if (*buffer == KeyRelease)
- {
- if (detail == serverCache_ -> keyPressLastKey)
- encodeBuffer.encodeBoolValue(1);
- else
- {
- encodeBuffer.encodeBoolValue(0);
- encodeBuffer.encodeValue((unsigned int) detail, 8);
- }
- }
- else if ((*buffer == ButtonPress) || (*buffer == ButtonRelease))
- encodeBuffer.encodeCachedValue(detail, 8,
- serverCache_ -> buttonCache);
- else
- encodeBuffer.encodeValue((unsigned int) detail, 8);
- unsigned int timestamp = GetULONG(buffer + 4, bigEndian_);
- unsigned int timestampDiff = timestamp - serverCache_ -> lastTimestamp;
- serverCache_ -> lastTimestamp = timestamp;
- encodeBuffer.encodeCachedValue(timestampDiff, 32,
- serverCache_ -> motionNotifyTimestampCache, 9);
- int skipRest = 0;
- if (*buffer == KeyRelease)
- {
- skipRest = 1;
- for (unsigned int i = 8; i < 31; i++)
- {
- if (buffer[i] != serverCache_ -> keyPressCache[i - 8])
- {
- skipRest = 0;
- break;
- }
- }
- encodeBuffer.encodeBoolValue(skipRest);
- }
- if (!skipRest)
- {
- const unsigned char *nextSrc = buffer + 8;
- for (unsigned int i = 0; i < 3; i++)
- {
- encodeBuffer.encodeCachedValue(GetULONG(nextSrc, bigEndian_), 29,
- *serverCache_ -> motionNotifyWindowCache[i], 6);
- nextSrc += 4;
- }
- unsigned int rootX = GetUINT(buffer + 20, bigEndian_);
- unsigned int rootY = GetUINT(buffer + 22, bigEndian_);
- unsigned int eventX = GetUINT(buffer + 24, bigEndian_);
- unsigned int eventY = GetUINT(buffer + 26, bigEndian_);
- eventX -= rootX;
- eventY -= rootY;
- encodeBuffer.encodeCachedValue(rootX -
- serverCache_ -> motionNotifyLastRootX, 16,
- serverCache_ -> motionNotifyRootXCache, 6);
- serverCache_ -> motionNotifyLastRootX = rootX;
- encodeBuffer.encodeCachedValue(rootY -
- serverCache_ -> motionNotifyLastRootY, 16,
- serverCache_ -> motionNotifyRootYCache, 6);
- serverCache_ -> motionNotifyLastRootY = rootY;
- encodeBuffer.encodeCachedValue(eventX, 16,
- serverCache_ -> motionNotifyEventXCache, 6);
- encodeBuffer.encodeCachedValue(eventY, 16,
- serverCache_ -> motionNotifyEventYCache, 6);
- encodeBuffer.encodeCachedValue(GetUINT(buffer + 28, bigEndian_),
- 16, serverCache_ -> motionNotifyStateCache);
- if ((*buffer == EnterNotify) || (*buffer == LeaveNotify))
- encodeBuffer.encodeValue((unsigned int) buffer[30], 2);
- else
- encodeBuffer.encodeBoolValue((unsigned int) buffer[30]);
- if ((*buffer == EnterNotify) || (*buffer == LeaveNotify))
- encodeBuffer.encodeValue((unsigned int) buffer[31], 2);
- else if (*buffer == KeyPress)
- {
- serverCache_ -> keyPressLastKey = detail;
- for (unsigned int i = 8; i < 31; i++)
- {
- serverCache_ -> keyPressCache[i - 8] = buffer[i];
- }
- }
- }
-
- //
- // Print info about achieved compression
- // and update the statistics.
- //
-
- int bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES)
- *logofs << "handleMotion: Handled event OPCODE#" << (unsigned int) buffer[0]
- << " for FD#" << fd_ << " sequence " << sequenceNum << ". "
- << size << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
- #endif
-
- statistics -> addEventBits(*buffer, size << 3, bits);
-
- #ifdef DEBUG
- *logofs << "handleMotion: Sent saved motion event for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- lastMotion_[0] = '\0';
-
- #ifdef DEBUG
- *logofs << "handleMotion: Reset last motion event for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 1;
-}
-
-int ServerChannel::handleConfiguration()
-{
- #ifdef TEST
- *logofs << "ServerChannel: Setting new buffer parameters "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- readBuffer_.setSize(control -> ServerInitialReadSize,
- control -> ServerMaximumBufferSize);
-
- writeBuffer_.setSize(control -> TransportXBufferSize,
- control -> TransportXBufferThreshold,
- control -> TransportMaximumBufferSize);
-
- transport_ -> setSize(control -> TransportXBufferSize,
- control -> TransportXBufferThreshold,
- control -> TransportMaximumBufferSize);
- return 1;
-}
-
-int ServerChannel::handleFinish()
-{
- #ifdef TEST
- *logofs << "ServerChannel: Finishing connection for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- congestion_ = 0;
- priority_ = 0;
-
- finish_ = 1;
-
- //
- // Reset the motion event.
- //
-
- lastMotion_[0] = '\0';
-
- transport_ -> fullReset();
-
- return 1;
-}
-
-int ServerChannel::handleAsyncEvents()
-{
- //
- // Encode more events while decoding the
- // proxy messages.
- //
-
- if (transport_ -> readable() > 0)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleAsyncEvents: WARNING! Encoding events "
- << "for FD#" << fd_ << " at " << strMsTimestamp()
- << ".\n" << logofs_flush;
- #endif
-
- #if defined(TEST) || defined(INFO)
-
- T_timestamp startTs = getTimestamp();
-
- #endif
-
- if (proxy -> handleAsyncRead(fd_) < 0)
- {
- return -1;
- }
-
- #if defined(TEST) || defined(INFO)
- *logofs << "handleAsyncEvents: Spent " << diffTimestamp(startTs,
- getTimestamp()) << " Ms handling events for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 1;
- }
-
- return 0;
-}
-
-int ServerChannel::handleUnpack(unsigned char &opcode, unsigned char *&buffer,
- unsigned int &size)
-{
- int resource = *(buffer + 1);
-
- #ifdef DEBUG
- *logofs << "handleUnpack: Unpacking image for resource " << resource
- << " with method " << (unsigned int) *(buffer + 12)
- << ".\n" << logofs_flush;
- #endif
-
- handleUnpackStateInit(resource);
-
- T_geometry *geometryState = unpackState_[resource] -> geometry;
- T_colormap *colormapState = unpackState_[resource] -> colormap;
- T_alpha *alphaState = unpackState_[resource] -> alpha;
-
- if (geometryState == NULL)
- {
- #ifdef PANIC
- *logofs << "handleUnpack: PANIC! Missing geometry unpacking "
- << "image for resource " << resource << ".\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Missing geometry unpacking "
- << "image for resource " << resource << ".\n";
-
- return -1;
- }
-
- //
- // Get the image data from the buffer.
- //
-
- imageState_ -> drawable = GetULONG(buffer + 4, bigEndian_);
- imageState_ -> gcontext = GetULONG(buffer + 8, bigEndian_);
-
- imageState_ -> method = *(buffer + 12);
-
- imageState_ -> format = *(buffer + 13);
- imageState_ -> srcDepth = *(buffer + 14);
- imageState_ -> dstDepth = *(buffer + 15);
-
- imageState_ -> srcLength = GetULONG(buffer + 16, bigEndian_);
- imageState_ -> dstLength = GetULONG(buffer + 20, bigEndian_);
-
- imageState_ -> srcX = GetUINT(buffer + 24, bigEndian_);
- imageState_ -> srcY = GetUINT(buffer + 26, bigEndian_);
- imageState_ -> srcWidth = GetUINT(buffer + 28, bigEndian_);
- imageState_ -> srcHeight = GetUINT(buffer + 30, bigEndian_);
-
- imageState_ -> dstX = GetUINT(buffer + 32, bigEndian_);
- imageState_ -> dstY = GetUINT(buffer + 34, bigEndian_);
- imageState_ -> dstWidth = GetUINT(buffer + 36, bigEndian_);
- imageState_ -> dstHeight = GetUINT(buffer + 38, bigEndian_);
-
- #ifdef TEST
- *logofs << "handleUnpack: Source X is " << imageState_ -> srcX
- << " Y is " << imageState_ -> srcY << " width is "
- << imageState_ -> srcWidth << " height is "
- << imageState_ -> srcHeight << ".\n"
- << logofs_flush;
- #endif
-
- #ifdef TEST
- *logofs << "handleUnpack: Destination X is " << imageState_ -> dstX
- << " Y is " << imageState_ -> dstY << " width is "
- << imageState_ -> dstWidth << " height is "
- << imageState_ -> dstHeight << ".\n"
- << logofs_flush;
- #endif
-
- if (imageState_ -> srcX != 0 || imageState_ -> srcY != 0)
- {
- #ifdef PANIC
- *logofs << "handleUnpack: PANIC! Unsupported source coordinates "
- << "in unpack request.\n" << logofs_flush;
- #endif
-
- return -1;
- }
- else if (imageState_ -> method == PACK_COLORMAP_256_COLORS &&
- (colormapState == NULL || colormapState -> data == NULL))
- {
- #ifdef PANIC
- *logofs << "handleUnpack: PANIC! Cannot find any unpack colormap.\n"
- << logofs_flush;
- #endif
-
- return -1;
- }
-
- //
- // Field srcLength carries size of image data in
- // packed format. Field dstLength is size of the
- // image in the original X bitmap format.
- //
-
- unsigned int srcDataOffset = 40;
-
- unsigned int srcSize = imageState_ -> srcLength;
-
- unsigned int removeSize = size;
-
- unsigned char *srcData = buffer + srcDataOffset;
-
- //
- // Get source and destination bits per pixel.
- //
-
- int srcBitsPerPixel = MethodBitsPerPixel(imageState_ -> method);
-
- if (srcBitsPerPixel <= 0)
- {
- #ifdef PANIC
- *logofs << "handleUnpack: PANIC! Can't identify source "
- << "bits per pixel for method " << (unsigned int)
- imageState_ -> method << ".\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't identify source bits "
- << "per pixel for method " << (unsigned int)
- imageState_ -> method << ".\n";
-
- writeBuffer_.removeMessage(removeSize);
-
- return -1;
- }
-
- #ifdef TEST
- *logofs << "handleUnpack: Source bits per pixel are "
- << srcBitsPerPixel << " source data size is "
- << srcSize << ".\n" << logofs_flush;
- #endif
-
- int dstBitsPerPixel = UnpackBitsPerPixel(geometryState, imageState_ -> dstDepth);
-
- if (dstBitsPerPixel <= 0)
- {
- #ifdef PANIC
- *logofs << "handleUnpack: PANIC! Can't identify "
- << "destination bits per pixel for depth "
- << (unsigned int) imageState_ -> dstDepth
- << ".\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't identify "
- << "destination bits per pixel for depth "
- << (unsigned int) imageState_ -> dstDepth
- << ".\n";
-
- writeBuffer_.removeMessage(removeSize);
-
- return -1;
- }
-
- //
- // Destination is a PutImage request.
- //
-
- unsigned int dstDataOffset = 24;
-
- //
- // Output buffer size must match the number of input
- // pixels multiplied by the number of bytes per pixel
- // of current geometry.
- //
-
- size = (RoundUp4(imageState_ -> dstWidth * dstBitsPerPixel / 8) *
- imageState_ -> dstHeight) + dstDataOffset;
-
- #ifdef TEST
- *logofs << "handleUnpack: Destination bits per pixel are "
- << dstBitsPerPixel << " destination data size is "
- << size - dstDataOffset << ".\n" << logofs_flush;
- #endif
-
- unsigned int dstSize = size - dstDataOffset;
-
- imageState_ -> dstLines = imageState_ -> dstHeight;
-
- unsigned char *dstData;
-
- //
- // Size of the final output buffer had to be stored
- // in the offset field of XImage/NXPackedImage.
- //
-
- #ifdef WARNING
-
- if (dstSize != imageState_ -> dstLength)
- {
- *logofs << "handleUnpack: WARNING! Destination size mismatch "
- << "with reported " << imageState_ -> dstLength
- << " and actual " << dstSize << ".\n"
- << logofs_flush;
- }
-
- #endif
-
- //
- // The decoding algorithm has put the packed image
- // in the plain write buffer. Let's use the scratch
- // buffer to uncompress the image.
- //
-
- buffer = writeBuffer_.addScratchMessage(size);
-
- dstData = buffer + dstDataOffset;
-
- //
- // Unpack image into the buffer.
- //
-
- *buffer = (unsigned char) X_PutImage;
-
- *(buffer + 1) = imageState_ -> format;
-
- PutUINT(size >> 2, buffer + 2, bigEndian_);
-
- PutULONG(imageState_ -> drawable, buffer + 4, bigEndian_);
- PutULONG(imageState_ -> gcontext, buffer + 8, bigEndian_);
-
- PutUINT(imageState_ -> dstWidth, buffer + 12, bigEndian_);
- PutUINT(imageState_ -> dstLines, buffer + 14, bigEndian_);
-
- PutUINT(imageState_ -> dstX, buffer + 16, bigEndian_);
- PutUINT(imageState_ -> dstY, buffer + 18, bigEndian_);
-
- *(buffer + 20) = 0;
- *(buffer + 21) = imageState_ -> dstDepth;
-
- #ifdef TEST
- *logofs << "handleUnpack: Write buffer size is "
- << writeBuffer_.getLength() << " scratch size is "
- << writeBuffer_.getScratchLength() << ".\n"
- << logofs_flush;
- #endif
-
- int result = 0;
-
- switch (imageState_ -> method)
- {
- case PACK_JPEG_8_COLORS:
- case PACK_JPEG_64_COLORS:
- case PACK_JPEG_256_COLORS:
- case PACK_JPEG_512_COLORS:
- case PACK_JPEG_4K_COLORS:
- case PACK_JPEG_32K_COLORS:
- case PACK_JPEG_64K_COLORS:
- case PACK_JPEG_256K_COLORS:
- case PACK_JPEG_2M_COLORS:
- case PACK_JPEG_16M_COLORS:
- {
- result = UnpackJpeg(geometryState, imageState_ -> method, srcData,
- srcSize, dstBitsPerPixel, imageState_ -> dstWidth,
- imageState_ -> dstHeight, dstData, dstSize);
- break;
- }
- case PACK_PNG_8_COLORS:
- case PACK_PNG_64_COLORS:
- case PACK_PNG_256_COLORS:
- case PACK_PNG_512_COLORS:
- case PACK_PNG_4K_COLORS:
- case PACK_PNG_32K_COLORS:
- case PACK_PNG_64K_COLORS:
- case PACK_PNG_256K_COLORS:
- case PACK_PNG_2M_COLORS:
- case PACK_PNG_16M_COLORS:
- {
- result = UnpackPng(geometryState, imageState_ -> method, srcData,
- srcSize, dstBitsPerPixel, imageState_ -> dstWidth,
- imageState_ -> dstHeight, dstData, dstSize);
- break;
- }
- case PACK_RGB_16M_COLORS:
- {
- result = UnpackRgb(geometryState, imageState_ -> method, srcData,
- srcSize, dstBitsPerPixel, imageState_ -> dstWidth,
- imageState_ -> dstHeight, dstData, dstSize);
- break;
- }
- case PACK_RLE_16M_COLORS:
- {
- result = UnpackRle(geometryState, imageState_ -> method, srcData,
- srcSize, dstBitsPerPixel, imageState_ -> dstWidth,
- imageState_ -> dstHeight, dstData, dstSize);
- break;
- }
- case PACK_BITMAP_16M_COLORS:
- {
- result = UnpackBitmap(geometryState, imageState_ -> method, srcData,
- srcSize, dstBitsPerPixel, imageState_ -> dstWidth,
- imageState_ -> dstHeight, dstData, dstSize);
- break;
- }
- case PACK_COLORMAP_256_COLORS:
- {
- result = Unpack8(geometryState, colormapState, srcBitsPerPixel,
- imageState_ -> srcWidth, imageState_ -> srcHeight, srcData,
- srcSize, dstBitsPerPixel, imageState_ -> dstWidth,
- imageState_ -> dstHeight, dstData, dstSize);
-
- break;
- }
- default:
- {
- const T_colormask *colorMask = MethodColorMask(imageState_ -> method);
-
- switch (imageState_ -> method)
- {
- case PACK_MASKED_8_COLORS:
- case PACK_MASKED_64_COLORS:
- case PACK_MASKED_256_COLORS:
- {
- result = Unpack8(geometryState, colorMask, imageState_ -> srcDepth,
- imageState_ -> srcWidth, imageState_ -> srcHeight,
- srcData, srcSize, imageState_ -> dstDepth,
- imageState_ -> dstWidth, imageState_ -> dstHeight,
- dstData, dstSize);
- break;
- }
- case PACK_MASKED_512_COLORS:
- case PACK_MASKED_4K_COLORS:
- case PACK_MASKED_32K_COLORS:
- case PACK_MASKED_64K_COLORS:
- {
- result = Unpack16(geometryState, colorMask, imageState_ -> srcDepth,
- imageState_ -> srcWidth, imageState_ -> srcHeight,
- srcData, srcSize, imageState_ -> dstDepth,
- imageState_ -> dstWidth, imageState_ -> dstHeight,
- dstData, dstSize);
- break;
- }
- case PACK_MASKED_256K_COLORS:
- case PACK_MASKED_2M_COLORS:
- case PACK_MASKED_16M_COLORS:
- {
- result = Unpack24(geometryState, colorMask, imageState_ -> srcDepth,
- imageState_ -> srcWidth, imageState_ -> srcHeight,
- srcData, srcSize, imageState_ -> dstDepth,
- imageState_ -> dstWidth, imageState_ -> dstHeight,
- dstData, dstSize);
- break;
- }
- default:
- {
- break;
- }
- }
- }
- }
-
- writeBuffer_.removeMessage(removeSize);
-
- if (result <= 0)
- {
- #ifdef PANIC
- *logofs << "handleUnpack: PANIC! Failed to unpack image "
- << "with method '" << (unsigned int) imageState_ -> method
- << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Warning" << ": Failed to unpack image "
- << "with method '" << (unsigned int) imageState_ -> method
- << "'.\n";
-
- //
- // TODO: We should mark the image somehow,
- // and force the remote to remove it from
- // the cache.
- //
-
- writeBuffer_.removeScratchMessage();
-
- return -1;
- }
-
- //
- // Alpha channel is used only on some 32 bits pixmaps
- // and only if render extension is in use. Presently
- // we don't have an efficient way to know in advance
- // if mask must be applied or not to the image. If an
- // alpha channel is set, the function will check if
- // the size of the alpha data matches the size of the
- // image. In the worst case we'll create an useless
- // alpha plane for a pixmap that doesn't need it.
- //
-
- if (alphaState != NULL && alphaState -> data != NULL &&
- imageState_ -> dstDepth == 32)
- {
- UnpackAlpha(alphaState, dstData, dstSize, imageByteOrder_);
- }
-
- return 1;
-}
-
-int ServerChannel::handleAuthorization(unsigned char *buffer)
-{
- //
- // At the present moment we don't support more than
- // a single display for each proxy, so authorization
- // data is shared among all the channels.
- //
- // Use the following code to simulate authentication
- // failures on a LSB machine:
- //
- // memcpy(buffer + 12 + (((buffer[6] + 256 *
- // buffer[7]) + 3) & ~3), "1234567890123456", 16);
- //
-
- if (auth == NULL)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleAuthorization: Forwarding the real cookie "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
- else if (auth -> checkCookie(buffer) == 1)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleAuthorization: Matched the fake cookie "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 1;
- }
- else
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleAuthorization: WARNING! Failed to match "
- << "the fake cookie for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- return -1;
- }
-}
-
-int ServerChannel::handleAuthorization(const unsigned char *buffer, int size)
-{
- //
- // Check the X server's response and, in the case of
- // an error, print the textual information reported
- // by the server.
- //
-
- if (*buffer != 1)
- {
- const char *reason = NULL;
-
- //
- // At the moment we don't take into account the end-
- // ianess of the reply. This should work in any case
- // because we simply try to match a few well-known
- // error strings.
- //
-
- if (size >= INVALID_COOKIE_SIZE + 8 &&
- memcmp(buffer + 8, INVALID_COOKIE_DATA,
- INVALID_COOKIE_SIZE) == 0)
- {
- reason = INVALID_COOKIE_DATA;
- }
- else if (size >= NO_AUTH_PROTO_SIZE + 8 &&
- memcmp(buffer + 8, NO_AUTH_PROTO_DATA,
- NO_AUTH_PROTO_SIZE) == 0)
- {
- reason = NO_AUTH_PROTO_DATA;
- }
- else
- {
- reason = "Unknown";
- }
-
- #ifdef WARNING
- *logofs << "handleAuthorization: WARNING! X connection failed "
- << "with error '" << reason << "' on FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- cerr << "Warning" << ": X connection failed "
- << "with error '" << reason << "'.\n";
- }
- #if defined(TEST) || defined(INFO)
- else
- {
- *logofs << "handleAuthorization: X connection successful "
- << "on FD#" << fd_ << ".\n" << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-//
-// Use a simple encoding. Need to handle the image
-// requests in the usual way and the X_ListExtensions
-// and X_QueryExtension to hide MIT-SHM and RENDER
-// in the reply.
-//
-
-int ServerChannel::handleFastWriteRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- //
- // All the NX requests are handled in the
- // main message loop.
- //
-
- //
- // Since ProtoStep7 (#issue 108)
- //
- // The X_PutImage can be handled here only
- // if a split was not requested.
- //
-
- if ((opcode >= X_NXFirstOpcode && opcode <= X_NXLastOpcode) ||
- (opcode == X_PutImage && splitState_.resource != nothing) ||
- opcode == X_ListExtensions ||
- opcode == X_QueryExtension)
- {
- return 0;
- }
-
- #ifdef DEBUG
- *logofs << "handleFastWriteRequest: Decoding raw request OPCODE#"
- << (unsigned int) opcode << " for FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- buffer = writeBuffer_.addMessage(4);
-
- #ifndef __sun
-
- unsigned int *next = (unsigned int *) decodeBuffer.decodeMemory(4);
-
- *((unsigned int *) buffer) = *next;
-
- #else /* #ifndef __sun */
-
- memcpy(buffer, decodeBuffer.decodeMemory(4), 4);
-
- #endif /* #ifndef __sun */
-
- size = GetUINT(buffer + 2, bigEndian_) << 2;
-
- if (size < 4)
- {
- #ifdef WARNING
- *logofs << "handleFastWriteRequest: WARNING! Assuming size 4 "
- << "for suspicious message of size " << size
- << ".\n" << logofs_flush;
- #endif
-
- size = 4;
- }
-
- writeBuffer_.registerPointer(&buffer);
-
- if (writeBuffer_.getAvailable() < size - 4 ||
- (int) size >= control -> TransportFlushBufferSize)
- {
- #ifdef DEBUG
- *logofs << "handleFastWriteRequest: Using scratch buffer for OPCODE#"
- << (unsigned int) opcode << " with size " << size << " and "
- << writeBuffer_.getLength() << " bytes in buffer.\n"
- << logofs_flush;
- #endif
-
- //
- // The procedure moving data to shared memory
- // assumes that the full message is stored in
- // the scratch buffer. We can safely let the
- // scratch buffer inherit the decode buffer
- // at the next offset.
- //
-
- writeBuffer_.removeMessage(4);
-
- buffer = writeBuffer_.addScratchMessage(((unsigned char *)
- decodeBuffer.decodeMemory(size - 4)) - 4, size);
- }
- else
- {
- writeBuffer_.addMessage(size - 4);
-
- #ifndef __sun
-
- if (size <= 32)
- {
- next = (unsigned int *) decodeBuffer.decodeMemory(size - 4);
-
- for (unsigned int i = 4; i < size; i += sizeof(unsigned int))
- {
- *((unsigned int *) (buffer + i)) = *next++;
- }
- }
- else
- {
- memcpy(buffer + 4, decodeBuffer.decodeMemory(size - 4), size - 4);
- }
-
- #else /* #ifndef __sun */
-
- memcpy(buffer + 4, decodeBuffer.decodeMemory(size - 4), size - 4);
-
- #endif /* #ifndef __sun */
- }
-
- //
- // Opcode could have been tainted by the client
- // proxy. Replace the original opcode with the
- // one sent in the decode buffer.
- //
-
- *buffer = opcode;
-
- writeBuffer_.unregisterPointer();
-
- if (opcode == X_PutImage)
- {
- handleImage(opcode, buffer, size);
- }
-
- #if defined(TEST) || defined(OPCODES)
-
- if (opcode != 0)
- {
- *logofs << "handleFastWriteRequest: Handled request "
- << "OPCODE#" << (unsigned int) opcode << " ("
- << DumpOpcode(opcode) << ") for FD#" << fd_
- << " sequence " << clientSequence_ << ". "
- << size << " bytes out.\n" << logofs_flush;
- }
- else
- {
- *logofs << "handleFastWriteRequest: Handled image or "
- << "other request for FD#" << fd_
- << " sequence " << clientSequence_ << ". "
- << size << " bytes out.\n" << logofs_flush;
- }
-
- #endif
-
- handleFlush(flush_if_needed);
-
- return 1;
-}
-
-//
-// Use the simplest encoding except for replies that
-// need to be managed some way.
-//
-
-int ServerChannel::handleFastReadReply(EncodeBuffer &encodeBuffer, const unsigned char &opcode,
- const unsigned char *&buffer, const unsigned int &size)
-{
- //
- // If we pushed a X_GetInputFocus in the sequence
- // queue this means that the original message was
- // a NX request for which we have to provide a NX
- // reply.
- //
-
- if ((opcode >= X_NXFirstOpcode &&
- opcode <= X_NXLastOpcode) ||
- opcode == X_QueryExtension ||
- opcode == X_ListExtensions ||
- opcode == X_GetInputFocus)
- {
- return 0;
- }
-
- #ifdef DEBUG
- *logofs << "handleFastReadReply: Encoding raw reply OPCODE#"
- << (unsigned int) opcode << " for FD#" << fd_
- << " with size " << size << ".\n"
- << logofs_flush;
- #endif
-
- encodeBuffer.encodeMemory(buffer, size);
-
- //
- // Send back the reply as soon
- // as possible.
- //
-
- priority_++;
-
- int bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES)
- *logofs << "handleFastReadReply: Handled raw reply OPCODE#"
- << (unsigned int) opcode << " for FD#" << fd_ << " sequence "
- << serverSequence_ << ". " << size << " bytes in, "
- << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
- #endif
-
- statistics -> addReplyBits(opcode, size << 3, bits);
-
- return 1;
-}
-
-int ServerChannel::handleFastReadEvent(EncodeBuffer &encodeBuffer, const unsigned char &opcode,
- const unsigned char *&buffer, const unsigned int &size)
-{
- #ifdef DEBUG
- *logofs << "handleFastReadEvent: Encoding raw "
- << (opcode == X_Error ? "error" : "event") << " OPCODE#"
- << (unsigned int) opcode << " for FD#" << fd_
- << " with size " << size << ".\n"
- << logofs_flush;
- #endif
-
- encodeBuffer.encodeMemory(buffer, size);
-
- switch (opcode)
- {
- case X_Error:
- case ButtonPress:
- case ButtonRelease:
- case KeyPress:
- case KeyRelease:
- {
- priority_++;
- }
- }
-
- int bits = encodeBuffer.diffBits();
-
- #if defined(TEST) || defined(OPCODES)
-
- if (opcode == X_Error)
- {
- unsigned char code = *(buffer + 1);
-
- *logofs << "handleFastReadEvent: Handled error ERR_CODE#"
- << (unsigned int) code << " for FD#" << fd_;
-
- *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_);
-
- *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_);
-
- *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10);
-
- *logofs << " sequence " << serverSequence_ << ". " << size
- << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
- }
- else
- {
- *logofs << "handleFastReadEvent: Handled event OPCODE#"
- << (unsigned int) *buffer << " for FD#" << fd_
- << " sequence " << serverSequence_ << ". " << size
- << " bytes in, " << bits << " bits (" << ((float) bits) / 8
- << " bytes) out.\n" << logofs_flush;
- }
-
- #endif
-
- statistics -> addEventBits(opcode, size << 3, bits);
-
- return 1;
-}
-
-void ServerChannel::initCommitQueue()
-{
- #ifdef TEST
- *logofs << "initCommitQueue: Resetting the queue of split commits "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE; i++)
- {
- commitSequenceQueue_[i] = 0;
- }
-}
-
-void ServerChannel::updateCommitQueue(unsigned short sequence)
-{
- for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE - 1; i++)
- {
- commitSequenceQueue_[i + 1] = commitSequenceQueue_[i];
- }
-
- #ifdef TEST
- *logofs << "updateCommitQueue: Saved " << sequence
- << " as last sequence number of image to commit.\n"
- << logofs_flush;
- #endif
-
- commitSequenceQueue_[0] = sequence;
-}
-
-int ServerChannel::checkCommitError(unsigned char error, unsigned short sequence,
- const unsigned char *buffer)
-{
- //
- // Check if error is due to an image commit
- // generated at the end of a split.
- //
- // TODO: It should zero the head of the list
- // when an event comes with a sequence number
- // greater than the value of the last element
- // added.
- //
-
- for (int i = 0; i < MAX_COMMIT_SEQUENCE_QUEUE &&
- commitSequenceQueue_[i] != 0; i++)
- {
- #ifdef TEST
- *logofs << "checkCommitError: Checking committed image's "
- << "sequence number " << commitSequenceQueue_[i]
- << " with input sequence " << sequence << ".\n"
- << logofs_flush;
- #endif
-
- if (commitSequenceQueue_[i] == sequence)
- {
- #ifdef WARNING
-
- *logofs << "checkCommitError: WARNING! Failed operation for "
- << "FD#" << fd_ << " with ERR_CODE#"
- << (unsigned int) *(buffer + 1);
-
- *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_);
-
- *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_);
-
- *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10);
-
- *logofs << " sequence " << sequence << ".\n";
-
- *logofs << logofs_flush;
-
- #endif
-
- cerr << "Warning" << ": Failed commit operation "
- << "with ERR_CODE#" << (unsigned int) error;
-
- cerr << " RES_ID#" << GetULONG(buffer + 4, bigEndian_);
-
- cerr << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_);
-
- cerr << " MAJ_OP#" << (unsigned int) *(buffer + 10);
-
- cerr << ".\n";
-
- #ifdef WARNING
- *logofs << "checkCommitError: WARNING! Suppressing error on "
- << "OPCODE#" << (unsigned int) opcodeStore_ -> commitSplit
- << " for FD#" << fd_ << " with sequence " << sequence
- << " at position " << i << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
- }
-
- return 0;
-}
-
-//
-// Check if the user pressed the CTRL+ALT+SHIFT+ESC
-// keystroke. At the present moment it uses different
-// keycodes based on the client OS. This should be
-// implemented in a way that is platform independent
-// (that's not an easy task, considered that we don't
-// have access to the higher level X libraries).
-//
-
-int ServerChannel::checkKeyboardEvent(unsigned char event, unsigned short sequence,
- const unsigned char *buffer)
-{
- #ifdef TEST
- *logofs << "checkKeyboardEvent: Checking escape sequence with byte [1] "
- << (void *) ((unsigned) *(buffer + 1)) << " and bytes [28-29] "
- << (void *) ((unsigned) GetUINT(buffer + 28, bigEndian_))
- << " for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- #ifdef __APPLE__
-
- int alert = (*(buffer + 1) == 0x3d &&
- GetUINT(buffer + 28, bigEndian_) == 0x2005);
-
- #else
-
- int alert = (*(buffer + 1) == 0x09 &&
- ((GetUINT(buffer + 28, bigEndian_) &
- 0x0d) == 0x0d));
-
- #endif
-
- if (alert == 1)
- {
- #ifdef PANIC
- *logofs << "checkKeyboardEvent: PANIC! Received sequence "
- << "CTRL+ALT+SHIFT+ESC " << "for FD#"<< fd_
- << ". Showing the abort dialog.\n" << logofs_flush;
- #endif
-
- cerr << "Warning" << ": Received sequence CTRL+ALT+SHIFT+ESC. "
- << "Showing the abort dialog.\n";
-
- HandleAlert(CLOSE_UNRESPONSIVE_X_SERVER_ALERT, 1);
- }
-
- return alert;
-}
-
-//
-// Handle the MIT-SHM initialization
-// messages exchanged with the remote
-// proxy.
-//
-
-int ServerChannel::handleShmemReply(EncodeBuffer &encodeBuffer, const unsigned char opcode,
- const unsigned int stage, const unsigned char *buffer,
- const unsigned int size)
-{
- #ifdef TEST
- *logofs << "handleShmemReply: Returning shmem reply for "
- << "stage " << stage << ".\n" << logofs_flush;
- #endif
-
- if (opcode == X_QueryExtension)
- {
- encodeBuffer.encodeValue(stage, 2);
-
-#ifndef ANDROID
- shmemState_ -> present = *(buffer + 8);
-#else
- shmemState_ -> present = 0;
- cerr << "Info: handleShmemReply: In android no shared memory. Setting present to 0 hardcoded\n";
-#endif
- shmemState_ -> opcode = *(buffer + 9);
- shmemState_ -> event = *(buffer + 10);
- shmemState_ -> error = *(buffer + 11);
-
- #ifdef TEST
- *logofs << "handleShmemReply: Extension present is "
- << shmemState_ -> present << " with base OPCODE#"
- << (unsigned int) shmemState_ -> opcode << " base event "
- << (unsigned int) shmemState_ -> event << " base error "
- << (unsigned int) shmemState_ -> error << ".\n"
- << logofs_flush;
- #endif
- }
- else if (opcode == X_GetInputFocus)
- {
- encodeBuffer.encodeValue(stage, 2);
-
- encodeBuffer.encodeBoolValue(0);
-
- if (shmemState_ -> present == 1 &&
- shmemState_ -> address != NULL &&
- shmemState_ -> segment > 0 &&
- shmemState_ -> id > 0)
- {
- cerr << "Info" << ": Using shared memory parameters 1/"
- << (shmemState_ -> size / 1024) << "K.\n";
-
-#ifndef ANDROID
- shmemState_ -> enabled = 1;
-#else
- cerr << "Info: handleShmemReply: In android no shared memory. Setting enabled to -1. This should not be displayed\n";
- shmemState_ -> enabled = -1;
-#endif
-
- encodeBuffer.encodeBoolValue(1);
- }
- else
- {
- #ifdef TEST
- *logofs << "handleShmemReply: WARNING! Not using shared memory "
- << "support in X server for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- cerr << "Info" << ": Using shared memory parameters 0/0K.\n";
-
- handleShmemStateRemove();
-
- encodeBuffer.encodeBoolValue(0);
- }
- }
- else
- {
- #ifdef PANIC
- *logofs << "handleShmemReply: PANIC! Conversation error "
- << "handling shared memory support for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- cerr << "Error" << ": Conversation error handling "
- << "shared memory support.\n";
-
- return -1;
- }
-
- return 1;
-}
-
-int ServerChannel::handleShmemRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- //
- // We need to query and initialize MIT-SHM on
- // the real X server. To do this we'll need 3
- // requests. At the end we'll have to encode
- // the final reply for the X client side.
- //
-
- handleShmemStateAlloc();
-
- unsigned int stage;
-
- decodeBuffer.decodeValue(stage, 2);
-
- unsigned int expected = shmemState_ -> stage + 1;
-
- if (stage != expected || stage > 2)
- {
- #ifdef PANIC
- *logofs << "handleShmemRequest: PANIC! Unexpected stage "
- << stage << " in handling shared memory "
- << "support for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Unexpected stage "
- << stage << " in handling shared memory "
- << "support for FD#" << fd_ << ".\n";
-
- return -1;
- }
-
- switch (stage)
- {
- case 0:
- {
- unsigned int enableClient;
- unsigned int enableServer;
-
- decodeBuffer.decodeBoolValue(enableClient);
- decodeBuffer.decodeBoolValue(enableServer);
-
- unsigned int clientSegment;
- unsigned int serverSegment;
-
- decodeBuffer.decodeValue(clientSegment, 29, 9);
- decodeBuffer.decodeValue(serverSegment, 29, 9);
-
- shmemState_ -> segment = serverSegment;
-
- #ifdef TEST
- *logofs << "handleShmemRequest: Size of the shared memory "
- << "segment will be " << control -> ShmemServerSize
- << ".\n" << logofs_flush;
- #endif
-
- #ifdef TEST
- *logofs << "handleShmemRequest: Sending X_QueryExtension request "
- << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int)
- opcodeStore_ -> getShmemParameters << " in stage "
- << stage << ".\n" << logofs_flush;
- #endif
-
- opcode = X_QueryExtension;
-
- size = 16;
- buffer = writeBuffer_.addMessage(size);
-
- PutUINT(7, buffer + 4, bigEndian_);
-
- //
- // Simply make the query fail if shared
- // memory support is disabled by the
- // user.
- //
-#ifndef ANDROID
- if (control -> ShmemServer == 1 &&
- control -> ShmemServerSize > 0 &&
- enableServer == 1)
- {
- memcpy(buffer + 8, "MIT-SHM", 7);
- }
- else
- {
- memcpy(buffer + 8, "NO-MIT-", 7);
- }
-#else
- cerr << "Info: handleShmemRequest: In android no shared memory. Returning NO-MIT- answer\n";
-
- memcpy(buffer + 8, "NO-MIT-", 7);
-#endif
- sequenceQueue_.push(clientSequence_, opcode,
- opcodeStore_ -> getShmemParameters, stage);
-
- //
- // Save the sequence number so we can
- // later identify any matching X error
- // received from server.
- //
-
- shmemState_ -> sequence = clientSequence_;
-
- break;
- }
- case 1:
- {
- if (shmemState_ -> present == 1)
- {
- //
- // Make the segment read-write for everybody on
- // Cygwin (to avoid any lack of support or any
- // performance issue) and on MacOS/X (where the
- // 0600 mask doesn't seem to work).
- //
-
- #if defined(__CYGWIN32__) || defined(__APPLE__)
-
- int permissions = 0777;
-
- #else
-
- int permissions = 0600;
-
- #endif
-
- shmemState_ -> size = control -> ShmemServerSize;
-
-#ifndef ANDROID
- shmemState_ -> id = shmget(IPC_PRIVATE, shmemState_ -> size,
- IPC_CREAT | permissions);
-#else
- cerr << "Info: handleShmemReqyest: In android no shared memory (shmget). This message should not be displayed present should never be 1 in android\n";
- shmemState_ -> id = -1;
-#endif
- if (shmemState_ -> id >= 0)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmemRequest: Allocated shared memory "
- << "segment of " << shmemState_ -> size
- << " bytes with id " << shmemState_ -> id
- << ".\n" << logofs_flush;
- #endif
-
-
-#ifndef ANDROID
- shmemState_ -> address = shmat(shmemState_ -> id, 0, 0);
-#else
- cerr << "Info: handleShmemReqyest: In android no shared memory (shmat). This message should not be displayed. present should never be 1 in android\n";
- shmemState_ -> address = NULL;
-#endif
- if (shmemState_ -> address != NULL)
- {
- #ifdef TEST
- *logofs << "handleShmemRequest: Sending X_ShmAttach request "
- << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int)
- opcodeStore_ -> getShmemParameters << " in stage "
- << stage << ".\n" << logofs_flush;
- #endif
-
- opcode = shmemState_ -> opcode;
-
- size = 16;
- buffer = writeBuffer_.addMessage(size);
-
- *(buffer + 1) = X_ShmAttach;
-
- PutULONG(shmemState_ -> segment, buffer + 4, bigEndian_);
- PutULONG(shmemState_ -> id, buffer + 8, bigEndian_);
-
- *(buffer + 12) = 1;
-
- shmemState_ -> sequence = clientSequence_;
-
- break;
- }
- else
- {
- #ifdef WARNING
- *logofs << "handleShmemRequest: WARNING! Can't attach the shared "
- << "memory segment. Error is " << EGET() << " '"
- << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Warning" << ": Can't attach the shared memory "
- << "segment. Error is " << EGET() << " '"
- << ESTR() << "'.\n";
- }
- }
- else
- {
- #ifndef __CYGWIN32__
-
- #ifdef WARNING
- *logofs << "handleShmemRequest: WARNING! Can't create the shared "
- << "memory segment. Error is " << EGET() << " '"
- << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- cerr << "Warning" << ": Can't create the shared memory "
- << "segment. Error is " << EGET() << " '"
- << ESTR() << "'.\n";
-
- #else
-
- #ifdef TEST
- *logofs << "handleShmemRequest: WARNING! Can't create the shared "
- << "memory segment. Error is " << EGET() << " '"
- << ESTR() << "'.\n" << logofs_flush;
- #endif
-
- #endif
- }
- }
-
- if (shmemState_ -> present != 0)
- {
- #ifdef TEST
- *logofs << "handleShmemRequest: Resetting shared memory "
- << "presence flag for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- shmemState_ -> present = 0;
- }
-
- handleNullRequest(opcode, buffer, size);
-
- break;
- }
- default:
- {
- #ifdef TEST
- *logofs << "handleShmemRequest: Sending X_GetInputFocus request "
- << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int)
- opcodeStore_ -> getShmemParameters << " in stage "
- << stage << ".\n" << logofs_flush;
- #endif
-
- opcode = X_GetInputFocus;
-
- size = 4;
- buffer = writeBuffer_.addMessage(size);
-
- sequenceQueue_.push(clientSequence_, opcode,
- opcodeStore_ -> getShmemParameters, stage);
- break;
- }
- }
-
- shmemState_ -> stage += 1;
-
- return 1;
-}
-
-//
-// Handling of MIT-SHM extension has been plugged late in
-// the design, so we have to make some assumptions. Image
-// is a X_PutImage request contained either in the scratch
-// buffer or in the normal write buffer. We need to move
-// the image data to the shared memory segment and replace
-// the X_PutImage request with a X_ShmPutImage.
-//
-
-int ServerChannel::handleShmem(unsigned char &opcode, unsigned char *&buffer,
- unsigned int &size)
-{
- if (shmemState_ == NULL || shmemState_ -> enabled != 1)
- {
- #ifdef TEST
-
- if (shmemState_ != NULL)
- {
- *logofs << "handleShmem: PANIC! Shared memory "
- << "state found but support is not enabled "
- << "for FD#" << fd_ << " in stage "
- << shmemState_ -> stage << ".\n"
- << logofs_flush;
- }
-
- #endif
-
- return 0;
- }
-#ifdef ANDROID
- cerr << "Info: handleShmem: In android no shared memory. enabled should never be 1. This should not be displayed\n";
- return 0;
-#endif
-
- //
- // Ignore null requests and requests that will not result
- // in a single X_PutImage. To conform with the other func-
- // tions, we get the opcode passed as a parameter. It can
- // be zero if we don't want the write loop to put opcode
- // and length in the resulting buffer. Anyway we are only
- // interested in the original opcode of the request, that
- // is stored in the image state.
- //
-
- unsigned char *dstData = buffer + 24;
- unsigned int dstDataSize = size - 24;
-
- if (dstDataSize == 0 || dstDataSize >
- (unsigned int) control -> MaximumRequestSize)
- {
- #ifdef TEST
- *logofs << "handleShmem: Ignoring image with opcode "
- << (unsigned int) imageState_ -> opcode
- << " and size " << size << " for FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
-
- #ifdef TEST
- *logofs << "handleShmem: Handling image with opcode "
- << (unsigned int) imageState_ -> opcode
- << " and size " << size << " for FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- //
- // Get image data from buffer.
- //
-
- if (imageState_ -> opcode == X_PutImage)
- {
- //
- // We still need to get the image's data.
- //
-
- imageState_ -> format = *(buffer + 1);
-
- imageState_ -> drawable = GetULONG(buffer + 4, bigEndian_);
- imageState_ -> gcontext = GetULONG(buffer + 8, bigEndian_);
-
- imageState_ -> dstWidth = GetUINT(buffer + 12, bigEndian_);
- imageState_ -> dstHeight = GetUINT(buffer + 14, bigEndian_);
-
- imageState_ -> srcX = 0;
- imageState_ -> srcY = 0;
-
- imageState_ -> srcWidth = imageState_ -> dstWidth;
- imageState_ -> srcHeight = imageState_ -> dstHeight;
-
- imageState_ -> dstX = GetUINT(buffer + 16, bigEndian_);
- imageState_ -> dstY = GetUINT(buffer + 18, bigEndian_);
-
- imageState_ -> leftPad = *(buffer + 20);
- imageState_ -> dstDepth = *(buffer + 21);
-
- imageState_ -> dstLines = imageState_ -> dstHeight;
-
- imageState_ -> dstLength = size - 24;
- }
-
- //
- // Skip the MIT-SHM operation if the image
- // is 1 bits-per-plane.
- //
-
- if (imageState_ -> dstDepth == 1)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmem: Ignoring image with opcode "
- << (unsigned int) imageState_ -> opcode << " depth "
- << (unsigned int) imageState_ -> dstDepth << " and "
- << "size " << size << " for FD#" << fd_
- << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
-
- //
- // If the image can't fit in the available
- // space, check if the completion event is
- // arrived.
- //
-
- #if defined(TEST) || defined(INFO)
-
- if (isTimestamp(shmemState_ -> last) == 0 &&
- shmemState_ -> offset != 0)
- {
- *logofs << "handleShmem: PANIC! No timestamp for sequence "
- << shmemState_ -> sequence << " with offset "
- << shmemState_ -> offset << ".\n"
- << logofs_flush;
- }
-
- #endif
-
- if (shmemState_ -> offset + imageState_ -> dstLength >
- shmemState_ -> size)
- {
- if (imageState_ -> dstLength > shmemState_ -> size)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmem: WARNING! Can't fit the image "
- << "in the available memory segment for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
- else if (handleShmemEvent() <= 0)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmem: WARNING! Missing completion "
- << "after " << diffTimestamp(shmemState_ -> last,
- getTimestamp()) << " Ms for shared memory "
- << "for FD#" << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 0;
- }
- }
-
- //
- // Let image start at current offset
- // in the shared segment.
- //
-
- #ifdef TEST
- *logofs << "handleShmem: Copying " << dstDataSize
- << " bytes to shared memory at offset "
- << shmemState_ -> offset << " for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- memcpy((unsigned char *) shmemState_ -> address +
- shmemState_ -> offset, dstData, dstDataSize);
-
- //
- // Get rid of the original X_PutImage
- // request.
- //
-
- if (writeBuffer_.getScratchData() != NULL)
- {
- writeBuffer_.removeScratchMessage();
- }
- else
- {
- writeBuffer_.removeMessage(size);
- }
-
- //
- // Add a X_ShmPutImage request to the
- // write buffer.
- //
-
- buffer = writeBuffer_.addMessage(40);
-
- *buffer = shmemState_ -> opcode;
-
- *(buffer + 1) = X_ShmPutImage;
-
- PutUINT(40 >> 2, buffer + 2, bigEndian_);
-
- PutULONG(imageState_ -> drawable, buffer + 4, bigEndian_);
- PutULONG(imageState_ -> gcontext, buffer + 8, bigEndian_);
-
- PutUINT(imageState_ -> dstWidth, buffer + 12, bigEndian_);
- PutUINT(imageState_ -> dstLines, buffer + 14, bigEndian_);
-
- PutUINT(imageState_ -> srcX, buffer + 16, bigEndian_);
- PutUINT(imageState_ -> srcY, buffer + 18, bigEndian_);
-
- PutUINT(imageState_ -> dstWidth, buffer + 20, bigEndian_);
- PutUINT(imageState_ -> dstLines, buffer + 22, bigEndian_);
-
- PutUINT(imageState_ -> dstX, buffer + 24, bigEndian_);
- PutUINT(imageState_ -> dstY, buffer + 26, bigEndian_);
-
- *(buffer + 28) = imageState_ -> dstDepth;
- *(buffer + 29) = imageState_ -> format;
- *(buffer + 30) = 1;
-
- PutULONG(shmemState_ -> segment, buffer + 32, bigEndian_);
- PutULONG(shmemState_ -> offset, buffer + 36, bigEndian_);
-
- shmemState_ -> offset += dstDataSize;
-
- shmemState_ -> sequence = clientSequence_;
- shmemState_ -> last = getTimestamp();
-
- #ifdef TEST
- *logofs << "handleShmem: Saved shared memory sequence "
- << shmemState_ -> sequence << " for FD#" << fd_
- << " with offset " << shmemState_ -> offset
- << " at " << strMsTimestamp() << ".\n"
- << logofs_flush;
- #endif
-
- //
- // Make the X server read immediately
- // from the shared memory buffer and
- // produce the completion event.
- //
-
- handleFlush(flush_if_any);
-
- return 1;
-}
-
-//
-// Try to read more events from the socket in the
-// attempt to get the completion event required
-// to reset the MIT-SHM segment.
-//
-
-int ServerChannel::handleShmemEvent()
-{
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmemEvent: Waiting for shared memory "
- << "sequence " << shmemState_ -> sequence
- << " for X server FD#" << fd_ << ".\n"
- << logofs_flush;
-
- T_timestamp startTs = getTimestamp();
-
- #endif
-
- while (isTimestamp(shmemState_ -> last) != 0)
- {
- if (handleWait(control -> ShmemTimeout) <= 0)
- {
- break;
- }
- #if defined(TEST) || defined(INFO)
- else
- {
- *logofs << "handleShmemEvent: WARNING! Encoded events "
- << "for FD#" << fd_ << " at " << strMsTimestamp()
- << ".\n" << logofs_flush;
- }
- #endif
- }
-
- if (isTimestamp(shmemState_ -> last) == 0)
- {
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmemEvent: Spent "
- << diffTimestamp(startTs, getTimestamp()) << " Ms "
- << "waiting for shared memory sequence for FD#"
- << fd_ << ".\n" << logofs_flush;
- #endif
-
- return 1;
- }
-
- #if defined(TEST) || defined(INFO)
- *logofs << "handleShmemEvent: WARNING! Can't reset shared "
- << "memory sequence for FD#" << fd_ << " after "
- << diffTimestamp(shmemState_ -> last, getTimestamp())
- << " Ms.\n" << logofs_flush;
- #endif
-
- return 0;
-}
-
-int ServerChannel::checkShmemEvent(unsigned char event, unsigned short sequence,
- const unsigned char *buffer)
-{
- if (isTimestamp(shmemState_ -> last) == 1 &&
- sequence == shmemState_ -> sequence)
- {
- #ifdef TEST
- *logofs << "checkShmemEvent: Reset shared memory sequence "
- << shmemState_ -> sequence << " for FD#" << fd_
- << " after " << diffTimestamp(shmemState_ -> last,
- getTimestamp()) << " Ms.\n" << logofs_flush;
- #endif
-
- shmemState_ -> sequence = 0;
- shmemState_ -> offset = 0;
- shmemState_ -> last = nullTimestamp();
- }
- #ifdef TEST
- else
- {
- *logofs << "checkShmemEvent: Skipping past shared memory "
- << "image sequence " << sequence << " for FD#"
- << fd_ << ".\n" << logofs_flush;
- }
- #endif
-
- return 1;
-}
-
-int ServerChannel::checkShmemError(unsigned char error, unsigned short sequence,
- const unsigned char *buffer)
-{
- #ifdef TEST
-
- *logofs << "checkShmemError: WARNING! Failed operation for "
- << "FD#" << fd_ << " in stage " << shmemState_ -> stage
- << " with ERR_CODE#" << (unsigned int) *(buffer + 1);
-
- *logofs << " RES_ID#" << GetULONG(buffer + 4, bigEndian_);
-
- *logofs << " MIN_OP#" << GetUINT(buffer + 8, bigEndian_);
-
- *logofs << " MAJ_OP#" << (unsigned int) *(buffer + 10);
-
- *logofs << " sequence " << sequence << ".\n";
-
- *logofs << logofs_flush;
-
- #endif
-
- //
- // If enabled flag is <= 0 we are still
- // in the inizialization phase. In this
- // case force presence to false.
- //
-
- if (shmemState_ -> enabled != 1)
- {
- if (shmemState_ -> present != 0)
- {
- #ifdef TEST
- *logofs << "checkShmemError: Resetting shared memory "
- << "presence flag for FD#" << fd_ << ".\n"
- << logofs_flush;
- #endif
-
- shmemState_ -> present = 0;
- }
-
- return 0;
- }
-
- if (shmemState_ -> sequence == sequence)
- {
- //
- // Reset the sequence and timestamp.
- //
-
- shmemState_ -> sequence = 0;
- shmemState_ -> offset = 0;
- shmemState_ -> last = nullTimestamp();
- }
-
- return 1;
-}
-
-int ServerChannel::handleFontRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- //
- // Send a synchronization request and use
- // the reply to return the requested font
- // path.
- //
-
- #ifdef TEST
- *logofs << "handleFontRequest: Sending X_GetInputFocus request "
- << "for FD#" << fd_ << " due to OPCODE#" << (unsigned int)
- opcodeStore_ -> getFontParameters << ".\n"
- << logofs_flush;
- #endif
-
- opcode = X_GetInputFocus;
-
- size = 4;
- buffer = writeBuffer_.addMessage(size);
-
- sequenceQueue_.push(clientSequence_, X_GetInputFocus,
- opcodeStore_ -> getFontParameters);
-
- return 1;
-}
-
-int ServerChannel::handleFontReply(EncodeBuffer &encodeBuffer, const unsigned char opcode,
- const unsigned char *buffer, const unsigned int size)
-{
- #ifdef TEST
- *logofs << "handleFontReply: Encoding font operation "
- << "reply with size " << size << ".\n"
- << logofs_flush;
- #endif
-
- char data[256];
-
- if (fontPort_ != -1)
- {
- sprintf(data + 1, "tcp/localhost:%d", fontPort_);
- }
- else
- {
- *(data + 1) = '\0';
- }
-
- *data = strlen(data + 1);
-
- unsigned char *next = (unsigned char *) data;
-
- unsigned int length = (unsigned int) (*next++);
-
- encodeBuffer.encodeValue(length, 8);
-
- encodeBuffer.encodeTextData(next, length);
-
- return 1;
-}
-
-int ServerChannel::handleCacheRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- unsigned int mask;
-
- decodeBuffer.decodeCachedValue(mask, 32, clientCache_ ->
- setCacheParametersCache);
-
- splitState_.save = (mask >> 8) & 0xff;
- splitState_.load = mask & 0xff;
-
- #ifdef TEST
- *logofs << "handleCacheRequest: Set cache parameters to "
- << "save " << splitState_.save << " load "
- << splitState_.load << ".\n" << logofs_flush;
- #endif
-
- handleNullRequest(opcode, buffer, size);
-
- return 1;
-}
-
-int ServerChannel::handleStartSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- //
- // Prepare for the split for the selected
- // resource. Old proxy versions only used
- // the split store at position 0.
- //
-
- // Since ProtoStep7 (#issue 108)
- unsigned char resource;
-
- decodeBuffer.decodeCachedValue(resource, 8,
- clientCache_ -> resourceCache);
-
- splitState_.resource = resource;
-
- splitState_.current = splitState_.resource;
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleStartSplitRequest: SPLIT! Registered id "
- << splitState_.resource << " as resource "
- << "waiting for a split.\n" << logofs_flush;
- #endif
-
- handleNullRequest(opcode, buffer, size);
-
- return 1;
-}
-
-int ServerChannel::handleEndSplitRequest(DecodeBuffer &decodeBuffer, unsigned char &opcode,
- unsigned char *&buffer, unsigned int &size)
-{
- //
- // Verify that the agent resource matches.
- //
-
- // Since ProtoStep7 (#issue 108)
- unsigned char resource;
-
- decodeBuffer.decodeCachedValue(resource, 8,
- clientCache_ -> resourceCache);
-
- #ifdef TEST
-
- if (splitState_.resource == nothing)
- {
- #ifdef PANIC
- *logofs << "handleEndSplitRequest: PANIC! SPLIT! Received an end of "
- << "split for resource id " << (unsigned int) *(buffer + 1)
- << " without a previous start.\n"
- << logofs_flush;
- #endif
-
- HandleCleanup();
- }
- else if (resource != splitState_.resource)
- {
- #ifdef PANIC
- *logofs << "handleEndSplitRequest: PANIC! SPLIT! Invalid resource id "
- << resource << " received while waiting for resource id "
- << splitState_.resource << ".\n" << logofs_flush;
- #endif
-
- HandleCleanup();
- }
-
- #endif
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleEndSplitRequest: SPLIT! Reset id "
- << splitState_.resource << " as resource "
- << "selected for splits.\n" << logofs_flush;
- #endif
-
- splitState_.resource = nothing;
-
- handleNullRequest(opcode, buffer, size);
-
- return 1;
-}
-
-int ServerChannel::handleSplitChecksum(DecodeBuffer &decodeBuffer, T_checksum &checksum)
-{
- unsigned int receive;
-
- // Since ProtoStep7 (#issue 108)
- decodeBuffer.decodeBoolValue(receive);
-
- if (receive == 1)
- {
- checksum = new md5_byte_t[MD5_LENGTH];
-
- for (unsigned int i = 0; i < MD5_LENGTH; i++)
- {
- decodeBuffer.decodeValue(receive, 8);
-
- if (checksum != NULL)
- {
- checksum[i] = (unsigned char) receive;
- }
- }
-
- #if defined(TEST) || defined(SPLIT)
- *logofs << "handleSplitChecksum: SPLIT! Received checksum "
- << "[" << DumpChecksum(checksum) << "].\n"
- << logofs_flush;
- #endif
-
- return 1;
- }
-
- return 0;
-}
-
-void ServerChannel::handleShmemStateAlloc()
-{
- if (shmemState_ == NULL)
- {
- shmemState_ = new T_shmem_state();
-
- shmemState_ -> stage = -1;
- shmemState_ -> present = -1;
- shmemState_ -> enabled = -1;
-
- shmemState_ -> segment = -1;
- shmemState_ -> id = -1;
- shmemState_ -> address = NULL;
- shmemState_ -> size = 0;
-
- shmemState_ -> opcode = 0xff;
- shmemState_ -> event = 0xff;
- shmemState_ -> error = 0xff;
-
- shmemState_ -> sequence = 0;
- shmemState_ -> offset = 0;
- shmemState_ -> last = nullTimestamp();
-
- shmemState_ -> checked = 0;
- }
-}
-
-void ServerChannel::handleShmemStateRemove()
-{
- if (shmemState_ != NULL)
- {
- if (shmemState_ -> address != NULL)
- {
-#ifndef ANDROID
- shmdt((char *) shmemState_ -> address);
-#else
- cerr << "Info: handleShmemStateRemove: In android no shared memory. This should not be displayed. address should always be NULL\n";
-#endif
- }
-
- if (shmemState_ -> id > 0)
- {
-#ifndef ANDROID
- shmctl(shmemState_ -> id, IPC_RMID, 0);
-#else
- cerr << "Info: handleShmemStateRemove: In android no shared memory. This should not be displayed. id should always be 0\n";
-#endif
- }
-
- delete shmemState_;
-
- shmemState_ = NULL;
- }
-}
-
-void ServerChannel::handleUnpackStateInit(int resource)
-{
- if (unpackState_[resource] == NULL)
- {
- unpackState_[resource] = new T_unpack_state();
-
- if (unpackState_[resource] == NULL)
- {
- #ifdef PANIC
- *logofs << "handleUnpackStateInit: PANIC! Can't allocate "
- << "memory for unpack state in context [A].\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't allocate memory for "
- << "unpack state in context [A].\n";
-
- HandleAbort();
- }
-
- unpackState_[resource] -> geometry = NULL;
- unpackState_[resource] -> colormap = NULL;
- unpackState_[resource] -> alpha = NULL;
- }
-}
-
-void ServerChannel::handleUnpackAllocGeometry(int resource)
-{
- if (unpackState_[resource] -> geometry == NULL)
- {
- unpackState_[resource] -> geometry = new T_geometry();
-
- if (unpackState_[resource] -> geometry == NULL)
- {
- #ifdef PANIC
- *logofs << "handleUnpackAllocGeometry: PANIC! Can't allocate "
- << "memory for unpack state in context [B].\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't allocate memory for "
- << "unpack state in context [B].\n";
-
- HandleAbort();
- }
-
- unpackState_[resource] -> geometry -> depth1_bpp = 4;
- unpackState_[resource] -> geometry -> depth4_bpp = 4;
- unpackState_[resource] -> geometry -> depth8_bpp = 8;
- unpackState_[resource] -> geometry -> depth16_bpp = 16;
- unpackState_[resource] -> geometry -> depth24_bpp = 32;
- unpackState_[resource] -> geometry -> depth32_bpp = 32;
-
- unpackState_[resource] -> geometry -> red_mask = 0xff0000;
- unpackState_[resource] -> geometry -> green_mask = 0x00ff00;
- unpackState_[resource] -> geometry -> blue_mask = 0x0000ff;
-
- unpackState_[resource] -> geometry -> image_byte_order = imageByteOrder_;
- unpackState_[resource] -> geometry -> bitmap_bit_order = bitmapBitOrder_;
- unpackState_[resource] -> geometry -> scanline_unit = scanlineUnit_;
- unpackState_[resource] -> geometry -> scanline_pad = scanlinePad_;
- }
-}
-
-void ServerChannel::handleUnpackAllocColormap(int resource)
-{
- if (unpackState_[resource] -> colormap == NULL)
- {
- unpackState_[resource] -> colormap = new T_colormap();
-
- if (unpackState_[resource] -> colormap == NULL)
- {
- #ifdef PANIC
- *logofs << "handleUnpackAllocColormap: PANIC! Can't allocate "
- << "memory for unpack state in context [C].\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't allocate memory for "
- << "unpack state in context [C].\n";
-
- HandleAbort();
- }
-
- unpackState_[resource] -> colormap -> entries = 0;
- unpackState_[resource] -> colormap -> data = NULL;
- }
-}
-
-void ServerChannel::handleUnpackAllocAlpha(int resource)
-{
- if (unpackState_[resource] -> alpha == NULL)
- {
- unpackState_[resource] -> alpha = new T_alpha();
-
- if (unpackState_[resource] -> alpha == NULL)
- {
- #ifdef PANIC
- *logofs << "handleUnpackAllocAlpha: PANIC! Can't allocate "
- << "memory for unpack state in context [D].\n"
- << logofs_flush;
- #endif
-
- cerr << "Error" << ": Can't allocate memory for "
- << "unpack state in context [D].\n";
-
- HandleAbort();
- }
-
- unpackState_[resource] -> alpha -> entries = 0;
- unpackState_[resource] -> alpha -> data = NULL;
- }
-}
-
-void ServerChannel::handleUnpackStateRemove(int resource)
-{
- if (unpackState_[resource] != NULL)
- {
- delete unpackState_[resource] -> geometry;
-
- if (unpackState_[resource] -> colormap != NULL)
- {
- delete [] unpackState_[resource] -> colormap -> data;
- }
-
- delete unpackState_[resource] -> colormap;
-
- if (unpackState_[resource] -> alpha != NULL)
- {
- delete [] unpackState_[resource] -> alpha -> data;
- }
-
- delete unpackState_[resource] -> alpha;
-
- delete unpackState_[resource];
-
- unpackState_[resource] = NULL;
- }
-}
-
-void ServerChannel::handleEncodeCharInfo(const unsigned char *nextSrc, EncodeBuffer &encodeBuffer)
-{
- unsigned int value = GetUINT(nextSrc, bigEndian_) |
- (GetUINT(nextSrc + 10, bigEndian_) << 16);
-
- encodeBuffer.encodeCachedValue(value, 32,
- *serverCache_ -> queryFontCharInfoCache[0], 6);
-
- nextSrc += 2;
-
- for (unsigned int i = 1; i < 5; i++)
- {
- unsigned int value = GetUINT(nextSrc, bigEndian_);
-
- nextSrc += 2;
-
- encodeBuffer.encodeCachedValue(value, 16,
- *serverCache_ -> queryFontCharInfoCache[i], 6);
- }
-}
-
-int ServerChannel::setBigEndian(int flag)
-{
- bigEndian_ = flag;
-
- readBuffer_.setBigEndian(flag);
-
- return 1;
-}
-
-int ServerChannel::setReferences()
-{
- #ifdef TEST
- *logofs << "ServerChannel: Initializing the static "
- << "members for the server channels.\n"
- << logofs_flush;
- #endif
-
- #ifdef REFERENCES
-
- references_ = 0;
-
- #endif
-
- return 1;
-}