/[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 725 by jsorg71, Sun Jun 27 17:51:54 2004 UTC revision 845 by jdmeijer, Thu Mar 10 23:09:35 2005 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- 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-2002     Copyright (C) Matthew Chapman 1999-2005
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 70  rdp_in_coord(STREAM s, sint16 * coord, B Line 70  rdp_in_coord(STREAM s, sint16 * 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, uint32 * colour)  rdp_in_colour(STREAM s, uint32 * colour)
# Line 269  process_line(STREAM s, LINE_ORDER * os, Line 287  process_line(STREAM s, LINE_ORDER * os,
287    
288          rdp_parse_pen(s, &os->pen, present >> 7);          rdp_parse_pen(s, &os->pen, present >> 7);
289    
290          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",
291                 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));
292    
293          if (os->opcode < 0x01 || os->opcode > 0x10)          if (os->opcode < 0x01 || os->opcode > 0x10)
# Line 462  process_triblt(STREAM s, TRIBLT_ORDER * Line 480  process_triblt(STREAM s, TRIBLT_ORDER *
480                    bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);                    bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
481  }  }
482    
483  /* Parse a delta co-ordinate in polyline order form */  /* Process a polygon order */
484  static int  static void
485  parse_delta(uint8 * buffer, int *offset)  process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta)
486  {  {
487          int value = buffer[(*offset)++];          int index, data, next;
488          int two_byte = value & 0x80;          uint8 flags = 0;
489            POINT *points;
490    
491          if (value & 0x40)       /* sign bit */          if (present & 0x01)
492                  value |= ~0x3f;                  rdp_in_coord(s, &os->x, delta);
493    
494            if (present & 0x02)
495                    rdp_in_coord(s, &os->y, delta);
496    
497            if (present & 0x04)
498                    in_uint8(s, os->opcode);
499    
500            if (present & 0x08)
501                    in_uint8(s, os->fillmode);
502    
503            if (present & 0x10)
504                    rdp_in_colour(s, &os->fgcolour);
505    
506            if (present & 0x20)
507                    in_uint8(s, os->npoints);
508    
509            if (present & 0x40)
510            {
511                    in_uint8(s, os->datasize);
512                    in_uint8a(s, os->data, os->datasize);
513            }
514    
515            DEBUG(("POLYGON(x=%d,y=%d,op=0x%x,fm=%d,fg=0x%x,n=%d,sz=%d)\n",
516                   os->x, os->y, os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize));
517    
518            DEBUG(("Data: "));
519    
520            for (index = 0; index < os->datasize; index++)
521                    DEBUG(("%02x ", os->data[index]));
522    
523            DEBUG(("\n"));
524    
525            if (os->opcode < 0x01 || os->opcode > 0x10)
526            {
527                    error("bad ROP2 0x%x\n", os->opcode);
528                    return;
529            }
530    
531            points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));
532            memset(points, 0, (os->npoints + 1) * sizeof(POINT));
533    
534            points[0].x = os->x;
535            points[0].y = os->y;
536    
537            index = 0;
538            data = ((os->npoints - 1) / 4) + 1;
539            for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
540            {
541                    if ((next - 1) % 4 == 0)
542                            flags = os->data[index++];
543    
544                    if (~flags & 0x80)
545                            points[next].x = parse_delta(os->data, &data);
546    
547                    if (~flags & 0x40)
548                            points[next].y = parse_delta(os->data, &data);
549    
550                    flags <<= 2;
551            }
552    
553            if (next - 1 == os->npoints)
554                    ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,
555                               os->fgcolour);
556          else          else
557                  value &= 0x3f;                  error("polygon parse error\n");
558    
559          if (two_byte)          xfree(points);
560                  value = (value << 8) | buffer[(*offset)++];  }
561    
562          return value;  /* Process a polygon2 order */
563    static void
564    process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta)
565    {
566            int index, data, next;
567            uint8 flags = 0;
568            POINT *points;
569    
570            if (present & 0x0001)
571                    rdp_in_coord(s, &os->x, delta);
572    
573            if (present & 0x0002)
574                    rdp_in_coord(s, &os->y, delta);
575    
576            if (present & 0x0004)
577                    in_uint8(s, os->opcode);
578    
579            if (present & 0x0008)
580                    in_uint8(s, os->fillmode);
581    
582            if (present & 0x0010)
583                    rdp_in_colour(s, &os->bgcolour);
584    
585            if (present & 0x0020)
586                    rdp_in_colour(s, &os->fgcolour);
587    
588            rdp_parse_brush(s, &os->brush, present >> 6);
589    
590            if (present & 0x0800)
591                    in_uint8(s, os->npoints);
592    
593            if (present & 0x1000)
594            {
595                    in_uint8(s, os->datasize);
596                    in_uint8a(s, os->data, os->datasize);
597            }
598    
599            DEBUG(("POLYGON2(x=%d,y=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x,n=%d,sz=%d)\n",
600                   os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour,
601                   os->npoints, os->datasize));
602    
603            DEBUG(("Data: "));
604    
605            for (index = 0; index < os->datasize; index++)
606                    DEBUG(("%02x ", os->data[index]));
607    
608            DEBUG(("\n"));
609    
610            if (os->opcode < 0x01 || os->opcode > 0x10)
611            {
612                    error("bad ROP2 0x%x\n", os->opcode);
613                    return;
614            }
615    
616            points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));
617            memset(points, 0, (os->npoints + 1) * sizeof(POINT));
618    
619            points[0].x = os->x;
620            points[0].y = os->y;
621    
622            index = 0;
623            data = ((os->npoints - 1) / 4) + 1;
624            for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++)
625            {
626                    if ((next - 1) % 4 == 0)
627                            flags = os->data[index++];
628    
629                    if (~flags & 0x80)
630                            points[next].x = parse_delta(os->data, &data);
631    
632                    if (~flags & 0x40)
633                            points[next].y = parse_delta(os->data, &data);
634    
635                    flags <<= 2;
636            }
637    
638            if (next - 1 == os->npoints)
639                    ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
640                               &os->brush, os->bgcolour, os->fgcolour);
641            else
642                    error("polygon2 parse error\n");
643    
644            xfree(points);
645  }  }
646    
647  /* Process a polyline order */  /* Process a polyline order */
648  static void  static void
649  process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)  process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
650  {  {
651          int index, line, data;          int index, next, data;
         int x, y, xfrom, yfrom;  
652          uint8 flags = 0;          uint8 flags = 0;
653          PEN pen;          PEN pen;
654          uint8 opcode;          POINT *points;
655    
656          if (present & 0x01)          if (present & 0x01)
657                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 527  process_polyline(STREAM s, POLYLINE_ORDE Line 690  process_polyline(STREAM s, POLYLINE_ORDE
690                  return;                  return;
691          }          }
692    
693          opcode = os->opcode - 1;          points = (POINT *) xmalloc((os->lines + 1) * sizeof(POINT));
694          x = os->x;          memset(points, 0, (os->lines + 1) * sizeof(POINT));
695          y = os->y;  
696            points[0].x = os->x;
697            points[0].y = os->y;
698          pen.style = pen.width = 0;          pen.style = pen.width = 0;
699          pen.colour = os->fgcolour;          pen.colour = os->fgcolour;
700    
701          index = 0;          index = 0;
702          data = ((os->lines - 1) / 4) + 1;          data = ((os->lines - 1) / 4) + 1;
703          for (line = 0; (line < os->lines) && (data < os->datasize); line++)          for (next = 1; (next <= os->lines) && (data < os->datasize); next++)
704          {          {
705                  xfrom = x;                  if ((next - 1) % 4 == 0)
                 yfrom = y;  
   
                 if (line % 4 == 0)  
706                          flags = os->data[index++];                          flags = os->data[index++];
707    
708                  if ((flags & 0xc0) == 0)                  if (~flags & 0x80)
709                          flags |= 0xc0;  /* none = both */                          points[next].x = parse_delta(os->data, &data);
   
                 if (flags & 0x40)  
                         x += parse_delta(os->data, &data);  
   
                 if (flags & 0x80)  
                         y += parse_delta(os->data, &data);  
710    
711                  ui_line(opcode, xfrom, yfrom, x, y, &pen);                  if (~flags & 0x40)
712                            points[next].y = parse_delta(os->data, &data);
713    
714                  flags <<= 2;                  flags <<= 2;
715          }          }
716    
717            if (next - 1 == os->lines)
718                    ui_polyline(os->opcode - 1, points, os->lines + 1, &pen);
719            else
720                    error("polyline parse error\n");
721    }
722    
723    /* Process an ellipse order */
724    static void
725    process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, BOOL delta)
726    {
727            if (present & 0x01)
728                    rdp_in_coord(s, &os->left, delta);
729    
730            if (present & 0x02)
731                    rdp_in_coord(s, &os->top, delta);
732    
733            if (present & 0x04)
734                    rdp_in_coord(s, &os->right, delta);
735    
736            if (present & 0x08)
737                    rdp_in_coord(s, &os->bottom, delta);
738    
739            if (present & 0x10)
740                    in_uint8(s, os->opcode);
741    
742            if (present & 0x20)
743                    in_uint8(s, os->fillmode);
744    
745            if (present & 0x40)
746                    rdp_in_colour(s, &os->fgcolour);
747    
748            DEBUG(("ELLIPSE(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,fg=0x%x)\n", os->left, os->top,
749                   os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour));
750    
751            ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
752                       os->bottom - os->top, NULL, 0, os->fgcolour);
753    }
754    
755    /* Process an ellipse2 order */
756    static void
757    process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, BOOL delta)
758    {
759            if (present & 0x0001)
760                    rdp_in_coord(s, &os->left, delta);
761    
762            if (present & 0x0002)
763                    rdp_in_coord(s, &os->top, delta);
764    
765            if (present & 0x0004)
766                    rdp_in_coord(s, &os->right, delta);
767    
768            if (present & 0x0008)
769                    rdp_in_coord(s, &os->bottom, delta);
770    
771            if (present & 0x0010)
772                    in_uint8(s, os->opcode);
773    
774            if (present & 0x0020)
775                    in_uint8(s, os->fillmode);
776    
777            if (present & 0x0040)
778                    rdp_in_colour(s, &os->bgcolour);
779    
780            if (present & 0x0080)
781                    rdp_in_colour(s, &os->fgcolour);
782    
783            rdp_parse_brush(s, &os->brush, present >> 8);
784    
785            DEBUG(("ELLIPSE2(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
786                   os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style,
787                   os->bgcolour, os->fgcolour));
788    
789            ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
790                       os->bottom - os->top, &os->brush, os->bgcolour, os->fgcolour);
791  }  }
792    
793  /* Process a text order */  /* Process a text order */
# Line 571  process_text2(STREAM s, TEXT2_ORDER * os Line 803  process_text2(STREAM s, TEXT2_ORDER * os
803                  in_uint8(s, os->flags);                  in_uint8(s, os->flags);
804    
805          if (present & 0x000004)          if (present & 0x000004)
806                  in_uint8(s, os->unknown);                  in_uint8(s, os->opcode);
807    
808          if (present & 0x000008)          if (present & 0x000008)
809                  in_uint8(s, os->mixmode);                  in_uint8(s, os->mixmode);
# Line 606  process_text2(STREAM s, TEXT2_ORDER * os Line 838  process_text2(STREAM s, TEXT2_ORDER * os
838          if (present & 0x002000)          if (present & 0x002000)
839                  in_uint16_le(s, os->boxbottom);                  in_uint16_le(s, os->boxbottom);
840    
841          if (present & 0x004000) /* fix for connecting to a server that */          rdp_parse_brush(s, &os->brush, present >> 14);
                 in_uint8s(s, 10);       /* was disconnected with mstsc.exe */  
         /* 0x008000, 0x020000, and 0x040000 are present too ??? */  
