/[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 15 by matty, Thu Sep 28 05:27:25 2000 UTC revision 738 by astrand, Mon Jul 12 21:07:39 2004 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-2002
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 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, 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 68  static void rdp_in_coord(STREAM s, uint1 Line 71  static void rdp_in_coord(STREAM s, uint1
71  }  }
72    
73  /* Read a colour entry */  /* Read a colour entry */
74  static void rdp_in_colour(STREAM s, uint8 *colour)  static void
75    rdp_in_colour(STREAM s, uint32 * colour)
76  {  {
77          in_uint8(s, *colour);          uint32 i;
78          s->p += 2;          in_uint8(s, i);
79            *colour = i;
80            in_uint8(s, i);
81            *colour |= i << 8;
82            in_uint8(s, i);
83            *colour |= i << 16;
84  }  }
85    
86  /* Parse bounds information */  /* Parse bounds information */
87  static BOOL rdp_parse_bounds(STREAM s, BOUNDS *bounds)  static BOOL
88    rdp_parse_bounds(STREAM s, BOUNDS * bounds)
89  {  {
90          uint8 present;          uint8 present;
91    
# Line 105  static BOOL rdp_parse_bounds(STREAM s, B Line 115  static BOOL rdp_parse_bounds(STREAM s, B
115  }  }
116    
117  /* Parse a pen */  /* Parse a pen */
118  static BOOL rdp_parse_pen(STREAM s, PEN *pen, uint32 present)  static BOOL
119    rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
120  {  {
121          if (present & 1)          if (present & 1)
122                  in_uint8(s, pen->style);                  in_uint8(s, pen->style);
# Line 120  static BOOL rdp_parse_pen(STREAM s, PEN Line 131  static BOOL rdp_parse_pen(STREAM s, PEN
131  }  }
132    
133  /* Parse a brush */  /* Parse a brush */
134  static BOOL rdp_parse_brush(STREAM s, BRUSH *brush, uint32 present)  static BOOL
135    rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
136  {  {
137          if (present & 1)          if (present & 1)
138                  in_uint8(s, brush->xorigin);                  in_uint8(s, brush->xorigin);
# Line 141  static BOOL rdp_parse_brush(STREAM s, BR Line 153  static BOOL rdp_parse_brush(STREAM s, BR
153  }  }
154    
155  /* Process a destination blt order */  /* Process a destination blt order */
156  static void process_destblt(STREAM s, DESTBLT_ORDER *os,  static void
157                                  uint32 present, BOOL delta)  process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)
158  {  {
159          if (present & 0x01)          if (present & 0x01)
160                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 159  static void process_destblt(STREAM s, DE Line 171  static void process_destblt(STREAM s, DE
171          if (present & 0x10)          if (present & 0x10)
172                  in_uint8(s, os->opcode);                  in_uint8(s, os->opcode);
173    
174          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",
175                os->opcode, os->x, os->y, os->cx, os->cy);                 os->opcode, os->x, os->y, os->cx, os->cy));
176    
177          ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);          ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
178  }  }
179    
180  /* Process a pattern blt order */  /* Process a pattern blt order */
181  static void process_patblt(STREAM s, PATBLT_ORDER *os,  static void
182                                  uint32 present, BOOL delta)  process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)
183  {  {
184          if (present & 0x0001)          if (present & 0x0001)
185                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 192  static void process_patblt(STREAM s, PAT Line 204  static void process_patblt(STREAM s, PAT
204    
205          rdp_parse_brush(s, &os->brush, present >> 7);          rdp_parse_brush(s, &os->brush, present >> 7);
206    
207          DEBUG("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n",          DEBUG(("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n", os->opcode, os->x,
208                os->opcode, os->x, os->y, os->cx, os->cy,                 os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
               os->brush.style, os->bgcolour, os->fgcolour);  
209    
210          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,
211                                  &os->brush, os->bgcolour, os->fgcolour);                    &os->brush, os->bgcolour, os->fgcolour);
212  }  }
213    
214  /* Process a screen blt order */  /* Process a screen blt order */
215  static void process_screenblt(STREAM s, SCREENBLT_ORDER *os,  static void
216                                          uint32 present, BOOL delta)  process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)
217  {  {
218          if (present & 0x0001)          if (present & 0x0001)
219                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 225  static void process_screenblt(STREAM s, Line 236  static void process_screenblt(STREAM s,
236          if (present & 0x0040)          if (present & 0x0040)
237                  rdp_in_coord(s, &os->srcy, delta);                  rdp_in_coord(s, &os->srcy, delta);
238    
239          DEBUG("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",          DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",
240                os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);                 os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy));
241    
242          ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy,          ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
                                 os->srcx, os->srcy);  
243  }  }
244    
245  /* Process a line order */  /* Process a line order */
246  static void process_line(STREAM s, LINE_ORDER *os, uint32 present, BOOL delta)  static void
247    process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
248  {  {
249          if (present & 0x0001)          if (present & 0x0001)
250                  in_uint16_le(s, os->mixmode);                  in_uint16_le(s, os->mixmode);
# Line 258  static void process_line(STREAM s, LINE_ Line 269  static void process_line(STREAM s, LINE_
269    
270          rdp_parse_pen(s, &os->pen, present >> 7);          rdp_parse_pen(s, &os->pen, present >> 7);
271    
272          DEBUG("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dx=%d,fg=0x%x)\n",          DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dy=%d,fg=0x%x)\n",
273                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);  
274    
275          if (os->opcode < 0x01 || os->opcode > 0x10)          if (os->opcode < 0x01 || os->opcode > 0x10)
276          {          {
277                  ERROR("bad ROP2 0x%x\n", os->opcode);                  error("bad ROP2 0x%x\n", os->opcode);
278                  return;                  return;
279          }          }
280    
281          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);  
282  }  }
283    
284  /* Process an opaque rectangle order */  /* Process an opaque rectangle order */
285  static void process_rect(STREAM s, RECT_ORDER *os, uint32 present, BOOL delta)  static void
286    process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
287  {  {
288            uint32 i;
289          if (present & 0x01)          if (present & 0x01)
290                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
291    
# Line 288  static void process_rect(STREAM s, RECT_ Line 299  static void process_rect(STREAM s, RECT_
299                  rdp_in_coord(s, &os->cy, delta);                  rdp_in_coord(s, &os->cy, delta);
300    
301          if (present & 0x10)          if (present & 0x10)
302                  in_uint8(s, os->colour);          {
303                    in_uint8(s, i);
304                    os->colour = (os->colour & 0xffffff00) | i;
305            }
306    
307            if (present & 0x20)
308            {
309                    in_uint8(s, i);
310                    os->colour = (os->colour & 0xffff00ff) | (i << 8);
311            }
312    
313          DEBUG("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n",          if (present & 0x40)
314                os->x, os->y, os->cx, os->cy, os->colour);          {
315                    in_uint8(s, i);
316                    os->colour = (os->colour & 0xff00ffff) | (i << 16);
317            }
318    
319            DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));
320    
321          ui_rect(os->x, os->y, os->cx, os->cy, os->colour);          ui_rect(os->x, os->y, os->cx, os->cy, os->colour);
322  }  }
323    
324  /* Process a desktop save order */  /* Process a desktop save order */
325  static void process_desksave(STREAM s, DESKSAVE_ORDER *os,  static void
326                                  uint32 present, BOOL delta)  process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
327  {  {
328          int width, height;          int width, height;
329    
# Line 320  static void process_desksave(STREAM s, D Line 345  static void process_desksave(STREAM s, D
345          if (present & 0x20)          if (present & 0x20)
346                  in_uint8(s, os->action);                  in_uint8(s, os->action);
347    
348          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",
349                os->left, os->top, os->right, os->bottom, os->offset,                 os->left, os->top, os->right, os->bottom, os->offset, os->action));
               os->action);  
