/[rdesktop]/sourceforge.net/trunk/rdesktop/orders.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/orders.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 355 - (hide annotations)
Fri Mar 28 09:09:17 2003 UTC (21 years, 1 month ago) by forsberg
File MIME type: text/plain
File size: 20626 byte(s)
Got bitmap decompression to work. It turned out Microsoft doesn't care about sending the compressed
bitmap header any longer, instead the size of the compressed bitmap data is sent in the bitmapLength
field of the cache bitmap order. Of course this doesn't concur with T.128.

Added more detailed debugging which helped in finding this.

1 forsberg 355 /* -*- c-basic-offset: 8 -*-
2 matty 10 rdesktop: A Remote Desktop Protocol client.
3     RDP order processing
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 matty 10
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "rdesktop.h"
22     #include "orders.h"
23    
24 matty 28 extern uint8 *next_packet;
25 matty 10 static RDP_ORDER_STATE order_state;
26 forsberg 355 extern BOOL use_rdp5;
27 matty 10
28     /* Read field indicating which parameters are present */
29 matty 25 static void
30 astrand 64 rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
31 matty 10 {
32     uint8 bits;
33     int i;
34    
35     if (flags & RDP_ORDER_SMALL)
36     {
37     size--;
38     }
39    
40     if (flags & RDP_ORDER_TINY)
41     {
42     if (size < 2)
43     size = 0;
44     else
45     size -= 2;
46     }
47    
48     *present = 0;
49     for (i = 0; i < size; i++)
50     {
51     in_uint8(s, bits);
52     *present |= bits << (i * 8);
53     }
54     }
55    
56     /* Read a co-ordinate (16-bit, or 8-bit delta) */
57 matty 25 static void
58 astrand 64 rdp_in_coord(STREAM s, uint16 * coord, BOOL delta)
59 matty 10 {
60 matthewc 299 sint8 change;
61 matty 10
62     if (delta)
63     {
64     in_uint8(s, change);
65 matthewc 299 *coord += change;
66 matty 10 }
67     else
68     {
69     in_uint16_le(s, *coord);
70     }
71     }
72    
73     /* Read a colour entry */
74 matty 25 static void
75 jsorg71 309 rdp_in_colour(STREAM s, uint32 * colour)
76 matty 10 {
77 jsorg71 309 uint32 i;
78     in_uint8(s, i);
79     *colour = i;
80     in_uint8(s, i);
81     *colour |= i << 8;
82     in_uint8(s, i);
83     *colour |= i << 16;
84 matty 10 }
85    
86     /* Parse bounds information */
87 matty 25 static BOOL
88 astrand 64 rdp_parse_bounds(STREAM s, BOUNDS * bounds)
89 matty 10 {
90     uint8 present;
91    
92     in_uint8(s, present);
93    
94     if (present & 1)
95     rdp_in_coord(s, &bounds->left, False);
96     else if (present & 16)
97     rdp_in_coord(s, &bounds->left, True);
98    
99     if (present & 2)
100     rdp_in_coord(s, &bounds->top, False);
101     else if (present & 32)
102     rdp_in_coord(s, &bounds->top, True);
103    
104     if (present & 4)
105     rdp_in_coord(s, &bounds->right, False);
106     else if (present & 64)
107     rdp_in_coord(s, &bounds->right, True);
108    
109     if (present & 8)
110     rdp_in_coord(s, &bounds->bottom, False);
111     else if (present & 128)
112     rdp_in_coord(s, &bounds->bottom, True);
113    
114     return s_check(s);
115     }
116    
117     /* Parse a pen */
118 matty 25 static BOOL
119 astrand 64 rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
120 matty 10 {
121     if (present & 1)
122     in_uint8(s, pen->style);
123    
124     if (present & 2)
125     in_uint8(s, pen->width);
126    
127     if (present & 4)
128     rdp_in_colour(s, &pen->colour);
129    
130     return s_check(s);
131     }
132    
133     /* Parse a brush */
134 matty 25 static BOOL
135 astrand 64 rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
136 matty 10 {
137     if (present & 1)
138     in_uint8(s, brush->xorigin);
139    
140     if (present & 2)
141     in_uint8(s, brush->yorigin);
142    
143     if (present & 4)
144     in_uint8(s, brush->style);
145    
146     if (present & 8)
147     in_uint8(s, brush->pattern[0]);
148    
149     if (present & 16)
150     in_uint8a(s, &brush->pattern[1], 7);
151    
152     return s_check(s);
153     }
154    
155     /* Process a destination blt order */
156 matty 25 static void
157 astrand 64 process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)
158 matty 10 {
159     if (present & 0x01)
160     rdp_in_coord(s, &os->x, delta);
161    
162     if (present & 0x02)
163     rdp_in_coord(s, &os->y, delta);
164    
165     if (present & 0x04)
166     rdp_in_coord(s, &os->cx, delta);
167    
168     if (present & 0x08)
169     rdp_in_coord(s, &os->cy, delta);
170    
171     if (present & 0x10)
172     in_uint8(s, os->opcode);
173    
174 matty 30 DEBUG(("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n",
175     os->opcode, os->x, os->y, os->cx, os->cy));
176 matty 10
177     ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
178     }
179    
180     /* Process a pattern blt order */
181 matty 25 static void
182 astrand 64 process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)
183 matty 10 {
184     if (present & 0x0001)
185     rdp_in_coord(s, &os->x, delta);
186    
187     if (present & 0x0002)
188     rdp_in_coord(s, &os->y, delta);
189    
190     if (present & 0x0004)
191     rdp_in_coord(s, &os->cx, delta);
192    
193     if (present & 0x0008)
194     rdp_in_coord(s, &os->cy, delta);
195    
196     if (present & 0x0010)
197     in_uint8(s, os->opcode);
198    
199     if (present & 0x0020)
200     rdp_in_colour(s, &os->bgcolour);
201    
202     if (present & 0x0040)
203     rdp_in_colour(s, &os->fgcolour);
204    
205     rdp_parse_brush(s, &os->brush, present >> 7);
206    
207 astrand 82 DEBUG(("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n", os->opcode, os->x,
208     os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
209 matty 10
210     ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
211 matty 24 &os->brush, os->bgcolour, os->fgcolour);
212 matty 10 }
213    
214     /* Process a screen blt order */
215 matty 25 static void
216 astrand 64 process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)
217 matty 10 {
218     if (present & 0x0001)
219     rdp_in_coord(s, &os->x, delta);
220    
221     if (present & 0x0002)
222     rdp_in_coord(s, &os->y, delta);
223    
224     if (present & 0x0004)
225     rdp_in_coord(s, &os->cx, delta);
226    
227     if (present & 0x0008)
228     rdp_in_coord(s, &os->cy, delta);
229    
230     if (present & 0x0010)
231     in_uint8(s, os->opcode);
232    
233     if (present & 0x0020)
234     rdp_in_coord(s, &os->srcx, delta);
235    
236     if (present & 0x0040)
237     rdp_in_coord(s, &os->srcy, delta);
238    
239 matty 30 DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",
240     os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy));
241 matty 10
242 astrand 82 ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
243 matty 10 }
244    
245     /* Process a line order */
246 matty 25 static void
247 astrand 64 process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
248 matty 10 {
249     if (present & 0x0001)
250     in_uint16_le(s, os->mixmode);
251    
252     if (present & 0x0002)
253     rdp_in_coord(s, &os->startx, delta);
254    
255     if (present & 0x0004)
256     rdp_in_coord(s, &os->starty, delta);
257    
258     if (present & 0x0008)
259     rdp_in_coord(s, &os->endx, delta);
260    
261     if (present & 0x0010)
262     rdp_in_coord(s, &os->endy, delta);
263    
264     if (present & 0x0020)
265     rdp_in_colour(s, &os->bgcolour);
266    
267     if (present & 0x0040)
268     in_uint8(s, os->opcode);
269    
270     rdp_parse_pen(s, &os->pen, present >> 7);
271    
272 matty 30 DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dx=%d,fg=0x%x)\n",
273 astrand 82 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));
274 matty 10
275     if (os->opcode < 0x01 || os->opcode > 0x10)
276     {
277 matty 30 error("bad ROP2 0x%x\n", os->opcode);
278 matty 10 return;
279     }
280    
281 astrand 82 ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
282 matty 10 }
283    
284     /* Process an opaque rectangle order */
285 matty 25 static void
286 astrand 64 process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
287 matty 10 {
288 jsorg71 309 uint32 i;
289 matty 10 if (present & 0x01)
290     rdp_in_coord(s, &os->x, delta);
291    
292     if (present & 0x02)
293     rdp_in_coord(s, &os->y, delta);
294    
295     if (present & 0x04)
296     rdp_in_coord(s, &os->cx, delta);
297    
298     if (present & 0x08)
299     rdp_in_coord(s, &os->cy, delta);
300    
301     if (present & 0x10)
302 jsorg71 309 {
303     in_uint8(s, i);
304     os->colour = (os->colour & 0xffffff00) | i;
305     }
306 matty 10
307 jsorg71 309 if (present & 0x20)
308     {
309     in_uint8(s, i);
310     os->colour = (os->colour & 0xffff00ff) | (i << 8);
311     }
312    
313     if (present & 0x40)
314     {
315     in_uint8(s, i);
316     os->colour = (os->colour & 0xff00ffff) | (i << 16);
317     }
318    
319 astrand 82 DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));
320 matty 10
321     ui_rect(os->x, os->y, os->cx, os->cy, os->colour);
322     }
323    
324     /* Process a desktop save order */
325 matty 25 static void
326 astrand 64 process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
327 matty 10 {
328     int width, height;
329    
330     if (present & 0x01)
331     in_uint32_le(s, os->offset);
332    
333     if (present & 0x02)
334     rdp_in_coord(s, &os->left, delta);
335    
336     if (present & 0x04)
337     rdp_in_coord(s, &os->top, delta);
338    
339     if (present & 0x08)
340     rdp_in_coord(s, &os->right, delta);
341    
342     if (present & 0x10)
343     rdp_in_coord(s, &os->bottom, delta);
344    
345     if (present & 0x20)
346     in_uint8(s, os->action);
347    
348 matty 30 DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",
349 astrand 82 os->left, os->top, os->right, os->bottom, os->offset, os->action));
350 matty 10
351     width = os->right - os->left + 1;
352     height = os->bottom - os->top + 1;
353    
354     if (os->action == 0)
355     ui_desktop_save(os->offset, os->left, os->top, width, height);
356     else
357 astrand 82 ui_desktop_restore(os->offset, os->left, os->top, width, height);
358 matty 10 }
359    
360     /* Process a memory blt order */
361 matty 25 static void
362 astrand 64 process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
363 matty 10 {
364     HBITMAP bitmap;
365    
366     if (present & 0x0001)
367     {
368     in_uint8(s, os->cache_id);
369     in_uint8(s, os->colour_table);
370     }
371    
372     if (present & 0x0002)
373     rdp_in_coord(s, &os->x, delta);
374    
375     if (present & 0x0004)
376     rdp_in_coord(s, &os->y, delta);
377    
378     if (present & 0x0008)
379     rdp_in_coord(s, &os->cx, delta);
380    
381     if (present & 0x0010)
382     rdp_in_coord(s, &os->cy, delta);
383    
384     if (present & 0x0020)
385     in_uint8(s, os->opcode);
386    
387     if (present & 0x0040)
388     rdp_in_coord(s, &os->srcx, delta);
389    
390     if (present & 0x0080)
391     rdp_in_coord(s, &os->srcy, delta);
392    
393     if (present & 0x0100)
394     in_uint16_le(s, os->cache_idx);
395    
396 matty 30 DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",
397 astrand 82 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx));
398 matty 10
399     bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
400     if (bitmap == NULL)
401     return;
402    
403 astrand 82 ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy);
404 matty 10 }
405    
406     /* Process a 3-way blt order */
407 matty 25 static void
408 astrand 64 process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
409 matty 10 {
410     HBITMAP bitmap;
411    
412     if (present & 0x000001)
413     {
414     in_uint8(s, os->cache_id);
415     in_uint8(s, os->colour_table);
416     }
417    
418     if (present & 0x000002)
419     rdp_in_coord(s, &os->x, delta);
420    
421     if (present & 0x000004)
422     rdp_in_coord(s, &os->y, delta);
423    
424     if (present & 0x000008)
425     rdp_in_coord(s, &os->cx, delta);
426    
427     if (present & 0x000010)
428     rdp_in_coord(s, &os->cy, delta);
429    
430     if (present & 0x000020)
431     in_uint8(s, os->opcode);
432    
433     if (present & 0x000040)
434     rdp_in_coord(s, &os->srcx, delta);
435    
436     if (present & 0x000080)
437     rdp_in_coord(s, &os->srcy, delta);
438    
439     if (present & 0x000100)
440     rdp_in_colour(s, &os->bgcolour);
441    
442     if (present & 0x000200)
443     rdp_in_colour(s, &os->fgcolour);
444    
445     rdp_parse_brush(s, &os->brush, present >> 10);
446    
447     if (present & 0x008000)
448     in_uint16_le(s, os->cache_idx);
449    
450     if (present & 0x010000)
451     in_uint16_le(s, os->unknown);
452    
453 astrand 82 DEBUG(("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
454     os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx,
455     os->brush.style, os->bgcolour, os->fgcolour));
456 matty 10
457     bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
458     if (bitmap == NULL)
459     return;
460    
461     ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
462 astrand 82 bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
463 matty 10 }
464    
465 matty 15 /* Parse a delta co-ordinate in polyline order form */
466 matty 25 static int
467 astrand 64 parse_delta(uint8 * buffer, int *offset)
468 matty 15 {
469     int value = buffer[(*offset)++];
470     int two_byte = value & 0x80;
471    
472 matty 24 if (value & 0x40) /* sign bit */
473 matty 15 value |= ~0x3f;
474     else
475     value &= 0x3f;
476    
477     if (two_byte)
478     value = (value << 8) | buffer[(*offset)++];
479    
480     return value;
481     }
482    
483     /* Process a polyline order */
484 matty 25 static void
485 astrand 64 process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
486 matty 15 {
487     int index, line, data;
488     int x, y, xfrom, yfrom;
489     uint8 flags = 0;
490     PEN pen;
491 jsorg71 55 uint8 opcode;
492 matty 15
493     if (present & 0x01)
494     rdp_in_coord(s, &os->x, delta);
495    
496     if (present & 0x02)
497     rdp_in_coord(s, &os->y, delta);
498    
499     if (present & 0x04)
500 matthewc 168 in_uint8(s, os->opcode);
501 matty 15
502     if (present & 0x10)
503     rdp_in_colour(s, &os->fgcolour);
504    
505     if (present & 0x20)
506     in_uint8(s, os->lines);
507    
508     if (present & 0x40)
509     {
510     in_uint8(s, os->datasize);
511     in_uint8a(s, os->data, os->datasize);
512     }
513    
514 matthewc 168 DEBUG(("POLYLINE(x=%d,y=%d,op=0x%x,fg=0x%x,n=%d,sz=%d)\n",
515     os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize));
516 matty 15
517 matty 30 DEBUG(("Data: "));
518 matty 15
519     for (index = 0; index < os->datasize; index++)
520 matty 30 DEBUG(("%02x ", os->data[index]));
521 matty 15
522 matty 30 DEBUG(("\n"));
523 matty 15
524 matthewc 168 if (os->opcode < 0x01 || os->opcode > 0x10)
525     {
526     error("bad ROP2 0x%x\n", os->opcode);
527     return;
528     }
529    
530     opcode = os->opcode - 1;
531 matty 15 x = os->x;
532     y = os->y;
533     pen.style = pen.width = 0;
534     pen.colour = os->fgcolour;
535    
536     index = 0;
537     data = ((os->lines - 1) / 4) + 1;
538     for (line = 0; (line < os->lines) && (data < os->datasize); line++)
539     {
540     xfrom = x;
541     yfrom = y;
542    
543     if (line % 4 == 0)
544     flags = os->data[index++];
545    
546     if ((flags & 0xc0) == 0)
547 matty 24 flags |= 0xc0; /* none = both */
548 matty 15
549     if (flags & 0x40)
550     x += parse_delta(os->data, &data);
551    
552     if (flags & 0x80)
553     y += parse_delta(os->data, &data);
554    
555 jsorg71 55 ui_line(opcode, xfrom, yfrom, x, y, &pen);
556 matty 15
557     flags <<= 2;
558     }
559     }
560    
561 matty 10 /* Process a text order */
562 matty 25 static void
563 astrand 64 process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
564 matty 10 {
565     int i;
566    
567     if (present & 0x000001)
568     in_uint8(s, os->font);
569    
570     if (present & 0x000002)
571     in_uint8(s, os->flags);
572    
573     if (present & 0x000004)
574     in_uint8(s, os->unknown);
575    
576     if (present & 0x000008)
577     in_uint8(s, os->mixmode);
578    
579     if (present & 0x000010)
580     rdp_in_colour(s, &os->fgcolour);
581    
582     if (present & 0x000020)
583     rdp_in_colour(s, &os->bgcolour);
584    
585     if (present & 0x000040)
586     in_uint16_le(s, os->clipleft);
587    
588     if (present & 0x000080)
589     in_uint16_le(s, os->cliptop);
590    
591     if (present & 0x000100)
592     in_uint16_le(s, os->clipright);
593    
594     if (present & 0x000200)
595     in_uint16_le(s, os->clipbottom);
596    
597     if (present & 0x000400)
598     in_uint16_le(s, os->boxleft);
599    
600     if (present & 0x000800)
601     in_uint16_le(s, os->boxtop);
602    
603     if (present & 0x001000)
604     in_uint16_le(s, os->boxright);
605    
606     if (present & 0x002000)
607     in_uint16_le(s, os->boxbottom);
608    
609 forsberg 349 if (present & 0x004000) /* fix for connecting to a server that */
610     in_uint8s(s, 10); /* was disconnected with mstsc.exe */
611     /* 0x008000, 0x020000, and 0x040000 are present too ??? */
612 jsorg71 336
613 matty 10 if (present & 0x080000)
614     in_uint16_le(s, os->x);
615    
616     if (present & 0x100000)
617     in_uint16_le(s, os->y);
618    
619     if (present & 0x200000)
620     {
621     in_uint8(s, os->length);
622     in_uint8a(s, os->text, os->length);
623     }
624    
625 astrand 64 DEBUG(("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,bb=%d,br=%d,fg=0x%x,bg=0x%x,font=%d,fl=0x%x,mix=%d,unk=0x%x,n=%d)\n", os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft, os->boxtop, os->boxright, os->boxbottom, os->fgcolour, os->bgcolour, os->font, os->flags, os->mixmode, os->unknown, os->length));
626 matty 10
627 matty 30 DEBUG(("Text: "));
628 matty 10
629     for (i = 0; i < os->length; i++)
630 matty 30 DEBUG(("%02x ", os->text[i]));
631 matty 10
632 matty 30 DEBUG(("\n"));
633 matty 10
634 matty 17 ui_draw_text(os->font, os->flags, os->mixmode, os->x, os->y,
635 matty 24 os->clipleft, os->cliptop,
636     os->clipright - os->clipleft,
637     os->clipbottom - os->cliptop,
638     os->boxleft, os->boxtop,
639     os->boxright - os->boxleft,
640 astrand 82 os->boxbottom - os->boxtop, os->bgcolour, os->fgcolour, os->text, os->length);
641 matty 10 }
642    
643     /* Process a raw bitmap cache order */
644 matty 25 static void
645     process_raw_bmpcache(STREAM s)
646 matty 10 {
647     HBITMAP bitmap;
648     uint16 cache_idx, bufsize;
649 jsorg71 314 uint8 cache_id, width, height, bpp, Bpp;
650 matty 28 uint8 *data, *inverted;
651     int y;
652 matty 10
653     in_uint8(s, cache_id);
654 matty 24 in_uint8s(s, 1); /* pad */
655 matty 10 in_uint8(s, width);
656     in_uint8(s, height);
657     in_uint8(s, bpp);
658 jsorg71 314 Bpp = (bpp + 7) / 8;
659 matty 10 in_uint16_le(s, bufsize);
660     in_uint16_le(s, cache_idx);
661     in_uint8p(s, data, bufsize);
662    
663 astrand 82 DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
664 jsorg71 314 inverted = xmalloc(width * height * Bpp);
665 matty 28 for (y = 0; y < height; y++)
666     {
667 astrand 318 memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
668     width * Bpp);
669 matty 28 }
670 matty 10
671 matty 28 bitmap = ui_create_bitmap(width, height, inverted);
672     xfree(inverted);
673 matty 10 cache_put_bitmap(cache_id, cache_idx, bitmap);
674     }
675    
676     /* Process a bitmap cache order */
677 matty 25 static void
678     process_bmpcache(STREAM s)
679 matty 10 {
680     HBITMAP bitmap;
681     uint16 cache_idx, size;
682 jsorg71 314 uint8 cache_id, width, height, bpp, Bpp;
683 matty 10 uint8 *data, *bmpdata;
684 forsberg 355 uint16 bufsize, pad2, row_size, final_size;
685     uint8 pad1;
686 matty 10
687     in_uint8(s, cache_id);
688 forsberg 355 in_uint8(s, pad1); /* pad */
689 matty 10 in_uint8(s, width);
690     in_uint8(s, height);
691     in_uint8(s, bpp);
692 jsorg71 314 Bpp = (bpp + 7) / 8;
693 forsberg 355 in_uint16_le(s, bufsize); /* bufsize */
694 matty 10 in_uint16_le(s, cache_idx);
695 forsberg 355
696     if (!use_rdp5) {
697    
698     /* Begin compressedBitmapData */
699     in_uint16_le(s, pad2); /* pad */
700     in_uint16_le(s, size);
701     // in_uint8s(s, 4); /* row_size, final_size */
702     in_uint16_le(s, row_size);
703     in_uint16_le(s, final_size);
704    
705     } else {
706     size = bufsize;
707     }
708 matty 10 in_uint8p(s, data, size);
709    
710 forsberg 355 DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d,bpp=%d,size=%d,pad1=%d,bufsize=%d,pad2=%d,rs=%d,fs=%d)\n",
711     width, height,
712     cache_id, cache_idx,
713     bpp, size, pad1, bufsize, pad2, row_size, final_size));
714 matty 10
715 jsorg71 314 bmpdata = xmalloc(width * height * Bpp);
716 matty 10
717 jsorg71 314 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
718 matty 10 {
719     bitmap = ui_create_bitmap(width, height, bmpdata);
720     cache_put_bitmap(cache_id, cache_idx, bitmap);
721     }
722 forsberg 349 else
723     {
724     DEBUG(("Failed to decompress bitmap data\n"));
725     }
726 matty 10
727     xfree(bmpdata);
728     }
729    
730     /* Process a colourmap cache order */
731 matty 25 static void
732     process_colcache(STREAM s)
733 matty 10 {
734     COLOURENTRY *entry;
735     COLOURMAP map;
736     HCOLOURMAP hmap;
737     uint8 cache_id;
738     int i;
739    
740     in_uint8(s, cache_id);
741     in_uint16_le(s, map.ncolours);
742    
743     map.colours = xmalloc(3 * map.ncolours);
744    
745     for (i = 0; i < map.ncolours; i++)
746     {
747     entry = &map.colours[i];
748     in_uint8(s, entry->blue);
749     in_uint8(s, entry->green);
750     in_uint8(s, entry->red);
751 matty 24 in_uint8s(s, 1); /* pad */
752 matty 10 }
753    
754 matty 30 DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
755 matty 10
756     hmap = ui_create_colourmap(&map);
757     ui_set_colourmap(hmap);
758    
759     xfree(map.colours);
760     }
761    
762     /* Process a font cache order */
763 matty 25 static void
764     process_fontcache(STREAM s)
765 matty 10 {
766     HGLYPH bitmap;
767     uint8 font, nglyphs;
768 matty 20 uint16 character, offset, baseline, width, height;
769 matty 24 int i, datasize;
770     uint8 *data;
771 matty 10
772     in_uint8(s, font);
773     in_uint8(s, nglyphs);
774    
775 matty 30 DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
776 matty 10
777     for (i = 0; i < nglyphs; i++)
778     {
779     in_uint16_le(s, character);
780 matty 20 in_uint16_le(s, offset);
781 matty 10 in_uint16_le(s, baseline);
782     in_uint16_le(s, width);
783     in_uint16_le(s, height);
784    
785     datasize = (height * ((width + 7) / 8) + 3) & ~3;
786     in_uint8p(s, data, datasize);
787    
788 matty 23 bitmap = ui_create_glyph(width, height, data);
789 astrand 82 cache_put_font(font, character, offset, baseline, width, height, bitmap);
790 matty 10 }
791     }
792    
793     /* Process a secondary order */
794 matty 25 static void
795     process_secondary_order(STREAM s)
796 matty 10 {
797     uint16 length;
798     uint8 type;
799     uint8 *next_order;
800    
801     in_uint16_le(s, length);
802 matty 24 in_uint8s(s, 2); /* flags */
803 matty 10 in_uint8(s, type);
804    
805     next_order = s->p + length + 7;
806    
807     switch (type)
808     {
809     case RDP_ORDER_RAW_BMPCACHE:
810     process_raw_bmpcache(s);
811     break;
812    
813     case RDP_ORDER_COLCACHE:
814     process_colcache(s);
815     break;
816    
817     case RDP_ORDER_BMPCACHE:
818     process_bmpcache(s);
819     break;
820    
821     case RDP_ORDER_FONTCACHE:
822     process_fontcache(s);
823     break;
824    
825     default:
826 matty 30 unimpl("secondary order %d\n", type);
827 matty 10 }
828    
829     s->p = next_order;
830     }
831    
832     /* Process an order PDU */
833 matty 25 void
834 forsberg 349 process_orders(STREAM s, uint16 num_orders)
835 matty 10 {
836     RDP_ORDER_STATE *os = &order_state;
837     uint32 present;
838     uint8 order_flags;
839     int size, processed = 0;
840     BOOL delta;
841    
842     while (processed < num_orders)
843     {
844     in_uint8(s, order_flags);
845    
846     if (!(order_flags & RDP_ORDER_STANDARD))
847     {
848 matty 30 error("order parsing failed\n");
849 matty 10 break;
850     }
851    
852     if (order_flags & RDP_ORDER_SECONDARY)
853     {
854     process_secondary_order(s);
855     }
856     else
857     {
858     if (order_flags & RDP_ORDER_CHANGE)
859     {
860     in_uint8(s, os->order_type);
861     }
862    
863     switch (os->order_type)
864     {
865     case RDP_ORDER_TRIBLT:
866     case RDP_ORDER_TEXT2:
867     size = 3;
868     break;
869    
870     case RDP_ORDER_PATBLT:
871     case RDP_ORDER_MEMBLT:
872     case RDP_ORDER_LINE:
873     size = 2;
874     break;
875    
876     default:
877     size = 1;
878     }
879    
880     rdp_in_present(s, &present, order_flags, size);
881    
882     if (order_flags & RDP_ORDER_BOUNDS)
883     {
884     if (!(order_flags & RDP_ORDER_LASTBOUNDS))
885     rdp_parse_bounds(s, &os->bounds);
886    
887     ui_set_clip(os->bounds.left,
888 matty 24 os->bounds.top,
889     os->bounds.right -
890     os->bounds.left + 1,
891 astrand 82 os->bounds.bottom - os->bounds.top + 1);
892 matty 10 }
893    
894     delta = order_flags & RDP_ORDER_DELTA;
895    
896     switch (os->order_type)
897     {
898     case RDP_ORDER_DESTBLT:
899 astrand 82 process_destblt(s, &os->destblt, present, delta);
900 matty 10 break;
901    
902     case RDP_ORDER_PATBLT:
903 astrand 82 process_patblt(s, &os->patblt, present, delta);
904 matty 10 break;
905    
906     case RDP_ORDER_SCREENBLT:
907 astrand 82 process_screenblt(s, &os->screenblt, present, delta);
908 matty 10 break;
909    
910     case RDP_ORDER_LINE:
911 astrand 82 process_line(s, &os->line, present, delta);
912 matty 10 break;
913    
914     case RDP_ORDER_RECT:
915 astrand 82 process_rect(s, &os->rect, present, delta);
916 matty 10 break;
917    
918     case RDP_ORDER_DESKSAVE:
919 astrand 82 process_desksave(s, &os->desksave, present, delta);
920 matty 10 break;
921    
922     case RDP_ORDER_MEMBLT:
923 astrand 82 process_memblt(s, &os->memblt, present, delta);
924 matty 10 break;
925    
926     case RDP_ORDER_TRIBLT:
927 astrand 82 process_triblt(s, &os->triblt, present, delta);
928 matty 10 break;
929    
930 matty 15 case RDP_ORDER_POLYLINE:
931 astrand 82 process_polyline(s, &os->polyline, present, delta);
932 matty 15 break;
933    
934 matty 10 case RDP_ORDER_TEXT2:
935 astrand 82 process_text2(s, &os->text2, present, delta);
936 matty 10 break;
937    
938     default:
939 matty 30 unimpl("order %d\n", os->order_type);
940 matty 10 return;
941     }
942    
943     if (order_flags & RDP_ORDER_BOUNDS)
944     ui_reset_clip();
945     }
946    
947     processed++;
948     }
949    
950     if (s->p != next_packet)
951 matty 30 error("%d bytes remaining\n", (int) (next_packet - s->p));
952 matty 10 }
953    
954     /* Reset order state */
955 matty 25 void
956 matthewc 192 reset_order_state(void)
957 matty 10 {
958     memset(&order_state, 0, sizeof(order_state));
959 matty 28 order_state.order_type = RDP_ORDER_PATBLT;
960 matty 10 }

  ViewVC Help
Powered by ViewVC 1.1.26