1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ 4 /* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */ 5 /* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */ 6 /* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */ 7 /* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/ 8 /* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ 9 /* */ 10 /* NXCOMP, NX protocol compression and NX extensions to this software */ 11 /* are copyright of the aforementioned persons and companies. */ 12 /* */ 13 /* Redistribution and use of the present software is allowed according */ 14 /* to terms specified in the file LICENSE.nxcomp which comes in the */ 15 /* source distribution. */ 16 /* */ 17 /* All rights reserved. */ 18 /* */ 19 /* NOTE: This software has received contributions from various other */ 20 /* contributors, only the core maintainers and supporters are listed as */ 21 /* copyright holders. Please contact us, if you feel you should be listed */ 22 /* as copyright holder, as well. */ 23 /* */ 24 /**************************************************************************/ 25 26 // 27 // Include the template for 28 // this message class. 29 // 30 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 35 #include "RenderComposite.h" 36 37 // 38 // Set the verbosity level. 39 // 40 41 #define PANIC 42 #define WARNING 43 #undef TEST 44 #undef DEBUG 45 46 #include MESSAGE_TAGS 47 48 // 49 // Message handling methods. 50 // 51 52 MESSAGE_BEGIN_ENCODE_MESSAGE 53 { 54 ClientCache *clientCache = (ClientCache *) channelCache; 55 56 encodeBuffer.encodeCachedValue(*(buffer + 4), 8, 57 clientCache -> renderOpCache); 58 59 encodeBuffer.encodeXidValue(GetULONG(buffer + 8, bigEndian), 60 clientCache -> renderSrcPictureCache); 61 62 encodeBuffer.encodeXidValue(GetULONG(buffer + 12, bigEndian), 63 clientCache -> renderMaskPictureCache); 64 65 encodeBuffer.encodeXidValue(GetULONG(buffer + 16, bigEndian), 66 clientCache -> renderDstPictureCache); 67 68 // 69 // Src X and Y. 70 // 71 72 encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 20, bigEndian), 73 clientCache -> renderLastX, 16, 74 clientCache -> renderXCache, 11); 75 76 encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 22, bigEndian), 77 clientCache -> renderLastY, 16, 78 clientCache -> renderYCache, 11); 79 // 80 // Mask X and Y. 81 // 82 83 encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 24, bigEndian), 84 clientCache -> renderLastX, 16, 85 clientCache -> renderXCache, 11); 86 87 encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 26, bigEndian), 88 clientCache -> renderLastY, 16, 89 clientCache -> renderYCache, 11); 90 91 // 92 // Dst X and Y. 93 // 94 95 encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 28, bigEndian), 96 clientCache -> renderLastX, 16, 97 clientCache -> renderXCache, 11); 98 99 encodeBuffer.encodeDiffCachedValue(GetUINT(buffer + 30, bigEndian), 100 clientCache -> renderLastY, 16, 101 clientCache -> renderYCache, 11); 102 103 // 104 // Width and height. 105 // 106 107 encodeBuffer.encodeCachedValue(GetUINT(buffer + 32, bigEndian), 16, 108 clientCache -> renderWidthCache, 11); 109 110 encodeBuffer.encodeCachedValue(GetUINT(buffer + 34, bigEndian), 16, 111 clientCache -> renderHeightCache, 11); 112 113 #ifdef TEST 114 *logofs << name() << ": Encoded message. Type is " 115 << (unsigned int) *(buffer + 1) << " size is " 116 << size << ".\n" << logofs_flush; 117 #endif 118 } 119 MESSAGE_END_ENCODE_MESSAGE 120 121 MESSAGE_BEGIN_DECODE_MESSAGE 122 { 123 ClientCache *clientCache = (ClientCache *) channelCache; 124 125 unsigned int value; 126 127 *(buffer + 1) = type; 128 129 decodeBuffer.decodeCachedValue(*(buffer + 4), 8, 130 clientCache -> renderOpCache); 131 132 decodeBuffer.decodeXidValue(value, clientCache -> renderSrcPictureCache); 133 134 PutULONG(value, buffer + 8, bigEndian); 135 136 decodeBuffer.decodeXidValue(value, clientCache -> renderMaskPictureCache); 137 138 PutULONG(value, buffer + 12, bigEndian); 139 140 decodeBuffer.decodeXidValue(value, clientCache -> renderDstPictureCache); 141 142 PutULONG(value, buffer + 16, bigEndian); 143 144 // 145 // Src X and Y. 146 // 147 148 decodeBuffer.decodeDiffCachedValue(value, 149 clientCache -> renderLastX, 16, 150 clientCache -> renderXCache, 11); 151 152 PutUINT(clientCache -> renderLastX, buffer + 20, bigEndian); 153 154 decodeBuffer.decodeDiffCachedValue(value, 155 clientCache -> renderLastY, 16, 156 clientCache -> renderYCache, 11); 157 158 PutUINT(clientCache -> renderLastY, buffer + 22, bigEndian); 159 160 // 161 // Mask X and Y. 162 // 163 164 decodeBuffer.decodeDiffCachedValue(value, 165 clientCache -> renderLastX, 16, 166 clientCache -> renderXCache, 11); 167 168 PutUINT(clientCache -> renderLastX, buffer + 24, bigEndian); 169 170 decodeBuffer.decodeDiffCachedValue(value, 171 clientCache -> renderLastY, 16, 172 clientCache -> renderYCache, 11); 173 174 PutUINT(clientCache -> renderLastY, buffer + 26, bigEndian); 175 176 // 177 // Dst X and Y. 178 // 179 180 decodeBuffer.decodeDiffCachedValue(value, 181 clientCache -> renderLastX, 16, 182 clientCache -> renderXCache, 11); 183 184 PutUINT(clientCache -> renderLastX, buffer + 28, bigEndian); 185 186 decodeBuffer.decodeDiffCachedValue(value, 187 clientCache -> renderLastY, 16, 188 clientCache -> renderYCache, 11); 189 190 PutUINT(clientCache -> renderLastY, buffer + 30, bigEndian); 191 192 // 193 // Width and height. 194 // 195 196 decodeBuffer.decodeCachedValue(value, 16, 197 clientCache -> renderWidthCache, 11); 198 199 PutUINT(value, buffer + 32, bigEndian); 200 201 decodeBuffer.decodeCachedValue(value, 16, 202 clientCache -> renderHeightCache, 11); 203 204 PutUINT(value, buffer + 34, bigEndian); 205 206 #ifdef TEST 207 *logofs << name() << ": Decoded message. Type is " 208 << (unsigned int) type << " size is " << size 209 << ".\n" << logofs_flush; 210 #endif 211 } 212 MESSAGE_END_DECODE_MESSAGE 213 214 MESSAGE_BEGIN_PARSE_IDENTITY 215 { 216 RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; 217 218 renderExtension -> data.composite.type = *(buffer + 1); 219 renderExtension -> data.composite.op = *(buffer + 4); 220 221 renderExtension -> data.composite.src_id = GetULONG(buffer + 8, bigEndian); 222 renderExtension -> data.composite.msk_id = GetULONG(buffer + 12, bigEndian); 223 renderExtension -> data.composite.dst_id = GetULONG(buffer + 16, bigEndian); 224 225 renderExtension -> data.composite.src_x = GetUINT(buffer + 20, bigEndian); 226 renderExtension -> data.composite.src_y = GetUINT(buffer + 22, bigEndian); 227 228 renderExtension -> data.composite.msk_x = GetUINT(buffer + 24, bigEndian); 229 renderExtension -> data.composite.msk_y = GetUINT(buffer + 26, bigEndian); 230 231 renderExtension -> data.composite.dst_x = GetUINT(buffer + 28, bigEndian); 232 renderExtension -> data.composite.dst_y = GetUINT(buffer + 30, bigEndian); 233 234 renderExtension -> data.composite.width = GetUINT(buffer + 32, bigEndian); 235 renderExtension -> data.composite.height = GetUINT(buffer + 34, bigEndian); 236 237 #ifdef TEST 238 *logofs << name() << ": Parsed identity. Type is " 239 << (unsigned int) renderExtension -> data.composite.type 240 << " size is " << renderExtension -> size_ << ".\n" 241 << logofs_flush; 242 #endif 243 } 244 MESSAGE_END_PARSE_IDENTITY 245 246 MESSAGE_BEGIN_UNPARSE_IDENTITY 247 { 248 RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; 249 250 *(buffer + 1) = renderExtension -> data.composite.type; 251 *(buffer + 4) = renderExtension -> data.composite.op; 252 253 PutULONG(renderExtension -> data.composite.src_id, buffer + 8, bigEndian); 254 PutULONG(renderExtension -> data.composite.msk_id, buffer + 12, bigEndian); 255 PutULONG(renderExtension -> data.composite.dst_id, buffer + 16, bigEndian); 256 257 PutUINT(renderExtension -> data.composite.src_x, buffer + 20, bigEndian); 258 PutUINT(renderExtension -> data.composite.src_y, buffer + 22, bigEndian); 259 260 PutUINT(renderExtension -> data.composite.msk_x, buffer + 24, bigEndian); 261 PutUINT(renderExtension -> data.composite.msk_y, buffer + 26, bigEndian); 262 263 PutUINT(renderExtension -> data.composite.dst_x, buffer + 28, bigEndian); 264 PutUINT(renderExtension -> data.composite.dst_y, buffer + 30, bigEndian); 265 266 PutUINT(renderExtension -> data.composite.width, buffer + 32, bigEndian); 267 PutUINT(renderExtension -> data.composite.height, buffer + 34, bigEndian); 268 269 #ifdef TEST 270 *logofs << name() << ": Unparsed identity. Type is " 271 << (unsigned int) renderExtension -> data.composite.type 272 << " size is " << renderExtension -> size_ << ".\n" 273 << logofs_flush; 274 #endif 275 } 276 MESSAGE_END_UNPARSE_IDENTITY 277 278 MESSAGE_BEGIN_IDENTITY_CHECKSUM 279 { 280 // 281 // Include the minor opcode and size in the 282 // identity, plus the operator, the x and y 283 // of the source and mask and the width and 284 // height of the destination. 285 // 286 287 md5_append(md5_state, buffer + 1, 4); 288 md5_append(md5_state, buffer + 20, 8); 289 md5_append(md5_state, buffer + 32, 4); 290 } 291 MESSAGE_END_IDENTITY_CHECKSUM 292 293 MESSAGE_BEGIN_ENCODE_UPDATE 294 { 295 RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; 296 RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage; 297 298 ClientCache *clientCache = (ClientCache *) channelCache; 299 300 #ifdef DEBUG 301 *logofs << name() << ": Source " << renderExtension -> data.composite.src_id 302 << " mask " << renderExtension -> data.composite.msk_id 303 << " destination " << renderExtension -> data.composite.msk_id 304 << ".\n" << logofs_flush; 305 #endif 306 307 encodeBuffer.encodeXidValue(renderExtension -> data.composite.src_id, 308 clientCache -> renderSrcPictureCache); 309 310 cachedRenderExtension -> data.composite.src_id = 311 renderExtension -> data.composite.src_id; 312 313 encodeBuffer.encodeXidValue(renderExtension -> data.composite.msk_id, 314 clientCache -> renderMaskPictureCache); 315 316 cachedRenderExtension -> data.composite.msk_id = 317 renderExtension -> data.composite.msk_id; 318 319 encodeBuffer.encodeXidValue(renderExtension -> data.composite.dst_id, 320 clientCache -> renderDstPictureCache); 321 322 cachedRenderExtension -> data.composite.dst_id = 323 renderExtension -> data.composite.dst_id; 324 325 // 326 // Dst X and Y. 327 // 328 329 unsigned int value; 330 unsigned int previous; 331 332 value = renderExtension -> data.composite.dst_x; 333 previous = cachedRenderExtension -> data.composite.dst_x; 334 335 encodeBuffer.encodeDiffCachedValue(value, previous, 16, 336 clientCache -> renderXCache, 11); 337 338 cachedRenderExtension -> data.composite.dst_x = value; 339 340 value = renderExtension -> data.composite.dst_y; 341 previous = cachedRenderExtension -> data.composite.dst_y; 342 343 encodeBuffer.encodeDiffCachedValue(value, previous, 16, 344 clientCache -> renderYCache, 11); 345 346 cachedRenderExtension -> data.composite.dst_y = value; 347 348 #ifdef TEST 349 *logofs << name() << ": Encoded update. Type is " 350 << (unsigned int) renderExtension -> data.composite.type 351 << " size is " << renderExtension -> size_ << ".\n" 352 << logofs_flush; 353 #endif 354 } 355 MESSAGE_END_ENCODE_UPDATE 356 357 MESSAGE_BEGIN_DECODE_UPDATE 358 { 359 RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message; 360 361 ClientCache *clientCache = (ClientCache *) channelCache; 362 363 decodeBuffer.decodeXidValue(renderExtension -> data.composite.src_id, 364 clientCache -> renderSrcPictureCache); 365 366 decodeBuffer.decodeXidValue(renderExtension -> data.composite.msk_id, 367 clientCache -> renderMaskPictureCache); 368 369 decodeBuffer.decodeXidValue(renderExtension -> data.composite.dst_id, 370 clientCache -> renderDstPictureCache); 371 372 // 373 // Dst X and Y. 374 // 375 376 unsigned int value; 377 unsigned int previous; 378 379 previous = renderExtension -> data.composite.dst_x; 380 381 decodeBuffer.decodeDiffCachedValue(value, previous, 16, 382 clientCache -> renderXCache, 11); 383 384 renderExtension -> data.composite.dst_x = value; 385 386 previous = renderExtension -> data.composite.dst_y; 387 388 decodeBuffer.decodeDiffCachedValue(value, previous, 16, 389 clientCache -> renderYCache, 11); 390 391 renderExtension -> data.composite.dst_y = value; 392 393 #ifdef TEST 394 *logofs << name() << ": Decoded update. Type is " 395 << (unsigned int) renderExtension -> data.composite.type 396 << " size is " << renderExtension -> size_ << ".\n" 397 << logofs_flush; 398 #endif 399 } 400 MESSAGE_END_DECODE_UPDATE 401