/[rdesktop]/sourceforge.net/rdesktop/trunk/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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 12 by matty, Tue Aug 15 12:01:01 2000 UTC revision 1485 by astrand, Tue Nov 25 08:05:25 2008 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     RDP order processing     RDP order processing
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2008
5    
6     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 21  Line 21 
21  #include "rdesktop.h"  #include "rdesktop.h"
22  #include "orders.h"  #include "orders.h"
23    
24  extern unsigned char *next_packet;  extern uint8 *g_next_packet;
25  static RDP_ORDER_STATE order_state;  static RDP_ORDER_STATE g_order_state;
26    extern RD_BOOL g_use_rdp5;
27    
28  /* Read field indicating which parameters are present */  /* Read field indicating which parameters are present */
29  static void rdp_in_present(STREAM s, uint32 *present, uint8 flags, int size)  static void
30    rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
31  {  {
32          uint8 bits;          uint8 bits;
33          int i;          int i;
# Line 52  static void rdp_in_present(STREAM s, uin Line 54  static void rdp_in_present(STREAM s, uin
54  }  }
55    
56  /* Read a co-ordinate (16-bit, or 8-bit delta) */  /* Read a co-ordinate (16-bit, or 8-bit delta) */
57  static void rdp_in_coord(STREAM s, uint16 *coord, BOOL delta)  static void
58    rdp_in_coord(STREAM s, sint16 * coord, RD_BOOL delta)
59  {  {
60          uint8 change;          sint8 change;
61    
62          if (delta)          if (delta)
63          {          {
64                  in_uint8(s, change);                  in_uint8(s, change);
65                  *coord += (char)change;                  *coord += change;
66          }          }
67          else          else
68          {          {
# Line 67  static void rdp_in_coord(STREAM s, uint1 Line 70  static void rdp_in_coord(STREAM s, uint1
70          }          }
71  }  }
72    
73    /* Parse a delta co-ordinate in polyline/polygon order form */
74    static int
75    parse_delta(uint8 * buffer, int *offset)
76    {
77            int value = buffer[(*offset)++];
78            int two_byte = value & 0x80;
79    
80            if (value & 0x40)       /* sign bit */
81                    value |= ~0x3f;
82            else
83                    value &= 0x3f;
84    
85            if (two_byte)
86                    value = (value << 8) | buffer[(*offset)++];
87    
88            return value;
89    }
90    
91  /* Read a colour entry */  /* Read a colour entry */
92  static void rdp_in_colour(STREAM s, uint8 *colour)  static void
93    rdp_in_colour(STREAM s, uint32 * colour)
94  {  {
95          in_uint8(s, *colour);          uint32 i;
96          s->p += 2;          in_uint8(s, i);
97            *colour = i;
98            in_uint8(s, i);
99            *colour |= i << 8;
100            in_uint8(s, i);
101            *colour |= i << 16;
102  }  }
103    
104  /* Parse bounds information */  /* Parse bounds information */
105  static BOOL rdp_parse_bounds(STREAM s, BOUNDS *bounds)  static RD_BOOL
106    rdp_parse_bounds(STREAM s, BOUNDS * bounds)
107  {  {
108          uint8 present;          uint8 present;
109    
# Line 105  static BOOL rdp_parse_bounds(STREAM s, B Line 133  static BOOL rdp_parse_bounds(STREAM s, B
133  }  }
134    
135  /* Parse a pen */  /* Parse a pen */
136  static BOOL rdp_parse_pen(STREAM s, PEN *pen, uint32 present)  static RD_BOOL
137    rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
138  {  {
139          if (present & 1)          if (present & 1)
140                  in_uint8(s, pen->style);                  in_uint8(s, pen->style);
# Line 119  static BOOL rdp_parse_pen(STREAM s, PEN Line 148  static BOOL rdp_parse_pen(STREAM s, PEN
148          return s_check(s);          return s_check(s);
149  }  }
150    
151    static void
152    setup_brush(BRUSH * out_brush, BRUSH * in_brush)
153    {
154            BRUSHDATA *brush_data;
155            uint8 cache_idx;
156            uint8 colour_code;
157    
158            memcpy(out_brush, in_brush, sizeof(BRUSH));
159            if (out_brush->style & 0x80)
160            {
161                    colour_code = out_brush->style & 0x0f;
162                    cache_idx = out_brush->pattern[0];
163                    brush_data = cache_get_brush_data(colour_code, cache_idx);
164                    if ((brush_data == NULL) || (brush_data->data == NULL))
165                    {
166                            error("error getting brush data, style %x\n", out_brush->style);
167                            out_brush->bd = NULL;
168                            memset(out_brush->pattern, 0, 8);
169                    }
170                    else
171                    {
172                            out_brush->bd = brush_data;
173                    }
174                    out_brush->style = 3;
175            }
176    }
177    
178  /* Parse a brush */  /* Parse a brush */
179  static BOOL rdp_parse_brush(STREAM s, BRUSH *brush, uint32 present)  static RD_BOOL
180    rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
181  {  {
182          if (present & 1)          if (present & 1)
183                  in_uint8(s, brush->xorigin);                  in_uint8(s, brush->xorigin);
# Line 141  static BOOL rdp_parse_brush(STREAM s, BR Line 198  static BOOL rdp_parse_brush(STREAM s, BR
198  }  }
199    
200  /* Process a destination blt order */  /* Process a destination blt order */
201  static void process_destblt(STREAM s, DESTBLT_ORDER *os,  static void
202                                  uint32 present, BOOL delta)  process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, RD_BOOL delta)
203  {  {
204          if (present & 0x01)          if (present & 0x01)
205                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 159  static void process_destblt(STREAM s, DE Line 216  static void process_destblt(STREAM s, DE
216          if (present & 0x10)          if (present & 0x10)
217                  in_uint8(s, os->opcode);                  in_uint8(s, os->opcode);
218    
219          DEBUG("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n",          DEBUG(("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n",
220                os->opcode, os->x, os->y, os->cx, os->cy);                 os->opcode, os->x, os->y, os->cx, os->cy));
221    
222          ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);          ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
223  }  }
224    
225  /* Process a pattern blt order */  /* Process a pattern blt order */
226  static void process_patblt(STREAM s, PATBLT_ORDER *os,  static void
227                                  uint32 present, BOOL delta)  process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, RD_BOOL delta)
228  {  {
229            BRUSH brush;
230    
231          if (present & 0x0001)          if (present & 0x0001)
232                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
233    
# Line 192  static void process_patblt(STREAM s, PAT Line 251  static void process_patblt(STREAM s, PAT
251    
252          rdp_parse_brush(s, &os->brush, present >> 7);          rdp_parse_brush(s, &os->brush, present >> 7);
253    
254          DEBUG("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n",          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,
255                os->opcode, os->x, os->y, os->cx, os->cy,                 os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
256                os->brush.style, os->bgcolour, os->fgcolour);  
257            setup_brush(&brush, &os->brush);
258    
259          ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,          ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
260                                  &os->brush, os->bgcolour, os->fgcolour);                    &brush, os->bgcolour, os->fgcolour);
261  }  }
262    
263  /* Process a screen blt order */  /* Process a screen blt order */
264  static void process_screenblt(STREAM s, SCREENBLT_ORDER *os,  static void
265                                          uint32 present, BOOL delta)  process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, RD_BOOL delta)
266  {  {
267          if (present & 0x0001)          if (present & 0x0001)
268                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 225  static void process_screenblt(STREAM s, Line 285  static void process_screenblt(STREAM s,
285          if (present & 0x0040)          if (present & 0x0040)
286                  rdp_in_coord(s, &os->srcy, delta);                  rdp_in_coord(s, &os->srcy, delta);
287    
288          DEBUG("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",          DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",
289                os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);                 os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy));
290    
291          ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy,          ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
                                 os->srcx, os->srcy);  
292  }  }
293    
294  /* Process a line order */  /* Process a line order */
295  static void process_line(STREAM s, LINE_ORDER *os, uint32 present, BOOL delta)  static void
296    process_line(STREAM s, LINE_ORDER * os, uint32 present, RD_BOOL delta)
297  {  {
298          if (present & 0x0001)          if (present & 0x0001)
299                  in_uint16_le(s, os->mixmode);                  in_uint16_le(s, os->mixmode);
# Line 258  static void process_line(STREAM s, LINE_ Line 318  static void process_line(STREAM s, LINE_
318    
319          rdp_parse_pen(s, &os->pen, present >> 7);          rdp_parse_pen(s, &os->pen, present >> 7);
320    
321          DEBUG("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dx=%d,fg=0x%x)\n",          DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dy=%d,fg=0x%x)\n",
322                os->opcode, os->startx, os->starty, os->endx, os->endy,                 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));
               os->pen.colour);  
