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 "PolyText16.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 PolyText16Store::parseIdentity(Message *message, const unsigned char *buffer,
40                                        unsigned int size, int bigEndian) const
41 {
42   PolyText16Message *polyText16 = (PolyText16Message *) message;
43 
44   //
45   // Here is the fingerprint.
46   //
47 
48   polyText16 -> drawable = GetULONG(buffer + 4, bigEndian);
49   polyText16 -> gcontext = GetULONG(buffer + 8, bigEndian);
50 
51   polyText16 -> x = GetUINT(buffer + 12, bigEndian);
52   polyText16 -> 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" << logofs_flush;
63 
64   #endif
65 
66   if ((int) size > dataOffset)
67   {
68     int current;
69     int length;
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 = POLYTEXT16_DATA_OFFSET;
91     length  = POLYTEXT16_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 CHAR2B string'
106         // field.
107         //
108 
109         length += ((item * 2) + delta + 1);
110 
111         nitem++;
112       }
113       else if (item == 255)
114       {
115         //
116         // Element is a font shift.
117         //
118 
119         length += 5;
120 
121         nitem++;
122       }
123 
124       #ifdef DUMP
125       *logofs << name() << " Item " << item << ".\n" << logofs_flush;
126       #endif
127 
128       current += length;
129     }
130     while(current < (int) size && item != 0);
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 PolyText16Store::unparseIdentity(const Message *message, unsigned char *buffer,
158                                          unsigned int size, int bigEndian) const
159 {
160   PolyText16Message *polyText16 = (PolyText16Message *) message;
161 
162   //
163   // Fill all the message's fields.
164   //
165 
166   PutULONG(polyText16 -> drawable, buffer + 4, bigEndian);
167   PutULONG(polyText16 -> gcontext, buffer + 8, bigEndian);
168 
169   PutUINT(polyText16 -> x, buffer + 12, bigEndian);
170   PutUINT(polyText16 -> 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 PolyText16Store::dumpIdentity(const Message *message) const
180 {
181   #ifdef DUMP
182 
183   PolyText16Message *polyText16 = (PolyText16Message *) message;
184 
185   *logofs << name() << ": Identity drawable " << polyText16 -> drawable
186           << ", gcontext " << polyText16 -> gcontext << ", x " << polyText16 -> x
187           << ", y " << polyText16 -> y << ", size " << polyText16 -> size_
188           << ".\n";
189 
190   #endif
191 }
192 
identityChecksum(const Message * message,const unsigned char * buffer,unsigned int size,int bigEndian) const193 void PolyText16Store::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 PolyText16Store::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
199                                          const Message *cachedMessage,
200                                              ChannelCache *channelCache) const
201 {
202   PolyText16Message *polyText16       = (PolyText16Message *) message;
203   PolyText16Message *cachedPolyText16 = (PolyText16Message *) cachedMessage;
204 
205   ClientCache *clientCache = (ClientCache *) channelCache;
206 
207   #ifdef TEST
208   *logofs << name() << ": Encoding value " << polyText16 -> drawable
209           << " as " << "drawable" << " field.\n" << logofs_flush;
210   #endif
211 
212   encodeBuffer.encodeXidValue(polyText16 -> drawable, clientCache -> drawableCache);
213 
214   cachedPolyText16 -> drawable = polyText16 -> drawable;
215 
216   #ifdef TEST
217   *logofs << name() << ": Encoding value " << polyText16 -> gcontext
218           << " as " << "gcontext" << " field.\n" << logofs_flush;
219   #endif
220 
221   encodeBuffer.encodeXidValue(polyText16 -> gcontext, clientCache -> gcCache);
222 
223   cachedPolyText16 -> gcontext = polyText16 -> gcontext;
224 
225   #ifdef TEST
226   *logofs << name() << ": Encoding value " << polyText16 -> x
227           << " as " << "x" << " field.\n" << logofs_flush;
228   #endif
229 
230   unsigned short int diff_x = polyText16 -> x - cachedPolyText16 -> x;
231 
232   encodeBuffer.encodeCachedValue(diff_x, 16,
233                      clientCache -> polyTextCacheX);
234 
235   cachedPolyText16 -> x = polyText16 -> x;
236 
237   #ifdef TEST
238   *logofs << name() << ": Encoding value " << polyText16 -> y
239           << " as " << "y" << " field.\n" << logofs_flush;
240   #endif
241 
242   unsigned short int diff_y = polyText16 -> y - cachedPolyText16 -> y;
243 
244   encodeBuffer.encodeCachedValue(diff_y, 16,
245                      clientCache -> polyTextCacheY);
246 
247   cachedPolyText16 -> y = polyText16 -> y;
248 }
249 
updateIdentity(DecodeBuffer & decodeBuffer,const Message * message,ChannelCache * channelCache) const250 void PolyText16Store::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
251                                          ChannelCache *channelCache) const
252 {
253   PolyText16Message *polyText16 = (PolyText16Message *) message;
254 
255   ClientCache *clientCache = (ClientCache *) channelCache;
256 
257   unsigned int value;
258 
259   decodeBuffer.decodeXidValue(value, clientCache -> drawableCache);
260 
261   polyText16 -> drawable = value;
262 
263   #ifdef DEBUG
264   *logofs << name() << ": Decoded value " << polyText16 -> drawable
265           << " as " << "drawable" << " field.\n" << logofs_flush;
266   #endif
267 
268   decodeBuffer.decodeXidValue(value, clientCache -> gcCache);
269 
270   polyText16 -> gcontext = value;
271 
272   #ifdef DEBUG
273   *logofs << name() << ": Decoded value " << polyText16 -> gcontext
274           << " as gcontext field.\n" << logofs_flush;
275   #endif
276 
277   decodeBuffer.decodeCachedValue(value, 16,
278                clientCache -> polyTextCacheX);
279 
280   polyText16 -> x += value;
281   polyText16 -> x &= 0xffff;
282 
283   #ifdef DEBUG
284   *logofs << name() << ": Decoded value " << polyText16 -> x
285           << " as x field.\n" << logofs_flush;
286   #endif
287 
288   decodeBuffer.decodeCachedValue(value, 16,
289                clientCache -> polyTextCacheY);
290 
291   polyText16 -> y += value;
292   polyText16 -> y &= 0xffff;
293 
294   #ifdef DEBUG
295   *logofs << name() << ": Decoded value " << polyText16 -> y
296           << " as y field.\n" << logofs_flush;
297   #endif
298 }
299 
300 
301