842    
843          if (present & 0x080000)          if (present & 0x080000)
844                  in_uint16_le(s, os->x);                  in_uint16_le(s, os->x);
# Line 622  process_text2(STREAM s, TEXT2_ORDER * os Line 852  process_text2(STREAM s, TEXT2_ORDER * os
852                  in_uint8a(s, os->text, os->length);                  in_uint8a(s, os->text, os->length);
853          }          }
854    
855          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));
856    
857          DEBUG(("Text: "));          DEBUG(("Text: "));
858    
# Line 631  process_text2(STREAM s, TEXT2_ORDER * os Line 861  process_text2(STREAM s, TEXT2_ORDER * os
861    
862          DEBUG(("\n"));          DEBUG(("\n"));
863    
864          ui_draw_text(os->font, os->flags, os->mixmode, os->x, os->y,          ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
865                       os->clipleft, os->cliptop,                       os->clipleft, os->cliptop, os->clipright - os->clipleft,
866                       os->clipright - os->clipleft,                       os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
867                       os->clipbottom - os->cliptop,                       os->boxright - os->boxleft, os->boxbottom - os->boxtop,
868                       os->boxleft, os->boxtop,                       &os->brush, os->bgcolour, os->fgcolour, os->text, os->length);
                      os->boxright - os->boxleft,  
                      os->boxbottom - os->boxtop, os->bgcolour, os->fgcolour, os->text, os->length);  