323    
324          if (os->opcode < 0x01 || os->opcode > 0x10)          if (os->opcode < 0x01 || os->opcode > 0x10)
325          {          {
326                  ERROR("bad ROP2 0x%x\n", os->opcode);                  error("bad ROP2 0x%x\n", os->opcode);
327                  return;                  return;
328          }          }
329    
330          ui_line(os->opcode-1, os->startx, os->starty,          ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
                         os->endx, os->endy, &os->pen);  
331  }  }
332    
333  /* Process an opaque rectangle order */  /* Process an opaque rectangle order */
334  static void process_rect(STREAM s, RECT_ORDER *os, uint32 present, BOOL delta)  static void
335    process_rect(STREAM s, RECT_ORDER * os, uint32 present, RD_BOOL delta)
336  {  {
337            uint32 i;
338          if (present & 0x01)          if (present & 0x01)
339                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
340    
# Line 288  static void process_rect(STREAM s, RECT_ Line 348  static void process_rect(STREAM s, RECT_
348                  rdp_in_coord(s, &os->cy, delta);                  rdp_in_coord(s, &os->cy, delta);
349    
350          if (present & 0x10)          if (present & 0x10)
351                  in_uint8(s, os->colour);          {
352                    in_uint8(s, i);
353                    os->colour = (os->colour & 0xffffff00) | i;
354            }
355    
356            if (present & 0x20)
357            {
358                    in_uint8(s, i);
359                    os->colour = (os->colour & 0xffff00ff) | (i << 8);
360            }
361    
362          DEBUG("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n",          if (present & 0x40)
363                os->x, os->y, os->cx, os->cy, os->colour);          {
364                    in_uint8(s, i);
365                    os->colour = (os->colour & 0xff00ffff) | (i << 16);
366            }
367    
368            DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));
369    
370          ui_rect(os->x, os->y, os->cx, os->cy, os->colour);          ui_rect(os->x, os->y, os->cx, os->cy, os->colour);
371  }  }
372    
373  /* Process a desktop save order */  /* Process a desktop save order */
374  static void process_desksave(STREAM s, DESKSAVE_ORDER *os,  static void
375                                  uint32 present, BOOL delta)  process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, RD_BOOL delta)
376  {  {
377          int width, height;          int width, height;
378    
# Line 320  static void process_desksave(STREAM s, D Line 394  static void process_desksave(STREAM s, D
394          if (present & 0x20)          if (present & 0x20)
395                  in_uint8(s, os->action);                  in_uint8(s, os->action);
396    
397          DEBUG("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",          DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",
398                os->left, os->top, os->right, os->bottom, os->offset,                 os->left, os->top, os->right, os->bottom, os->offset, os->action));
               os->action);  
399    
400          width = os->right - os->left + 1;          width = os->right - os->left + 1;
401          height = os->bottom - os->top + 1;          height = os->bottom - os->top + 1;
# Line 334  static void process_desksave(STREAM s, D Line 407  static void process_desksave(STREAM s, D
407  }  }
408    
409  /* Process a memory blt order */  /* Process a memory blt order */
410  static void process_memblt(STREAM s, MEMBLT_ORDER *os,  static void
411                                  uint32 present, BOOL delta)  process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, RD_BOOL delta)
412  {  {
413          HBITMAP bitmap;          RD_HBITMAP bitmap;
414    
415          if (present & 0x0001)          if (present & 0x0001)
416          {          {
# Line 369  static void process_memblt(STREAM s, MEM Line 442  static void process_memblt(STREAM s, MEM
442          if (present & 0x0100)          if (present & 0x0100)
443                  in_uint16_le(s, os->cache_idx);                  in_uint16_le(s, os->cache_idx);
444    
445          DEBUG("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",          DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",
446                os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id,                 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx));
               os->cache_idx);  
447    
448          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
449          if (bitmap == NULL)          if (bitmap == NULL)
450                  return;                  return;
451    
452          ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy,          ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy);
                         bitmap, os->srcx, os->srcy);  
