libfreerdp-core: add support for server-side bitmap updates

This commit is contained in:
Marc-André Moreau 2013-08-07 21:47:03 -04:00
parent e31b9b7709
commit 8ca74a2766
2 changed files with 110 additions and 36 deletions

View File

@ -178,7 +178,7 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
switch (updateType)
{
case UPDATE_TYPE_BITMAP:
if (!update_read_bitmap(update, s, &update->bitmap_update))
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
return FALSE;
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
break;

View File

@ -68,80 +68,139 @@ BOOL update_recv_orders(rdpUpdate* update, wStream* s)
return TRUE;
}
BOOL update_read_bitmap_data(wStream* s, BITMAP_DATA* bitmap_data)
BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData)
{
if (Stream_GetRemainingLength(s) < 18)
return FALSE;
Stream_Read_UINT16(s, bitmap_data->destLeft);
Stream_Read_UINT16(s, bitmap_data->destTop);
Stream_Read_UINT16(s, bitmap_data->destRight);
Stream_Read_UINT16(s, bitmap_data->destBottom);
Stream_Read_UINT16(s, bitmap_data->width);
Stream_Read_UINT16(s, bitmap_data->height);
Stream_Read_UINT16(s, bitmap_data->bitsPerPixel);
Stream_Read_UINT16(s, bitmap_data->flags);
Stream_Read_UINT16(s, bitmap_data->bitmapLength);
Stream_Read_UINT16(s, bitmapData->destLeft);
Stream_Read_UINT16(s, bitmapData->destTop);
Stream_Read_UINT16(s, bitmapData->destRight);
Stream_Read_UINT16(s, bitmapData->destBottom);
Stream_Read_UINT16(s, bitmapData->width);
Stream_Read_UINT16(s, bitmapData->height);
Stream_Read_UINT16(s, bitmapData->bitsPerPixel);
Stream_Read_UINT16(s, bitmapData->flags);
Stream_Read_UINT16(s, bitmapData->bitmapLength);
if (bitmap_data->flags & BITMAP_COMPRESSION)
if (bitmapData->flags & BITMAP_COMPRESSION)
{
if (!(bitmap_data->flags & NO_BITMAP_COMPRESSION_HDR))
if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))
{
Stream_Read_UINT16(s, bitmap_data->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
Stream_Read_UINT16(s, bitmap_data->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
Stream_Read_UINT16(s, bitmap_data->cbScanWidth); /* cbScanWidth (2 bytes) */
Stream_Read_UINT16(s, bitmap_data->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
bitmap_data->bitmapLength = bitmap_data->cbCompMainBodySize;
Stream_Read_UINT16(s, bitmapData->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
Stream_Read_UINT16(s, bitmapData->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
Stream_Read_UINT16(s, bitmapData->cbScanWidth); /* cbScanWidth (2 bytes) */
Stream_Read_UINT16(s, bitmapData->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
bitmapData->bitmapLength = bitmapData->cbCompMainBodySize;
}
bitmap_data->compressed = TRUE;
Stream_GetPointer(s, bitmap_data->bitmapDataStream);
Stream_Seek(s, bitmap_data->bitmapLength);
bitmapData->compressed = TRUE;
Stream_GetPointer(s, bitmapData->bitmapDataStream);
Stream_Seek(s, bitmapData->bitmapLength);
}
else
{
if (Stream_GetRemainingLength(s) < bitmap_data->bitmapLength)
if (Stream_GetRemainingLength(s) < bitmapData->bitmapLength)
return FALSE;
bitmap_data->compressed = FALSE;
Stream_GetPointer(s, bitmap_data->bitmapDataStream);
Stream_Seek(s, bitmap_data->bitmapLength);
bitmapData->compressed = FALSE;
Stream_GetPointer(s, bitmapData->bitmapDataStream);
Stream_Seek(s, bitmapData->bitmapLength);
}
return TRUE;
}
BOOL update_read_bitmap(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmap_update)
BOOL update_write_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData)
{
Stream_EnsureRemainingCapacity(s, 64 + bitmapData->bitmapLength);
Stream_Write_UINT16(s, bitmapData->destLeft);
Stream_Write_UINT16(s, bitmapData->destTop);
Stream_Write_UINT16(s, bitmapData->destRight);
Stream_Write_UINT16(s, bitmapData->destBottom);
Stream_Write_UINT16(s, bitmapData->width);
Stream_Write_UINT16(s, bitmapData->height);
Stream_Write_UINT16(s, bitmapData->bitsPerPixel);
Stream_Write_UINT16(s, bitmapData->flags);
Stream_Write_UINT16(s, bitmapData->bitmapLength);
if (bitmapData->compressed)
bitmapData->flags |= BITMAP_COMPRESSION;
if (update->context->settings->NoBitmapCompressionHeader)
bitmapData->flags |= NO_BITMAP_COMPRESSION_HDR;
if (bitmapData->flags & BITMAP_COMPRESSION)
{
if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))
{
Stream_Write_UINT16(s, bitmapData->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
Stream_Write_UINT16(s, bitmapData->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
Stream_Write_UINT16(s, bitmapData->cbScanWidth); /* cbScanWidth (2 bytes) */
Stream_Write_UINT16(s, bitmapData->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
}
Stream_Write(s, bitmapData->bitmapDataStream, bitmapData->bitmapLength);
}
else
{
Stream_Write(s, bitmapData->bitmapDataStream, bitmapData->bitmapLength);
}
return TRUE;
}
BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate)
{
int i;
if (Stream_GetRemainingLength(s) < 2)
return FALSE;
Stream_Read_UINT16(s, bitmap_update->number); /* numberRectangles (2 bytes) */
Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
if (bitmap_update->number > bitmap_update->count)
if (bitmapUpdate->number > bitmapUpdate->count)
{
UINT16 count;
count = bitmap_update->number * 2;
count = bitmapUpdate->number * 2;
bitmap_update->rectangles = (BITMAP_DATA*) realloc(bitmap_update->rectangles,
bitmapUpdate->rectangles = (BITMAP_DATA*) realloc(bitmapUpdate->rectangles,
sizeof(BITMAP_DATA) * count);
memset(&bitmap_update->rectangles[bitmap_update->count], 0,
sizeof(BITMAP_DATA) * (count - bitmap_update->count));
memset(&bitmapUpdate->rectangles[bitmapUpdate->count], 0,
sizeof(BITMAP_DATA) * (count - bitmapUpdate->count));
bitmap_update->count = count;
bitmapUpdate->count = count;
}
/* rectangles */
for (i = 0; i < (int) bitmap_update->number; i++)
for (i = 0; i < (int) bitmapUpdate->number; i++)
{
if (!update_read_bitmap_data(s, &bitmap_update->rectangles[i]))
if (!update_read_bitmap_data(update, s, &bitmapUpdate->rectangles[i]))
return FALSE;
}
return TRUE;
}
BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate)
{
int i;
Stream_EnsureRemainingCapacity(s, 32);
Stream_Write_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
/* rectangles */
for (i = 0; i < (int) bitmapUpdate->number; i++)
{
if (!update_write_bitmap_data(update, s, &bitmapUpdate->rectangles[i]))
return FALSE;
}
return TRUE;
}
BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_update)
{
int i;
@ -369,7 +428,7 @@ BOOL update_recv(rdpUpdate* update, wStream* s)
break;
case UPDATE_TYPE_BITMAP:
if (!update_read_bitmap(update, s, &update->bitmap_update))
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
return FALSE;
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
break;
@ -793,6 +852,20 @@ static void update_send_desktop_resize(rdpContext* context)
rdp_server_reactivate(context->rdp);
}
static void update_send_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
wStream* s;
rdpRdp* rdp = context->rdp;
rdpUpdate* update = context->update;
s = fastpath_update_pdu_init(rdp->fastpath);
update_write_bitmap_update(update, s, bitmapUpdate);
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_BITMAP, s);
Stream_Release(s);
}
/**
* Primary Drawing Orders
*/
@ -1423,6 +1496,7 @@ void update_register_server_callbacks(rdpUpdate* update)
update->SetBounds = update_set_bounds;
update->Synchronize = update_send_synchronize;
update->DesktopResize = update_send_desktop_resize;
update->BitmapUpdate = update_send_bitmap_update;
update->SurfaceBits = update_send_surface_bits;
update->SurfaceFrameMarker = update_send_surface_frame_marker;
update->SurfaceCommand = update_send_surface_command;