1 /**************************************************************************/
2 /* */
3 /* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/. */
4 /* */
5 /* NXCOMP, NX protocol compression and NX extensions to this software */
6 /* are copyright of NoMachine. Redistribution and use of the present */
7 /* software is allowed according to terms specified in the file LICENSE */
8 /* which comes in the source distribution. */
9 /* */
10 /* Check http://www.nomachine.com/licensing.html for applicability. */
11 /* */
12 /* NX and NoMachine are trademarks of Medialogic S.p.A. */
13 /* */
14 /* All rights reserved. */
15 /* */
16 /**************************************************************************/
17
18 #include "PolyText8.h"
19
20 #include "ClientCache.h"
21
22 #include "EncodeBuffer.h"
23 #include "DecodeBuffer.h"
24
25 //
26 // Set the verbosity level.
27 //
28
29 #define PANIC
30 #define WARNING
31 #undef TEST
32 #undef DEBUG
33 #undef DUMP
34
35 //
36 // Here are the methods to handle messages' content.
37 //
38
parseIdentity(Message * message,const unsigned char * buffer,unsigned int size,int bigEndian) const39 int PolyText8Store::parseIdentity(Message *message, const unsigned char *buffer,
40 unsigned int size, int bigEndian) const
41 {
42 PolyText8Message *polyText8 = (PolyText8Message *) message;
43
44 //
45 // Here is the fingerprint.
46 //
47
48 polyText8 -> drawable = GetULONG(buffer + 4, bigEndian);
49 polyText8 -> gcontext = GetULONG(buffer + 8, bigEndian);
50
51 polyText8 -> x = GetUINT(buffer + 12, bigEndian);
52 polyText8 -> y = GetUINT(buffer + 14, bigEndian);
53
54 //
55 // Clean up padding bytes.
56 //
57
58 #ifdef DUMP
59
60 DumpData(buffer, size);
61
62 *logofs << "\n\n" << logofs_flush;
63
64 #endif
65
66 if ((int) size > dataOffset)
67 {
68 int length;
69 int current;
70 int delta;
71 int item;
72
73 unsigned int nitem;
74
75 unsigned char *pad = NULL;
76 unsigned char *end = NULL;
77
78 delta = 1;
79 nitem = 0;
80
81 #ifdef DUMP
82 *logofs << name() << " Size " << size << ".\n" << logofs_flush;
83 #endif
84
85 //
86 // Data is a list of TextItem where element
87 // can be a string or a font shift.
88 //
89
90 current = POLYTEXT8_DATA_OFFSET;
91 length = POLYTEXT8_DATA_OFFSET;
92
93 do
94 {
95 #ifdef DUMP
96 *logofs << name() << " Current " << current << ".\n" << logofs_flush;
97 #endif
98
99 item = GetUINT(buffer + length , bigEndian);
100
101 if (item < 255)
102 {
103 //
104 // Text element. Number represents
105 // the 'Length of string' field.
106 //
107
108 length += (item + delta + 1);
109
110 nitem++;
111 }
112 else if (item == 255)
113 {
114 //
115 // Element is a font shift.
116 //
117
118 length += 5;
119
120 nitem++;
121 }
122
123 #ifdef DUMP
124 *logofs << name() << " Item " << item << ".\n" << logofs_flush;
125 #endif
126
127 current += length;
128 }
129 while(current < (int) size && item != 0);
130
131
132 #ifdef DUMP
133 *logofs << name() << " Final length " << length << ".\n" << logofs_flush;
134 #endif
135
136 end = ((unsigned char *) buffer) + size;
137
138 pad = ((unsigned char *) buffer) + length;
139
140 for (; pad < end && nitem >= 1; pad++)
141 {
142 #ifdef DUMP
143 *logofs << name() << " Padding " << " .\n" << logofs_flush;
144 #endif
145
146 *pad = 0;
147 }
148 }
149
150 #ifdef DEBUG
151 *logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush;
152 #endif
153
154 return 1;
155 }
156
unparseIdentity(const Message * message,unsigned char * buffer,unsigned int size,int bigEndian) const157 int PolyText8Store::unparseIdentity(const Message *message, unsigned char *buffer,
158 unsigned int size, int bigEndian) const
159 {
160 PolyText8Message *polyText8 = (PolyText8Message *) message;
161
162 //
163 // Fill all the message's fields.
164 //
165
166 PutULONG(polyText8 -> drawable, buffer + 4, bigEndian);
167 PutULONG(polyText8 -> gcontext, buffer + 8, bigEndian);
168
169 PutUINT(polyText8 -> x, buffer + 12, bigEndian);
170 PutUINT(polyText8 -> y, buffer + 14, bigEndian);
171
172 #ifdef DEBUG
173 *logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush;
174 #endif
175
176 return 1;
177 }
178
dumpIdentity(const Message * message) const179 void PolyText8Store::dumpIdentity(const Message *message) const
180 {
181 #ifdef DUMP
182
183 PolyText8Message *polyText8 = (PolyText8Message *) message;
184
185 *logofs << name() << ": Identity drawable " << polyText8 -> drawable
186 << ", gcontext " << polyText8 -> gcontext << ", x " << polyText8 -> x
187 << ", y " << polyText8 -> y << ", size " << polyText8 -> size_
188 << ".\n";
189
190 #endif
191 }
192
identityChecksum(const Message * message,const unsigned char * buffer,unsigned int size,int bigEndian) const193 void PolyText8Store::identityChecksum(const Message *message, const unsigned char *buffer,
194 unsigned int size, int bigEndian) const
195 {
196 }
197
updateIdentity(EncodeBuffer & encodeBuffer,const Message * message,const Message * cachedMessage,ChannelCache * channelCache) const198 void PolyText8Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
199 const Message *cachedMessage,
200 ChannelCache *channelCache) const
201 {
202 PolyText8Message *polyText8 = (PolyText8Message *) message;
203 PolyText8Message *cachedPolyText8 = (PolyText8Message *) cachedMessage;
204
205 ClientCache *clientCache = (ClientCache *) channelCache;
206
207 #ifdef TEST
208 *logofs << name() << ": Encoding value " << polyText8 -> drawable
209 << " as " << "drawable" << " field.\n" << logofs_flush;
210 #endif
211
212 encodeBuffer.encodeXidValue(polyText8 -> drawable, clientCache -> drawableCache);
213
214 cachedPolyText8 -> drawable = polyText8 -> drawable;
215
216 #ifdef TEST
217 *logofs << name() << ": Encoding value " << polyText8 -> gcontext
218 << " as " << "gcontext" << " field.\n" << logofs_flush;
219 #endif
220
221 encodeBuffer.encodeXidValue(polyText8 -> gcontext, clientCache -> gcCache);
222
223 cachedPolyText8 -> gcontext = polyText8 -> gcontext;
224
225 #ifdef TEST
226 *logofs << name() << ": Encoding value " << polyText8 -> x
227 << " as " << "x" << " field.\n" << logofs_flush;
228 #endif
229
230 unsigned short int diff_x = polyText8 -> x - cachedPolyText8 -> x;
231
232 encodeBuffer.encodeCachedValue(diff_x, 16,
233 clientCache -> polyTextCacheX);
234
235 cachedPolyText8 -> x = polyText8 -> x;
236
237 #ifdef TEST
238 *logofs << name() << ": Encoding value " << polyText8 -> y
239 << " as " << "y" << " field.\n" << logofs_flush;
240 #endif
241
242 unsigned short int diff_y = polyText8 -> y - cachedPolyText8 -> y;
243
244 encodeBuffer.encodeCachedValue(diff_y, 16,
245 clientCache -> polyTextCacheY);
246
247 cachedPolyText8 -> y = polyText8 -> y;
248 }
249
updateIdentity(DecodeBuffer & decodeBuffer,const Message * message,ChannelCache * channelCache) const250 void PolyText8Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
251 ChannelCache *channelCache) const
252 {
253 PolyText8Message *polyText8 = (PolyText8Message *) message;
254
255 ClientCache *clientCache = (ClientCache *) channelCache;
256
257 unsigned int value;
258
259 decodeBuffer.decodeXidValue(value, clientCache -> drawableCache);
260
261 polyText8 -> drawable = value;
262
263 #ifdef DEBUG
264 *logofs << name() << ": Decoded value " << polyText8 -> drawable
265 << " as " << "drawable" << " field.\n" << logofs_flush;
266 #endif
267
268 decodeBuffer.decodeXidValue(value, clientCache -> gcCache);
269
270 polyText8 -> gcontext = value;
271
272 #ifdef DEBUG
273 *logofs << name() << ": Decoded value " << polyText8 -> gcontext
274 << " as gcontext field.\n" << logofs_flush;
275 #endif
276
277 decodeBuffer.decodeCachedValue(value, 16,
278 clientCache -> polyTextCacheX);
279
280 polyText8 -> x += value;
281 polyText8 -> x &= 0xffff;
282
283 #ifdef DEBUG
284 *logofs << name() << ": Decoded value " << polyText8 -> x
285 << " as x field.\n" << logofs_flush;
286 #endif
287
288 decodeBuffer.decodeCachedValue(value, 16,
289 clientCache -> polyTextCacheY);
290
291 polyText8 -> y += value;
292 polyText8 -> y &= 0xffff;
293
294 #ifdef DEBUG
295 *logofs << name() << ": Decoded value " << polyText8 -> y
296 << " as y field.\n" << logofs_flush;
297 #endif
298 }
299