mirror of https://github.com/FreeRDP/FreeRDP
channels/rdpgfx: fix parsing of pdus in an array
This commit is contained in:
parent
eda172c894
commit
f194a7b156
|
@ -139,11 +139,6 @@ int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void rdpgfx_copy_rect16(RDPGFX_RECT16* dst, RDPGFX_RECT16* src)
|
||||
{
|
||||
CopyMemory(dst, src, sizeof(RDPGFX_RECT16));
|
||||
}
|
||||
|
||||
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32)
|
||||
{
|
||||
Stream_Read_UINT8(s, color32->B); /* B (1 byte) */
|
||||
|
|
|
@ -36,7 +36,6 @@ int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16);
|
|||
|
||||
int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16);
|
||||
int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16);
|
||||
void rdpgfx_copy_rect16(RDPGFX_RECT16* dst, RDPGFX_RECT16* src);
|
||||
|
||||
int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32);
|
||||
int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32);
|
||||
|
|
|
@ -63,7 +63,7 @@ int rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
|
|||
header.flags = 0;
|
||||
header.cmdId = RDPGFX_CMDID_CAPSADVERTISE;
|
||||
|
||||
pdu.capsSetCount = 2;
|
||||
pdu.capsSetCount = 1;
|
||||
pdu.capsSets = (RDPGFX_CAPSET*) capsSets;
|
||||
|
||||
capsSet = &capsSets[0];
|
||||
|
@ -172,6 +172,7 @@ int rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RDPGFX_
|
|||
|
||||
int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
int pad;
|
||||
UINT32 index;
|
||||
MONITOR_DEF* monitor;
|
||||
RDPGFX_RESET_GRAPHICS_PDU pdu;
|
||||
|
@ -197,7 +198,8 @@ int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s
|
|||
Stream_Read_UINT32(s, monitor->flags); /* flags (4 bytes) */
|
||||
}
|
||||
|
||||
/* pad (total size is 340 bytes) */
|
||||
pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20));
|
||||
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
|
||||
|
||||
fprintf(stderr, "RdpGfxRecvResetGraphicsPdu: width: %d height: %d count: %d\n",
|
||||
pdu.width, pdu.height, pdu.monitorCount);
|
||||
|
@ -367,6 +369,7 @@ int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream
|
|||
Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */
|
||||
|
||||
pdu.bitmapData = Stream_Pointer(s);
|
||||
Stream_Seek(s, pdu.bitmapDataLength);
|
||||
|
||||
fprintf(stderr, "RdpGfxRecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X "
|
||||
"destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d\n",
|
||||
|
@ -376,19 +379,22 @@ int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream
|
|||
|
||||
cmd.surfaceId = pdu.surfaceId;
|
||||
cmd.codecId = pdu.codecId;
|
||||
cmd.codecContextId = 0;
|
||||
cmd.pixelFormat = pdu.pixelFormat;
|
||||
rdpgfx_copy_rect16(&(cmd.destRect), &(pdu.destRect));
|
||||
cmd.bitmapDataLength = pdu.bitmapDataLength;
|
||||
cmd.bitmapData = pdu.bitmapData;
|
||||
cmd.contextId = 0;
|
||||
cmd.format = pdu.pixelFormat;
|
||||
cmd.left = pdu.destRect.left;
|
||||
cmd.top = pdu.destRect.top;
|
||||
cmd.right = pdu.destRect.right;
|
||||
cmd.bottom = pdu.destRect.bottom;
|
||||
cmd.width = cmd.right - cmd.left + 1;
|
||||
cmd.height = cmd.bottom - cmd.top + 1;
|
||||
cmd.length = pdu.bitmapDataLength;
|
||||
cmd.data = pdu.bitmapData;
|
||||
|
||||
if (context && context->SurfaceCommand)
|
||||
{
|
||||
context->SurfaceCommand(context, &cmd);
|
||||
}
|
||||
|
||||
rdpgfx_decode(gfx, &cmd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -407,6 +413,7 @@ int rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream
|
|||
Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */
|
||||
|
||||
pdu.bitmapData = Stream_Pointer(s);
|
||||
Stream_Seek(s, pdu.bitmapDataLength);
|
||||
|
||||
fprintf(stderr, "RdpGfxRecvWireToSurface2Pdu: surfaceId: %d codecId: 0x%04X "
|
||||
"codecContextId: %d pixelFormat: 0x%04X bitmapDataLength: %d\n",
|
||||
|
@ -414,19 +421,22 @@ int rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream
|
|||
|
||||
cmd.surfaceId = pdu.surfaceId;
|
||||
cmd.codecId = pdu.codecId;
|
||||
cmd.codecContextId = pdu.codecContextId;
|
||||
cmd.pixelFormat = pdu.pixelFormat;
|
||||
ZeroMemory(&(cmd.destRect), sizeof(RDPGFX_RECT16));
|
||||
cmd.bitmapDataLength = pdu.bitmapDataLength;
|
||||
cmd.bitmapData = pdu.bitmapData;
|
||||
cmd.contextId = pdu.codecContextId;
|
||||
cmd.format = pdu.pixelFormat;
|
||||
cmd.left = 0;
|
||||
cmd.top = 0;
|
||||
cmd.right = 0;
|
||||
cmd.bottom = 0;
|
||||
cmd.width = 0;
|
||||
cmd.height = 0;
|
||||
cmd.length = pdu.bitmapDataLength;
|
||||
cmd.data = pdu.bitmapData;
|
||||
|
||||
if (context && context->SurfaceCommand)
|
||||
{
|
||||
context->SurfaceCommand(context, &cmd);
|
||||
}
|
||||
|
||||
rdpgfx_decode(gfx, &cmd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -632,8 +642,11 @@ int rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wSt
|
|||
int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
int status;
|
||||
int beg, end;
|
||||
RDPGFX_HEADER header;
|
||||
|
||||
beg = Stream_GetPosition(s);
|
||||
|
||||
rdpgfx_read_header(s, &header);
|
||||
|
||||
#if 1
|
||||
|
@ -716,7 +729,19 @@ int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
|
|||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
end = Stream_GetPosition(s);
|
||||
|
||||
if (end != (beg + header.pduLength))
|
||||
{
|
||||
fprintf(stderr, "Unexpected pdu end: Actual: %d, Expected: %d\n",
|
||||
end, (beg + header.pduLength));
|
||||
|
||||
exit(0);
|
||||
|
||||
Stream_SetPosition(s, (beg + header.pduLength));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer)
|
||||
|
@ -740,7 +765,10 @@ static int rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
|
|||
|
||||
s = Stream_New(pDstData, DstSize);
|
||||
|
||||
status = rdpgfx_recv_pdu(callback, s);
|
||||
while (Stream_GetPosition(s) < Stream_Length(s))
|
||||
{
|
||||
status = rdpgfx_recv_pdu(callback, s);
|
||||
}
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
|
|
|
@ -67,46 +67,32 @@ int xf_EndFrame(RdpgfxClientContext* context, RDPGFX_END_FRAME_PDU* endFrame)
|
|||
int xf_SurfaceCommand_Uncompressed(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
|
||||
{
|
||||
BYTE* data;
|
||||
UINT32 width;
|
||||
UINT32 height;
|
||||
XImage* image;
|
||||
RDPGFX_RECT16* destRect;
|
||||
|
||||
destRect = &(cmd->destRect);
|
||||
|
||||
width = destRect->right - destRect->left + 1;
|
||||
height = destRect->bottom - destRect->top + 1;
|
||||
|
||||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
|
||||
|
||||
/* Validate that the data received is large enough */
|
||||
if ((width * height * 4) <= cmd->bitmapDataLength)
|
||||
data = (BYTE*) malloc(cmd->width * cmd->height * 4);
|
||||
|
||||
freerdp_image_flip(cmd->data, data, cmd->width, cmd->height, 32);
|
||||
|
||||
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0, (char*) data, cmd->width, cmd->height, 32, 0);
|
||||
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
|
||||
cmd->left, cmd->top, cmd->width, cmd->height);
|
||||
|
||||
XFree(image);
|
||||
|
||||
free(data);
|
||||
|
||||
if (!xfc->remote_app)
|
||||
{
|
||||
data = (BYTE*) malloc(width * height * 4);
|
||||
|
||||
freerdp_image_flip(cmd->bitmapData, data, width, height, 32);
|
||||
|
||||
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0, (char*) data, width, height, 32, 0);
|
||||
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
|
||||
destRect->left, destRect->top, width, height);
|
||||
|
||||
XFree(image);
|
||||
|
||||
free(data);
|
||||
|
||||
if (!xfc->remote_app)
|
||||
{
|
||||
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc,
|
||||
destRect->left, destRect->top, width, height, destRect->left, destRect->top);
|
||||
}
|
||||
|
||||
//xf_gdi_surface_update_frame(xfc, destRect->left, destRect->top, width, height);
|
||||
|
||||
XSetClipMask(xfc->display, xfc->gc, None);
|
||||
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc,
|
||||
cmd->left, cmd->top, cmd->width, cmd->height, cmd->left, cmd->top);
|
||||
}
|
||||
|
||||
XSetClipMask(xfc->display, xfc->gc, None);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -115,11 +101,8 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP
|
|||
int i, tx, ty;
|
||||
XImage* image;
|
||||
RFX_MESSAGE* message;
|
||||
RDPGFX_RECT16* destRect;
|
||||
|
||||
destRect = &(cmd->destRect);
|
||||
|
||||
message = rfx_process_message(xfc->rfx, cmd->bitmapData, cmd->bitmapDataLength);
|
||||
message = rfx_process_message(xfc->rfx, cmd->data, cmd->length);
|
||||
|
||||
if (!message)
|
||||
return -1;
|
||||
|
@ -127,18 +110,16 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP
|
|||
XSetFunction(xfc->display, xfc->gc, GXcopy);
|
||||
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
|
||||
|
||||
XSetClipRectangles(xfc->display, xfc->gc,
|
||||
destRect->left, destRect->top,
|
||||
XSetClipRectangles(xfc->display, xfc->gc, cmd->left, cmd->top,
|
||||
(XRectangle*) message->rects, message->numRects, YXBanded);
|
||||
|
||||
/* Draw the tiles to primary surface, each is 64x64. */
|
||||
for (i = 0; i < message->numTiles; i++)
|
||||
{
|
||||
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
|
||||
(char*) message->tiles[i]->data, 64, 64, 32, 0);
|
||||
|
||||
tx = message->tiles[i]->x + destRect->left;
|
||||
ty = message->tiles[i]->y + destRect->top;
|
||||
tx = message->tiles[i]->x + cmd->left;
|
||||
ty = message->tiles[i]->y + cmd->top;
|
||||
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, tx, ty, 64, 64);
|
||||
XFree(image);
|
||||
|
@ -147,12 +128,13 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP
|
|||
/* Copy the updated region from backstore to the window. */
|
||||
for (i = 0; i < message->numRects; i++)
|
||||
{
|
||||
tx = message->rects[i].x + destRect->left;
|
||||
ty = message->rects[i].y + destRect->top;
|
||||
tx = message->rects[i].x + cmd->left;
|
||||
ty = message->rects[i].y + cmd->top;
|
||||
|
||||
if (!xfc->remote_app)
|
||||
{
|
||||
XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
|
||||
XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, tx, ty,
|
||||
message->rects[i].width, message->rects[i].height, tx, ty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,8 +149,6 @@ int xf_SurfaceCommand(RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
|
|||
int status = 1;
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
|
||||
printf("xf_SurfaceCommand: context: %p xfc: %p cmd: %p\n", context, xfc, cmd);
|
||||
|
||||
switch (cmd->codecId)
|
||||
{
|
||||
case RDPGFX_CODECID_UNCOMPRESSED:
|
||||
|
|
|
@ -165,17 +165,20 @@ struct _RDPGFX_WIRE_TO_SURFACE_PDU_2
|
|||
};
|
||||
typedef struct _RDPGFX_WIRE_TO_SURFACE_PDU_2 RDPGFX_WIRE_TO_SURFACE_PDU_2;
|
||||
|
||||
/* RDPGFX_SURFACE_COMMAND encapsulates both RDPGFX_WIRE_TO_SURFACE_PDU 1/2 */
|
||||
|
||||
struct _RDPGFX_SURFACE_COMMAND
|
||||
{
|
||||
UINT16 surfaceId;
|
||||
UINT16 codecId;
|
||||
UINT32 codecContextId;
|
||||
RDPGFX_PIXELFORMAT pixelFormat;
|
||||
RDPGFX_RECT16 destRect;
|
||||
UINT32 bitmapDataLength;
|
||||
BYTE* bitmapData;
|
||||
UINT32 surfaceId;
|
||||
UINT32 codecId;
|
||||
UINT32 contextId;
|
||||
UINT32 format;
|
||||
UINT32 left;
|
||||
UINT32 top;
|
||||
UINT32 right;
|
||||
UINT32 bottom;
|
||||
UINT32 width;
|
||||
UINT32 height;
|
||||
UINT32 length;
|
||||
BYTE* data;
|
||||
};
|
||||
typedef struct _RDPGFX_SURFACE_COMMAND RDPGFX_SURFACE_COMMAND;
|
||||
|
||||
|
|
Loading…
Reference in New Issue