869  }  }
870    
871  /* Process a raw bitmap cache order */  /* Process a raw bitmap cache order */
# Line 670  process_raw_bmpcache(STREAM s) Line 898  process_raw_bmpcache(STREAM s)
898    
899          bitmap = ui_create_bitmap(width, height, inverted);          bitmap = ui_create_bitmap(width, height, inverted);
900          xfree(inverted);          xfree(inverted);
901          cache_put_bitmap(cache_id, cache_idx, bitmap, 0);          cache_put_bitmap(cache_id, cache_idx, bitmap);
902  }  }
903    
904  /* Process a bitmap cache order */  /* Process a bitmap cache order */
# Line 719  process_bmpcache(STREAM s) Line 947  process_bmpcache(STREAM s)
947          if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))          if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
948          {          {
949                  bitmap = ui_create_bitmap(width, height, bmpdata);                  bitmap = ui_create_bitmap(width, height, bmpdata);
950                  cache_put_bitmap(cache_id, cache_idx, bitmap, 0);                  cache_put_bitmap(cache_id, cache_idx, bitmap);
951          }          }
952          else          else
953          {          {
# Line 772  process_bmpcache2(STREAM s, uint16 flags Line 1000  process_bmpcache2(STREAM s, uint16 flags
1000          in_uint8p(s, data, bufsize);          in_uint8p(s, data, bufsize);
1001    
1002          DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",          DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
1003                          compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));                 compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
1004    
1005          bmpdata = (uint8 *) xmalloc(width * height * Bpp);          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1006    
# Line 789  process_bmpcache2(STREAM s, uint16 flags Line 1017  process_bmpcache2(STREAM s, uint16 flags
1017          {          {
1018                  for (y = 0; y < height; y++)                  for (y = 0; y < height; y++)
1019                          memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],                          memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
1020                                          &data[y * (width * Bpp)], width * Bpp);                                 &data[y * (width * Bpp)], width * Bpp);
1021          }          }
1022    
1023          bitmap = ui_create_bitmap(width, height, bmpdata);          bitmap = ui_create_bitmap(width, height, bmpdata);
1024    
1025          if (bitmap)          if (bitmap)
1026          {          {
1027                  cache_put_bitmap(cache_id, cache_idx, bitmap, 0);                  cache_put_bitmap(cache_id, cache_idx, bitmap);
1028                  if (flags & PERSIST)                  if (flags & PERSIST)
1029                          pstcache_put_bitmap(cache_id, cache_idx, bitmap_id, width, height,                          pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height,
1030                                          width * height * Bpp, bmpdata);                                               width * height * Bpp, bmpdata);
1031          }          }
1032          else          else
1033          {          {
# Line 879  process_secondary_order(STREAM s) Line 1107  process_secondary_order(STREAM s)
1107          /* The length isn't calculated correctly by the server.          /* The length isn't calculated correctly by the server.
1108           * For very compact orders the length becomes negative           * For very compact orders the length becomes negative
1109           * so a signed integer must be used. */           * so a signed integer must be used. */
1110          sint16 length;          uint16 length;
1111          uint16 flags;          uint16 flags;
1112          uint8 type;          uint8 type;
1113          uint8 *next_order;          uint8 *next_order;
1114    
1115          in_uint16_le(s, (uint16) length);          in_uint16_le(s, length);
1116          in_uint16_le(s, flags);         /* used by bmpcache2 */          in_uint16_le(s, flags); /* used by bmpcache2 */
1117          in_uint8(s, type);          in_uint8(s, type);
1118    
1119          next_order = s->p + length + 7;          next_order = s->p + (sint16) length + 7;
1120    
1121          switch (type)          switch (type)
1122          {          {
# Line 964  process_orders(STREAM s, uint16 num_orde Line 1192  process_orders(STREAM s, uint16 num_orde
1192                                  case RDP_ORDER_PATBLT:                                  case RDP_ORDER_PATBLT:
1193                                  case RDP_ORDER_MEMBLT:                                  case RDP_ORDER_MEMBLT:
1194                                  case RDP_ORDER_LINE:                                  case RDP_ORDER_LINE:
1195                                    case RDP_ORDER_POLYGON2:
1196                                    case RDP_ORDER_ELLIPSE2:
1197                                          size = 2;                                          size = 2;
1198                                          break;                                          break;
1199    
# Line 1021  process_orders(STREAM s, uint16 num_orde Line 1251  process_orders(STREAM s, uint16 num_orde
1251                                          process_triblt(s, &os->triblt, present, delta);                                          process_triblt(s, &os->triblt, present, delta);
1252                                          break;                                          break;
1253    
1254                                    case RDP_ORDER_POLYGON:
1255                                            process_polygon(s, &os->polygon, present, delta);
1256                                            break;
1257    
1258                                    case RDP_ORDER_POLYGON2:
1259                                            process_polygon2(s, &os->polygon2, present, delta);
1260                                            break;
1261    
1262                                  case RDP_ORDER_POLYLINE:                                  case RDP_ORDER_POLYLINE:
1263                                          process_polyline(s, &os->polyline, present, delta);                                          process_polyline(s, &os->polyline, present, delta);
1264                                          break;                                          break;
1265    
1266                                    case RDP_ORDER_ELLIPSE:
1267                                            process_ellipse(s, &os->ellipse, present, delta);
1268                                            break;
1269    
1270                                    case RDP_ORDER_ELLIPSE2:
1271                                            process_ellipse2(s, &os->ellipse2, present, delta);
1272                                            break;
1273    
1274                                  case RDP_ORDER_TEXT2:                                  case RDP_ORDER_TEXT2:
1275                                          process_text2(s, &os->text2, present, delta);                                          process_text2(s, &os->text2, present, delta);
1276                                          break;                                          break;

Legend:
Removed from v.725  
changed lines
  Added in v.845

  ViewVC Help
Powered by ViewVC 1.1.26