453  }  }
454    
455  /* Process a 3-way blt order */  /* Process a 3-way blt order */
456  static void process_triblt(STREAM s, TRIBLT_ORDER *os,  static void
457                                  uint32 present, BOOL delta)  process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, RD_BOOL delta)
458  {  {
459          HBITMAP bitmap;          RD_HBITMAP bitmap;
460            BRUSH brush;
461    
462          if (present & 0x000001)          if (present & 0x000001)
463          {          {
# Line 428  static void process_triblt(STREAM s, TRI Line 500  static void process_triblt(STREAM s, TRI
500          if (present & 0x010000)          if (present & 0x010000)
501                  in_uint16_le(s, os->unknown);                  in_uint16_le(s, os->unknown);
502    
503          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",          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",
504                os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id,                 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx,
505                os->cache_idx, os->brush.style, os->bgcolour, os->fgcolour);                 os->brush.style, os->bgcolour, os->fgcolour));
506    
507          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
508          if (bitmap == NULL)          if (bitmap == NULL)
509                  return;                  return;
510    
511            setup_brush(&brush, &os->brush);
512    
513          ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,          ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
514                          bitmap, os->srcx, os->srcy,                    bitmap, os->srcx, os->srcy, &brush, os->bgcolour, os->fgcolour);
515                          &os->brush, os->bgcolour, os->fgcolour);  }
516    
517    /* Process a polygon order */
518    static void
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            DEBUG(("POLYGON(x=%d,y=%d,op=0x%x,fm=%d,fg=0x%x,n=%d,sz=%d)\n",
550                   os->x, os->y, os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize));
551    
552            DEBUG(("Data: "));
553    
554            for (index = 0; index < os->datasize; index++)
555                    DEBUG(("%02x ", os->data[index]));
556    
557            DEBUG(("\n"));
558    
559            if (os->opcode < 0x01 || os->opcode > 0x10)
560            {
561                    error("bad ROP2 0x%x\n", os->opcode);
562                    return;
563            }
564    
565            points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
566            memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
567    
568            points[0].x = os->x;
569            points[0].y = os->y;
570    
571            index = 0;
572            data = ((os->npoints - 1) / 4) + 1;
573            for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
574            {
575                    if ((next - 1) % 4 == 0)
576                            flags = os->data[index++];
577    
578                    if (~flags & 0x80)
579                            points[next].x = parse_delta(os->data, &data);
580    
581                    if (~flags & 0x40)
582                            points[next].y = parse_delta(os->data, &data);
583    
584                    flags <<= 2;
585            }
586    
587            if (next - 1 == os->npoints)
588                    ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,
589                               os->fgcolour);
590            else
591                    error("polygon parse error\n");
592    
593            xfree(points);
594    }
595    
596    /* Process a polygon2 order */
597    static void
598    process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, RD_BOOL delta)
599    {
600            int index, data, next;
601            uint8 flags = 0;
602            RD_POINT *points;
603            BRUSH brush;
604    
605            if (present & 0x0001)
606                    rdp_in_coord(s, &os->x, delta);
607    
608            if (present & 0x0002)
609                    rdp_in_coord(s, &os->y, delta);
610    
611            if (present & 0x0004)
612                    in_uint8(s, os->opcode);
613    
614            if (present & 0x0008)
615                    in_uint8(s, os->fillmode);
616    
617            if (present & 0x0010)
618                    rdp_in_colour(s, &os->bgcolour);
619    
620            if (present & 0x0020)
621                    rdp_in_colour(s, &os->fgcolour);
622    
623            rdp_parse_brush(s, &os->brush, present >> 6);
624    
625            if (present & 0x0800)
626                    in_uint8(s, os->npoints);
627    
628            if (present & 0x1000)
629            {
630                    in_uint8(s, os->datasize);
631                    in_uint8a(s, os->data, os->datasize);
632            }
633    
634            DEBUG(("POLYGON2(x=%d,y=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x,n=%d,sz=%d)\n",
635                   os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour,
636                   os->npoints, os->datasize));
637    
638            DEBUG(("Data: "));
639    
640            for (index = 0; index < os->datasize; index++)
641                    DEBUG(("%02x ", os->data[index]));
642    
643            DEBUG(("\n"));
644    
645            if (os->opcode < 0x01 || os->opcode > 0x10)
646            {
647                    error("bad ROP2 0x%x\n", os->opcode);
648                    return;
649            }
650    
651            setup_brush(&brush, &os->brush);
652    
653            points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
654            memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
655    
656            points[0].x = os->x;
657            points[0].y = os->y;
658    
659            index = 0;
660            data = ((os->npoints - 1) / 4) + 1;
661            for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
662            {
663                    if ((next - 1) % 4 == 0)
664                            flags = os->data[index++];
665    
666                    if (~flags & 0x80)
667                            points[next].x = parse_delta(os->data, &data);
668    
669                    if (~flags & 0x40)
670                            points[next].y = parse_delta(os->data, &data);
671    
672                    flags <<= 2;
673            }
674    
675            if (next - 1 == os->npoints)
676                    ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
677                               &brush, os->bgcolour, os->fgcolour);
678            else
679                    error("polygon2 parse error\n");
680    
681            xfree(points);
682    }
683    
684    /* Process a polyline order */
685    static void
686    process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, RD_BOOL delta)
687    {
688            int index, next, data;
689            uint8 flags = 0;
690            PEN pen;
691            RD_POINT *points;
692    
693            if (present & 0x01)
694                    rdp_in_coord(s, &os->x, delta);
695    
696            if (present & 0x02)
697                    rdp_in_coord(s, &os->y, delta);
698    
699            if (present & 0x04)
700                    in_uint8(s, os->opcode);
701    
702            if (present & 0x10)
703                    rdp_in_colour(s, &os->fgcolour);
704    
705            if (present & 0x20)
706                    in_uint8(s, os->lines);
707    
708            if (present & 0x40)
709            {
710                    in_uint8(s, os->datasize);
711                    in_uint8a(s, os->data, os->datasize);
712            }
713    
714            DEBUG(("POLYLINE(x=%d,y=%d,op=0x%x,fg=0x%x,n=%d,sz=%d)\n",
715                   os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize));
716    
717            DEBUG(("Data: "));
718    
719            for (index = 0; index < os->datasize; index++)
720                    DEBUG(("%02x ", os->data[index]));
721    
722            DEBUG(("\n"));
723    
724            if (os->opcode < 0x01 || os->opcode > 0x10)
725            {
726                    error("bad ROP2 0x%x\n", os->opcode);
727                    return;
728            }
729    
730            points = (RD_POINT *) xmalloc((os->lines + 1) * sizeof(RD_POINT));
731            memset(points, 0, (os->lines + 1) * sizeof(RD_POINT));
732    
733            points[0].x = os->x;
734            points[0].y = os->y;
735            pen.style = pen.width = 0;
736            pen.colour = os->fgcolour;
737    
738            index = 0;
739            data = ((os->lines - 1) / 4) + 1;
740            for (next = 1; (next <= os->lines) && (data < os->datasize); next++)
741            {
742                    if ((next - 1) % 4 == 0)
743                            flags = os->data[index++];
744    
745                    if (~flags & 0x80)
746                            points[next].x = parse_delta(os->data, &data);
747    
748                    if (~flags & 0x40)
749                            points[next].y = parse_delta(os->data, &data);
750    
751                    flags <<= 2;
752            }
753    
754            if (next - 1 == os->lines)
755                    ui_polyline(os->opcode - 1, points, os->lines + 1, &pen);
756            else
757                    error("polyline parse error\n");
758    
759            xfree(points);
760    }
761    
762    /* Process an ellipse order */
763    static void
764    process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, RD_BOOL delta)
765    {
766            if (present & 0x01)
767                    rdp_in_coord(s, &os->left, delta);
768    
769            if (present & 0x02)
770                    rdp_in_coord(s, &os->top, delta);
771    
772            if (present & 0x04)
773                    rdp_in_coord(s, &os->right, delta);
774    
775            if (present & 0x08)
776                    rdp_in_coord(s, &os->bottom, delta);
777    
778            if (present & 0x10)
779                    in_uint8(s, os->opcode);
780    
781            if (present & 0x20)
782                    in_uint8(s, os->fillmode);
783    
784            if (present & 0x40)
785                    rdp_in_colour(s, &os->fgcolour);
786    
787            DEBUG(("ELLIPSE(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,fg=0x%x)\n", os->left, os->top,
788                   os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour));
789    
790            ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
791                       os->bottom - os->top, NULL, 0, os->fgcolour);
792    }
793    
794    /* Process an ellipse2 order */
795    static void
796    process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, RD_BOOL delta)
797    {
798            BRUSH brush;
799    
800            if (present & 0x0001)
801                    rdp_in_coord(s, &os->left, delta);
802    
803            if (present & 0x0002)
804                    rdp_in_coord(s, &os->top, delta);
805    
806            if (present & 0x0004)
807                    rdp_in_coord(s, &os->right, delta);
808    
809            if (present & 0x0008)
810                    rdp_in_coord(s, &os->bottom, delta);
811    
812            if (present & 0x0010)
813                    in_uint8(s, os->opcode);
814    
815            if (present & 0x0020)
816                    in_uint8(s, os->fillmode);
817    
818            if (present & 0x0040)
819                    rdp_in_colour(s, &os->bgcolour);
820    
821            if (present & 0x0080)
822                    rdp_in_colour(s, &os->fgcolour);
823    
824            rdp_parse_brush(s, &os->brush, present >> 8);
825    
826            DEBUG(("ELLIPSE2(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
827                   os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style,
828                   os->bgcolour, os->fgcolour));
829    
830            setup_brush(&brush, &os->brush);
831    
832            ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
833                       os->bottom - os->top, &brush, os->bgcolour, os->fgcolour);
834  }  }
835    
836  /* Process a text order */  /* Process a text order */
837  static void process_text2(STREAM s, TEXT2_ORDER *os, uint32 present, BOOL delta)  static void
838    process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, RD_BOOL delta)
839  {  {
         DATABLOB *entry;  
840          int i;          int i;
841            BRUSH brush;
842    
843          if (present & 0x000001)          if (present & 0x000001)
844                  in_uint8(s, os->font);                  in_uint8(s, os->font);
# Line 454  static void process_text2(STREAM s, TEXT Line 847  static void process_text2(STREAM s, TEXT
847                  in_uint8(s, os->flags);                  in_uint8(s, os->flags);
848    
849          if (present & 0x000004)          if (present & 0x000004)
850                  in_uint8(s, os->unknown);                  in_uint8(s, os->opcode);
851    
852          if (present & 0x000008)          if (present & 0x000008)
853                  in_uint8(s, os->mixmode);                  in_uint8(s, os->mixmode);
# Line 489  static void process_text2(STREAM s, TEXT Line 882  static void process_text2(STREAM s, TEXT
882          if (present & 0x002000)          if (present & 0x002000)
883                  in_uint16_le(s, os->boxbottom);                  in_uint16_le(s, os->boxbottom);
884    
885            rdp_parse_brush(s, &os->brush, present >> 14);
886    
887          if (present & 0x080000)          if (present & 0x080000)
888                  in_uint16_le(s, os->x);                  in_uint16_le(s, os->x);
889    
# Line 501  static void process_text2(STREAM s, TEXT Line 896  static void process_text2(STREAM s, TEXT
896                  in_uint8a(s, os->text, os->length);                  in_uint8a(s, os->text, os->length);
897          }          }
898    
899          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",          DEBUG(("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)\n", os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft, os->boxtop, os->boxright, os->boxbottom, os->brush.style, os->bgcolour, os->fgcolour, os->font, os->flags, os->opcode, os->mixmode, os->length));
                 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);  
