diff --git a/channels/rdpgfx/client/rdpgfx_common.c b/channels/rdpgfx/client/rdpgfx_common.c index f37864e32..fde1f9325 100644 --- a/channels/rdpgfx/client/rdpgfx_common.c +++ b/channels/rdpgfx/client/rdpgfx_common.c @@ -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) */ diff --git a/channels/rdpgfx/client/rdpgfx_common.h b/channels/rdpgfx/client/rdpgfx_common.h index fcb39d9bc..d2b1ea1d4 100644 --- a/channels/rdpgfx/client/rdpgfx_common.h +++ b/channels/rdpgfx/client/rdpgfx_common.h @@ -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); diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 54222d710..7197e5f4c 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -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); diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 2a94b74d2..a014425b1 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -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: diff --git a/include/freerdp/channels/rdpgfx.h b/include/freerdp/channels/rdpgfx.h index 63c374153..e4070194b 100644 --- a/include/freerdp/channels/rdpgfx.h +++ b/include/freerdp/channels/rdpgfx.h @@ -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;