350    
351          width = os->right - os->left + 1;          width = os->right - os->left + 1;
352          height = os->bottom - os->top + 1;          height = os->bottom - os->top + 1;
# Line 334  static void process_desksave(STREAM s, D Line 358  static void process_desksave(STREAM s, D
358  }  }
359    
360  /* Process a memory blt order */  /* Process a memory blt order */
361  static void process_memblt(STREAM s, MEMBLT_ORDER *os,  static void
362                                  uint32 present, BOOL delta)  process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
363  {  {
364          HBITMAP bitmap;          HBITMAP bitmap;
365    
# Line 369  static void process_memblt(STREAM s, MEM Line 393  static void process_memblt(STREAM s, MEM
393          if (present & 0x0100)          if (present & 0x0100)
394                  in_uint16_le(s, os->cache_idx);                  in_uint16_le(s, os->cache_idx);
395    
396          DEBUG("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",          DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",
397                os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id,                 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx));
               os->cache_idx);  
398    
399          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
400          if (bitmap == NULL)          if (bitmap == NULL)
401                  return;                  return;
402    
403          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);  
404  }  }
405    
406  /* Process a 3-way blt order */  /* Process a 3-way blt order */
407  static void process_triblt(STREAM s, TRIBLT_ORDER *os,  static void
408                                  uint32 present, BOOL delta)  process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
409  {  {
410          HBITMAP bitmap;          HBITMAP bitmap;
411    
# Line 428  static void process_triblt(STREAM s, TRI Line 450  static void process_triblt(STREAM s, TRI
450          if (present & 0x010000)          if (present & 0x010000)
451                  in_uint16_le(s, os->unknown);                  in_uint16_le(s, os->unknown);
452    
453          DEBUG("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n",          DEBUG(("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
454                os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id,                 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx,
455                os->cache_idx, os->brush.style, os->bgcolour, os->fgcolour);                 os->brush.style, os->bgcolour, os->fgcolour));
456    
457          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);          bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
458          if (bitmap == NULL)          if (bitmap == NULL)
459                  return;                  return;
460    
461          ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,          ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
462                          bitmap, os->srcx, os->srcy,                    bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
                         &os->brush, os->bgcolour, os->fgcolour);  
463  }  }
464    
465  /* Parse a delta co-ordinate in polyline order form */  /* Parse a delta co-ordinate in polyline order form */
466  static int parse_delta(uint8 *buffer, int *offset)  static int
467    parse_delta(uint8 * buffer, int *offset)
468  {  {
469          int value = buffer[(*offset)++];          int value = buffer[(*offset)++];
470          int two_byte = value & 0x80;          int two_byte = value & 0x80;
471    
472          if (value & 0x40) /* sign bit */          if (value & 0x40)       /* sign bit */
473                  value |= ~0x3f;                  value |= ~0x3f;
474          else          else
475                  value &= 0x3f;                  value &= 0x3f;
# Line 459  static int parse_delta(uint8 *buffer, in Line 481  static int parse_delta(uint8 *buffer, in
481  }  }
482    
483  /* Process a polyline order */  /* Process a polyline order */
484  static void process_polyline(STREAM s, POLYLINE_ORDER *os,  static void
485                                  uint32 present, BOOL delta)  process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
486  {  {
487          int index, line, data;          int index, line, data;
488          int x, y, xfrom, yfrom;          int x, y, xfrom, yfrom;
489          uint8 flags = 0;          uint8 flags = 0;
490          PEN pen;          PEN pen;
491            uint8 opcode;
492    
493          if (present & 0x01)          if (present & 0x01)
494                  rdp_in_coord(s, &os->x, delta);                  rdp_in_coord(s, &os->x, delta);
# Line 474  static void process_polyline(STREAM s, P Line 497  static void process_polyline(STREAM s, P
497                  rdp_in_coord(s, &os->y, delta);                  rdp_in_coord(s, &os->y, delta);
498    
499          if (present & 0x04)          if (present & 0x04)
500                  in_uint8(s, os->flags);                  in_uint8(s, os->opcode);
501    
502          if (present & 0x10)          if (present & 0x10)
503                  rdp_in_colour(s, &os->fgcolour);                  rdp_in_colour(s, &os->fgcolour);
# Line 488  static void process_polyline(STREAM s, P Line 511  static void process_polyline(STREAM s, P
511                  in_uint8a(s, os->data, os->datasize);                  in_uint8a(s, os->data, os->datasize);
512          }          }
513    
514          DEBUG("POLYLINE(x=%d,y=%d,fl=0x%x,fg=0x%x,n=%d,sz=%d)\n",          DEBUG(("POLYLINE(x=%d,y=%d,op=0x%x,fg=0x%x,n=%d,sz=%d)\n",
515                  os->x, os->y, os->flags, os->fgcolour, os->lines, os->datasize);                 os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize));
516    
517          DEBUG("Data: ");          DEBUG(("Data: "));
518    
519          for (index = 0; index < os->datasize; index++)          for (index = 0; index < os->datasize; index++)
520                  DEBUG("%02x ", os->data[index]);                  DEBUG(("%02x ", os->data[index]));
521    
522          DEBUG("\n");          DEBUG(("\n"));
523    
524            if (os->opcode < 0x01 || os->opcode > 0x10)
525            {
526                    error("bad ROP2 0x%x\n", os->opcode);
527                    return;
528            }
529    
530            opcode = os->opcode - 1;
531          x = os->x;          x = os->x;
532          y = os->y;          y = os->y;
533          pen.style = pen.width = 0;          pen.style = pen.width = 0;
# Line 514  static void process_polyline(STREAM s, P Line 544  static void process_polyline(STREAM s, P
544                          flags = os->data[index++];                          flags = os->data[index++];
545    
546                  if ((flags & 0xc0) == 0)                  if ((flags & 0xc0) == 0)
547                          flags |= 0xc0;   /* none = both */                          flags |= 0xc0;  /* none = both */
548    
549                  if (flags & 0x40)                  if (flags & 0x40)
550                          x += parse_delta(os->data, &data);                          x += parse_delta(os->data, &data);
# Line 522  static void process_polyline(STREAM s, P Line 552  static void process_polyline(STREAM s, P
552                  if (flags & 0x80)                  if (flags & 0x80)
553                          y += parse_delta(os->data, &data);                          y += parse_delta(os->data, &data);
554    
555                  ui_line(ROP2_COPY, xfrom, yfrom, x, y, &pen);                  ui_line(opcode, xfrom, yfrom, x, y, &pen);
556    
557                  flags <<= 2;                  flags <<= 2;
558          }          }
559  }  }
560    
561  /* Process a text order */  /* Process a text order */
562  static void process_text2(STREAM s, TEXT2_ORDER *os, uint32 present, BOOL delta)  static void
563    process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
564  {  {
         DATABLOB *entry;  
565          int i;          int i;
566    
567          if (present & 0x000001)          if (present & 0x000001)
# Line 576  static void process_text2(STREAM s, TEXT Line 606  static void process_text2(STREAM s, TEXT
606          if (present & 0x002000)          if (present & 0x002000)
607                  in_uint16_le(s, os->boxbottom);                  in_uint16_le(s, os->boxbottom);
608    
609            if (present & 0x004000) /* fix for connecting to a server that */
610                    in_uint8s(s, 10);       /* was disconnected with mstsc.exe */
611            /* 0x008000, 0x020000, and 0x040000 are present too ??? */
612    
613          if (present & 0x080000)          if (present & 0x080000)
614                  in_uint16_le(s, os->x);                  in_uint16_le(s, os->x);
615    
# Line 588  static void process_text2(STREAM s, TEXT Line 622  static void process_text2(STREAM s, TEXT
622                  in_uint8a(s, os->text, os->length);                  in_uint8a(s, os->text, os->length);
623          }          }
624    
625          DEBUG("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,bb=%d,br=%d,fg=0x%x,bg=0x%x,font=%d,fl=0x%x,mix=%d,unk=0x%x,n=%d)\n",          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));
                 os->x, os->y, os->clipleft, os->cliptop, os->clipright,  
                 os->clipbottom, os->boxleft, os->boxtop, os->boxright,  
                 os->boxbottom, os->fgcolour, os->bgcolour, os->font,  
                 os->flags, os->mixmode, os->unknown, os->length);  
