/[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 732 - (show annotations)
Wed Jun 30 17:59:40 2004 UTC (19 years, 10 months ago) by jsorg71
File MIME type: text/plain
File size: 22891 byte(s)
fix a minor DEDUG spelling error

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 *g_next_packet;
25 static RDP_ORDER_STATE g_order_state;
26 extern BOOL g_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, sint16 * 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,dy=%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 = (uint8 *) 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, 0);
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 pad2 = row_size = final_size = 0xffff; /* Shut the compiler up */
688
689 in_uint8(s, cache_id);
690 in_uint8(s, pad1); /* pad */
691 in_uint8(s, width);
692 in_uint8(s, height);
693 in_uint8(s, bpp);
694 Bpp = (bpp + 7) / 8;
695 in_uint16_le(s, bufsize); /* bufsize */
696 in_uint16_le(s, cache_idx);
697
698 if (g_use_rdp5)
699 {
700 size = bufsize;
701 }
702 else
703 {
704
705 /* Begin compressedBitmapData */
706 in_uint16_le(s, pad2); /* pad */
707 in_uint16_le(s, size);
708 /* in_uint8s(s, 4); *//* row_size, final_size */
709 in_uint16_le(s, row_size);
710 in_uint16_le(s, final_size);
711
712 }
713 in_uint8p(s, data, size);
714
715 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", width, height, cache_id, cache_idx, bpp, size, pad1, bufsize, pad2, row_size, final_size));
716
717 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
718
719 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
720 {
721 bitmap = ui_create_bitmap(width, height, bmpdata);
722 cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
723 }
724 else
725 {
726 DEBUG(("Failed to decompress bitmap data\n"));
727 }
728
729 xfree(bmpdata);
730 }
731
732 /* Process a bitmap cache v2 order */
733 static void
734 process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
735 {
736 HBITMAP bitmap;
737 int y;
738 uint8 cache_id, cache_idx_low, width, height, Bpp;
739 uint16 cache_idx, bufsize;
740 uint8 *data, *bmpdata, *bitmap_id;
741
742 bitmap_id = NULL; /* prevent compiler warning */
743 cache_id = flags & ID_MASK;
744 Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
745
746 if (flags & PERSIST)
747 {
748 in_uint8p(s, bitmap_id, 8);
749 }
750
751 if (flags & SQUARE)
752 {
753 in_uint8(s, width);
754 height = width;
755 }
756 else
757 {
758 in_uint8(s, width);
759 in_uint8(s, height);
760 }
761
762 in_uint16_be(s, bufsize);
763 bufsize &= BUFSIZE_MASK;
764 in_uint8(s, cache_idx);
765
766 if (cache_idx & LONG_FORMAT)
767 {
768 in_uint8(s, cache_idx_low);
769 cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
770 }
771
772 in_uint8p(s, data, bufsize);
773
774 DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
775 compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
776
777 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
778
779 if (compressed)
780 {
781 if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
782 {
783 DEBUG(("Failed to decompress bitmap data\n"));
784 xfree(bmpdata);
785 return;
786 }
787 }
788 else
789 {
790 for (y = 0; y < height; y++)
791 memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
792 &data[y * (width * Bpp)], width * Bpp);
793 }
794
795 bitmap = ui_create_bitmap(width, height, bmpdata);
796
797 if (bitmap)
798 {
799 cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
800 if (flags & PERSIST)
801 pstcache_put_bitmap(cache_id, cache_idx, bitmap_id, width, height,
802 width * height * Bpp, bmpdata);
803 }
804 else
805 {
806 DEBUG(("process_bmpcache2: ui_create_bitmap failed\n"));
807 }
808
809 xfree(bmpdata);
810 }
811
812 /* Process a colourmap cache order */
813 static void
814 process_colcache(STREAM s)
815 {
816 COLOURENTRY *entry;
817 COLOURMAP map;
818 HCOLOURMAP hmap;
819 uint8 cache_id;
820 int i;
821
822 in_uint8(s, cache_id);
823 in_uint16_le(s, map.ncolours);
824
825 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
826
827 for (i = 0; i < map.ncolours; i++)
828 {
829 entry = &map.colours[i];
830 in_uint8(s, entry->blue);
831 in_uint8(s, entry->green);
832 in_uint8(s, entry->red);
833 in_uint8s(s, 1); /* pad */
834 }
835
836 DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
837
838 hmap = ui_create_colourmap(&map);
839 ui_set_colourmap(hmap);
840
841 xfree(map.colours);
842 }
843
844 /* Process a font cache order */
845 static void
846 process_fontcache(STREAM s)
847 {
848 HGLYPH bitmap;
849 uint8 font, nglyphs;
850 uint16 character, offset, baseline, width, height;
851 int i, datasize;
852 uint8 *data;
853
854 in_uint8(s, font);
855 in_uint8(s, nglyphs);
856
857 DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
858
859 for (i = 0; i < nglyphs; i++)
860 {
861 in_uint16_le(s, character);
862 in_uint16_le(s, offset);
863 in_uint16_le(s, baseline);
864 in_uint16_le(s, width);
865 in_uint16_le(s, height);
866
867 datasize = (height * ((width + 7) / 8) + 3) & ~3;
868 in_uint8p(s, data, datasize);
869
870 bitmap = ui_create_glyph(width, height, data);
871 cache_put_font(font, character, offset, baseline, width, height, bitmap);
872 }
873 }
874
875 /* Process a secondary order */
876 static void
877 process_secondary_order(STREAM s)
878 {
879 /* The length isn't calculated correctly by the server.
880 * For very compact orders the length becomes negative
881 * so a signed integer must be used. */
882 uint16 length;
883 uint16 flags;
884 uint8 type;
885 uint8 *next_order;
886
887 in_uint16_le(s, length);
888 in_uint16_le(s, flags); /* used by bmpcache2 */
889 in_uint8(s, type);
890
891 next_order = s->p + (sint16)length + 7;
892
893 switch (type)
894 {
895 case RDP_ORDER_RAW_BMPCACHE:
896 process_raw_bmpcache(s);
897 break;
898
899 case RDP_ORDER_COLCACHE:
900 process_colcache(s);
901 break;
902
903 case RDP_ORDER_BMPCACHE:
904 process_bmpcache(s);
905 break;
906
907 case RDP_ORDER_FONTCACHE:
908 process_fontcache(s);
909 break;
910
911 case RDP_ORDER_RAW_BMPCACHE2:
912 process_bmpcache2(s, flags, False); /* uncompressed */
913 break;
914
915 case RDP_ORDER_BMPCACHE2:
916 process_bmpcache2(s, flags, True); /* compressed */
917 break;
918
919 default:
920 unimpl("secondary order %d\n", type);
921 }
922
923 s->p = next_order;
924 }
925
926 /* Process an order PDU */
927 void
928 process_orders(STREAM s, uint16 num_orders)
929 {
930 RDP_ORDER_STATE *os = &g_order_state;
931 uint32 present;
932 uint8 order_flags;
933 int size, processed = 0;
934 BOOL delta;
935
936 while (processed < num_orders)
937 {
938 in_uint8(s, order_flags);
939
940 if (!(order_flags & RDP_ORDER_STANDARD))
941 {
942 error("order parsing failed\n");
943 break;
944 }
945
946 if (order_flags & RDP_ORDER_SECONDARY)
947 {
948 process_secondary_order(s);
949 }
950 else
951 {
952 if (order_flags & RDP_ORDER_CHANGE)
953 {
954 in_uint8(s, os->order_type);
955 }
956
957 switch (os->order_type)
958 {
959 case RDP_ORDER_TRIBLT:
960 case RDP_ORDER_TEXT2:
961 size = 3;
962 break;
963
964 case RDP_ORDER_PATBLT:
965 case RDP_ORDER_MEMBLT:
966 case RDP_ORDER_LINE:
967 size = 2;
968 break;
969
970 default:
971 size = 1;
972 }
973
974 rdp_in_present(s, &present, order_flags, size);
975
976 if (order_flags & RDP_ORDER_BOUNDS)
977 {
978 if (!(order_flags & RDP_ORDER_LASTBOUNDS))
979 rdp_parse_bounds(s, &os->bounds);
980
981 ui_set_clip(os->bounds.left,
982 os->bounds.top,
983 os->bounds.right -
984 os->bounds.left + 1,
985 os->bounds.bottom - os->bounds.top + 1);
986 }
987
988 delta = order_flags & RDP_ORDER_DELTA;
989
990 switch (os->order_type)
991 {
992 case RDP_ORDER_DESTBLT:
993 process_destblt(s, &os->destblt, present, delta);
994 break;
995
996 case RDP_ORDER_PATBLT:
997 process_patblt(s, &os->patblt, present, delta);
998 break;
999
1000 case RDP_ORDER_SCREENBLT:
1001 process_screenblt(s, &os->screenblt, present, delta);
1002 break;
1003
1004 case RDP_ORDER_LINE:
1005 process_line(s, &os->line, present, delta);
1006 break;
1007
1008 case RDP_ORDER_RECT:
1009 process_rect(s, &os->rect, present, delta);
1010 break;
1011
1012 case RDP_ORDER_DESKSAVE:
1013 process_desksave(s, &os->desksave, present, delta);
1014 break;
1015
1016 case RDP_ORDER_MEMBLT:
1017 process_memblt(s, &os->memblt, present, delta);
1018 break;
1019
1020 case RDP_ORDER_TRIBLT:
1021 process_triblt(s, &os->triblt, present, delta);
1022 break;
1023
1024 case RDP_ORDER_POLYLINE:
1025 process_polyline(s, &os->polyline, present, delta);
1026 break;
1027
1028 case RDP_ORDER_TEXT2:
1029 process_text2(s, &os->text2, present, delta);
1030 break;
1031
1032 default:
1033 unimpl("order %d\n", os->order_type);
1034 return;
1035 }
1036
1037 if (order_flags & RDP_ORDER_BOUNDS)
1038 ui_reset_clip();
1039 }
1040
1041 processed++;
1042 }
1043 #if 0
1044 /* not true when RDP_COMPRESSION is set */
1045 if (s->p != g_next_packet)
1046 error("%d bytes remaining\n", (int) (g_next_packet - s->p));
1047 #endif
1048
1049 }
1050
1051 /* Reset order state */
1052 void
1053 reset_order_state(void)
1054 {
1055 memset(&g_order_state, 0, sizeof(g_order_state));
1056 g_order_state.order_type = RDP_ORDER_PATBLT;
1057 }

  ViewVC Help
Powered by ViewVC 1.1.26