libfreerdp-core: add server-side Memblt and CacheGlyph

This commit is contained in:
Marc-André Moreau
2013-05-07 11:41:32 -04:00
parent e048147bde
commit 230380184d
3 changed files with 180 additions and 11 deletions

View File

@@ -271,13 +271,14 @@ static INLINE BOOL update_write_2byte_unsigned(wStream* s, UINT32 value)
if (value >= 0x7F)
{
byte = ((value & 0x7F00) >> 8);
stream_write_BYTE(s, byte);
stream_write_BYTE(s, byte | 0x80);
byte = (value & 0xFF);
stream_write_BYTE(s, byte);
}
else
{
stream_write_BYTE(s, value);
byte = (value & 0x7F);
stream_write_BYTE(s, byte);
}
return TRUE;
@@ -301,12 +302,52 @@ static INLINE BOOL update_read_2byte_signed(wStream* s, INT32* value)
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
stream_read_BYTE(s, byte);
*value = (*value << 8) | byte;
}
if (negative)
*value *= -1;
return TRUE;
}
static INLINE BOOL update_write_2byte_signed(wStream* s, INT32 value)
{
BYTE byte;
BOOL negative = FALSE;
if (value < 0)
{
negative = TRUE;
value *= -1;
}
if (value > 0x3FFF)
return FALSE;
if (value >= 0x3F)
{
byte = ((value & 0x3F00) >> 8);
if (negative)
byte |= 0x40;
stream_write_BYTE(s, byte | 0x80);
byte = (value & 0xFF);
stream_write_BYTE(s, byte);
}
else
{
byte = (value & 0x3F);
if (negative)
byte |= 0x40;
stream_write_BYTE(s, byte);
}
return TRUE;
}
@@ -968,6 +1009,43 @@ BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* m
memblt->colorIndex = (memblt->cacheId >> 8);
memblt->cacheId = (memblt->cacheId & 0xFF);
return TRUE;
}
BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt)
{
UINT16 cacheId;
cacheId = (memblt->cacheId & 0xFF) | ((memblt->colorIndex & 0xFF) << 8);
orderInfo->fieldFlags |= ORDER_FIELD_01;
stream_write_UINT16(s, memblt->cacheId);
orderInfo->fieldFlags |= ORDER_FIELD_02;
update_write_coord(s, memblt->nLeftRect);
orderInfo->fieldFlags |= ORDER_FIELD_03;
update_write_coord(s, memblt->nTopRect);
orderInfo->fieldFlags |= ORDER_FIELD_04;
update_write_coord(s, memblt->nWidth);
orderInfo->fieldFlags |= ORDER_FIELD_05;
update_write_coord(s, memblt->nHeight);
orderInfo->fieldFlags |= ORDER_FIELD_06;
stream_write_BYTE(s, memblt->bRop);
orderInfo->fieldFlags |= ORDER_FIELD_07;
update_write_coord(s, memblt->nXSrc);
orderInfo->fieldFlags |= ORDER_FIELD_08;
update_write_coord(s, memblt->nYSrc);
orderInfo->fieldFlags |= ORDER_FIELD_09;
stream_write_UINT16(s, memblt->cacheIndex);
return TRUE;
}
@@ -1506,18 +1584,18 @@ BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_or
return TRUE;
}
BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, UINT16 flags)
BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16 flags)
{
int i;
GLYPH_DATA_V2* glyph;
cache_glyph_v2_order->cacheId = (flags & 0x000F);
cache_glyph_v2_order->flags = (flags & 0x00F0) >> 4;
cache_glyph_v2_order->cGlyphs = (flags & 0xFF00) >> 8;
cache_glyph_v2->cacheId = (flags & 0x000F);
cache_glyph_v2->flags = (flags & 0x00F0) >> 4;
cache_glyph_v2->cGlyphs = (flags & 0xFF00) >> 8;
for (i = 0; i < (int) cache_glyph_v2_order->cGlyphs; i++)
for (i = 0; i < (int) cache_glyph_v2->cGlyphs; i++)
{
glyph = &cache_glyph_v2_order->glyphData[i];
glyph = &cache_glyph_v2->glyphData[i];
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
@@ -1544,7 +1622,43 @@ BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_gl
if (flags & CG_GLYPH_UNICODE_PRESENT)
{
return stream_skip(s, cache_glyph_v2_order->cGlyphs * 2);
return stream_skip(s, cache_glyph_v2->cGlyphs * 2);
}
return TRUE;
}
BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags)
{
int i;
GLYPH_DATA_V2* glyph;
*flags = (cache_glyph_v2->cacheId & 0x000F) |
((cache_glyph_v2->flags & 0x000F) << 4) |
((cache_glyph_v2->cGlyphs & 0x00FF) << 8);
for (i = 0; i < (int) cache_glyph_v2->cGlyphs; i++)
{
glyph = &cache_glyph_v2->glyphData[i];
stream_write_BYTE(s, glyph->cacheIndex);
if (!update_write_2byte_signed(s, glyph->x) ||
!update_write_2byte_signed(s, glyph->y) ||
!update_write_2byte_unsigned(s, glyph->cx) ||
!update_write_2byte_unsigned(s, glyph->cy))
{
return FALSE;
}
glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy;
glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0;
stream_write(s, glyph->aj, glyph->cb);
}
if (*flags & CG_GLYPH_UNICODE_PRESENT)
{
Stream_Zero(s, cache_glyph_v2->cGlyphs * 2);
}
return TRUE;

View File

@@ -202,6 +202,7 @@ BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, M
BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to);
BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline);
BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt);
BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt);
BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt);
BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap);
BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index);
@@ -219,6 +220,7 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_
BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16 flags);
BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16 flags);
BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, UINT16 flags);
BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags);
BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16 flags);
BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap);

View File

@@ -619,6 +619,31 @@ static void update_send_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaq
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s);
}
static void update_send_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
{
wStream* s;
BYTE *bm, *em;
ORDER_INFO orderInfo;
rdpRdp* rdp = context->rdp;
orderInfo.fieldFlags = 0;
s = fastpath_update_pdu_init(rdp->fastpath);
bm = Stream_Pointer(s);
Stream_Seek(s, 5);
update_write_memblt_order(s, &orderInfo, memblt);
em = Stream_Pointer(s);
Stream_Pointer(s) = bm;
stream_write_UINT16(s, 1); /* numberOrders (2 bytes) */
stream_write_BYTE(s, ORDER_STANDARD | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */
stream_write_BYTE(s, ORDER_TYPE_MEMBLT); /* orderType (1 byte) */
stream_write_BYTE(s, orderInfo.fieldFlags); /* fieldFlags (variable) */
Stream_Pointer(s) = em;
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s);
}
static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
{
wStream* s;
@@ -637,14 +662,40 @@ static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORD
Stream_Pointer(s) = bm;
stream_write_UINT16(s, 1); /* numberOrders (2 bytes) */
stream_write_BYTE(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */
stream_write_UINT16(s, 0); /* orderLength (2 bytes) */
stream_write_UINT16(s, 0); /* extraFlags (2 bytes) */
stream_write_UINT16(s, (em - bm) - 13); /* orderLength (2 bytes) */
stream_write_UINT16(s, flags); /* extraFlags (2 bytes) */
stream_write_BYTE(s, ORDER_TYPE_BITMAP_UNCOMPRESSED_V2); /* orderType (1 byte) */
Stream_Pointer(s) = em;
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s);
}
static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_glyph_v2)
{
wStream* s;
UINT16 flags;
BYTE *bm, *em;
rdpRdp* rdp = context->rdp;
flags = 0;
s = fastpath_update_pdu_init(rdp->fastpath);
bm = Stream_Pointer(s);
Stream_Seek(s, 8);
update_write_cache_glyph_v2_order(s, cache_glyph_v2, &flags);
em = Stream_Pointer(s);
Stream_Pointer(s) = bm;
stream_write_UINT16(s, 1); /* numberOrders (2 bytes) */
stream_write_BYTE(s, ORDER_STANDARD | ORDER_SECONDARY | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */
stream_write_UINT16(s, (em - bm) - 13); /* orderLength (2 bytes) */
stream_write_UINT16(s, flags); /* extraFlags (2 bytes) */
stream_write_BYTE(s, ORDER_TYPE_CACHE_GLYPH); /* orderType (1 byte) */
Stream_Pointer(s) = em;
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s);
}
static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system)
{
wStream* s;
@@ -775,7 +826,9 @@ void update_register_server_callbacks(rdpUpdate* update)
update->SurfaceCommand = update_send_surface_command;
update->primary->ScrBlt = update_send_scrblt;
update->primary->OpaqueRect = update_send_opaque_rect;
update->primary->MemBlt = update_send_memblt;
update->secondary->CacheBitmapV2 = update_send_cache_bitmap_v2;
update->secondary->CacheGlyphV2 = update_send_cache_glyph_v2;
update->pointer->PointerSystem = update_send_pointer_system;
update->pointer->PointerColor = update_send_pointer_color;
update->pointer->PointerNew = update_send_pointer_new;