626    
627          DEBUG("Text: ");          DEBUG(("Text: "));
628    
629          for (i = 0; i < os->length; i++)          for (i = 0; i < os->length; i++)
630                  DEBUG("%02x ", os->text[i]);                  DEBUG(("%02x ", os->text[i]));
631    
632          DEBUG("\n");          DEBUG(("\n"));
633    
634          /* Process special cache strings */          ui_draw_text(os->font, os->flags, os->mixmode, os->x, os->y,
635          if ((os->length >= 2) && (os->text[0] == 0xfe))                       os->clipleft, os->cliptop,
636          {                       os->clipright - os->clipleft,
637                  entry = cache_get_text(os->text[1]);                       os->clipbottom - os->cliptop,
638                         os->boxleft, os->boxtop,
639                  if (entry == NULL)                       os->boxright - os->boxleft,
640                          return;                       os->boxbottom - os->boxtop, os->bgcolour, os->fgcolour, os->text, os->length);
                   
                 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);  
         }  
   
         ui_draw_text(os->font, os->flags, os->mixmode,  
                         os->x, os->y, os->boxleft, os->boxtop,  
                         os->boxright - os->boxleft,  
                         os->boxbottom - os->boxtop,  
                         os->bgcolour, os->fgcolour, os->text, os->length);  