900    
901          DEBUG("Text: ");          DEBUG(("Text: "));
902    
903          for (i = 0; i < os->length; i++)          for (i = 0; i < os->length; i++)
904                  DEBUG("%02x ", os->text[i]);                  DEBUG(("%02x ", os->text[i]));
905    
906          DEBUG("\n");          DEBUG(("\n"));
   
         /* Process special cache strings */  
         if ((os->length == 2) && (os->text[0] == 0xfe))  
         {  
                 entry = cache_get_text(os->text[1]);  
907    
908                  if (entry == NULL)          setup_brush(&brush, &os->brush);
                         return;  
                   
                 memcpy(os->text, entry->data, entry->size);  
                 os->length = entry->size;  
         }  
         else if ((os->length >= 3) && (os->text[os->length-3] == 0xff))  
         {  
                 os->length -= 3;  
                 cache_put_text(os->text[os->length+1], os->text, os->length);  
         }  
909    
910          ui_draw_text(os->font, os->flags, os->mixmode,          ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
911                          os->x, os->y, os->boxleft, os->boxtop,                       os->clipleft, os->cliptop, os->clipright - os->clipleft,
912                          os->boxright - os->boxleft,                       os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
913                          os->boxbottom - os->boxtop,                       os->boxright - os->boxleft, os->boxbottom - os->boxtop,
914                          os->bgcolour, os->fgcolour, os->text, os->length);                       &brush, os->bgcolour, os->fgcolour, os->text, os->length);
915  }  }
916    
917  /* Process a raw bitmap cache order */  /* Process a raw bitmap cache order */
918  static void process_raw_bmpcache(STREAM s)  static void
919    process_raw_bmpcache(STREAM s)
920  {  {
921          HBITMAP bitmap;          RD_HBITMAP bitmap;
922          uint16 cache_idx, bufsize;          uint16 cache_idx, bufsize;
923          uint8 cache_id, width, height, bpp;          uint8 cache_id, width, height, bpp, Bpp;
924          uint8 *data;          uint8 *data, *inverted;
925            int y;
926    
927          in_uint8(s, cache_id);          in_uint8(s, cache_id);
928          in_uint8s(s, 1); /* pad */          in_uint8s(s, 1);        /* pad */
929          in_uint8(s, width);          in_uint8(s, width);
930          in_uint8(s, height);          in_uint8(s, height);
931          in_uint8(s, bpp);          in_uint8(s, bpp);
932            Bpp = (bpp + 7) / 8;
933          in_uint16_le(s, bufsize);          in_uint16_le(s, bufsize);
934          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
935          in_uint8p(s, data, bufsize);          in_uint8p(s, data, bufsize);
936    
937          DEBUG("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n",          DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
938                width, height, cache_id, cache_idx);          inverted = (uint8 *) xmalloc(width * height * Bpp);
939            for (y = 0; y < height; y++)
940            {
941                    memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
942                           width * Bpp);
943            }
944    
945          bitmap = ui_create_bitmap(width, height, data);          bitmap = ui_create_bitmap(width, height, inverted);
946            xfree(inverted);
947          cache_put_bitmap(cache_id, cache_idx, bitmap);          cache_put_bitmap(cache_id, cache_idx, bitmap);
948  }  }
949    
950  /* Process a bitmap cache order */  /* Process a bitmap cache order */
951  static void process_bmpcache(STREAM s)  static void
952    process_bmpcache(STREAM s)
953  {  {
954          HBITMAP bitmap;          RD_HBITMAP bitmap;
955          uint16 cache_idx, size;          uint16 cache_idx, size;
956          uint8 cache_id, width, height, bpp;          uint8 cache_id, width, height, bpp, Bpp;
957          uint8 *data, *bmpdata;          uint8 *data, *bmpdata;
958            uint16 bufsize, pad2, row_size, final_size;
959            uint8 pad1;
960    
961            pad2 = row_size = final_size = 0xffff;  /* Shut the compiler up */
962    
963          in_uint8(s, cache_id);          in_uint8(s, cache_id);
964          in_uint8s(s, 1); /* pad */          in_uint8(s, pad1);      /* pad */
965          in_uint8(s, width);          in_uint8(s, width);
966          in_uint8(s, height);          in_uint8(s, height);
967          in_uint8(s, bpp);          in_uint8(s, bpp);
968          in_uint8s(s, 2); /* bufsize */          Bpp = (bpp + 7) / 8;
969            in_uint16_le(s, bufsize);       /* bufsize */
970          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
971          in_uint8s(s, 2); /* pad */  
972          in_uint16_le(s, size);          if (g_use_rdp5)
973          in_uint8s(s, 4); /* row_size, final_size */          {
974                    size = bufsize;
975            }
976            else
977            {
978    
979                    /* Begin compressedBitmapData */
980                    in_uint16_le(s, pad2);  /* pad */
981                    in_uint16_le(s, size);
982                    /*      in_uint8s(s, 4);  *//* row_size, final_size */
983                    in_uint16_le(s, row_size);
984                    in_uint16_le(s, final_size);
985    
986            }
987          in_uint8p(s, data, size);          in_uint8p(s, data, size);
988    
989          DEBUG("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n",          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));
               width, height, cache_id, cache_idx);  
