mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: add server-side Memblt and CacheGlyph
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user