/[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 382 - (show annotations)
Fri May 30 22:04:25 2003 UTC (20 years, 11 months ago) by jsorg71
File MIME type: text/plain
File size: 20732 byte(s)
adding g_ prefix to global vars, orders.c done

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 g_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, 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,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 = (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);
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 (!use_rdp5) {
699
700 /* Begin compressedBitmapData */
701 in_uint16_le(s, pad2); /* pad */
702 in_uint16_le(s, size);
703 // in_uint8s(s, 4); /* row_size, final_size */
704 in_uint16_le(s, row_size);
705 in_uint16_le(s, final_size);
706
707 } else {
708 size = bufsize;
709 }
710 in_uint8p(s, data, size);
711
712 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",
713 width, height,
714 cache_id, cache_idx,
715 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);
723 }
724 else
725 {
726 DEBUG(("Failed to decompress bitmap data\n"));
727 }
728
729 xfree(bmpdata);
730 }
731
732 /* Process a colourmap cache order */
733 static void
734 process_colcache(STREAM s)
735 {
736 COLOURENTRY *entry;
737 COLOURMAP map;
738 HCOLOURMAP hmap;
739 uint8 cache_id;
740 int i;
741
742 in_uint8(s, cache_id);
743 in_uint16_le(s, map.ncolours);
744
745 map.colours = (COLOURENTRY*)xmalloc(3 * map.ncolours);
746
747 for (i = 0; i < map.ncolours; i++)
748 {
749 entry = &map.colours[i];
750 in_uint8(s, entry->blue);
751 in_uint8(s, entry->green);
752 in_uint8(s, entry->red);
753 in_uint8s(s, 1); /* pad */
754 }
755
756 DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
757
758 hmap = ui_create_colourmap(&map);
759 ui_set_colourmap(hmap);
760
761 xfree(map.colours);
762 }
763
764 /* Process a font cache order */
765 static void
766 process_fontcache(STREAM s)
767 {
768 HGLYPH bitmap;
769 uint8 font, nglyphs;
770 uint16 character, offset, baseline, width, height;
771 int i, datasize;
772 uint8 *data;
773
774 in_uint8(s, font);
775 in_uint8(s, nglyphs);
776
777 DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
778
779 for (i = 0; i < nglyphs; i++)
780 {
781 in_uint16_le(s, character);
782 in_uint16_le(s, offset);
783 in_uint16_le(s, baseline);
784 in_uint16_le(s, width);
785 in_uint16_le(s, height);
786
787 datasize = (height * ((width + 7) / 8) + 3) & ~3;
788 in_uint8p(s, data, datasize);
789
790 bitmap = ui_create_glyph(width, height, data);
791 cache_put_font(font, character, offset, baseline, width, height, bitmap);
792 }
793 }
794
795 /* Process a secondary order */
796 static void
797 process_secondary_order(STREAM s)
798 {
799 uint16 length;
800 uint8 type;
801 uint8 *next_order;
802
803 in_uint16_le(s, length);
804 in_uint8s(s, 2); /* flags */
805 in_uint8(s, type);
806
807 next_order = s->p + length + 7;
808
809 switch (type)
810 {
811 case RDP_ORDER_RAW_BMPCACHE:
812 process_raw_bmpcache(s);
813 break;
814
815 case RDP_ORDER_COLCACHE:
816 process_colcache(s);
817 break;
818
819 case RDP_ORDER_BMPCACHE:
820 process_bmpcache(s);
821 break;
822
823 case RDP_ORDER_FONTCACHE:
824 process_fontcache(s);
825 break;
826
827 default:
828 unimpl("secondary order %d\n", type);
829 }
830
831 s->p = next_order;
832 }
833
834 /* Process an order PDU */
835 void
836 process_orders(STREAM s, uint16 num_orders)
837 {
838 RDP_ORDER_STATE *os = &g_order_state;
839 uint32 present;
840 uint8 order_flags;
841 int size, processed = 0;
842 BOOL delta;
843
844 while (processed < num_orders)
845 {
846 in_uint8(s, order_flags);
847
848 if (!(order_flags & RDP_ORDER_STANDARD))
849 {
850 error("order parsing failed\n");
851 break;
852 }
853
854 if (order_flags & RDP_ORDER_SECONDARY)
855 {
856 process_secondary_order(s);
857 }
858 else
859 {
860 if (order_flags & RDP_ORDER_CHANGE)
861 {
862 in_uint8(s, os->order_type);
863 }
864
865 switch (os->order_type)
866 {
867 case RDP_ORDER_TRIBLT:
868 case RDP_ORDER_TEXT2:
869 size = 3;
870 break;
871
872 case RDP_ORDER_PATBLT:
873 case RDP_ORDER_MEMBLT:
874 case RDP_ORDER_LINE:
875 size = 2;
876 break;
877
878 default:
879 size = 1;
880 }
881
882 rdp_in_present(s, &present, order_flags, size);
883
884 if (order_flags & RDP_ORDER_BOUNDS)
885 {
886 if (!(order_flags & RDP_ORDER_LASTBOUNDS))
887 rdp_parse_bounds(s, &os->bounds);
888
889 ui_set_clip(os->bounds.left,
890 os->bounds.top,
891 os->bounds.right -
892 os->bounds.left + 1,
893 os->bounds.bottom - os->bounds.top + 1);
894 }
895
896 delta = order_flags & RDP_ORDER_DELTA;
897
898 switch (os->order_type)
899 {
900 case RDP_ORDER_DESTBLT:
901 process_destblt(s, &os->destblt, present, delta);
902 break;
903
904 case RDP_ORDER_PATBLT:
905 process_patblt(s, &os->patblt, present, delta);
906 break;
907
908 case RDP_ORDER_SCREENBLT:
909 process_screenblt(s, &os->screenblt, present, delta);
910 break;
911
912 case RDP_ORDER_LINE:
913 process_line(s, &os->line, present, delta);
914 break;
915
916 case RDP_ORDER_RECT:
917 process_rect(s, &os->rect, present, delta);
918 break;
919
920 case RDP_ORDER_DESKSAVE:
921 process_desksave(s, &os->desksave, present, delta);
922 break;
923
924 case RDP_ORDER_MEMBLT:
925 process_memblt(s, &os->memblt, present, delta);
926 break;
927
928 case RDP_ORDER_TRIBLT:
929 process_triblt(s, &os->triblt, present, delta);
930 break;
931
932 case RDP_ORDER_POLYLINE:
933 process_polyline(s, &os->polyline, present, delta);
934 break;
935
936 case RDP_ORDER_TEXT2:
937 process_text2(s, &os->text2, present, delta);
938 break;
939
940 default:
941 unimpl("order %d\n", os->order_type);
942 return;
943 }
944
945 if (order_flags & RDP_ORDER_BOUNDS)
946 ui_reset_clip();
947 }
948
949 processed++;
950 }
951
952 if (s->p != next_packet)
953 error("%d bytes remaining\n", (int) (next_packet - s->p));
954 }
955
956 /* Reset order state */
957 void
958 reset_order_state(void)
959 {
960 memset(&g_order_state, 0, sizeof(g_order_state));
961 g_order_state.order_type = RDP_ORDER_PATBLT;
962 }

  ViewVC Help
Powered by ViewVC 1.1.26