990    
991          bmpdata = xmalloc(width * height);          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
992    
993          if (bitmap_decompress(bmpdata, width, height, data, size))          if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
994          {          {
995                  bitmap = ui_create_bitmap(width, height, bmpdata);                  bitmap = ui_create_bitmap(width, height, bmpdata);
996                  cache_put_bitmap(cache_id, cache_idx, bitmap);                  cache_put_bitmap(cache_id, cache_idx, bitmap);
997          }          }
998            else
999            {
1000                    DEBUG(("Failed to decompress bitmap data\n"));
1001            }
1002    
1003            xfree(bmpdata);
1004    }
1005    
1006    /* Process a bitmap cache v2 order */
1007    static void
1008    process_bmpcache2(STREAM s, uint16 flags, RD_BOOL compressed)
1009    {
1010            RD_HBITMAP bitmap;
1011            int y;
1012            uint8 cache_id, cache_idx_low, width, height, Bpp;
1013            uint16 cache_idx, bufsize;
1014            uint8 *data, *bmpdata, *bitmap_id;
1015    
1016            bitmap_id = NULL;       /* prevent compiler warning */
1017            cache_id = flags & ID_MASK;
1018            Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
1019    
1020            if (flags & PERSIST)
1021            {
1022                    in_uint8p(s, bitmap_id, 8);
1023            }
1024    
1025            if (flags & SQUARE)
1026            {
1027                    in_uint8(s, width);
1028                    height = width;
1029            }
1030            else
1031            {
1032                    in_uint8(s, width);
1033                    in_uint8(s, height);
1034            }
1035    
1036            in_uint16_be(s, bufsize);
1037            bufsize &= BUFSIZE_MASK;
1038            in_uint8(s, cache_idx);
1039    
1040            if (cache_idx & LONG_FORMAT)
1041            {
1042                    in_uint8(s, cache_idx_low);
1043                    cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
1044            }
1045    
1046            in_uint8p(s, data, bufsize);
1047    
1048            DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
1049                   compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
1050    
1051            bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1052    
1053            if (compressed)
1054            {
1055                    if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
1056                    {
1057                            DEBUG(("Failed to decompress bitmap data\n"));
1058                            xfree(bmpdata);
1059                            return;
1060                    }
1061            }
1062            else
1063            {
1064                    for (y = 0; y < height; y++)
1065                            memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
1066                                   &data[y * (width * Bpp)], width * Bpp);
1067            }
1068    
1069            bitmap = ui_create_bitmap(width, height, bmpdata);
1070    
1071            if (bitmap)
1072            {
1073                    cache_put_bitmap(cache_id, cache_idx, bitmap);
1074                    if (flags & PERSIST)
1075                            pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height,
1076                                                 width * height * Bpp, bmpdata);
1077            }
1078            else
1079            {
1080                    DEBUG(("process_bmpcache2: ui_create_bitmap failed\n"));
1081            }
1082    
1083          xfree(bmpdata);          xfree(bmpdata);
1084  }  }
1085    
1086  /* Process a colourmap cache order */  /* Process a colourmap cache order */
1087  static void process_colcache(STREAM s)  static void
1088    process_colcache(STREAM s)
1089  {  {
1090          COLOURENTRY *entry;          COLOURENTRY *entry;
1091          COLOURMAP map;          COLOURMAP map;
1092          HCOLOURMAP hmap;          RD_HCOLOURMAP hmap;
1093          uint8 cache_id;          uint8 cache_id;
1094          int i;          int i;
1095    
1096          in_uint8(s, cache_id);          in_uint8(s, cache_id);
1097          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1098    
1099          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1100    
1101          for (i = 0; i < map.ncolours; i++)          for (i = 0; i < map.ncolours; i++)
1102          {          {
# Line 616  static void process_colcache(STREAM s) Line 1104  static void process_colcache(STREAM s)
1104                  in_uint8(s, entry->blue);                  in_uint8(s, entry->blue);
1105                  in_uint8(s, entry->green);                  in_uint8(s, entry->green);
1106                  in_uint8(s, entry->red);                  in_uint8(s, entry->red);
1107                  in_uint8s(s, 1); /* pad */                  in_uint8s(s, 1);        /* pad */
1108          }          }
1109    
1110          DEBUG("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours);          DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
1111    
1112          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
1113          ui_set_colourmap(hmap);  
1114            if (cache_id)
1115                    ui_set_colourmap(hmap);
1116    
1117          xfree(map.colours);          xfree(map.colours);
1118  }  }
1119    
1120  /* Process a font cache order */  /* Process a font cache order */
1121  static void process_fontcache(STREAM s)  static void
1122    process_fontcache(STREAM s)
1123  {  {
1124          HGLYPH bitmap;          RD_HGLYPH bitmap;
1125          uint8 font, nglyphs;          uint8 font, nglyphs;
1126          uint16 character, baseline, width, height;          uint16 character, offset, baseline, width, height;
1127          uint8 *data, *rev_data, in, out;          int i, datasize;
1128          int i, j, datasize;          uint8 *data;
1129    
1130          in_uint8(s, font);          in_uint8(s, font);
1131          in_uint8(s, nglyphs);          in_uint8(s, nglyphs);
1132    
1133          DEBUG("FONTCACHE(font=%d,n=%d)\n", font, nglyphs);          DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
1134    
1135          for (i = 0; i < nglyphs; i++)          for (i = 0; i < nglyphs; i++)
1136          {          {
1137                  in_uint16_le(s, character);                  in_uint16_le(s, character);
1138                  in_uint8s(s, 2); /* unknown */                  in_uint16_le(s, offset);
1139                  in_uint16_le(s, baseline);                  in_uint16_le(s, baseline);
1140                  in_uint16_le(s, width);                  in_uint16_le(s, width);
1141                  in_uint16_le(s, height);                  in_uint16_le(s, height);
# Line 652  static void process_fontcache(STREAM s) Line 1143  static void process_fontcache(STREAM s)
1143                  datasize = (height * ((width + 7) / 8) + 3) & ~3;                  datasize = (height * ((width + 7) / 8) + 3) & ~3;
1144                  in_uint8p(s, data, datasize);                  in_uint8p(s, data, datasize);
1145    
1146                  /* Need to reverse bit order */                  bitmap = ui_create_glyph(width, height, data);
1147                  rev_data = xmalloc(datasize);                  cache_put_font(font, character, offset, baseline, width, height, bitmap);
1148            }
1149    }
1150    
1151                  for (j = 0; j < datasize; j++)  static void
1152    process_compressed_8x8_brush_data(uint8 * in, uint8 * out, int Bpp)
1153    {
1154            int x, y, pal_index, in_index, shift, do2, i;
1155            uint8 *pal;
1156    
1157            in_index = 0;
1158            pal = in + 16;
1159            /* read it bottom up */
1160            for (y = 7; y >= 0; y--)
1161            {
1162                    /* 2 bytes per row */
1163                    x = 0;
1164                    for (do2 = 0; do2 < 2; do2++)
1165                  {                  {
1166                          in = data[j];                          /* 4 pixels per byte */
1167                          out = 0;                          shift = 6;
1168                          if (in & 1) out |= 128;                          while (shift >= 0)
1169                          if (in & 2) out |= 64;                          {
1170                          if (in & 4) out |= 32;                                  pal_index = (in[in_index] >> shift) & 3;
1171                          if (in & 8) out |= 16;                                  /* size of palette entries depends on Bpp */
1172                          if (in & 16) out |= 8;                                  for (i = 0; i < Bpp; i++)
1173                          if (in & 32) out |= 4;                                  {
1174                          if (in & 64) out |= 2;                                          out[(y * 8 + x) * Bpp + i] = pal[pal_index * Bpp + i];
1175                          if (in & 128) out |= 1;                                  }
1176                          rev_data[j] = out;                                  x++;
1177                                    shift -= 2;
1178                            }
1179                            in_index++;
1180                  }                  }
1181            }
1182    }
1183    
1184                  bitmap = ui_create_glyph(width, height, rev_data);  /* Process a brush cache order */
1185                  xfree(rev_data);  static void
1186    process_brushcache(STREAM s, uint16 flags)
1187    {
1188            BRUSHDATA brush_data;
1189            uint8 cache_idx, colour_code, width, height, size, type;
1190            uint8 *comp_brush;
1191            int index;
1192            int Bpp;
1193    
1194                  cache_put_font(font, character, baseline, width, height, bitmap);          in_uint8(s, cache_idx);
1195            in_uint8(s, colour_code);
1196            in_uint8(s, width);
1197            in_uint8(s, height);
1198            in_uint8(s, type);      /* type, 0x8x = cached */
1199            in_uint8(s, size);
1200    
1201            DEBUG(("BRUSHCACHE(idx=%d,dp=%d,wd=%d,ht=%d,sz=%d)\n", cache_idx, depth,
1202                   width, height, size));
1203    
1204            if ((width == 8) && (height == 8))
1205            {
1206                    if (colour_code == 1)
1207                    {
1208                            brush_data.colour_code = 1;
1209                            brush_data.data_size = 8;
1210                            brush_data.data = xmalloc(8);
1211                            if (size == 8)
1212                            {
1213                                    /* read it bottom up */
1214                                    for (index = 7; index >= 0; index--)
1215                                    {
1216                                            in_uint8(s, brush_data.data[index]);
1217                                    }
1218                            }
1219                            else
1220                            {
1221                                    warning("incompatible brush, colour_code %d size %d\n", colour_code,
1222                                            size);
1223                            }
1224                            cache_put_brush_data(1, cache_idx, &brush_data);
1225                    }
1226                    else if ((colour_code >= 3) && (colour_code <= 6))
1227                    {
1228                            Bpp = colour_code - 2;
1229                            brush_data.colour_code = colour_code;
1230                            brush_data.data_size = 8 * 8 * Bpp;
1231                            brush_data.data = xmalloc(8 * 8 * Bpp);
1232                            if (size == 16 + 4 * Bpp)
1233                            {
1234                                    in_uint8p(s, comp_brush, 16 + 4 * Bpp);
1235                                    process_compressed_8x8_brush_data(comp_brush, brush_data.data, Bpp);
1236                            }
1237                            else
1238                            {
1239                                    in_uint8a(s, brush_data.data, 8 * 8 * Bpp);
1240                            }
1241                            cache_put_brush_data(colour_code, cache_idx, &brush_data);
1242                    }
1243                    else
1244                    {
1245                            warning("incompatible brush, colour_code %d size %d\n", colour_code, size);
1246                    }
1247            }
1248            else
1249            {
1250                    warning("incompatible brush, width height %d %d\n", width, height);
1251          }          }
1252  }  }
1253    
1254  /* Process a secondary order */  /* Process a secondary order */
1255  static void process_secondary_order(STREAM s)  static void
1256    process_secondary_order(STREAM s)
1257  {  {
1258            /* The length isn't calculated correctly by the server.
1259             * For very compact orders the length becomes negative
1260             * so a signed integer must be used. */
1261          uint16 length;          uint16 length;
1262            uint16 flags;
1263          uint8 type;          uint8 type;
1264          uint8 *next_order;          uint8 *next_order;
1265    
1266          in_uint16_le(s, length);          in_uint16_le(s, length);
1267          in_uint8s(s, 2); /* flags */          in_uint16_le(s, flags); /* used by bmpcache2 */
1268          in_uint8(s, type);          in_uint8(s, type);
1269    
1270          next_order = s->p + length + 7;          next_order = s->p + (sint16) length + 7;
1271    
1272          switch (type)          switch (type)
1273          {          {
# Line 708  static void process_secondary_order(STRE Line 1287  static void process_secondary_order(STRE
1287                          process_fontcache(s);                          process_fontcache(s);
1288                          break;                          break;
1289    
1290                    case RDP_ORDER_RAW_BMPCACHE2:
1291                            process_bmpcache2(s, flags, False);     /* uncompressed */
1292                            break;
1293    
1294                    case RDP_ORDER_BMPCACHE2:
1295                            process_bmpcache2(s, flags, True);      /* compressed */
1296                            break;
1297    
1298                    case RDP_ORDER_BRUSHCACHE:
1299                            process_brushcache(s, flags);
1300                            break;
1301    
1302                  default:                  default:
1303                          NOTIMP("secondary order %d\n", type);                          unimpl("secondary order %d\n", type);
1304          }          }
1305    
1306          s->p = next_order;          s->p = next_order;
1307  }  }
1308    
1309  /* Process an order PDU */  /* Process an order PDU */
1310  void process_orders(STREAM s)  void
1311    process_orders(STREAM s, uint16 num_orders)
1312  {  {
1313          RDP_ORDER_STATE *os = &order_state;          RDP_ORDER_STATE *os = &g_order_state;
1314          uint32 present;          uint32 present;
         uint16 num_orders;  
1315          uint8 order_flags;          uint8 order_flags;
1316          int size, processed = 0;          int size, processed = 0;
1317          BOOL delta;          RD_BOOL delta;
   
         in_uint8s(s, 2); /* pad */  
         in_uint16_le(s, num_orders);  
         in_uint8s(s, 2); /* pad */  
1318    
1319          while (processed < num_orders)          while (processed < num_orders)
1320          {          {
# Line 735  void process_orders(STREAM s) Line 1322  void process_orders(STREAM s)
1322    
1323                  if (!(order_flags & RDP_ORDER_STANDARD))                  if (!(order_flags & RDP_ORDER_STANDARD))
1324                  {                  {
1325                          ERROR("order parsing failed\n");                          error("order parsing failed\n");
1326                          break;                          break;
1327                  }                  }
1328    
# Line 760  void process_orders(STREAM s) Line 1347  void process_orders(STREAM s)
1347                                  case RDP_ORDER_PATBLT:                                  case RDP_ORDER_PATBLT:
1348                                  case RDP_ORDER_MEMBLT:                                  case RDP_ORDER_MEMBLT:
1349                                  case RDP_ORDER_LINE:                                  case RDP_ORDER_LINE:
1350                                    case RDP_ORDER_POLYGON2:
1351                                    case RDP_ORDER_ELLIPSE2:
1352                                          size = 2;                                          size = 2;
1353                                          break;                                          break;
1354    
# Line 775  void process_orders(STREAM s) Line 1364  void process_orders(STREAM s)
1364                                          rdp_parse_bounds(s, &os->bounds);                                          rdp_parse_bounds(s, &os->bounds);
1365    
1366                                  ui_set_clip(os->bounds.left,                                  ui_set_clip(os->bounds.left,
1367                                          os->bounds.top,                                              os->bounds.top,
1368                                          os->bounds.right - os->bounds.left + 1,                                              os->bounds.right -
1369                                          os->bounds.bottom - os->bounds.top + 1);                                              os->bounds.left + 1,
1370                                                os->bounds.bottom - os->bounds.top + 1);
1371                          }                          }
1372    
1373                          delta = order_flags & RDP_ORDER_DELTA;                          delta = order_flags & RDP_ORDER_DELTA;
# Line 785  void process_orders(STREAM s) Line 1375  void process_orders(STREAM s)
1375                          switch (os->order_type)                          switch (os->order_type)
1376                          {                          {
1377                                  case RDP_ORDER_DESTBLT:                                  case RDP_ORDER_DESTBLT:
1378                                          process_destblt(s, &os->destblt,                                          process_destblt(s, &os->destblt, present, delta);
                                                         present, delta);  
1379                                          break;                                          break;
1380    
1381                                  case RDP_ORDER_PATBLT:                                  case RDP_ORDER_PATBLT:
1382                                          process_patblt(s, &os->patblt,                                          process_patblt(s, &os->patblt, present, delta);
                                                        present, delta);  
1383                                          break;                                          break;
1384    
1385                                  case RDP_ORDER_SCREENBLT:                                  case RDP_ORDER_SCREENBLT:
1386                                          process_screenblt(s, &os->screenblt,                                          process_screenblt(s, &os->screenblt, present, delta);
                                                           present, delta);  
1387                                          break;                                          break;
1388    
1389                                  case RDP_ORDER_LINE:                                  case RDP_ORDER_LINE:
1390                                          process_line(s, &os->line,                                          process_line(s, &os->line, present, delta);
                                                         present, delta);  
1391                                          break;                                          break;
1392    
1393                                  case RDP_ORDER_RECT:                                  case RDP_ORDER_RECT:
1394                                          process_rect(s, &os->rect,                                          process_rect(s, &os->rect, present, delta);
                                                      present, delta);  
1395                                          break;                                          break;
1396    
1397                                  case RDP_ORDER_DESKSAVE:                                  case RDP_ORDER_DESKSAVE:
1398                                          process_desksave(s, &os->desksave,                                          process_desksave(s, &os->desksave, present, delta);
                                                          present, delta);  
1399                                          break;                                          break;
1400    
1401                                  case RDP_ORDER_MEMBLT:                                  case RDP_ORDER_MEMBLT:
1402                                          process_memblt(s, &os->memblt,                                          process_memblt(s, &os->memblt, present, delta);
                                                        present, delta);  
1403                                          break;                                          break;
1404    
1405                                  case RDP_ORDER_TRIBLT:                                  case RDP_ORDER_TRIBLT:
1406                                          process_triblt(s, &os->triblt,                                          process_triblt(s, &os->triblt, present, delta);
1407                                                         present, delta);                                          break;
1408    
1409                                    case RDP_ORDER_POLYGON:
1410                                            process_polygon(s, &os->polygon, present, delta);
1411                                            break;
1412    
1413                                    case RDP_ORDER_POLYGON2:
1414                                            process_polygon2(s, &os->polygon2, present, delta);
1415                                            break;
1416    
1417                                    case RDP_ORDER_POLYLINE:
1418                                            process_polyline(s, &os->polyline, present, delta);
1419                                            break;
1420    
1421                                    case RDP_ORDER_ELLIPSE:
1422                                            process_ellipse(s, &os->ellipse, present, delta);
1423                                            break;
1424    
1425                                    case RDP_ORDER_ELLIPSE2:
1426                                            process_ellipse2(s, &os->ellipse2, present, delta);
1427                                          break;                                          break;
1428    
1429                                  case RDP_ORDER_TEXT2:                                  case RDP_ORDER_TEXT2:
1430                                          process_text2(s, &os->text2,                                          process_text2(s, &os->text2, present, delta);
                                                       present, delta);  
1431                                          break;                                          break;
1432    
1433                                  default:                                  default:
1434                                          NOTIMP("order %d\n", os->order_type);                                          unimpl("order %d\n", os->order_type);
1435                                          return;                                          return;
1436                          }                          }
1437    
# Line 840  void process_orders(STREAM s) Line 1441  void process_orders(STREAM s)
1441    
1442                  processed++;                  processed++;
1443          }          }
1444    #if 0
1445            /* not true when RDP_COMPRESSION is set */
1446            if (s->p != g_next_packet)
1447                    error("%d bytes remaining\n", (int) (g_next_packet - s->p));
1448    #endif
1449    
         if (s->p != next_packet)  
                 WARN("%d bytes remaining\n", (int)(next_packet - s->p));  
1450  }  }
1451    
1452  /* Reset order state */  /* Reset order state */
1453  void reset_order_state()  void
1454    reset_order_state(void)
1455  {  {
1456          memset(&order_state, 0, sizeof(order_state));          memset(&g_order_state, 0, sizeof(g_order_state));
1457            g_order_state.order_type = RDP_ORDER_PATBLT;
1458  }  }
   

Legend:
Removed from v.12  
changed lines
  Added in v.1485

  ViewVC Help
Powered by ViewVC 1.1.26