/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 355 - (show annotations)
Fri Mar 28 09:09:17 2003 UTC (21 years, 2 months 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 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 RDP order processing
4 Copyright (C) Matthew Chapman 1999-2002
5
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 extern uint8 *next_packet;
25 static RDP_ORDER_STATE order_state;
26 extern BOOL use_rdp5;
27
28 /* Read field indicating which parameters are present */
29 static void
30 rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
31 {
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 static void
58 rdp_in_coord(STREAM s, uint16 * coord, BOOL delta)
59 {
60 sint8 change;
61
62 if (delta)
63 {
64 in_uint8(s, change);
65 *coord += change;
66 }
67 else
68 {
69 in_uint16_le(s, *coord);
70 }
71 }
72
73 /* Read a colour entry */
74 static void
75 rdp_in_colour(STREAM s, uint32 * colour)
76 {
77 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 }
85
86 /* Parse bounds information */
87 static BOOL
88 rdp_parse_bounds(STREAM s, BOUNDS * bounds)
89 {
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 static BOOL
119 rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
120 {
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 static BOOL
135 rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
136 {
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 static void
157 process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)
158 {
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 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
177 ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
178 }
179
180 /* Process a pattern blt order */
181 static void
182 process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)
183 {
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 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
210 ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
211 &os->brush, os->bgcolour, os->fgcolour);
212 }
213
214 /* Process a screen blt order */
215 static void
216 process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)
217 {
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 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
242 ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
243 }
244
245 /* Process a line order */
246 static void
247 process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
248 {
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 DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dx=%d,fg=0x%x)\n",
273 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));
274
275 if (os->opcode < 0x01 || os->opcode > 0x10)
276 {
277 error("bad ROP2 0x%x\n", os->opcode);
278 return;
279 }
280
281 ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
282 }
283
284 /* Process an opaque rectangle order */
285 static void
286 process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
287 {
288 uint32 i;
289 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 {
303 in_uint8(s, i);
304 os->colour = (os->colour & 0xffffff00) | i;
305 }
306
307 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 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
321 ui_rect(os->x, os->y, os->cx, os->cy, os->colour);
322 }
323
324 /* Process a desktop save order */
325 static void
326 process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
327 {
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 DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",
349 os->left, os->top, os->right, os->bottom, os->offset, os->action));
350
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 ui_desktop_restore(os->offset, os->left, os->top, width, height);
358 }
359
360 /* Process a memory blt order */
361 static void
362 process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
363 {
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 DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",
397 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx));
398
399 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
400 if (bitmap == NULL)
401 return;
402
403 ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy);
404 }
405
406 /* Process a 3-way blt order */
407 static void
408 process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
409 {
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 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
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 bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
463 }
464
465 /* Parse a delta co-ordinate in polyline order form */
466 static int
467 parse_delta(uint8 * buffer, int *offset)
468 {
469 int value = buffer[(*offset)++];
470 int two_byte = value & 0x80;
471
472 if (value & 0x40) /* sign bit */
473 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 static void
485 process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
486 {
487 int index, line, data;
488 int x, y, xfrom, yfrom;
489 uint8 flags = 0;
490 PEN pen;
491 uint8 opcode;
492
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 in_uint8(s, os->opcode);
501
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 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
517 DEBUG(("Data: "));
518
519 for (index = 0; index < os->datasize; index++)
520 DEBUG(("%02x ", os->data[index]));
521
522 DEBUG(("\n"));
523
524 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 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 flags |= 0xc0; /* none = both */
548
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 ui_line(opcode, xfrom, yfrom, x, y, &pen);
556
557 flags <<= 2;
558 }
559 }
560
561 /* Process a text order */
562 static void
563 process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
564 {
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 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
613 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 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
627 DEBUG(("Text: "));
628
629 for (i = 0; i < os->length; i++)
630 DEBUG(("%02x ", os->text[i]));
631
632 DEBUG(("\n"));
633
634 ui_draw_text(os->font, os->flags, os->mixmode, os->x, os->y,
635 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 os->boxbottom - os->boxtop, os->bgcolour, os->fgcolour, os->text, os->length);
641 }
642
643 /* Process a raw bitmap cache order */
644 static void
645 process_raw_bmpcache(STREAM s)
646 {
647 HBITMAP bitmap;
648 uint16 cache_idx, bufsize;
649 uint8 cache_id, width, height, bpp, Bpp;
650 uint8 *data, *inverted;
651 int y;
652
653 in_uint8(s, cache_id);
654 in_uint8s(s, 1); /* pad */
655 in_uint8(s, width);
656 in_uint8(s, height);
657 in_uint8(s, bpp);
658 Bpp = (bpp + 7) / 8;
659 in_uint16_le(s, bufsize);
660 in_uint16_le(s, cache_idx);
661 in_uint8p(s, data, bufsize);
662
663 DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
664 inverted = xmalloc(width * height * Bpp);
665 for (y = 0; y < height; y++)
666 {
667 memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
668 width * Bpp);
669 }
670
671 bitmap = ui_create_bitmap(width, height, inverted);
672 xfree(inverted);
673 cache_put_bitmap(cache_id, cache_idx, bitmap);
674 }
675
676 /* Process a bitmap cache order */
677 static void
678 process_bmpcache(STREAM s)
679 {
680 HBITMAP bitmap;
681 uint16 cache_idx, size;
682 uint8 cache_id, width, height, bpp, Bpp;
683 uint8 *data, *bmpdata;
684 uint16 bufsize, pad2, row_size, final_size;
685 uint8 pad1;
686
687 in_uint8(s, cache_id);
688 in_uint8(s, pad1); /* pad */
689 in_uint8(s, width);
690 in_uint8(s, height);
691 in_uint8(s, bpp);
692 Bpp = (bpp + 7) / 8;
693 in_uint16_le(s, bufsize); /* bufsize */
694 in_uint16_le(s, cache_idx);
695
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 in_uint8p(s, data, size);
709
710 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
715 bmpdata = xmalloc(width * height * Bpp);
716
717 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
718 {
719 bitmap = ui_create_bitmap(width, height, bmpdata);
720 cache_put_bitmap(cache_id, cache_idx, bitmap);
721 }
722 else
723 {
724 DEBUG(("Failed to decompress bitmap data\n"));
725 }
726
727 xfree(bmpdata);
728 }
729
730 /* Process a colourmap cache order */
731 static void
732 process_colcache(STREAM s)
733 {
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 in_uint8s(s, 1); /* pad */
752 }
753
754 DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
755
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 static void
764 process_fontcache(STREAM s)
765 {
766 HGLYPH bitmap;
767 uint8 font, nglyphs;
768 uint16 character, offset, baseline, width, height;
769 int i, datasize;
770 uint8 *data;
771
772 in_uint8(s, font);
773 in_uint8(s, nglyphs);
774
775 DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
776
777 for (i = 0; i < nglyphs; i++)
778 {
779 in_uint16_le(s, character);
780 in_uint16_le(s, offset);
781 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 bitmap = ui_create_glyph(width, height, data);
789 cache_put_font(font, character, offset, baseline, width, height, bitmap);
790 }
791 }
792
793 /* Process a secondary order */
794 static void
795 process_secondary_order(STREAM s)
796 {
797 uint16 length;
798 uint8 type;
799 uint8 *next_order;
800
801 in_uint16_le(s, length);
802 in_uint8s(s, 2); /* flags */
803 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 unimpl("secondary order %d\n", type);
827 }
828
829 s->p = next_order;
830 }
831
832 /* Process an order PDU */
833 void
834 process_orders(STREAM s, uint16 num_orders)
835 {
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 error("order parsing failed\n");
849 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 os->bounds.top,
889 os->bounds.right -
890 os->bounds.left + 1,
891 os->bounds.bottom - os->bounds.top + 1);
892 }
893
894 delta = order_flags & RDP_ORDER_DELTA;
895
896 switch (os->order_type)
897 {
898 case RDP_ORDER_DESTBLT:
899 process_destblt(s, &os->destblt, present, delta);
900 break;
901
902 case RDP_ORDER_PATBLT:
903 process_patblt(s, &os->patblt, present, delta);
904 break;
905
906 case RDP_ORDER_SCREENBLT:
907 process_screenblt(s, &os->screenblt, present, delta);
908 break;
909
910 case RDP_ORDER_LINE:
911 process_line(s, &os->line, present, delta);
912 break;
913
914 case RDP_ORDER_RECT:
915 process_rect(s, &os->rect, present, delta);
916 break;
917
918 case RDP_ORDER_DESKSAVE:
919 process_desksave(s, &os->desksave, present, delta);
920 break;
921
922 case RDP_ORDER_MEMBLT:
923 process_memblt(s, &os->memblt, present, delta);
924 break;
925
926 case RDP_ORDER_TRIBLT:
927 process_triblt(s, &os->triblt, present, delta);
928 break;
929
930 case RDP_ORDER_POLYLINE:
931 process_polyline(s, &os->polyline, present, delta);
932 break;
933
934 case RDP_ORDER_TEXT2:
935 process_text2(s, &os->text2, present, delta);
936 break;
937
938 default:
939 unimpl("order %d\n", os->order_type);
940 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 error("%d bytes remaining\n", (int) (next_packet - s->p));
952 }
953
954 /* Reset order state */
955 void
956 reset_order_state(void)
957 {
958 memset(&order_state, 0, sizeof(order_state));
959 order_state.order_type = RDP_ORDER_PATBLT;
960 }

  ViewVC Help
Powered by ViewVC 1.1.26