1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 RDP order processing
4 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "rdesktop.h"
21 #include "orders.h"
22
23 extern size_t g_next_packet;
24 static RDP_ORDER_STATE g_order_state;
25 extern RDP_VERSION g_rdp_version;
26
27 /* Read field indicating which parameters are present */
28 static void
rdp_in_present(STREAM s,uint32 * present,uint8 flags,int size)29 rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
30 {
31 uint8 bits;
32 int i;
33
34 if (flags & RDP_ORDER_SMALL)
35 {
36 size--;
37 }
38
39 if (flags & RDP_ORDER_TINY)
40 {
41 if (size < 2)
42 size = 0;
43 else
44 size -= 2;
45 }
46
47 *present = 0;
48 for (i = 0; i < size; i++)
49 {
50 in_uint8(s, bits);
51 *present |= bits << (i * 8);
52 }
53 }
54
55 /* Read a co-ordinate (16-bit, or 8-bit delta) */
56 static void
rdp_in_coord(STREAM s,sint16 * coord,RD_BOOL delta)57 rdp_in_coord(STREAM s, sint16 * coord, RD_BOOL delta)
58 {
59 sint8 change;
60
61 if (delta)
62 {
63 in_uint8(s, change);
64 *coord += change;
65 }
66 else
67 {
68 in_uint16_le(s, *coord);
69 }
70 }
71
72 /* Parse a delta co-ordinate in polyline/polygon order form */
73 static int
parse_delta(uint8 * buffer,int * offset)74 parse_delta(uint8 * buffer, int *offset)
75 {
76 int value = buffer[(*offset)++];
77 int two_byte = value & 0x80;
78
79 if (value & 0x40) /* sign bit */
80 value |= ~0x3f;
81 else
82 value &= 0x3f;
83
84 if (two_byte)
85 value = (value << 8) | buffer[(*offset)++];
86
87 return value;
88 }
89
90 /* Read a colour entry */
91 static void
rdp_in_colour(STREAM s,uint32 * colour)92 rdp_in_colour(STREAM s, uint32 * colour)
93 {
94 uint32 i;
95 in_uint8(s, i);
96 *colour = i;
97 in_uint8(s, i);
98 *colour |= i << 8;
99 in_uint8(s, i);
100 *colour |= i << 16;
101 }
102
103 /* Parse bounds information */
104 static void
rdp_parse_bounds(STREAM s,BOUNDS * bounds)105 rdp_parse_bounds(STREAM s, BOUNDS * bounds)
106 {
107 uint8 present;
108
109 in_uint8(s, present);
110
111 if (present & 1)
112 rdp_in_coord(s, &bounds->left, False);
113 else if (present & 16)
114 rdp_in_coord(s, &bounds->left, True);
115
116 if (present & 2)
117 rdp_in_coord(s, &bounds->top, False);
118 else if (present & 32)
119 rdp_in_coord(s, &bounds->top, True);
120
121 if (present & 4)
122 rdp_in_coord(s, &bounds->right, False);
123 else if (present & 64)
124 rdp_in_coord(s, &bounds->right, True);
125
126 if (present & 8)
127 rdp_in_coord(s, &bounds->bottom, False);
128 else if (present & 128)
129 rdp_in_coord(s, &bounds->bottom, True);
130 }
131
132 /* Parse a pen */
133 static void
rdp_parse_pen(STREAM s,PEN * pen,uint32 present)134 rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
135 {
136 if (present & 1)
137 in_uint8(s, pen->style);
138
139 if (present & 2)
140 in_uint8(s, pen->width);
141
142 if (present & 4)
143 rdp_in_colour(s, &pen->colour);
144 }
145
146 static void
setup_brush(BRUSH * out_brush,BRUSH * in_brush)147 setup_brush(BRUSH * out_brush, BRUSH * in_brush)
148 {
149 BRUSHDATA *brush_data;
150 uint8 cache_idx;
151 uint8 colour_code;
152
153 memcpy(out_brush, in_brush, sizeof(BRUSH));
154 if (out_brush->style & 0x80)
155 {
156 colour_code = out_brush->style & 0x0f;
157 cache_idx = out_brush->pattern[0];
158 brush_data = cache_get_brush_data(colour_code, cache_idx);
159 if ((brush_data == NULL) || (brush_data->data == NULL))
160 {
161 logger(Graphics, Error, "setup_brush(), error getting brush data, style %x",
162 out_brush->style);
163 out_brush->bd = NULL;
164 memset(out_brush->pattern, 0, 8);
165 }
166 else
167 {
168 out_brush->bd = brush_data;
169 }
170 out_brush->style = 3;
171 }
172 }
173
174 /* Parse a brush */
175 static void
rdp_parse_brush(STREAM s,BRUSH * brush,uint32 present)176 rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
177 {
178 if (present & 1)
179 in_uint8(s, brush->xorigin);
180
181 if (present & 2)
182 in_uint8(s, brush->yorigin);
183
184 if (present & 4)
185 in_uint8(s, brush->style);
186
187 if (present & 8)
188 in_uint8(s, brush->pattern[0]);
189
190 if (present & 16)
191 in_uint8a(s, &brush->pattern[1], 7);
192 }
193
194 /* Process a destination blt order */
195 static void
process_destblt(STREAM s,DESTBLT_ORDER * os,uint32 present,RD_BOOL delta)196 process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, RD_BOOL delta)
197 {
198 if (present & 0x01)
199 rdp_in_coord(s, &os->x, delta);
200
201 if (present & 0x02)
202 rdp_in_coord(s, &os->y, delta);
203
204 if (present & 0x04)
205 rdp_in_coord(s, &os->cx, delta);
206
207 if (present & 0x08)
208 rdp_in_coord(s, &os->cy, delta);
209
210 if (present & 0x10)
211 in_uint8(s, os->opcode);
212
213 logger(Graphics, Debug, "process_destblt(), op=0x%x, x=%d, y=%d, cx=%d, cy=%d",
214 os->opcode, os->x, os->y, os->cx, os->cy);
215
216 ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
217 }
218
219 /* Process a pattern blt order */
220 static void
process_patblt(STREAM s,PATBLT_ORDER * os,uint32 present,RD_BOOL delta)221 process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, RD_BOOL delta)
222 {
223 BRUSH brush;
224
225 if (present & 0x0001)
226 rdp_in_coord(s, &os->x, delta);
227
228 if (present & 0x0002)
229 rdp_in_coord(s, &os->y, delta);
230
231 if (present & 0x0004)
232 rdp_in_coord(s, &os->cx, delta);
233
234 if (present & 0x0008)
235 rdp_in_coord(s, &os->cy, delta);
236
237 if (present & 0x0010)
238 in_uint8(s, os->opcode);
239
240 if (present & 0x0020)
241 rdp_in_colour(s, &os->bgcolour);
242
243 if (present & 0x0040)
244 rdp_in_colour(s, &os->fgcolour);
245
246 rdp_parse_brush(s, &os->brush, present >> 7);
247
248 logger(Graphics, Debug,
249 "process_patblt(), op=0x%x, x=%d, y=%d, cx=%d, cy=%d, bs=%d, bg=0x%x, fg=0x%x)",
250 os->opcode, os->x, os->y, os->cx, os->cy, os->brush.style, os->bgcolour,
251 os->fgcolour);
252
253 setup_brush(&brush, &os->brush);
254
255 ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
256 &brush, os->bgcolour, os->fgcolour);
257 }
258
259 /* Process a screen blt order */
260 static void
process_screenblt(STREAM s,SCREENBLT_ORDER * os,uint32 present,RD_BOOL delta)261 process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, RD_BOOL delta)
262 {
263 if (present & 0x0001)
264 rdp_in_coord(s, &os->x, delta);
265
266 if (present & 0x0002)
267 rdp_in_coord(s, &os->y, delta);
268
269 if (present & 0x0004)
270 rdp_in_coord(s, &os->cx, delta);
271
272 if (present & 0x0008)
273 rdp_in_coord(s, &os->cy, delta);
274
275 if (present & 0x0010)
276 in_uint8(s, os->opcode);
277
278 if (present & 0x0020)
279 rdp_in_coord(s, &os->srcx, delta);
280
281 if (present & 0x0040)
282 rdp_in_coord(s, &os->srcy, delta);
283
284 logger(Graphics, Debug,
285 "process_screenblt(), op=0x%x, x=%d, y=%d, cx=%d, cy=%d, srcx=%d, srcy=%d)",
286 os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
287
288 ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
289 }
290
291 /* Process a line order */
292 static void
process_line(STREAM s,LINE_ORDER * os,uint32 present,RD_BOOL delta)293 process_line(STREAM s, LINE_ORDER * os, uint32 present, RD_BOOL delta)
294 {
295 if (present & 0x0001)
296 in_uint16_le(s, os->mixmode);
297
298 if (present & 0x0002)
299 rdp_in_coord(s, &os->startx, delta);
300
301 if (present & 0x0004)
302 rdp_in_coord(s, &os->starty, delta);
303
304 if (present & 0x0008)
305 rdp_in_coord(s, &os->endx, delta);
306
307 if (present & 0x0010)
308 rdp_in_coord(s, &os->endy, delta);
309
310 if (present & 0x0020)
311 rdp_in_colour(s, &os->bgcolour);
312
313 if (present & 0x0040)
314 in_uint8(s, os->opcode);
315
316 rdp_parse_pen(s, &os->pen, present >> 7);
317
318 logger(Graphics, Debug, "process_line(), op=0x%x, sx=%d, sy=%d, dx=%d, dy=%d, fg=0x%x)",
319 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour);
320
321 if (os->opcode < 0x01 || os->opcode > 0x10)
322 {
323 logger(Graphics, Error, "process_line(), bad ROP2 0x%x", os->opcode);
324 return;
325 }
326
327 ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
328 }
329
330 /* Process an opaque rectangle order */
331 static void
process_rect(STREAM s,RECT_ORDER * os,uint32 present,RD_BOOL delta)332 process_rect(STREAM s, RECT_ORDER * os, uint32 present, RD_BOOL delta)
333 {
334 uint32 i;
335 if (present & 0x01)
336 rdp_in_coord(s, &os->x, delta);
337
338 if (present & 0x02)
339 rdp_in_coord(s, &os->y, delta);
340
341 if (present & 0x04)
342 rdp_in_coord(s, &os->cx, delta);
343
344 if (present & 0x08)
345 rdp_in_coord(s, &os->cy, delta);
346
347 if (present & 0x10)
348 {
349 in_uint8(s, i);
350 os->colour = (os->colour & 0xffffff00) | i;
351 }
352
353 if (present & 0x20)
354 {
355 in_uint8(s, i);
356 os->colour = (os->colour & 0xffff00ff) | (i << 8);
357 }
358
359 if (present & 0x40)
360 {
361 in_uint8(s, i);
362 os->colour = (os->colour & 0xff00ffff) | (i << 16);
363 }
364
365 logger(Graphics, Debug, "process_rect(), x=%d, y=%d, cx=%d, cy=%d, fg=0x%x",
366 os->x, os->y, os->cx, os->cy, os->colour);
367
368 ui_rect(os->x, os->y, os->cx, os->cy, os->colour);
369 }
370
371 /* Process a desktop save order */
372 static void
process_desksave(STREAM s,DESKSAVE_ORDER * os,uint32 present,RD_BOOL delta)373 process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, RD_BOOL delta)
374 {
375 int width, height;
376
377 if (present & 0x01)
378 in_uint32_le(s, os->offset);
379
380 if (present & 0x02)
381 rdp_in_coord(s, &os->left, delta);
382
383 if (present & 0x04)
384 rdp_in_coord(s, &os->top, delta);
385
386 if (present & 0x08)
387 rdp_in_coord(s, &os->right, delta);
388
389 if (present & 0x10)
390 rdp_in_coord(s, &os->bottom, delta);
391
392 if (present & 0x20)
393 in_uint8(s, os->action);
394
395 logger(Graphics, Debug, "process_desksave(), l=%d, t=%d, r=%d, b=%d, off=%d, op=%d",
396 os->left, os->top, os->right, os->bottom, os->offset, os->action);
397
398 width = os->right - os->left + 1;
399 height = os->bottom - os->top + 1;
400
401 if (os->action == 0)
402 ui_desktop_save(os->offset, os->left, os->top, width, height);
403 else
404 ui_desktop_restore(os->offset, os->left, os->top, width, height);
405 }
406
407 /* Process a memory blt order */
408 static void
process_memblt(STREAM s,MEMBLT_ORDER * os,uint32 present,RD_BOOL delta)409 process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, RD_BOOL delta)
410 {
411 RD_HBITMAP bitmap;
412
413 if (present & 0x0001)
414 {
415 in_uint8(s, os->cache_id);
416 in_uint8(s, os->colour_table);
417 }
418
419 if (present & 0x0002)
420 rdp_in_coord(s, &os->x, delta);
421
422 if (present & 0x0004)
423 rdp_in_coord(s, &os->y, delta);
424
425 if (present & 0x0008)
426 rdp_in_coord(s, &os->cx, delta);
427
428 if (present & 0x0010)
429 rdp_in_coord(s, &os->cy, delta);
430
431 if (present & 0x0020)
432 in_uint8(s, os->opcode);
433
434 if (present & 0x0040)
435 rdp_in_coord(s, &os->srcx, delta);
436
437 if (present & 0x0080)
438 rdp_in_coord(s, &os->srcy, delta);
439
440 if (present & 0x0100)
441 in_uint16_le(s, os->cache_idx);
442
443 logger(Graphics, Debug,
444 "process_memblt(), op=0x%x, x=%d, y=%d, cx=%d, cy=%d, id=%d, idx=%d", os->opcode,
445 os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx);
446
447 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
448 if (bitmap == NULL)
449 return;
450
451 ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy);
452 }
453
454 /* Process a 3-way blt order */
455 static void
process_triblt(STREAM s,TRIBLT_ORDER * os,uint32 present,RD_BOOL delta)456 process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, RD_BOOL delta)
457 {
458 RD_HBITMAP bitmap;
459 BRUSH brush;
460
461 if (present & 0x000001)
462 {
463 in_uint8(s, os->cache_id);
464 in_uint8(s, os->colour_table);
465 }
466
467 if (present & 0x000002)
468 rdp_in_coord(s, &os->x, delta);
469
470 if (present & 0x000004)
471 rdp_in_coord(s, &os->y, delta);
472
473 if (present & 0x000008)
474 rdp_in_coord(s, &os->cx, delta);
475
476 if (present & 0x000010)
477 rdp_in_coord(s, &os->cy, delta);
478
479 if (present & 0x000020)
480 in_uint8(s, os->opcode);
481
482 if (present & 0x000040)
483 rdp_in_coord(s, &os->srcx, delta);
484
485 if (present & 0x000080)
486 rdp_in_coord(s, &os->srcy, delta);
487
488 if (present & 0x000100)
489 rdp_in_colour(s, &os->bgcolour);
490
491 if (present & 0x000200)
492 rdp_in_colour(s, &os->fgcolour);
493
494 rdp_parse_brush(s, &os->brush, present >> 10);
495
496 if (present & 0x008000)
497 in_uint16_le(s, os->cache_idx);
498
499 if (present & 0x010000)
500 in_uint16_le(s, os->unknown);
501
502 logger(Graphics, Debug,
503 "process_triblt(), op=0x%x, x=%d, y=%d, cx=%d, cy=%d, id=%d, idx=%d, bs=%d, bg=0x%x, fg=0x%x",
504 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx,
505 os->brush.style, os->bgcolour, os->fgcolour);
506
507 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
508 if (bitmap == NULL)
509 return;
510
511 setup_brush(&brush, &os->brush);
512
513 ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
514 bitmap, os->srcx, os->srcy, &brush, os->bgcolour, os->fgcolour);
515 }
516
517 /* Process a polygon order */
518 static void
process_polygon(STREAM s,POLYGON_ORDER * os,uint32 present,RD_BOOL delta)519 process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, RD_BOOL delta)
520 {
521 int index, data, next;
522 uint8 flags = 0;
523 RD_POINT *points;
524
525 if (present & 0x01)
526 rdp_in_coord(s, &os->x, delta);
527
528 if (present & 0x02)
529 rdp_in_coord(s, &os->y, delta);
530
531 if (present & 0x04)
532 in_uint8(s, os->opcode);
533
534 if (present & 0x08)
535 in_uint8(s, os->fillmode);
536
537 if (present & 0x10)
538 rdp_in_colour(s, &os->fgcolour);
539
540 if (present & 0x20)
541 in_uint8(s, os->npoints);
542
543 if (present & 0x40)
544 {
545 in_uint8(s, os->datasize);
546 in_uint8a(s, os->data, os->datasize);
547 }
548
549 logger(Graphics, Debug,
550 "process_polygon(), x=%d, y=%d, op=0x%x, fm=%d, fg=0x%x, n=%d, sz=%d", os->x, os->y,
551 os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize);
552
553 if (os->opcode < 0x01 || os->opcode > 0x10)
554 {
555 logger(Graphics, Error, "process_polygon(), bad ROP2 0x%x", os->opcode);
556 return;
557 }
558
559 points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
560 memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
561
562 points[0].x = os->x;
563 points[0].y = os->y;
564
565 index = 0;
566 data = ((os->npoints - 1) / 4) + 1;
567 for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
568 {
569 if ((next - 1) % 4 == 0)
570 flags = os->data[index++];
571
572 if (~flags & 0x80)
573 points[next].x = parse_delta(os->data, &data);
574
575 if (~flags & 0x40)
576 points[next].y = parse_delta(os->data, &data);
577
578 flags <<= 2;
579 }
580
581 if (next - 1 == os->npoints)
582 ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,
583 os->fgcolour);
584 else
585 logger(Graphics, Error, "process_polygon(), polygon parse error");
586
587 xfree(points);
588 }
589
590 /* Process a polygon2 order */
591 static void
process_polygon2(STREAM s,POLYGON2_ORDER * os,uint32 present,RD_BOOL delta)592 process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, RD_BOOL delta)
593 {
594 int index, data, next;
595 uint8 flags = 0;
596 RD_POINT *points;
597 BRUSH brush;
598
599 if (present & 0x0001)
600 rdp_in_coord(s, &os->x, delta);
601
602 if (present & 0x0002)
603 rdp_in_coord(s, &os->y, delta);
604
605 if (present & 0x0004)
606 in_uint8(s, os->opcode);
607
608 if (present & 0x0008)
609 in_uint8(s, os->fillmode);
610
611 if (present & 0x0010)
612 rdp_in_colour(s, &os->bgcolour);
613
614 if (present & 0x0020)
615 rdp_in_colour(s, &os->fgcolour);
616
617 rdp_parse_brush(s, &os->brush, present >> 6);
618
619 if (present & 0x0800)
620 in_uint8(s, os->npoints);
621
622 if (present & 0x1000)
623 {
624 in_uint8(s, os->datasize);
625 in_uint8a(s, os->data, os->datasize);
626 }
627
628 logger(Graphics, Debug,
629 "process_polygon2(), x=%d, y=%d, op=0x%x, fm=%d, bs=%d, bg=0x%x, fg=0x%x, n=%d, sz=%d)",
630 os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour,
631 os->npoints, os->datasize);
632
633 if (os->opcode < 0x01 || os->opcode > 0x10)
634 {
635 logger(Graphics, Error, "process_polygon2(), bad ROP2 0x%x", os->opcode);
636 return;
637 }
638
639 setup_brush(&brush, &os->brush);
640
641 points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
642 memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
643
644 points[0].x = os->x;
645 points[0].y = os->y;
646
647 index = 0;
648 data = ((os->npoints - 1) / 4) + 1;
649 for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
650 {
651 if ((next - 1) % 4 == 0)
652 flags = os->data[index++];
653
654 if (~flags & 0x80)
655 points[next].x = parse_delta(os->data, &data);
656
657 if (~flags & 0x40)
658 points[next].y = parse_delta(os->data, &data);
659
660 flags <<= 2;
661 }
662
663 if (next - 1 == os->npoints)
664 ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
665 &brush, os->bgcolour, os->fgcolour);
666 else
667 logger(Graphics, Error, "process_polygon2(), polygon parse error");
668
669 xfree(points);
670 }
671
672 /* Process a polyline order */
673 static void
process_polyline(STREAM s,POLYLINE_ORDER * os,uint32 present,RD_BOOL delta)674 process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, RD_BOOL delta)
675 {
676 int index, next, data;
677 uint8 flags = 0;
678 PEN pen;
679 RD_POINT *points;
680
681 if (present & 0x01)
682 rdp_in_coord(s, &os->x, delta);
683
684 if (present & 0x02)
685 rdp_in_coord(s, &os->y, delta);
686
687 if (present & 0x04)
688 in_uint8(s, os->opcode);
689
690 if (present & 0x10)
691 rdp_in_colour(s, &os->fgcolour);
692
693 if (present & 0x20)
694 in_uint8(s, os->lines);
695
696 if (present & 0x40)
697 {
698 in_uint8(s, os->datasize);
699 in_uint8a(s, os->data, os->datasize);
700 }
701
702 logger(Graphics, Debug, "process_polyline(), x=%d, y=%d, op=0x%x, fg=0x%x, n=%d, sz=%d)",
703 os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize);
704
705 if (os->opcode < 0x01 || os->opcode > 0x10)
706 {
707 logger(Graphics, Error, "process_polyline(), bad ROP2 0x%x", os->opcode);
708 return;
709 }
710
711 points = (RD_POINT *) xmalloc((os->lines + 1) * sizeof(RD_POINT));
712 memset(points, 0, (os->lines + 1) * sizeof(RD_POINT));
713
714 points[0].x = os->x;
715 points[0].y = os->y;
716 pen.style = pen.width = 0;
717 pen.colour = os->fgcolour;
718
719 index = 0;
720 data = ((os->lines - 1) / 4) + 1;
721 for (next = 1; (next <= os->lines) && (data < os->datasize); next++)
722 {
723 if ((next - 1) % 4 == 0)
724 flags = os->data[index++];
725
726 if (~flags & 0x80)
727 points[next].x = parse_delta(os->data, &data);
728
729 if (~flags & 0x40)
730 points[next].y = parse_delta(os->data, &data);
731
732 flags <<= 2;
733 }
734
735 if (next - 1 == os->lines)
736 ui_polyline(os->opcode - 1, points, os->lines + 1, &pen);
737 else
738 logger(Graphics, Error, "process_polyline(), parse error");
739
740 xfree(points);
741 }
742
743 /* Process an ellipse order */
744 static void
process_ellipse(STREAM s,ELLIPSE_ORDER * os,uint32 present,RD_BOOL delta)745 process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, RD_BOOL delta)
746 {
747 if (present & 0x01)
748 rdp_in_coord(s, &os->left, delta);
749
750 if (present & 0x02)
751 rdp_in_coord(s, &os->top, delta);
752
753 if (present & 0x04)
754 rdp_in_coord(s, &os->right, delta);
755
756 if (present & 0x08)
757 rdp_in_coord(s, &os->bottom, delta);
758
759 if (present & 0x10)
760 in_uint8(s, os->opcode);
761
762 if (present & 0x20)
763 in_uint8(s, os->fillmode);
764
765 if (present & 0x40)
766 rdp_in_colour(s, &os->fgcolour);
767
768 logger(Graphics, Debug,
769 "process_ellipse(), l=%d, t=%d, r=%d, b=%d, op=0x%x, fm=%d, fg=0x%x", os->left,
770 os->top, os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour);
771
772 ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
773 os->bottom - os->top, NULL, 0, os->fgcolour);
774 }
775
776 /* Process an ellipse2 order */
777 static void
process_ellipse2(STREAM s,ELLIPSE2_ORDER * os,uint32 present,RD_BOOL delta)778 process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, RD_BOOL delta)
779 {
780 BRUSH brush;
781
782 if (present & 0x0001)
783 rdp_in_coord(s, &os->left, delta);
784
785 if (present & 0x0002)
786 rdp_in_coord(s, &os->top, delta);
787
788 if (present & 0x0004)
789 rdp_in_coord(s, &os->right, delta);
790
791 if (present & 0x0008)
792 rdp_in_coord(s, &os->bottom, delta);
793
794 if (present & 0x0010)
795 in_uint8(s, os->opcode);
796
797 if (present & 0x0020)
798 in_uint8(s, os->fillmode);
799
800 if (present & 0x0040)
801 rdp_in_colour(s, &os->bgcolour);
802
803 if (present & 0x0080)
804 rdp_in_colour(s, &os->fgcolour);
805
806 rdp_parse_brush(s, &os->brush, present >> 8);
807
808 logger(Graphics, Debug,
809 "process_ellipse2(), l=%d, t=%d, r=%d, b=%d, op=0x%x, fm=%d, bs=%d, bg=0x%x, fg=0x%x",
810 os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style,
811 os->bgcolour, os->fgcolour);
812
813 setup_brush(&brush, &os->brush);
814
815 ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
816 os->bottom - os->top, &brush, os->bgcolour, os->fgcolour);
817 }
818
819 /* Process a text order */
820 static void
process_text2(STREAM s,TEXT2_ORDER * os,uint32 present,RD_BOOL delta)821 process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, RD_BOOL delta)
822 {
823 UNUSED(delta);
824 BRUSH brush;
825
826 if (present & 0x000001)
827 in_uint8(s, os->font);
828
829 if (present & 0x000002)
830 in_uint8(s, os->flags);
831
832 if (present & 0x000004)
833 in_uint8(s, os->opcode);
834
835 if (present & 0x000008)
836 in_uint8(s, os->mixmode);
837
838 if (present & 0x000010)
839 rdp_in_colour(s, &os->fgcolour);
840
841 if (present & 0x000020)
842 rdp_in_colour(s, &os->bgcolour);
843
844 if (present & 0x000040)
845 in_uint16_le(s, os->clipleft);
846
847 if (present & 0x000080)
848 in_uint16_le(s, os->cliptop);
849
850 if (present & 0x000100)
851 in_uint16_le(s, os->clipright);
852
853 if (present & 0x000200)
854 in_uint16_le(s, os->clipbottom);
855
856 if (present & 0x000400)
857 in_uint16_le(s, os->boxleft);
858
859 if (present & 0x000800)
860 in_uint16_le(s, os->boxtop);
861
862 if (present & 0x001000)
863 in_uint16_le(s, os->boxright);
864
865 if (present & 0x002000)
866 in_uint16_le(s, os->boxbottom);
867
868 rdp_parse_brush(s, &os->brush, present >> 14);
869
870 if (present & 0x080000)
871 in_uint16_le(s, os->x);
872
873 if (present & 0x100000)
874 in_uint16_le(s, os->y);
875
876 if (present & 0x200000)
877 {
878 in_uint8(s, os->length);
879 in_uint8a(s, os->text, os->length);
880 }
881
882 logger(Graphics, Debug,
883 "process_text2(), x=%d, y=%d, cl=%d, ct=%d, cr=%d, cb=%d, bl=%d, bt=%d, br=%d, bb=%d, bs=%d, bg=0x%x, fg=0x%x, font=%d, fl=0x%x, op=0x%x, mix=%d, n=%d",
884 os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft,
885 os->boxtop, os->boxright, os->boxbottom, os->brush.style, os->bgcolour, os->fgcolour,
886 os->font, os->flags, os->opcode, os->mixmode, os->length);
887
888 setup_brush(&brush, &os->brush);
889
890 ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
891 os->clipleft, os->cliptop, os->clipright - os->clipleft,
892 os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
893 os->boxright - os->boxleft, os->boxbottom - os->boxtop,
894 &brush, os->bgcolour, os->fgcolour, os->text, os->length);
895 }
896
897 /* Process a raw bitmap cache order */
898 static void
process_raw_bmpcache(STREAM s)899 process_raw_bmpcache(STREAM s)
900 {
901 RD_HBITMAP bitmap;
902 uint16 cache_idx, bufsize;
903 uint8 cache_id, width, height, bpp, Bpp;
904 uint8 *data, *inverted;
905 int y;
906
907 in_uint8(s, cache_id);
908 in_uint8s(s, 1); /* pad */
909 in_uint8(s, width);
910 in_uint8(s, height);
911 in_uint8(s, bpp);
912 Bpp = (bpp + 7) / 8;
913 in_uint16_le(s, bufsize);
914 in_uint16_le(s, cache_idx);
915 in_uint8p(s, data, bufsize);
916
917 logger(Graphics, Debug, "process_raw_bpmcache(), cx=%d, cy=%d, id=%d, idx=%d", width,
918 height, cache_id, cache_idx);
919 inverted = (uint8 *) xmalloc(width * height * Bpp);
920 for (y = 0; y < height; y++)
921 {
922 memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
923 width * Bpp);
924 }
925
926 bitmap = ui_create_bitmap(width, height, inverted);
927 xfree(inverted);
928 cache_put_bitmap(cache_id, cache_idx, bitmap);
929 }
930
931 /* Process a bitmap cache order */
932 static void
process_bmpcache(STREAM s)933 process_bmpcache(STREAM s)
934 {
935 RD_HBITMAP bitmap;
936 uint16 cache_idx, size;
937 uint8 cache_id, width, height, bpp, Bpp;
938 uint8 *data, *bmpdata;
939 uint16 bufsize, pad2, row_size, final_size;
940 uint8 pad1;
941
942 pad2 = row_size = final_size = 0xffff; /* Shut the compiler up */
943
944 in_uint8(s, cache_id);
945 in_uint8(s, pad1); /* pad */
946 in_uint8(s, width);
947 in_uint8(s, height);
948 in_uint8(s, bpp);
949 Bpp = (bpp + 7) / 8;
950 in_uint16_le(s, bufsize); /* bufsize */
951 in_uint16_le(s, cache_idx);
952
953 if (g_rdp_version >= RDP_V5)
954 {
955 size = bufsize;
956 }
957 else
958 {
959
960 /* Begin compressedBitmapData */
961 in_uint16_le(s, pad2); /* pad */
962 in_uint16_le(s, size);
963 /* in_uint8s(s, 4); *//* row_size, final_size */
964 in_uint16_le(s, row_size);
965 in_uint16_le(s, final_size);
966
967 }
968 in_uint8p(s, data, size);
969 logger(Graphics, Debug,
970 "process_bmpcache(), cx=%d, cy=%d, id=%d, idx=%d, bpp=%d, size=%d, pad1=%d, bufsize=%d, pad2=%d, rs=%d, fs=%d",
971 width, height, cache_id, cache_idx, bpp, size, pad1, bufsize, pad2, row_size,
972 final_size);
973
974 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
975
976 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
977 {
978 bitmap = ui_create_bitmap(width, height, bmpdata);
979 cache_put_bitmap(cache_id, cache_idx, bitmap);
980 }
981 else
982 {
983 logger(Graphics, Error, "process_bmpcache(), Failed to decompress bitmap data");
984 }
985
986 xfree(bmpdata);
987 }
988
989 /* Process a bitmap cache v2 order */
990 static void
process_bmpcache2(STREAM s,uint16 flags,RD_BOOL compressed)991 process_bmpcache2(STREAM s, uint16 flags, RD_BOOL compressed)
992 {
993 RD_HBITMAP bitmap;
994 int y;
995 uint8 cache_id, cache_idx_low, width, height, Bpp;
996 uint16 cache_idx, bufsize;
997 uint8 *data, *bmpdata, *bitmap_id;
998
999 bitmap_id = NULL; /* prevent compiler warning */
1000 cache_id = flags & ID_MASK;
1001 Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
1002
1003 if (flags & PERSIST)
1004 {
1005 in_uint8p(s, bitmap_id, 8);
1006 }
1007
1008 if (flags & SQUARE)
1009 {
1010 in_uint8(s, width);
1011 height = width;
1012 }
1013 else
1014 {
1015 in_uint8(s, width);
1016 in_uint8(s, height);
1017 }
1018
1019 in_uint16_be(s, bufsize);
1020 bufsize &= BUFSIZE_MASK;
1021 in_uint8(s, cache_idx);
1022
1023 if (cache_idx & LONG_FORMAT)
1024 {
1025 in_uint8(s, cache_idx_low);
1026 cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
1027 }
1028
1029 in_uint8p(s, data, bufsize);
1030
1031 logger(Graphics, Debug,
1032 "process_bmpcache2(), compr=%d, flags=%x, cx=%d, cy=%d, id=%d, idx=%d, Bpp=%d, bs=%d",
1033 compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize);
1034
1035 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1036
1037 if (compressed)
1038 {
1039 if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
1040 {
1041 logger(Graphics, Error,
1042 "process_bmpcache2(), failed to decompress bitmap data");
1043 xfree(bmpdata);
1044 return;
1045 }
1046 }
1047 else
1048 {
1049 for (y = 0; y < height; y++)
1050 memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
1051 &data[y * (width * Bpp)], width * Bpp);
1052 }
1053
1054 bitmap = ui_create_bitmap(width, height, bmpdata);
1055
1056 if (bitmap)
1057 {
1058 cache_put_bitmap(cache_id, cache_idx, bitmap);
1059 if (flags & PERSIST)
1060 pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height,
1061 width * height * Bpp, bmpdata);
1062 }
1063 else
1064 {
1065 logger(Graphics, Error, "process_bmpcache2(), ui_create_bitmap(), failed");
1066 }
1067
1068 xfree(bmpdata);
1069 }
1070
1071 /* Process a colourmap cache order */
1072 static void
process_colcache(STREAM s)1073 process_colcache(STREAM s)
1074 {
1075 COLOURENTRY *entry;
1076 COLOURMAP map;
1077 RD_HCOLOURMAP hmap;
1078 uint8 cache_id;
1079 int i;
1080
1081 in_uint8(s, cache_id);
1082 in_uint16_le(s, map.ncolours);
1083
1084 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1085
1086 for (i = 0; i < map.ncolours; i++)
1087 {
1088 entry = &map.colours[i];
1089 in_uint8(s, entry->blue);
1090 in_uint8(s, entry->green);
1091 in_uint8(s, entry->red);
1092 in_uint8s(s, 1); /* pad */
1093 }
1094
1095 logger(Graphics, Debug, "process_colcache(), id=%d, n=%d", cache_id, map.ncolours);
1096
1097 hmap = ui_create_colourmap(&map);
1098
1099 if (cache_id)
1100 ui_set_colourmap(hmap);
1101
1102 xfree(map.colours);
1103 }
1104
1105 /* Process a font cache order */
1106 static void
process_fontcache(STREAM s)1107 process_fontcache(STREAM s)
1108 {
1109 RD_HGLYPH bitmap;
1110 uint8 font, nglyphs;
1111 uint16 character, offset, baseline, width, height;
1112 int i, datasize;
1113 uint8 *data;
1114
1115 in_uint8(s, font);
1116 in_uint8(s, nglyphs);
1117
1118 logger(Graphics, Debug, "process_fontcache(), font=%d, n=%d", font, nglyphs);
1119
1120 for (i = 0; i < nglyphs; i++)
1121 {
1122 in_uint16_le(s, character);
1123 in_uint16_le(s, offset);
1124 in_uint16_le(s, baseline);
1125 in_uint16_le(s, width);
1126 in_uint16_le(s, height);
1127
1128 datasize = (height * ((width + 7) / 8) + 3) & ~3;
1129 in_uint8p(s, data, datasize);
1130
1131 bitmap = ui_create_glyph(width, height, data);
1132 cache_put_font(font, character, offset, baseline, width, height, bitmap);
1133 }
1134 }
1135
1136 static void
process_compressed_8x8_brush_data(uint8 * in,uint8 * out,int Bpp)1137 process_compressed_8x8_brush_data(uint8 * in, uint8 * out, int Bpp)
1138 {
1139 int x, y, pal_index, in_index, shift, do2, i;
1140 uint8 *pal;
1141
1142 in_index = 0;
1143 pal = in + 16;
1144 /* read it bottom up */
1145 for (y = 7; y >= 0; y--)
1146 {
1147 /* 2 bytes per row */
1148 x = 0;
1149 for (do2 = 0; do2 < 2; do2++)
1150 {
1151 /* 4 pixels per byte */
1152 shift = 6;
1153 while (shift >= 0)
1154 {
1155 pal_index = (in[in_index] >> shift) & 3;
1156 /* size of palette entries depends on Bpp */
1157 for (i = 0; i < Bpp; i++)
1158 {
1159 out[(y * 8 + x) * Bpp + i] = pal[pal_index * Bpp + i];
1160 }
1161 x++;
1162 shift -= 2;
1163 }
1164 in_index++;
1165 }
1166 }
1167 }
1168
1169 /* Process a brush cache order */
1170 static void
process_brushcache(STREAM s,uint16 flags)1171 process_brushcache(STREAM s, uint16 flags)
1172 {
1173 UNUSED(flags);
1174 BRUSHDATA brush_data;
1175 uint8 cache_idx, colour_code, width, height, size, type;
1176 uint8 *comp_brush;
1177 int index;
1178 int Bpp;
1179
1180 in_uint8(s, cache_idx);
1181 in_uint8(s, colour_code);
1182 in_uint8(s, width);
1183 in_uint8(s, height);
1184 in_uint8(s, type); /* type, 0x8x = cached */
1185 in_uint8(s, size);
1186
1187 logger(Graphics, Debug, "process_brushcache(), idx=%d, wd=%d, ht=%d, type=0x%x sz=%d",
1188 cache_idx, width, height, type, size);
1189
1190 if ((width == 8) && (height == 8))
1191 {
1192 if (colour_code == 1)
1193 {
1194 brush_data.colour_code = 1;
1195 brush_data.data_size = 8;
1196 brush_data.data = xmalloc(8);
1197 if (size == 8)
1198 {
1199 /* read it bottom up */
1200 for (index = 7; index >= 0; index--)
1201 {
1202 in_uint8(s, brush_data.data[index]);
1203 }
1204 }
1205 else
1206 {
1207 logger(Graphics, Warning,
1208 "process_brushcache(), incompatible brush, colour_code %d size %d",
1209 colour_code, size);
1210 }
1211 cache_put_brush_data(1, cache_idx, &brush_data);
1212 }
1213 else if ((colour_code >= 3) && (colour_code <= 6))
1214 {
1215 Bpp = colour_code - 2;
1216 brush_data.colour_code = colour_code;
1217 brush_data.data_size = 8 * 8 * Bpp;
1218 brush_data.data = xmalloc(8 * 8 * Bpp);
1219 if (size == 16 + 4 * Bpp)
1220 {
1221 in_uint8p(s, comp_brush, 16 + 4 * Bpp);
1222 process_compressed_8x8_brush_data(comp_brush, brush_data.data, Bpp);
1223 }
1224 else
1225 {
1226 in_uint8a(s, brush_data.data, 8 * 8 * Bpp);
1227 }
1228 cache_put_brush_data(colour_code, cache_idx, &brush_data);
1229 }
1230 else
1231 {
1232 logger(Graphics, Warning,
1233 "process_brushcache(), incompatible brush, colour_code %d size %d",
1234 colour_code, size);
1235 }
1236 }
1237 else
1238 {
1239 logger(Graphics, Warning,
1240 "process_brushcache(), incompatible brush, width height %d %d", width,
1241 height);
1242 }
1243 }
1244
1245 /* Process a secondary order */
1246 static void
process_secondary_order(STREAM s)1247 process_secondary_order(STREAM s)
1248 {
1249 /* The length isn't calculated correctly by the server.
1250 * For very compact orders the length becomes negative
1251 * so a signed integer must be used. */
1252 sint16 length;
1253 uint16 flags;
1254 uint8 type;
1255 size_t next_order;
1256 struct stream packet = *s;
1257
1258 in_uint16_le(s, length);
1259 in_uint16_le(s, flags); /* used by bmpcache2 */
1260 in_uint8(s, type);
1261
1262 length += 13; /* MS-RDPEGDI is ridiculous and says that you need to add 13 to this
1263 field to get the total packet length. "For historical reasons". */
1264 length -= 6; /* Subtract six bytes of headers and you'll get the size of the remaining
1265 order data. */
1266
1267 if (!s_check_rem(s, length))
1268 {
1269 rdp_protocol_error("next order pointer would overrun stream", &packet);
1270 }
1271
1272 next_order = s_tell(s) + length;
1273
1274 switch (type)
1275 {
1276 case RDP_ORDER_RAW_BMPCACHE:
1277 process_raw_bmpcache(s);
1278 break;
1279
1280 case RDP_ORDER_COLCACHE:
1281 process_colcache(s);
1282 break;
1283
1284 case RDP_ORDER_BMPCACHE:
1285 process_bmpcache(s);
1286 break;
1287
1288 case RDP_ORDER_FONTCACHE:
1289 process_fontcache(s);
1290 break;
1291
1292 case RDP_ORDER_RAW_BMPCACHE2:
1293 process_bmpcache2(s, flags, False); /* uncompressed */
1294 break;
1295
1296 case RDP_ORDER_BMPCACHE2:
1297 process_bmpcache2(s, flags, True); /* compressed */
1298 break;
1299
1300 case RDP_ORDER_BRUSHCACHE:
1301 process_brushcache(s, flags);
1302 break;
1303
1304 default:
1305 logger(Graphics, Warning,
1306 "process_secondary_order(), unhandled secondary order %d", type);
1307 }
1308
1309 s_seek(s, next_order);
1310 }
1311
1312 /* Process an order PDU */
1313 void
process_orders(STREAM s,uint16 num_orders)1314 process_orders(STREAM s, uint16 num_orders)
1315 {
1316 RDP_ORDER_STATE *os = &g_order_state;
1317 uint32 present;
1318 uint8 order_flags;
1319 int size, processed = 0;
1320 RD_BOOL delta;
1321
1322 while (processed < num_orders)
1323 {
1324 in_uint8(s, order_flags);
1325
1326 if (!(order_flags & RDP_ORDER_STANDARD))
1327 {
1328 logger(Graphics, Error, "process_orders(), order parsing failed");
1329 break;
1330 }
1331
1332 if (order_flags & RDP_ORDER_SECONDARY)
1333 {
1334 process_secondary_order(s);
1335 }
1336 else
1337 {
1338 if (order_flags & RDP_ORDER_CHANGE)
1339 {
1340 in_uint8(s, os->order_type);
1341 }
1342
1343 switch (os->order_type)
1344 {
1345 case RDP_ORDER_TRIBLT:
1346 case RDP_ORDER_TEXT2:
1347 size = 3;
1348 break;
1349
1350 case RDP_ORDER_PATBLT:
1351 case RDP_ORDER_MEMBLT:
1352 case RDP_ORDER_LINE:
1353 case RDP_ORDER_POLYGON2:
1354 case RDP_ORDER_ELLIPSE2:
1355 size = 2;
1356 break;
1357
1358 default:
1359 size = 1;
1360 }
1361
1362 rdp_in_present(s, &present, order_flags, size);
1363
1364 if (order_flags & RDP_ORDER_BOUNDS)
1365 {
1366 if (!(order_flags & RDP_ORDER_LASTBOUNDS))
1367 rdp_parse_bounds(s, &os->bounds);
1368
1369 ui_set_clip(os->bounds.left,
1370 os->bounds.top,
1371 os->bounds.right -
1372 os->bounds.left + 1,
1373 os->bounds.bottom - os->bounds.top + 1);
1374 }
1375
1376 delta = order_flags & RDP_ORDER_DELTA;
1377
1378 switch (os->order_type)
1379 {
1380 case RDP_ORDER_DESTBLT:
1381 process_destblt(s, &os->destblt, present, delta);
1382 break;
1383
1384 case RDP_ORDER_PATBLT:
1385 process_patblt(s, &os->patblt, present, delta);
1386 break;
1387
1388 case RDP_ORDER_SCREENBLT:
1389 process_screenblt(s, &os->screenblt, present, delta);
1390 break;
1391
1392 case RDP_ORDER_LINE:
1393 process_line(s, &os->line, present, delta);
1394 break;
1395
1396 case RDP_ORDER_RECT:
1397 process_rect(s, &os->rect, present, delta);
1398 break;
1399
1400 case RDP_ORDER_DESKSAVE:
1401 process_desksave(s, &os->desksave, present, delta);
1402 break;
1403
1404 case RDP_ORDER_MEMBLT:
1405 process_memblt(s, &os->memblt, present, delta);
1406 break;
1407
1408 case RDP_ORDER_TRIBLT:
1409 process_triblt(s, &os->triblt, present, delta);
1410 break;
1411
1412 case RDP_ORDER_POLYGON:
1413 process_polygon(s, &os->polygon, present, delta);
1414 break;
1415
1416 case RDP_ORDER_POLYGON2:
1417 process_polygon2(s, &os->polygon2, present, delta);
1418 break;
1419
1420 case RDP_ORDER_POLYLINE:
1421 process_polyline(s, &os->polyline, present, delta);
1422 break;
1423
1424 case RDP_ORDER_ELLIPSE:
1425 process_ellipse(s, &os->ellipse, present, delta);
1426 break;
1427
1428 case RDP_ORDER_ELLIPSE2:
1429 process_ellipse2(s, &os->ellipse2, present, delta);
1430 break;
1431
1432 case RDP_ORDER_TEXT2:
1433 process_text2(s, &os->text2, present, delta);
1434 break;
1435
1436 default:
1437 logger(Graphics, Warning,
1438 "process_orders(), unhandled order type %d",
1439 os->order_type);
1440 return;
1441 }
1442
1443 if (order_flags & RDP_ORDER_BOUNDS)
1444 ui_reset_clip();
1445 }
1446
1447 processed++;
1448 }
1449 #if 0
1450 /* not true when RDP_COMPRESSION is set */
1451 if (s_tell(s) != g_next_packet)
1452 logger(Graphics, Error, "process_orders(), %d bytes remaining",
1453 (int) (g_next_packet - s_tell(s)));
1454 #endif
1455
1456 }
1457
1458 /* Reset order state */
1459 void
reset_order_state(void)1460 reset_order_state(void)
1461 {
1462 memset(&g_order_state, 0, sizeof(g_order_state));
1463 g_order_state.order_type = RDP_ORDER_PATBLT;
1464 }
1465