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