641  }  }
642    
643  /* Process a raw bitmap cache order */  /* Process a raw bitmap cache order */
644  static void process_raw_bmpcache(STREAM s)  static void
645    process_raw_bmpcache(STREAM s)
646  {  {
647          HBITMAP bitmap;          HBITMAP bitmap;
648          uint16 cache_idx, bufsize;          uint16 cache_idx, bufsize;
649          uint8 cache_id, width, height, bpp;          uint8 cache_id, width, height, bpp, Bpp;
650          uint8 *data;          uint8 *data, *inverted;
651            int y;
652    
653          in_uint8(s, cache_id);          in_uint8(s, cache_id);
654          in_uint8s(s, 1); /* pad */          in_uint8s(s, 1);        /* pad */
655          in_uint8(s, width);          in_uint8(s, width);
656          in_uint8(s, height);          in_uint8(s, height);
657          in_uint8(s, bpp);          in_uint8(s, bpp);
658            Bpp = (bpp + 7) / 8;
659          in_uint16_le(s, bufsize);          in_uint16_le(s, bufsize);
660          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
661          in_uint8p(s, data, bufsize);          in_uint8p(s, data, bufsize);
662    
663          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));
664                width, height, cache_id, cache_idx);          inverted = (uint8 *) xmalloc(width * height * Bpp);
665            for (y = 0; y < height; y++)
666            {
667                    memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
668                           width * Bpp);
669            }
670    
671          bitmap = ui_create_bitmap(width, height, data);          bitmap = ui_create_bitmap(width, height, inverted);
672          cache_put_bitmap(cache_id, cache_idx, bitmap);          xfree(inverted);
673            cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
674  }  }
675    
676  /* Process a bitmap cache order */  /* Process a bitmap cache order */
677  static void process_bmpcache(STREAM s)  static void
678    process_bmpcache(STREAM s)
679  {  {
680          HBITMAP bitmap;          HBITMAP bitmap;
681          uint16 cache_idx, size;          uint16 cache_idx, size;
682          uint8 cache_id, width, height, bpp;          uint8 cache_id, width, height, bpp, Bpp;
683          uint8 *data, *bmpdata;          uint8 *data, *bmpdata;
684            uint16 bufsize, pad2, row_size, final_size;
685            uint8 pad1;
686    
687            pad2 = row_size = final_size = 0xffff;  /* Shut the compiler up */
688    
689          in_uint8(s, cache_id);          in_uint8(s, cache_id);
690          in_uint8s(s, 1); /* pad */          in_uint8(s, pad1);      /* pad */
691          in_uint8(s, width);          in_uint8(s, width);
692          in_uint8(s, height);          in_uint8(s, height);
693          in_uint8(s, bpp);          in_uint8(s, bpp);
694          in_uint8s(s, 2); /* bufsize */          Bpp = (bpp + 7) / 8;
695            in_uint16_le(s, bufsize);       /* bufsize */
696          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
697          in_uint8s(s, 2); /* pad */  
698          in_uint16_le(s, size);          if (g_use_rdp5)
699          in_uint8s(s, 4); /* row_size, final_size */          {
700                    size = bufsize;
701            }
702            else
703            {
704    
705                    /* Begin compressedBitmapData */
706                    in_uint16_le(s, pad2);  /* pad */
707                    in_uint16_le(s, size);
708                    /*      in_uint8s(s, 4);  *//* row_size, final_size */
709                    in_uint16_le(s, row_size);
710                    in_uint16_le(s, final_size);
711    
712            }
713          in_uint8p(s, data, size);          in_uint8p(s, data, size);
714    
715          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);  
716    
717          bmpdata = xmalloc(width * height);          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
718    
719          if (bitmap_decompress(bmpdata, width, height, data, size))          if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
720          {          {
721                  bitmap = ui_create_bitmap(width, height, bmpdata);                  bitmap = ui_create_bitmap(width, height, bmpdata);
722                  cache_put_bitmap(cache_id, cache_idx, bitmap);                  cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
723            }
724            else
725            {
726                    DEBUG(("Failed to decompress bitmap data\n"));
727            }
728    
729            xfree(bmpdata);
730    }
731    
732    /* Process a bitmap cache v2 order */
733    static void
734    process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
735    {
736            HBITMAP bitmap;
737            int y;
738            uint8 cache_id, cache_idx_low, width, height, Bpp;
739            uint16 cache_idx, bufsize;
740            uint8 *data, *bmpdata, *bitmap_id;
741    
742            bitmap_id = NULL;       /* prevent compiler warning */
743            cache_id = flags & ID_MASK;
744            Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
745    
746            if (flags & PERSIST)
747            {
748                    in_uint8p(s, bitmap_id, 8);
749            }
750    
751            if (flags & SQUARE)
752            {
753                    in_uint8(s, width);
754                    height = width;
755            }
756            else
757            {
758                    in_uint8(s, width);
759                    in_uint8(s, height);
760            }
761    
762            in_uint16_be(s, bufsize);
763            bufsize &= BUFSIZE_MASK;
764            in_uint8(s, cache_idx);
765    
766            if (cache_idx & LONG_FORMAT)
767            {
768                    in_uint8(s, cache_idx_low);
769                    cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
770            }
771    
772            in_uint8p(s, data, bufsize);
773    
774            DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
775                   compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
776    
777            bmpdata = (uint8 *) xmalloc(width * height * Bpp);
778    
779            if (compressed)
780            {
781                    if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
782                    {
783                            DEBUG(("Failed to decompress bitmap data\n"));
784                            xfree(bmpdata);
785                            return;
786                    }
787            }
788            else
789            {
790                    for (y = 0; y < height; y++)
791                            memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
792                                   &data[y * (width * Bpp)], width * Bpp);
793            }
794    
795            bitmap = ui_create_bitmap(width, height, bmpdata);
796    
797            if (bitmap)
798            {
799                    cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
800                    if (flags & PERSIST)
801                            pstcache_put_bitmap(cache_id, cache_idx, bitmap_id, width, height,
802                                                width * height * Bpp, bmpdata);
803            }
804            else
805            {
806                    DEBUG(("process_bmpcache2: ui_create_bitmap failed\n"));
807          }          }
808    
809          xfree(bmpdata);          xfree(bmpdata);
810  }  }
811    
812  /* Process a colourmap cache order */  /* Process a colourmap cache order */
813  static void process_colcache(STREAM s)  static void
814    process_colcache(STREAM s)
815  {  {
816          COLOURENTRY *entry;          COLOURENTRY *entry;
817          COLOURMAP map;          COLOURMAP map;
# Line 695  static void process_colcache(STREAM s) Line 822  static void process_colcache(STREAM s)
822          in_uint8(s, cache_id);          in_uint8(s, cache_id);
823          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
824    
825          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
826    
827          for (i = 0; i < map.ncolours; i++)          for (i = 0; i < map.ncolours; i++)
828          {          {
# Line 703  static void process_colcache(STREAM s) Line 830  static void process_colcache(STREAM s)
830                  in_uint8(s, entry->blue);                  in_uint8(s, entry->blue);
831                  in_uint8(s, entry->green);                  in_uint8(s, entry->green);
832                  in_uint8(s, entry->red);                  in_uint8(s, entry->red);
833                  in_uint8s(s, 1); /* pad */                  in_uint8s(s, 1);        /* pad */
834          }          }
835    
836          DEBUG("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours);          DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
837    
838          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
839          ui_set_colourmap(hmap);          ui_set_colourmap(hmap);
# Line 715  static void process_colcache(STREAM s) Line 842  static void process_colcache(STREAM s)
842  }  }
843    
844  /* Process a font cache order */  /* Process a font cache order */
845  static void process_fontcache(STREAM s)  static void
846    process_fontcache(STREAM s)
847  {  {
848          HGLYPH bitmap;          HGLYPH bitmap;
849          uint8 font, nglyphs;          uint8 font, nglyphs;
850          uint16 character, baseline, width, height;          uint16 character, offset, baseline, width, height;
851          uint8 *data, *rev_data, in, out;          int i, datasize;
852          int i, j, datasize;          uint8 *data;
853    
854          in_uint8(s, font);          in_uint8(s, font);
855          in_uint8(s, nglyphs);          in_uint8(s, nglyphs);
856    
857          DEBUG("FONTCACHE(font=%d,n=%d)\n", font, nglyphs);          DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
858    
859          for (i = 0; i < nglyphs; i++)          for (i = 0; i < nglyphs; i++)
860          {          {
861                  in_uint16_le(s, character);                  in_uint16_le(s, character);
862                  in_uint8s(s, 2); /* unknown */                  in_uint16_le(s, offset);
863                  in_uint16_le(s, baseline);                  in_uint16_le(s, baseline);
864                  in_uint16_le(s, width);                  in_uint16_le(s, width);
865                  in_uint16_le(s, height);                  in_uint16_le(s, height);
# Line 739  static void process_fontcache(STREAM s) Line 867  static void process_fontcache(STREAM s)
867                  datasize = (height * ((width + 7) / 8) + 3) & ~3;                  datasize = (height * ((width + 7) / 8) + 3) & ~3;
868                  in_uint8p(s, data, datasize);                  in_uint8p(s, data, datasize);
869    
870                  /* Need to reverse bit order */                  bitmap = ui_create_glyph(width, height, data);
871                  rev_data = xmalloc(datasize);                  cache_put_font(font, character, offset, baseline, width, height, bitmap);
   
                 for (j = 0; j < datasize; j++)  
                 {  
                         in = data[j];  
                         out = 0;  
                         if (in & 1) out |= 128;  
                         if (in & 2) out |= 64;  
                         if (in & 4) out |= 32;  
                         if (in & 8) out |= 16;  
                         if (in & 16) out |= 8;  
                         if (in & 32) out |= 4;  
                         if (in & 64) out |= 2;  
                         if (in & 128) out |= 1;  
                         rev_data[j] = out;  
                 }  
   
                 bitmap = ui_create_glyph(width, height, rev_data);  
                 xfree(rev_data);  
   
                 cache_put_font(font, character, baseline, width, height, bitmap);  
872          }          }
873  }  }
874    
875  /* Process a secondary order */  /* Process a secondary order */
876  static void process_secondary_order(STREAM s)  static void
877    process_secondary_order(STREAM s)
878  {  {
879            /* The length isn't calculated correctly by the server.
880             * For very compact orders the length becomes negative
881             * so a signed integer must be used. */
882          uint16 length;          uint16 length;
883            uint16 flags;
884          uint8 type;          uint8 type;
885          uint8 *next_order;          uint8 *next_order;
886    
887          in_uint16_le(s, length);          in_uint16_le(s, length);
888          in_uint8s(s, 2); /* flags */          in_uint16_le(s, flags); /* used by bmpcache2 */
889          in_uint8(s, type);          in_uint8(s, type);
890    
891          next_order = s->p + length + 7;          next_order = s->p + (sint16) length + 7;
892    
893          switch (type)          switch (type)
894          {          {
# Line 795  static void process_secondary_order(STRE Line 908  static void process_secondary_order(STRE
908                          process_fontcache(s);                          process_fontcache(s);
909                          break;                          break;
910    
911                    case RDP_ORDER_RAW_BMPCACHE2:
912                            process_bmpcache2(s, flags, False);     /* uncompressed */
913                            break;
914    
915                    case RDP_ORDER_BMPCACHE2:
916                            process_bmpcache2(s, flags, True);      /* compressed */
917                            break;
918    
919                  default:                  default:
920                          NOTIMP("secondary order %d\n", type);                          unimpl("secondary order %d\n", type);
921          }          }
922    
923          s->p = next_order;          s->p = next_order;
924  }  }
925    
926  /* Process an order PDU */  /* Process an order PDU */
927  void process_orders(STREAM s)  void
928    process_orders(STREAM s, uint16 num_orders)
929  {  {
930          RDP_ORDER_STATE *os = &order_state;          RDP_ORDER_STATE *os = &g_order_state;
931          uint32 present;          uint32 present;
         uint16 num_orders;  
932          uint8 order_flags;          uint8 order_flags;
933          int size, processed = 0;          int size, processed = 0;
934          BOOL delta;          BOOL delta;
935    
         in_uint8s(s, 2); /* pad */  
         in_uint16_le(s, num_orders);  
         in_uint8s(s, 2); /* pad */  
   
936          while (processed < num_orders)          while (processed < num_orders)
937          {          {
938                  in_uint8(s, order_flags);                  in_uint8(s, order_flags);
939    
940                  if (!(order_flags & RDP_ORDER_STANDARD))                  if (!(order_flags & RDP_ORDER_STANDARD))
941                  {                  {
942                          ERROR("order parsing failed\n");                          error("order parsing failed\n");
943                          break;                          break;
944                  }                  }
945    
# Line 862  void process_orders(STREAM s) Line 979  void process_orders(STREAM s)
979                                          rdp_parse_bounds(s, &os->bounds);                                          rdp_parse_bounds(s, &os->bounds);
980    
981                                  ui_set_clip(os->bounds.left,                                  ui_set_clip(os->bounds.left,
982                                          os->bounds.top,                                              os->bounds.top,
983                                          os->bounds.right - os->bounds.left + 1,                                              os->bounds.right -
984                                          os->bounds.bottom - os->bounds.top + 1);                                              os->bounds.left + 1,
985                                                os->bounds.bottom - os->bounds.top + 1);
986                          }                          }
987    
988                          delta = order_flags & RDP_ORDER_DELTA;                          delta = order_flags & RDP_ORDER_DELTA;
# Line 872  void process_orders(STREAM s) Line 990  void process_orders(STREAM s)
990                          switch (os->order_type)                          switch (os->order_type)
991                          {                          {
992                                  case RDP_ORDER_DESTBLT:                                  case RDP_ORDER_DESTBLT:
993                                          process_destblt(s, &os->destblt,                                          process_destblt(s, &os->destblt, present, delta);
                                                         present, delta);  
994                                          break;                                          break;
995    
996                                  case RDP_ORDER_PATBLT:                                  case RDP_ORDER_PATBLT:
997                                          process_patblt(s, &os->patblt,                                          process_patblt(s, &os->patblt, present, delta);
                                                        present, delta);  
998                                          break;                                          break;
999    
1000                                  case RDP_ORDER_SCREENBLT:                                  case RDP_ORDER_SCREENBLT:
1001                                          process_screenblt(s, &os->screenblt,                                          process_screenblt(s, &os->screenblt, present, delta);
                                                           present, delta);  
1002                                          break;                                          break;
1003    
1004                                  case RDP_ORDER_LINE:                                  case RDP_ORDER_LINE:
1005                                          process_line(s, &os->line,                                          process_line(s, &os->line, present, delta);
                                                         present, delta);  
1006                                          break;                                          break;
1007    
1008                                  case RDP_ORDER_RECT:                                  case RDP_ORDER_RECT:
1009                                          process_rect(s, &os->rect,                                          process_rect(s, &os->rect, present, delta);
                                                      present, delta);  
1010                                          break;                                          break;
1011    
1012                                  case RDP_ORDER_DESKSAVE:                                  case RDP_ORDER_DESKSAVE:
1013                                          process_desksave(s, &os->desksave,                                          process_desksave(s, &os->desksave, present, delta);
                                                          present, delta);  
1014                                          break;                                          break;
1015    
1016                                  case RDP_ORDER_MEMBLT:                                  case RDP_ORDER_MEMBLT:
1017                                          process_memblt(s, &os->memblt,                                          process_memblt(s, &os->memblt, present, delta);
                                                        present, delta);  
1018                                          break;                                          break;
1019    
1020                                  case RDP_ORDER_TRIBLT:                                  case RDP_ORDER_TRIBLT:
1021                                          process_triblt(s, &os->triblt,                                          process_triblt(s, &os->triblt, present, delta);
                                                        present, delta);  
1022                                          break;                                          break;
1023    
1024                                  case RDP_ORDER_POLYLINE:                                  case RDP_ORDER_POLYLINE:
1025                                          process_polyline(s, &os->polyline,                                          process_polyline(s, &os->polyline, present, delta);
                                                          present, delta);  
1026                                          break;                                          break;
1027    
1028                                  case RDP_ORDER_TEXT2:                                  case RDP_ORDER_TEXT2:
1029                                          process_text2(s, &os->text2,                                          process_text2(s, &os->text2, present, delta);
                                                       present, delta);  
1030                                          break;                                          break;
1031    
1032                                  default:                                  default:
1033                                          NOTIMP("order %d\n", os->order_type);                                          unimpl("order %d\n", os->order_type);
1034                                          return;                                          return;
1035                          }                          }
1036    
# Line 932  void process_orders(STREAM s) Line 1040  void process_orders(STREAM s)
1040    
1041                  processed++;                  processed++;
1042          }          }
1043    #if 0
1044            /* not true when RDP_COMPRESSION is set */
1045            if (s->p != g_next_packet)
1046                    error("%d bytes remaining\n", (int) (g_next_packet - s->p));
1047    #endif
1048    
         if (s->p != next_packet)  
                 WARN("%d bytes remaining\n", (int)(next_packet - s->p));  
1049  }  }
1050    
1051  /* Reset order state */  /* Reset order state */
1052  void reset_order_state()  void
1053    reset_order_state(void)
1054  {  {
1055          memset(&order_state, 0, sizeof(order_state));          memset(&g_order_state, 0, sizeof(g_order_state));
1056            g_order_state.order_type = RDP_ORDER_PATBLT;
1057  }  }
   

Legend:
Removed from v.15  
changed lines
  Added in v.738

  ViewVC Help
Powered by ViewVC 1.1.26