📄 orders.c
字号:
os->boxright - os->boxleft, os->boxbottom - os->boxtop,
&os->brush, os->bgcolour, os->fgcolour, os->text, os->length);
#endif
}
/* Process a raw bitmap cache order */
static void
process_raw_bmpcache(RDPCLIENT * This, STREAM s)
{
HBITMAP bitmap;
uint16 cache_idx, bufsize;
uint8 cache_id, width, height, bpp, Bpp;
uint8 *data;
in_uint8(s, cache_id);
in_uint8s(s, 1); /* pad */
in_uint8(s, width);
in_uint8(s, height);
in_uint8(s, bpp);
Bpp = (bpp + 7) / 8;
in_uint16_le(s, bufsize);
in_uint16_le(s, cache_idx);
in_uint8p(s, data, bufsize);
DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
#if 0
inverted = (uint8 *) xmalloc(width * height * Bpp);
for (y = 0; y < height; y++)
{
memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
width * Bpp);
}
#endif
#if 0
bitmap = ui_create_bitmap(This, width, height, inverted);
xfree(inverted);
#else
bitmap = ui_create_bitmap(This, width, height, data);
#endif
cache_put_bitmap(This, cache_id, cache_idx, bitmap);
}
/* Process a bitmap cache order */
static void
process_bmpcache(RDPCLIENT * This, STREAM s)
{
HBITMAP bitmap;
uint16 cache_idx, size;
uint8 cache_id, width, height, bpp, Bpp;
uint8 *data, *bmpdata;
uint16 bufsize, pad2, row_size, final_size;
uint8 pad1;
pad2 = row_size = final_size = 0xffff; /* Shut the compiler up */
in_uint8(s, cache_id);
in_uint8(s, pad1); /* pad */
in_uint8(s, width);
in_uint8(s, height);
in_uint8(s, bpp);
Bpp = (bpp + 7) / 8;
in_uint16_le(s, bufsize); /* bufsize */
in_uint16_le(s, cache_idx);
if (This->use_rdp5)
{
size = bufsize;
}
else
{
/* Begin compressedBitmapData */
in_uint16_le(s, pad2); /* pad */
in_uint16_le(s, size);
/* in_uint8s(s, 4); *//* row_size, final_size */
in_uint16_le(s, row_size);
in_uint16_le(s, final_size);
}
in_uint8p(s, data, size);
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));
bmpdata = (uint8 *) malloc(width * height * Bpp);
if(bmpdata == NULL)
return;
if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
{
bitmap = ui_create_bitmap(This, width, height, bmpdata);
cache_put_bitmap(This, cache_id, cache_idx, bitmap);
}
else
{
DEBUG(("Failed to decompress bitmap data\n"));
}
free(bmpdata);
}
/* Process a bitmap cache v2 order */
static void
process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed)
{
HBITMAP bitmap;
uint8 cache_id, cache_idx_low, width, height, Bpp;
uint16 cache_idx, bufsize;
uint8 *data, *bmpdata, *bitmap_id;
bitmap_id = NULL; /* prevent compiler warning */
cache_id = flags & ID_MASK;
Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
if (flags & PERSIST)
{
in_uint8p(s, bitmap_id, 8);
}
if (flags & SQUARE)
{
in_uint8(s, width);
height = width;
}
else
{
in_uint8(s, width);
in_uint8(s, height);
}
in_uint16_be(s, bufsize);
bufsize &= BUFSIZE_MASK;
in_uint8(s, cache_idx);
if (cache_idx & LONG_FORMAT)
{
in_uint8(s, cache_idx_low);
cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
}
in_uint8p(s, data, bufsize);
DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
if (compressed)
{
bmpdata = (uint8 *) malloc(width * height * Bpp);
if(bmpdata == NULL)
return;
if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
{
DEBUG(("Failed to decompress bitmap data\n"));
free(bmpdata);
return;
}
}
else
{
#if 0
for (y = 0; y < height; y++)
memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
&data[y * (width * Bpp)], width * Bpp);
#else
bmpdata = data;
#endif
}
bitmap = ui_create_bitmap(This, width, height, bmpdata);
if (bitmap)
{
cache_put_bitmap(This, cache_id, cache_idx, bitmap);
if (flags & PERSIST)
pstcache_save_bitmap(This, cache_id, cache_idx, bitmap_id, width, height,
width * height * Bpp, bmpdata);
}
else
{
DEBUG(("process_bmpcache2: ui_create_bitmap failed\n"));
}
if (compressed)
free(bmpdata);
}
/* Process a colourmap cache order */
static void
process_colcache(RDPCLIENT * This, STREAM s)
{
COLOURENTRY *entry;
COLOURMAP map;
HCOLOURMAP hmap;
uint8 cache_id;
int i;
in_uint8(s, cache_id);
in_uint16_le(s, map.ncolours);
map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours);
if(map.colours == NULL)
{
in_uint8s(s, map.ncolours * 4);
return;
}
for (i = 0; i < map.ncolours; i++)
{
entry = &map.colours[i];
in_uint8(s, entry->blue);
in_uint8(s, entry->green);
in_uint8(s, entry->red);
in_uint8s(s, 1); /* pad */
}
DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
hmap = ui_create_colourmap(This, &map);
if (cache_id)
ui_set_colourmap(This, hmap);
free(map.colours);
}
/* Process a font cache order */
static void
process_fontcache(RDPCLIENT * This, STREAM s)
{
HGLYPH bitmap;
uint8 font, nglyphs;
uint16 character, offset, baseline, width, height;
int i, datasize;
uint8 *data;
in_uint8(s, font);
in_uint8(s, nglyphs);
DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
for (i = 0; i < nglyphs; i++)
{
in_uint16_le(s, character);
in_uint16_le(s, offset);
in_uint16_le(s, baseline);
in_uint16_le(s, width);
in_uint16_le(s, height);
datasize = (height * ((width + 7) / 8) + 3) & ~3;
in_uint8p(s, data, datasize);
bitmap = ui_create_glyph(This, width, height, data);
cache_put_font(This, font, character, offset, baseline, width, height, bitmap);
}
}
/* Process a secondary order */
static void
process_secondary_order(RDPCLIENT * This, STREAM s)
{
/* The length isn't calculated correctly by the server.
* For very compact orders the length becomes negative
* so a signed integer must be used. */
uint16 length;
uint16 flags;
uint8 type;
uint8 *next_order;
in_uint16_le(s, length);
in_uint16_le(s, flags); /* used by bmpcache2 */
in_uint8(s, type);
next_order = s->p + (sint16) length + 7;
switch (type)
{
case RDP_ORDER_RAW_BMPCACHE:
process_raw_bmpcache(This, s);
break;
case RDP_ORDER_COLCACHE:
process_colcache(This, s);
break;
case RDP_ORDER_BMPCACHE:
process_bmpcache(This, s);
break;
case RDP_ORDER_FONTCACHE:
process_fontcache(This, s);
break;
case RDP_ORDER_RAW_BMPCACHE2:
process_bmpcache2(This, s, flags, False); /* uncompressed */
break;
case RDP_ORDER_BMPCACHE2:
process_bmpcache2(This, s, flags, True); /* compressed */
break;
default:
unimpl("secondary order %d\n", type);
}
s->p = next_order;
}
/* Process an order PDU */
void
process_orders(RDPCLIENT * This, STREAM s, uint16 num_orders)
{
RDP_ORDER_STATE *os = &This->orders.order_state;
uint32 present;
uint8 order_flags;
int size, processed = 0;
BOOL delta;
while (processed < num_orders)
{
in_uint8(s, order_flags);
if (!(order_flags & RDP_ORDER_STANDARD))
{
error("order parsing failed\n");
break;
}
if (order_flags & RDP_ORDER_SECONDARY)
{
process_secondary_order(This, s);
}
else
{
if (order_flags & RDP_ORDER_CHANGE)
{
in_uint8(s, os->order_type);
}
switch (os->order_type)
{
case RDP_ORDER_TRIBLT:
case RDP_ORDER_TEXT2:
size = 3;
break;
case RDP_ORDER_PATBLT:
case RDP_ORDER_MEMBLT:
case RDP_ORDER_LINE:
case RDP_ORDER_POLYGON2:
case RDP_ORDER_ELLIPSE2:
size = 2;
break;
default:
size = 1;
}
rdp_in_present(s, &present, order_flags, size);
if (order_flags & RDP_ORDER_BOUNDS)
{
if (!(order_flags & RDP_ORDER_LASTBOUNDS))
rdp_parse_bounds(s, &os->bounds);
ui_set_clip(This, os->bounds.left,
os->bounds.top,
os->bounds.right -
os->bounds.left + 1,
os->bounds.bottom - os->bounds.top + 1);
}
delta = order_flags & RDP_ORDER_DELTA;
switch (os->order_type)
{
case RDP_ORDER_DESTBLT:
process_destblt(This, s, &os->destblt, present, delta);
break;
case RDP_ORDER_PATBLT:
process_patblt(This, s, &os->patblt, present, delta);
break;
case RDP_ORDER_SCREENBLT:
process_screenblt(This, s, &os->screenblt, present, delta);
break;
case RDP_ORDER_LINE:
process_line(This, s, &os->line, present, delta);
break;
case RDP_ORDER_RECT:
process_rect(This, s, &os->rect, present, delta);
break;
case RDP_ORDER_DESKSAVE:
process_desksave(This, s, &os->desksave, present, delta);
break;
case RDP_ORDER_MEMBLT:
process_memblt(This, s, &os->memblt, present, delta);
break;
case RDP_ORDER_TRIBLT:
process_triblt(This, s, &os->triblt, present, delta);
break;
case RDP_ORDER_POLYGON:
process_polygon(This, s, &os->polygon, present, delta);
break;
case RDP_ORDER_POLYGON2:
process_polygon2(This, s, &os->polygon2, present, delta);
break;
case RDP_ORDER_POLYLINE:
process_polyline(This, s, &os->polyline, present, delta);
break;
case RDP_ORDER_ELLIPSE:
process_ellipse(This, s, &os->ellipse, present, delta);
break;
case RDP_ORDER_ELLIPSE2:
process_ellipse2(This, s, &os->ellipse2, present, delta);
break;
case RDP_ORDER_TEXT2:
process_text2(This, s, &os->text2, present, delta);
break;
default:
unimpl("order %d\n", os->order_type);
return;
}
if (order_flags & RDP_ORDER_BOUNDS)
ui_reset_clip(This);
}
processed++;
}
#if 0
/* not true when RDP_COMPRESSION is set */
if (s->p != This->next_packet)
error("%d bytes remaining\n", (int) (This->next_packet - s->p));
#endif
}
/* Reset order state */
void
reset_order_state(RDPCLIENT * This)
{
memset(&This->orders.order_state, 0, sizeof(This->orders.order_state));
This->orders.order_state.order_type = RDP_ORDER_PATBLT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -