/[rdesktop]/sourceforge.net/trunk/rdesktop/orders.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

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

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

revision 168 by matthewc, Tue Sep 17 07:23:32 2002 UTC revision 1474 by jsorg71, Fri Jul 11 03:35:24 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-2001     Copyright (C) Matthew Chapman 1999-2007
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 uint8 *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  static void
# Line 54  rdp_in_present(STREAM s, uint32 * presen Line 55  rdp_in_present(STREAM s, uint32 * presen
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  static void
58  rdp_in_coord(STREAM s, uint16 * coord, BOOL delta)  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 += (signed char) change;                  *coord += change;
66          }          }
67          else          else
68          {          {
# Line 69  rdp_in_coord(STREAM s, uint16 * coord, B Line 70  rdp_in_coord(STREAM s, uint16 * coord, B
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  static void
93  rdp_in_colour(STREAM s, uint8 * colour)  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  static RD_BOOL
106  rdp_parse_bounds(STREAM s, BOUNDS * bounds)  rdp_parse_bounds(STREAM s, BOUNDS * bounds)
107  {  {
108          uint8 present;          uint8 present;
# Line 109  rdp_parse_bounds(STREAM s, BOUNDS * boun Line 133  rdp_parse_bounds(STREAM s, BOUNDS * boun
133  }  }
134    
135  /* Parse a pen */  /* Parse a pen */
136  static BOOL  static RD_BOOL
137  rdp_parse_pen(STREAM s, PEN * pen, uint32 present)  rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
138  {  {
139          if (present & 1)          if (present & 1)
# Line 124  rdp_parse_pen(STREAM s, PEN * pen, uint3 Line 148  rdp_parse_pen(STREAM s, PEN * pen, uint3
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            uint16 cache_idx;
156            uint8 brush_bpp;
157    
158            memcpy(out_brush, in_brush, sizeof(BRUSH));
159            if (out_brush->style & 0x80)
160            {
161                    brush_bpp = out_brush->style & 0x0f;
162                    if (brush_bpp == 1) /* 1 bpp */
163                    {
164                            cache_idx = out_brush->pattern[0];
165                            brush_data = cache_get_brush_data(cache_idx);
166                            if (brush_data == NULL)
167                            {
168                                    error("error getting brush data, style %x\n", out_brush->style);
169                            }
170                            else
171                            {
172                                    memcpy(out_brush->pattern, brush_data->pattern,
173                                           sizeof(out_brush->pattern));
174                            }
175                    }
176                    else
177                    {
178                            error("bad brush bpp %d\n", brush_bpp);
179                    }
180                    out_brush->style = 3;
181            }
182    }
183    
184  /* Parse a brush */  /* Parse a brush */
185  static BOOL  static RD_BOOL
186  rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)  rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
187  {  {
188          if (present & 1)          if (present & 1)
# Line 148  rdp_parse_brush(STREAM s, BRUSH * brush, Line 205  rdp_parse_brush(STREAM s, BRUSH * brush,
205    
206  /* Process a destination blt order */  /* Process a destination blt order */
207  static void  static void
208  process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)  process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, RD_BOOL delta)
209  {  {
210          if (present & 0x01)          if (present & 0x01)
211                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 173  process_destblt(STREAM s, DESTBLT_ORDER Line 230  process_destblt(STREAM s, DESTBLT_ORDER
230    
231  /* Process a pattern blt order */  /* Process a pattern blt order */
232  static void  static void
233  process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)  process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, RD_BOOL delta)
234  {  {
235            BRUSH brush;
236    
237          if (present & 0x0001)          if (present & 0x0001)
238                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
239    
# Line 201  process_patblt(STREAM s, PATBLT_ORDER * Line 260  process_patblt(STREAM s, PATBLT_ORDER *
260          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,          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,
261                 os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));                 os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
262    
263            setup_brush(&brush, &os->brush);
264    
265          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,
266                    &os->brush, os->bgcolour, os->fgcolour);                    &brush, os->bgcolour, os->fgcolour);
267  }  }
268    
269  /* Process a screen blt order */  /* Process a screen blt order */
270  static void  static void
271  process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)  process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, RD_BOOL delta)
272  {  {
273          if (present & 0x0001)          if (present & 0x0001)
274                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 238  process_screenblt(STREAM s, SCREENBLT_OR Line 299  process_screenblt(STREAM s, SCREENBLT_OR
299    
300  /* Process a line order */  /* Process a line order */
301  static void  static void
302  process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)  process_line(STREAM s, LINE_ORDER * os, uint32 present, RD_BOOL delta)
303  {  {
304          if (present & 0x0001)          if (present & 0x0001)
305                  in_uint16_le(s, os->mixmode);                  in_uint16_le(s, os->mixmode);
# Line 263  process_line(STREAM s, LINE_ORDER * os, Line 324  process_line(STREAM s, LINE_ORDER * os,
324    
325          rdp_parse_pen(s, &os->pen, present >> 7);          rdp_parse_pen(s, &os->pen, present >> 7);
326    
327          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",
328                 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));                 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));
329    
330          if (os->opcode < 0x01 || os->opcode > 0x10)          if (os->opcode < 0x01 || os->opcode > 0x10)
# Line 277  process_line(STREAM s, LINE_ORDER * os, Line 338  process_line(STREAM s, LINE_ORDER * os,
338    
339  /* Process an opaque rectangle order */  /* Process an opaque rectangle order */
340  static void  static void
341  process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)  process_rect(STREAM s, RECT_ORDER * os, uint32 present, RD_BOOL delta)
342  {  {
343            uint32 i;
344          if (present & 0x01)          if (present & 0x01)
345                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
346    
# Line 292  process_rect(STREAM s, RECT_ORDER * os, Line 354  process_rect(STREAM s, RECT_ORDER * os,
354                  rdp_in_coord(s, &os->cy, delta);                  rdp_in_coord(s, &os->cy, delta);
355    
356          if (present & 0x10)          if (present & 0x10)
357                  in_uint8(s, os->colour);          {
358                    in_uint8(s, i);
359                    os->colour = (os->colour & 0xffffff00) | i;
360            }
361    
362            if (present & 0x20)
363            {
364                    in_uint8(s, i);
365                    os->colour = (os->colour & 0xffff00ff) | (i << 8);
366            }
367    
368            if (present & 0x40)
369            {
370                    in_uint8(s, i);
371                    os->colour = (os->colour & 0xff00ffff) | (i << 16);
372            }
373    
374          DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));          DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));
375    
# Line 301  process_rect(STREAM s, RECT_ORDER * os, Line 378  process_rect(STREAM s, RECT_ORDER * os,
378    
379  /* Process a desktop save order */  /* Process a desktop save order */
380  static void  static void
381  process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)  process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, RD_BOOL delta)
382  {  {
383          int width, height;          int width, height;
384    
# Line 337  process_desksave(STREAM s, DESKSAVE_ORDE Line 414  process_desksave(STREAM s, DESKSAVE_ORDE
414    
415  /* Process a memory blt order */  /* Process a memory blt order */
416  static void  static void
417  process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)  process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, RD_BOOL delta)
418  {  {
419          HBITMAP bitmap;          RD_HBITMAP bitmap;
420    
421          if (present & 0x0001)          if (present & 0x0001)
422          {          {
# Line 383  process_memblt(STREAM s, MEMBLT_ORDER * Line 460  process_memblt(STREAM s, MEMBLT_ORDER *
460    
461  /* Process a 3-way blt order */  /* Process a 3-way blt order */
462  static void  static void
463  process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)  process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, RD_BOOL delta)
464  {  {
465          HBITMAP bitmap;          RD_HBITMAP bitmap;
466            BRUSH brush;
467    
468          if (present & 0x000001)          if (present & 0x000001)
469          {          {
# Line 436  process_triblt(STREAM s, TRIBLT_ORDER * Line 514  process_triblt(STREAM s, TRIBLT_ORDER *
514          if (bitmap == NULL)          if (bitmap == NULL)
515                  return;                  return;
516    
517            setup_brush(&brush, &os->brush);
518    
519          ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,          ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
520                    bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);                    bitmap, os->srcx, os->srcy, &brush, os->bgcolour, os->fgcolour);
521  }  }
522    
523  /* Parse a delta co-ordinate in polyline order form */  /* Process a polygon order */
524  static int  static void
525  parse_delta(uint8 * buffer, int *offset)  process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, RD_BOOL delta)
526  {  {
527          int value = buffer[(*offset)++];          int index, data, next;
528          int two_byte = value & 0x80;          uint8 flags = 0;
529            RD_POINT *points;
530    
531          if (value & 0x40)       /* sign bit */          if (present & 0x01)
532                  value |= ~0x3f;                  rdp_in_coord(s, &os->x, delta);
533    
534            if (present & 0x02)
535                    rdp_in_coord(s, &os->y, delta);
536    
537            if (present & 0x04)
538                    in_uint8(s, os->opcode);
539    
540            if (present & 0x08)
541                    in_uint8(s, os->fillmode);
542    
543            if (present & 0x10)
544                    rdp_in_colour(s, &os->fgcolour);
545    
546            if (present & 0x20)
547                    in_uint8(s, os->npoints);
548    
549            if (present & 0x40)
550            {
551                    in_uint8(s, os->datasize);
552                    in_uint8a(s, os->data, os->datasize);
553            }
554    
555            DEBUG(("POLYGON(x=%d,y=%d,op=0x%x,fm=%d,fg=0x%x,n=%d,sz=%d)\n",
556                   os->x, os->y, os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize));
557    
558            DEBUG(("Data: "));
559    
560            for (index = 0; index < os->datasize; index++)
561                    DEBUG(("%02x ", os->data[index]));
562    
563            DEBUG(("\n"));
564    
565            if (os->opcode < 0x01 || os->opcode > 0x10)
566            {
567                    error("bad ROP2 0x%x\n", os->opcode);
568                    return;
569            }
570    
571            points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
572            memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
573    
574            points[0].x = os->x;
575            points[0].y = os->y;
576    
577            index = 0;
578            data = ((os->npoints - 1) / 4) + 1;
579            for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
580            {
581                    if ((next - 1) % 4 == 0)
582                            flags = os->data[index++];
583    
584                    if (~flags & 0x80)
585                            points[next].x = parse_delta(os->data, &data);
586    
587                    if (~flags & 0x40)
588                            points[next].y = parse_delta(os->data, &data);
589    
590                    flags <<= 2;
591            }
592    
593            if (next - 1 == os->npoints)
594                    ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,
595                               os->fgcolour);
596          else          else
597                  value &= 0x3f;                  error("polygon parse error\n");
598    
599          if (two_byte)          xfree(points);
600                  value = (value << 8) | buffer[(*offset)++];  }
601    
602          return value;  /* Process a polygon2 order */
603    static void
604    process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, RD_BOOL delta)
605    {
606            int index, data, next;
607            uint8 flags = 0;
608            RD_POINT *points;
609            BRUSH brush;
610    
611            if (present & 0x0001)
612                    rdp_in_coord(s, &os->x, delta);
613    
614            if (present & 0x0002)
615                    rdp_in_coord(s, &os->y, delta);
616    
617            if (present & 0x0004)
618                    in_uint8(s, os->opcode);
619    
620            if (present & 0x0008)
621                    in_uint8(s, os->fillmode);
622    
623            if (present & 0x0010)
624                    rdp_in_colour(s, &os->bgcolour);
625    
626            if (present & 0x0020)
627                    rdp_in_colour(s, &os->fgcolour);
628    
629            rdp_parse_brush(s, &os->brush, present >> 6);
630    
631            if (present & 0x0800)
632                    in_uint8(s, os->npoints);
633    
634            if (present & 0x1000)
635            {
636                    in_uint8(s, os->datasize);
637                    in_uint8a(s, os->data, os->datasize);
638            }
639    
640            DEBUG(("POLYGON2(x=%d,y=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x,n=%d,sz=%d)\n",
641                   os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour,
642                   os->npoints, os->datasize));
643    
644            DEBUG(("Data: "));
645    
646            for (index = 0; index < os->datasize; index++)
647                    DEBUG(("%02x ", os->data[index]));
648    
649            DEBUG(("\n"));
650    
651            if (os->opcode < 0x01 || os->opcode > 0x10)
652            {
653                    error("bad ROP2 0x%x\n", os->opcode);
654                    return;
655            }
656    
657            setup_brush(&brush, &os->brush);
658    
659            points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
660            memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
661    
662            points[0].x = os->x;
663            points[0].y = os->y;
664    
665            index = 0;
666            data = ((os->npoints - 1) / 4) + 1;
667            for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
668            {
669                    if ((next - 1) % 4 == 0)
670                            flags = os->data[index++];
671    
672                    if (~flags & 0x80)
673                            points[next].x = parse_delta(os->data, &data);
674    
675                    if (~flags & 0x40)
676                            points[next].y = parse_delta(os->data, &data);
677    
678                    flags <<= 2;
679            }
680    
681            if (next - 1 == os->npoints)
682                    ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
683                               &brush, os->bgcolour, os->fgcolour);
684            else
685                    error("polygon2 parse error\n");
686    
687            xfree(points);
688  }  }
689    
690  /* Process a polyline order */  /* Process a polyline order */
691  static void  static void
692  process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)  process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, RD_BOOL delta)
693  {  {
694          int index, line, data;          int index, next, data;
         int x, y, xfrom, yfrom;  
695          uint8 flags = 0;          uint8 flags = 0;
696          PEN pen;          PEN pen;
697          uint8 opcode;          RD_POINT *points;
698    
699          if (present & 0x01)          if (present & 0x01)
700                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 505  process_polyline(STREAM s, POLYLINE_ORDE Line 733  process_polyline(STREAM s, POLYLINE_ORDE
733                  return;                  return;
734          }          }
735    
736          opcode = os->opcode - 1;          points = (RD_POINT *) xmalloc((os->lines + 1) * sizeof(RD_POINT));
737          x = os->x;          memset(points, 0, (os->lines + 1) * sizeof(RD_POINT));
738          y = os->y;  
739            points[0].x = os->x;
740            points[0].y = os->y;
741          pen.style = pen.width = 0;          pen.style = pen.width = 0;
742          pen.colour = os->fgcolour;          pen.colour = os->fgcolour;
743    
744          index = 0;          index = 0;
745          data = ((os->lines - 1) / 4) + 1;          data = ((os->lines - 1) / 4) + 1;
746          for (line = 0; (line < os->lines) && (data < os->datasize); line++)          for (next = 1; (next <= os->lines) && (data < os->datasize); next++)
747          {          {
748                  xfrom = x;                  if ((next - 1) % 4 == 0)
                 yfrom = y;  
   
                 if (line % 4 == 0)  
749                          flags = os->data[index++];                          flags = os->data[index++];
750    
751                  if ((flags & 0xc0) == 0)                  if (~flags & 0x80)
752                          flags |= 0xc0;  /* none = both */                          points[next].x = parse_delta(os->data, &data);
   
                 if (flags & 0x40)  
                         x += parse_delta(os->data, &data);  
753    
754                  if (flags & 0x80)                  if (~flags & 0x40)
755                          y += parse_delta(os->data, &data);                          points[next].y = parse_delta(os->data, &data);
   
                 ui_line(opcode, xfrom, yfrom, x, y, &pen);  
756    
757                  flags <<= 2;                  flags <<= 2;
758          }          }
759    
760            if (next - 1 == os->lines)
761                    ui_polyline(os->opcode - 1, points, os->lines + 1, &pen);
762            else
763                    error("polyline parse error\n");
764    
765            xfree(points);
766    }
767    
768    /* Process an ellipse order */
769    static void
770    process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, RD_BOOL delta)
771    {
772            if (present & 0x01)
773                    rdp_in_coord(s, &os->left, delta);
774    
775            if (present & 0x02)
776                    rdp_in_coord(s, &os->top, delta);
777    
778            if (present & 0x04)
779                    rdp_in_coord(s, &os->right, delta);
780    
781            if (present & 0x08)
782                    rdp_in_coord(s, &os->bottom, delta);
783    
784            if (present & 0x10)
785                    in_uint8(s, os->opcode);
786    
787            if (present & 0x20)
788                    in_uint8(s, os->fillmode);
789    
790            if (present & 0x40)
791                    rdp_in_colour(s, &os->fgcolour);
792    
793            DEBUG(("ELLIPSE(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,fg=0x%x)\n", os->left, os->top,
794                   os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour));
795    
796            ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
797                       os->bottom - os->top, NULL, 0, os->fgcolour);
798    }
799    
800    /* Process an ellipse2 order */
801    static void
802    process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, RD_BOOL delta)
803    {
804            BRUSH brush;
805    
806            if (present & 0x0001)
807                    rdp_in_coord(s, &os->left, delta);
808    
809            if (present & 0x0002)
810                    rdp_in_coord(s, &os->top, delta);
811    
812            if (present & 0x0004)
813                    rdp_in_coord(s, &os->right, delta);
814    
815            if (present & 0x0008)
816                    rdp_in_coord(s, &os->bottom, delta);
817    
818            if (present & 0x0010)
819                    in_uint8(s, os->opcode);
820    
821            if (present & 0x0020)
822                    in_uint8(s, os->fillmode);
823    
824            if (present & 0x0040)
825                    rdp_in_colour(s, &os->bgcolour);
826    
827            if (present & 0x0080)
828                    rdp_in_colour(s, &os->fgcolour);
829    
830            rdp_parse_brush(s, &os->brush, present >> 8);
831    
832            DEBUG(("ELLIPSE2(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
833                   os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style,
834                   os->bgcolour, os->fgcolour));
835    
836            setup_brush(&brush, &os->brush);
837    
838            ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
839                       os->bottom - os->top, &brush, os->bgcolour, os->fgcolour);
840  }  }
841    
842  /* Process a text order */  /* Process a text order */
843  static void  static void
844  process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)  process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, RD_BOOL delta)
845  {  {
846          int i;          int i;
847            BRUSH brush;
848    
849          if (present & 0x000001)          if (present & 0x000001)
850                  in_uint8(s, os->font);                  in_uint8(s, os->font);
# Line 549  process_text2(STREAM s, TEXT2_ORDER * os Line 853  process_text2(STREAM s, TEXT2_ORDER * os
853                  in_uint8(s, os->flags);                  in_uint8(s, os->flags);
854    
855          if (present & 0x000004)          if (present & 0x000004)
856                  in_uint8(s, os->unknown);                  in_uint8(s, os->opcode);
857    
858          if (present & 0x000008)          if (present & 0x000008)
859                  in_uint8(s, os->mixmode);                  in_uint8(s, os->mixmode);
# Line 584  process_text2(STREAM s, TEXT2_ORDER * os Line 888  process_text2(STREAM s, TEXT2_ORDER * os
888          if (present & 0x002000)          if (present & 0x002000)
889                  in_uint16_le(s, os->boxbottom);                  in_uint16_le(s, os->boxbottom);
890    
891            rdp_parse_brush(s, &os->brush, present >> 14);
892    
893          if (present & 0x080000)          if (present & 0x080000)
894                  in_uint16_le(s, os->x);                  in_uint16_le(s, os->x);
895    
# Line 596  process_text2(STREAM s, TEXT2_ORDER * os Line 902  process_text2(STREAM s, TEXT2_ORDER * os
902                  in_uint8a(s, os->text, os->length);                  in_uint8a(s, os->text, os->length);
903          }          }
904    
905          DEBUG(("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,bb=%d,br=%d,fg=0x%x,bg=0x%x,font=%d,fl=0x%x,mix=%d,unk=0x%x,n=%d)\n", os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft, os->boxtop, os->boxright, os->boxbottom, os->fgcolour, os->bgcolour, os->font, os->flags, os->mixmode, os->unknown, os->length));          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));
906    
907          DEBUG(("Text: "));          DEBUG(("Text: "));
908    
# Line 605  process_text2(STREAM s, TEXT2_ORDER * os Line 911  process_text2(STREAM s, TEXT2_ORDER * os
911    
912          DEBUG(("\n"));          DEBUG(("\n"));
913    
914          ui_draw_text(os->font, os->flags, os->mixmode, os->x, os->y,          setup_brush(&brush, &os->brush);
915                       os->clipleft, os->cliptop,  
916                       os->clipright - os->clipleft,          ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
917                       os->clipbottom - os->cliptop,                       os->clipleft, os->cliptop, os->clipright - os->clipleft,
918                       os->boxleft, os->boxtop,                       os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
919                       os->boxright - os->boxleft,                       os->boxright - os->boxleft, os->boxbottom - os->boxtop,
920                       os->boxbottom - os->boxtop, os->bgcolour, os->fgcolour, os->text, os->length);                       &brush, os->bgcolour, os->fgcolour, os->text, os->length);
921  }  }
922    
923  /* Process a raw bitmap cache order */  /* Process a raw bitmap cache order */
924  static void  static void
925  process_raw_bmpcache(STREAM s)  process_raw_bmpcache(STREAM s)
926  {  {
927          HBITMAP bitmap;          RD_HBITMAP bitmap;
928          uint16 cache_idx, bufsize;          uint16 cache_idx, bufsize;
929          uint8 cache_id, width, height, bpp;          uint8 cache_id, width, height, bpp, Bpp;
930          uint8 *data, *inverted;          uint8 *data, *inverted;
931          int y;          int y;
932    
# Line 629  process_raw_bmpcache(STREAM s) Line 935  process_raw_bmpcache(STREAM s)
935          in_uint8(s, width);          in_uint8(s, width);
936          in_uint8(s, height);          in_uint8(s, height);
937          in_uint8(s, bpp);          in_uint8(s, bpp);
938            Bpp = (bpp + 7) / 8;
939          in_uint16_le(s, bufsize);          in_uint16_le(s, bufsize);
940          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
941          in_uint8p(s, data, bufsize);          in_uint8p(s, data, bufsize);
942    
943          DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));          DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
944          inverted = xmalloc(width * height);          inverted = (uint8 *) xmalloc(width * height * Bpp);
945          for (y = 0; y < height; y++)          for (y = 0; y < height; y++)
946          {          {
947                  memcpy(&inverted[(height - y - 1) * width], &data[y * width], width);                  memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
948                           width * Bpp);
949          }          }
950    
951          bitmap = ui_create_bitmap(width, height, inverted);          bitmap = ui_create_bitmap(width, height, inverted);
# Line 649  process_raw_bmpcache(STREAM s) Line 957  process_raw_bmpcache(STREAM s)
957  static void  static void
958  process_bmpcache(STREAM s)  process_bmpcache(STREAM s)
959  {  {
960          HBITMAP bitmap;          RD_HBITMAP bitmap;
961          uint16 cache_idx, size;          uint16 cache_idx, size;
962          uint8 cache_id, width, height, bpp;          uint8 cache_id, width, height, bpp, Bpp;
963          uint8 *data, *bmpdata;          uint8 *data, *bmpdata;
964            uint16 bufsize, pad2, row_size, final_size;
965            uint8 pad1;
966    
967            pad2 = row_size = final_size = 0xffff;  /* Shut the compiler up */
968    
969          in_uint8(s, cache_id);          in_uint8(s, cache_id);
970          in_uint8s(s, 1);        /* pad */          in_uint8(s, pad1);      /* pad */
971          in_uint8(s, width);          in_uint8(s, width);
972          in_uint8(s, height);          in_uint8(s, height);
973          in_uint8(s, bpp);          in_uint8(s, bpp);
974          in_uint8s(s, 2);        /* bufsize */          Bpp = (bpp + 7) / 8;
975            in_uint16_le(s, bufsize);       /* bufsize */
976          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
977          in_uint8s(s, 2);        /* pad */  
978          in_uint16_le(s, size);          if (g_use_rdp5)
979          in_uint8s(s, 4);        /* row_size, final_size */          {
980                    size = bufsize;
981            }
982            else
983            {
984    
985                    /* Begin compressedBitmapData */
986                    in_uint16_le(s, pad2);  /* pad */
987                    in_uint16_le(s, size);
988                    /*      in_uint8s(s, 4);  *//* row_size, final_size */
989                    in_uint16_le(s, row_size);
990                    in_uint16_le(s, final_size);
991    
992            }
993          in_uint8p(s, data, size);          in_uint8p(s, data, size);
994    
995          DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));          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));
996    
997          bmpdata = xmalloc(width * height);          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
998    
999          if (bitmap_decompress(bmpdata, width, height, data, size))          if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1000          {          {
1001                  bitmap = ui_create_bitmap(width, height, bmpdata);                  bitmap = ui_create_bitmap(width, height, bmpdata);
1002                  cache_put_bitmap(cache_id, cache_idx, bitmap);                  cache_put_bitmap(cache_id, cache_idx, bitmap);
1003          }          }
1004            else
1005            {
1006                    DEBUG(("Failed to decompress bitmap data\n"));
1007            }
1008    
1009            xfree(bmpdata);
1010    }
1011    
1012    /* Process a bitmap cache v2 order */
1013    static void
1014    process_bmpcache2(STREAM s, uint16 flags, RD_BOOL compressed)
1015    {
1016            RD_HBITMAP bitmap;
1017            int y;
1018            uint8 cache_id, cache_idx_low, width, height, Bpp;
1019            uint16 cache_idx, bufsize;
1020            uint8 *data, *bmpdata, *bitmap_id;
1021    
1022            bitmap_id = NULL;       /* prevent compiler warning */
1023            cache_id = flags & ID_MASK;
1024            Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
1025    
1026            if (flags & PERSIST)
1027            {
1028                    in_uint8p(s, bitmap_id, 8);
1029            }
1030    
1031            if (flags & SQUARE)
1032            {
1033                    in_uint8(s, width);
1034                    height = width;
1035            }
1036            else
1037            {
1038                    in_uint8(s, width);
1039                    in_uint8(s, height);
1040            }
1041    
1042            in_uint16_be(s, bufsize);
1043            bufsize &= BUFSIZE_MASK;
1044            in_uint8(s, cache_idx);
1045    
1046            if (cache_idx & LONG_FORMAT)
1047            {
1048                    in_uint8(s, cache_idx_low);
1049                    cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
1050            }
1051    
1052            in_uint8p(s, data, bufsize);
1053    
1054            DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
1055                   compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
1056    
1057            bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1058    
1059            if (compressed)
1060            {
1061                    if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
1062                    {
1063                            DEBUG(("Failed to decompress bitmap data\n"));
1064                            xfree(bmpdata);
1065                            return;
1066                    }
1067            }
1068            else
1069            {
1070                    for (y = 0; y < height; y++)
1071                            memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
1072                                   &data[y * (width * Bpp)], width * Bpp);
1073            }
1074    
1075            bitmap = ui_create_bitmap(width, height, bmpdata);
1076    
1077            if (bitmap)
1078            {
1079                    cache_put_bitmap(cache_id, cache_idx, bitmap);
1080                    if (flags & PERSIST)
1081                            pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height,
1082                                                 width * height * Bpp, bmpdata);
1083            }
1084            else
1085            {
1086                    DEBUG(("process_bmpcache2: ui_create_bitmap failed\n"));
1087            }
1088    
1089          xfree(bmpdata);          xfree(bmpdata);
1090  }  }
# Line 685  process_colcache(STREAM s) Line 1095  process_colcache(STREAM s)
1095  {  {
1096          COLOURENTRY *entry;          COLOURENTRY *entry;
1097          COLOURMAP map;          COLOURMAP map;
1098          HCOLOURMAP hmap;          RD_HCOLOURMAP hmap;
1099          uint8 cache_id;          uint8 cache_id;
1100          int i;          int i;
1101    
1102          in_uint8(s, cache_id);          in_uint8(s, cache_id);
1103          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1104    
1105          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1106    
1107          for (i = 0; i < map.ncolours; i++)          for (i = 0; i < map.ncolours; i++)
1108          {          {
# Line 706  process_colcache(STREAM s) Line 1116  process_colcache(STREAM s)
1116          DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));          DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
1117    
1118          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
1119          ui_set_colourmap(hmap);  
1120            if (cache_id)
1121                    ui_set_colourmap(hmap);
1122    
1123          xfree(map.colours);          xfree(map.colours);
1124  }  }
# Line 715  process_colcache(STREAM s) Line 1127  process_colcache(STREAM s)
1127  static void  static void
1128  process_fontcache(STREAM s)  process_fontcache(STREAM s)
1129  {  {
1130          HGLYPH bitmap;          RD_HGLYPH bitmap;
1131          uint8 font, nglyphs;          uint8 font, nglyphs;
1132          uint16 character, offset, baseline, width, height;          uint16 character, offset, baseline, width, height;
1133          int i, datasize;          int i, datasize;
# Line 742  process_fontcache(STREAM s) Line 1154  process_fontcache(STREAM s)
1154          }          }
1155  }  }
1156    
1157    /* Process a brush cache order */
1158    static void
1159    process_brushcache(STREAM s, uint16 flags)
1160    {
1161            BRUSHDATA brush_data;
1162            uint8 cache_idx, depth, width, height, size;
1163    
1164            in_uint8(s, cache_idx);
1165            in_uint8(s, depth);
1166            in_uint8(s, width);
1167            in_uint8(s, height);
1168            in_uint8s(s, 1); /* type, 0x80 = cached */
1169            in_uint8(s, size);
1170    
1171            DEBUG(("BRUSHCACHE(idx=%d,dp=%d,wd=%d,ht=%d,sz=%d)\n", cache_idx, depth,
1172                    width, height, size));
1173    
1174            if ((depth == 1) && (width == 8) && (height == 8) && (size == 8))
1175            {
1176                    in_uint8a(s, brush_data.pattern, sizeof(brush_data.pattern));
1177                    cache_put_brush_data(cache_idx, &brush_data);
1178            }
1179            else
1180            {
1181                    warning("ignoring incompatible brush type. display may be incorrect\n");
1182            }
1183    }
1184    
1185  /* Process a secondary order */  /* Process a secondary order */
1186  static void  static void
1187  process_secondary_order(STREAM s)  process_secondary_order(STREAM s)
1188  {  {
1189            /* The length isn't calculated correctly by the server.
1190             * For very compact orders the length becomes negative
1191             * so a signed integer must be used. */
1192          uint16 length;          uint16 length;
1193            uint16 flags;
1194          uint8 type;          uint8 type;
1195          uint8 *next_order;          uint8 *next_order;
1196    
1197          in_uint16_le(s, length);          in_uint16_le(s, length);
1198          in_uint8s(s, 2);        /* flags */          in_uint16_le(s, flags); /* used by bmpcache2 */
1199          in_uint8(s, type);          in_uint8(s, type);
1200    
1201          next_order = s->p + length + 7;          next_order = s->p + (sint16) length + 7;
1202    
1203          switch (type)          switch (type)
1204          {          {
# Line 774  process_secondary_order(STREAM s) Line 1218  process_secondary_order(STREAM s)
1218                          process_fontcache(s);                          process_fontcache(s);
1219                          break;                          break;
1220    
1221                    case RDP_ORDER_RAW_BMPCACHE2:
1222                            process_bmpcache2(s, flags, False);     /* uncompressed */
1223                            break;
1224    
1225                    case RDP_ORDER_BMPCACHE2:
1226                            process_bmpcache2(s, flags, True);      /* compressed */
1227                            break;
1228    
1229                    case RDP_ORDER_BRUSHCACHE:
1230                            process_brushcache(s, flags);
1231                            break;
1232    
1233                  default:                  default:
1234                          unimpl("secondary order %d\n", type);                          unimpl("secondary order %d\n", type);
1235          }          }
# Line 783  process_secondary_order(STREAM s) Line 1239  process_secondary_order(STREAM s)
1239    
1240  /* Process an order PDU */  /* Process an order PDU */
1241  void  void
1242  process_orders(STREAM s)  process_orders(STREAM s, uint16 num_orders)
1243  {  {
1244          RDP_ORDER_STATE *os = &order_state;          RDP_ORDER_STATE *os = &g_order_state;
1245          uint32 present;          uint32 present;
         uint16 num_orders;  
1246          uint8 order_flags;          uint8 order_flags;
1247          int size, processed = 0;          int size, processed = 0;
1248          BOOL delta;          RD_BOOL delta;
   
         in_uint8s(s, 2);        /* pad */  
         in_uint16_le(s, num_orders);  
         in_uint8s(s, 2);        /* pad */  
1249    
1250          while (processed < num_orders)          while (processed < num_orders)
1251          {          {
# Line 827  process_orders(STREAM s) Line 1278  process_orders(STREAM s)
1278                                  case RDP_ORDER_PATBLT:                                  case RDP_ORDER_PATBLT:
1279                                  case RDP_ORDER_MEMBLT:                                  case RDP_ORDER_MEMBLT:
1280                                  case RDP_ORDER_LINE:                                  case RDP_ORDER_LINE:
1281                                    case RDP_ORDER_POLYGON2:
1282                                    case RDP_ORDER_ELLIPSE2:
1283                                          size = 2;                                          size = 2;
1284                                          break;                                          break;
1285    
# Line 884  process_orders(STREAM s) Line 1337  process_orders(STREAM s)
1337                                          process_triblt(s, &os->triblt, present, delta);                                          process_triblt(s, &os->triblt, present, delta);
1338                                          break;                                          break;
1339    
1340                                    case RDP_ORDER_POLYGON:
1341                                            process_polygon(s, &os->polygon, present, delta);
1342                                            break;
1343    
1344                                    case RDP_ORDER_POLYGON2:
1345                                            process_polygon2(s, &os->polygon2, present, delta);
1346                                            break;
1347    
1348                                  case RDP_ORDER_POLYLINE:                                  case RDP_ORDER_POLYLINE:
1349                                          process_polyline(s, &os->polyline, present, delta);                                          process_polyline(s, &os->polyline, present, delta);
1350                                          break;                                          break;
1351    
1352                                    case RDP_ORDER_ELLIPSE:
1353                                            process_ellipse(s, &os->ellipse, present, delta);
1354                                            break;
1355    
1356                                    case RDP_ORDER_ELLIPSE2:
1357                                            process_ellipse2(s, &os->ellipse2, present, delta);
1358                                            break;
1359    
1360                                  case RDP_ORDER_TEXT2:                                  case RDP_ORDER_TEXT2:
1361                                          process_text2(s, &os->text2, present, delta);                                          process_text2(s, &os->text2, present, delta);
1362                                          break;                                          break;
# Line 903  process_orders(STREAM s) Line 1372  process_orders(STREAM s)
1372    
1373                  processed++;                  processed++;
1374          }          }
1375    #if 0
1376            /* not true when RDP_COMPRESSION is set */
1377            if (s->p != g_next_packet)
1378                    error("%d bytes remaining\n", (int) (g_next_packet - s->p));
1379    #endif
1380    
         if (s->p != next_packet)  
                 error("%d bytes remaining\n", (int) (next_packet - s->p));  
1381  }  }
1382    
1383  /* Reset order state */  /* Reset order state */
1384  void  void
1385  reset_order_state()  reset_order_state(void)
1386  {  {
1387          memset(&order_state, 0, sizeof(order_state));          memset(&g_order_state, 0, sizeof(g_order_state));
1388          order_state.order_type = RDP_ORDER_PATBLT;          g_order_state.order_type = RDP_ORDER_PATBLT;
1389  }  }

Legend:
Removed from v.168  
changed lines
  Added in v.1474

  ViewVC Help
Powered by ViewVC 1.1.26