diff --git a/channels/rdpgfx/client/CMakeLists.txt b/channels/rdpgfx/client/CMakeLists.txt index f940d1707..dc47804ce 100644 --- a/channels/rdpgfx/client/CMakeLists.txt +++ b/channels/rdpgfx/client/CMakeLists.txt @@ -20,6 +20,8 @@ define_channel_client("rdpgfx") set(${MODULE_PREFIX}_SRCS rdpgfx_main.c rdpgfx_main.h + rdpgfx_codec.c + rdpgfx_codec.h rdpgfx_common.c rdpgfx_common.h) diff --git a/channels/rdpgfx/client/rdpgfx_codec.c b/channels/rdpgfx/client/rdpgfx_codec.c new file mode 100644 index 000000000..a749478a8 --- /dev/null +++ b/channels/rdpgfx/client/rdpgfx_codec.c @@ -0,0 +1,111 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Graphics Pipeline Extension + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "rdpgfx_codec.h" + +int rdpgfx_decode_uncompressed(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode_remotefx(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + fprintf(stderr, "RdpGfxDecodeRemoteFx\n"); + + return 1; +} + +int rdpgfx_decode_clear(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode_planar(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode_h264(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode_alpha(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode_progressive(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode_progressive_v2(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + return 1; +} + +int rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) +{ + int status; + + switch (cmd->codecId) + { + case RDPGFX_CODECID_UNCOMPRESSED: + status = rdpgfx_decode_uncompressed(gfx, cmd); + break; + + case RDPGFX_CODECID_CAVIDEO: + status = rdpgfx_decode_remotefx(gfx, cmd); + break; + + case RDPGFX_CODECID_CLEARCODEC: + status = rdpgfx_decode_clear(gfx, cmd); + break; + + case RDPGFX_CODECID_PLANAR: + status = rdpgfx_decode_planar(gfx, cmd); + break; + + case RDPGFX_CODECID_H264: + status = rdpgfx_decode_h264(gfx, cmd); + break; + + case RDPGFX_CODECID_ALPHA: + status = rdpgfx_decode_alpha(gfx, cmd); + break; + + case RDPGFX_CODECID_CAPROGRESSIVE: + status = rdpgfx_decode_progressive(gfx, cmd); + break; + + case RDPGFX_CODECID_CAPROGRESSIVE_V2: + status = rdpgfx_decode_progressive_v2(gfx, cmd); + break; + } + + return 1; +} diff --git a/channels/rdpgfx/client/rdpgfx_codec.h b/channels/rdpgfx/client/rdpgfx_codec.h new file mode 100644 index 000000000..51ff0d63f --- /dev/null +++ b/channels/rdpgfx/client/rdpgfx_codec.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Graphics Pipeline Extension + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H +#define FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H + +#include +#include + +#include + +#include "rdpgfx_main.h" + +int rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd); + +#endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H */ diff --git a/channels/rdpgfx/client/rdpgfx_common.c b/channels/rdpgfx/client/rdpgfx_common.c index c2ea76d7d..f37864e32 100644 --- a/channels/rdpgfx/client/rdpgfx_common.c +++ b/channels/rdpgfx/client/rdpgfx_common.c @@ -26,12 +26,89 @@ #include "rdpgfx_common.h" -int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* point16) +const char* RDPGFX_CMDID_STRINGS[] = { - Stream_Read_UINT16(s, point16->x); /* x (2 bytes) */ - Stream_Read_UINT16(s, point16->y); /* y (2 bytes) */ + "RDPGFX_CMDID_UNUSED_0000", + "RDPGFX_CMDID_WIRETOSURFACE_1", + "RDPGFX_CMDID_WIRETOSURFACE_2", + "RDPGFX_CMDID_DELETEENCODINGCONTEXT", + "RDPGFX_CMDID_SOLIDFILL", + "RDPGFX_CMDID_SURFACETOSURFACE", + "RDPGFX_CMDID_SURFACETOCACHE", + "RDPGFX_CMDID_CACHETOSURFACE", + "RDPGFX_CMDID_EVICTCACHEENTRY", + "RDPGFX_CMDID_CREATESURFACE", + "RDPGFX_CMDID_DELETESURFACE", + "RDPGFX_CMDID_STARTFRAME", + "RDPGFX_CMDID_ENDFRAME", + "RDPGFX_CMDID_FRAMEACKNOWLEDGE", + "RDPGFX_CMDID_RESETGRAPHICS", + "RDPGFX_CMDID_MAPSURFACETOOUTPUT", + "RDPGFX_CMDID_CACHEIMPORTOFFER", + "RDPGFX_CMDID_CACHEIMPORTREPLY", + "RDPGFX_CMDID_CAPSADVERTISE", + "RDPGFX_CMDID_CAPSCONFIRM", + "RDPGFX_CMDID_UNUSED_0014", + "RDPGFX_CMDID_MAPSURFACETOWINDOW" +}; - return 0; +const char* rdpgfx_get_cmd_id_string(UINT16 cmdId) +{ + if (cmdId <= RDPGFX_CMDID_MAPSURFACETOWINDOW) + return RDPGFX_CMDID_STRINGS[cmdId]; + else + return "RDPGFX_CMDID_UNKNOWN"; +} + +const char* rdpgfx_get_codec_id_string(UINT16 codecId) +{ + switch (codecId) + { + case RDPGFX_CODECID_UNCOMPRESSED: + return "RDPGFX_CODECID_UNCOMPRESSED"; + case RDPGFX_CODECID_CAVIDEO: + return "RDPGFX_CODECID_CAVIDEO"; + case RDPGFX_CODECID_CLEARCODEC: + return "RDPGFX_CODECID_CLEARCODEC"; + case RDPGFX_CODECID_PLANAR: + return "RDPGFX_CODECID_PLANAR"; + case RDPGFX_CODECID_H264: + return "RDPGFX_CODECID_H264"; + case RDPGFX_CODECID_ALPHA: + return "RDPGFX_CODECID_ALPHA"; + case RDPGFX_CODECID_CAPROGRESSIVE: + return "RDPGFX_CODECID_CAPROGRESSIVE"; + case RDPGFX_CODECID_CAPROGRESSIVE_V2: + return "RDPGFX_CODECID_CAPROGRESSIVE_V2"; + } + + return "RDPGFX_CODECID_UNKNOWN"; +} + +int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header) +{ + Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ + Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */ + Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ + + return 1; +} + +int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header) +{ + Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ + Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */ + Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ + + return 1; +} + +int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16) +{ + Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */ + Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */ + + return 1; } int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16) @@ -39,7 +116,7 @@ int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16) Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */ Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */ - return 0; + return 1; } int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16) @@ -49,7 +126,7 @@ int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16) Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */ Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ - return 0; + return 1; } int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16) @@ -59,7 +136,12 @@ int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16) Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */ Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ - return 0; + 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) @@ -69,7 +151,7 @@ int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) Stream_Read_UINT8(s, color32->R); /* R (1 byte) */ Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */ - return 0; + return 1; } int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32) @@ -79,23 +161,5 @@ int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32) Stream_Write_UINT8(s, color32->R); /* R (1 byte) */ Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */ - return 0; -} - -int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header) -{ - Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ - Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */ - Stream_Read_UINT16(s, header->pduLength); /* pduLength (4 bytes) */ - - return 0; -} - -int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header) -{ - Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ - Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */ - Stream_Write_UINT16(s, header->pduLength); /* pduLength (4 bytes) */ - - return 0; + return 1; } diff --git a/channels/rdpgfx/client/rdpgfx_common.h b/channels/rdpgfx/client/rdpgfx_common.h index df80c2af6..fcb39d9bc 100644 --- a/channels/rdpgfx/client/rdpgfx_common.h +++ b/channels/rdpgfx/client/rdpgfx_common.h @@ -25,14 +25,21 @@ #include -int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* point16); -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); -int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32); -int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32); +const char* rdpgfx_get_cmd_id_string(UINT16 cmdId); +const char* rdpgfx_get_codec_id_string(UINT16 codecId); + int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header); int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header); +int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16); +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); + #endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_COMMON_H */ diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index a6ba91486..7ac460577 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -2,7 +2,7 @@ * FreeRDP: A Remote Desktop Protocol Implementation * Graphics Pipeline Extension * - * Copyright 2013 Marc-Andre Moreau + * Copyright 2013-2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,157 +37,12 @@ #include #include -#include #include "rdpgfx_common.h" +#include "rdpgfx_codec.h" #include "rdpgfx_main.h" -struct _RDPGFX_CHANNEL_CALLBACK -{ - IWTSVirtualChannelCallback iface; - - IWTSPlugin* plugin; - IWTSVirtualChannelManager* channel_mgr; - IWTSVirtualChannel* channel; -}; -typedef struct _RDPGFX_CHANNEL_CALLBACK RDPGFX_CHANNEL_CALLBACK; - -struct _RDPGFX_LISTENER_CALLBACK -{ - IWTSListenerCallback iface; - - IWTSPlugin* plugin; - IWTSVirtualChannelManager* channel_mgr; - RDPGFX_CHANNEL_CALLBACK* channel_callback; -}; -typedef struct _RDPGFX_LISTENER_CALLBACK RDPGFX_LISTENER_CALLBACK; - -struct _RDPGFX_PLUGIN -{ - IWTSPlugin iface; - - IWTSListener* listener; - RDPGFX_LISTENER_CALLBACK* listener_callback; - - BOOL ThinClient; - BOOL SmallCache; - BOOL H264; - - ZGFX_CONTEXT* zgfx; - UINT32 UnacknowledgedFrames; - UINT32 TotalDecodedFrames; -}; -typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN; - -const char* RDPGFX_CMDID_STRINGS[] = -{ - "RDPGFX_CMDID_UNUSED_0000", - "RDPGFX_CMDID_WIRETOSURFACE_1", - "RDPGFX_CMDID_WIRETOSURFACE_2", - "RDPGFX_CMDID_DELETEENCODINGCONTEXT", - "RDPGFX_CMDID_SOLIDFILL", - "RDPGFX_CMDID_SURFACETOSURFACE", - "RDPGFX_CMDID_SURFACETOCACHE", - "RDPGFX_CMDID_CACHETOSURFACE", - "RDPGFX_CMDID_EVICTCACHEENTRY", - "RDPGFX_CMDID_CREATESURFACE", - "RDPGFX_CMDID_DELETESURFACE", - "RDPGFX_CMDID_STARTFRAME", - "RDPGFX_CMDID_ENDFRAME", - "RDPGFX_CMDID_FRAMEACKNOWLEDGE", - "RDPGFX_CMDID_RESETGRAPHICS", - "RDPGFX_CMDID_MAPSURFACETOOUTPUT", - "RDPGFX_CMDID_CACHEIMPORTOFFER", - "RDPGFX_CMDID_CACHEIMPORTREPLY", - "RDPGFX_CMDID_CAPSADVERTISE", - "RDPGFX_CMDID_CAPSCONFIRM", - "RDPGFX_CMDID_UNUSED_0014", - "RDPGFX_CMDID_MAPSURFACETOWINDOW" -}; - -const char* rdpgfx_get_cmdid_string(UINT16 cmdId) -{ - if (cmdId <= RDPGFX_CMDID_MAPSURFACETOWINDOW) - return RDPGFX_CMDID_STRINGS[cmdId]; - else - return "RDPGFX_CMDID_UNKNOWN"; -} - -int rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header) -{ - Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ - Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */ - Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ - - return 1; -} - -int rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header) -{ - Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ - Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */ - Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ - - return 1; -} - -int rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16) -{ - Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */ - Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */ - - return 1; -} - -int rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16) -{ - Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */ - Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */ - - return 1; -} - -int rdpgfx_read_rect16(wStream* s, RDPGFX_RECT16* rect16) -{ - Stream_Read_UINT16(s, rect16->left); /* left (2 bytes) */ - Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */ - Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */ - Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ - - return 1; -} - -int rdpgfx_write_rect16(wStream* s, RDPGFX_RECT16* rect16) -{ - Stream_Write_UINT16(s, rect16->left); /* left (2 bytes) */ - Stream_Write_UINT16(s, rect16->top); /* top (2 bytes) */ - Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */ - Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ - - return 1; -} - -int rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) -{ - Stream_Read_UINT8(s, color32->B); /* B (1 byte) */ - Stream_Read_UINT8(s, color32->G); /* G (1 byte) */ - Stream_Read_UINT8(s, color32->R); /* R (1 byte) */ - Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */ - - return 1; -} - -int rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32) -{ - Stream_Write_UINT8(s, color32->B); /* B (1 byte) */ - Stream_Write_UINT8(s, color32->G); /* G (1 byte) */ - Stream_Write_UINT8(s, color32->R); /* R (1 byte) */ - Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */ - - return 1; -} - int rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) { int status; @@ -201,9 +56,9 @@ int rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) gfx = (RDPGFX_PLUGIN*) callback->plugin; - gfx->ThinClient = FALSE; - gfx->SmallCache = TRUE; - gfx->H264 = TRUE; + gfx->ThinClient = TRUE; + gfx->SmallCache = FALSE; + gfx->H264 = FALSE; header.flags = 0; header.cmdId = RDPGFX_CMDID_CAPSADVERTISE; @@ -451,38 +306,50 @@ int rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { + RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; + RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ - Stream_Read_UINT16(s, pdu.destRect.left); /* left (2 bytes) */ - Stream_Read_UINT16(s, pdu.destRect.top); /* top (2 bytes) */ - Stream_Read_UINT16(s, pdu.destRect.right); /* right (2 bytes) */ - Stream_Read_UINT16(s, pdu.destRect.bottom); /* bottom (2 bytes) */ + rdpgfx_read_rect16(s, &(pdu.destRect)); /* destRect (8 bytes) */ Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ pdu.bitmapData = Stream_Pointer(s); - fprintf(stderr, "RdpGfxRecvWireToSurface1Pdu: surfaceId: %d codecId: 0x%04X pixelFormat: 0x%04X " + fprintf(stderr, "RdpGfxRecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d\n", - pdu.surfaceId, pdu.codecId, pdu.pixelFormat, + pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); + 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; + + rdpgfx_decode(gfx, &cmd); + return 1; } int rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { + RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_2 pdu; + RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ + Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ pdu.bitmapData = Stream_Pointer(s); @@ -491,6 +358,16 @@ int rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream "codecContextId: %d pixelFormat: 0x%04X bitmapDataLength: %d\n", pdu.surfaceId, pdu.codecId, pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength); + 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; + + rdpgfx_decode(gfx, &cmd); + return 1; } @@ -653,7 +530,7 @@ int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) #if 1 printf("cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d\n", - rdpgfx_get_cmdid_string(header.cmdId), header.cmdId, header.flags, header.pduLength); + rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength); #endif switch (header.cmdId) diff --git a/channels/rdpgfx/client/rdpgfx_main.h b/channels/rdpgfx/client/rdpgfx_main.h index 74cfcbef3..1055a3371 100644 --- a/channels/rdpgfx/client/rdpgfx_main.h +++ b/channels/rdpgfx/client/rdpgfx_main.h @@ -2,7 +2,7 @@ * FreeRDP: A Remote Desktop Protocol Implementation * Graphics Pipeline Extension * - * Copyright 2013 Marc-Andre Moreau + * Copyright 2013-2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,17 +20,50 @@ #ifndef FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H #define FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include #include #include #include +#include +struct _RDPGFX_CHANNEL_CALLBACK +{ + IWTSVirtualChannelCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + IWTSVirtualChannel* channel; +}; +typedef struct _RDPGFX_CHANNEL_CALLBACK RDPGFX_CHANNEL_CALLBACK; + +struct _RDPGFX_LISTENER_CALLBACK +{ + IWTSListenerCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + RDPGFX_CHANNEL_CALLBACK* channel_callback; +}; +typedef struct _RDPGFX_LISTENER_CALLBACK RDPGFX_LISTENER_CALLBACK; + +struct _RDPGFX_PLUGIN +{ + IWTSPlugin iface; + + IWTSListener* listener; + RDPGFX_LISTENER_CALLBACK* listener_callback; + + BOOL ThinClient; + BOOL SmallCache; + BOOL H264; + + ZGFX_CONTEXT* zgfx; + UINT32 UnacknowledgedFrames; + UINT32 TotalDecodedFrames; +}; +typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN; #endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_MAIN_H */ diff --git a/include/freerdp/channels/rdpgfx.h b/include/freerdp/channels/rdpgfx.h index 25c650712..63c374153 100644 --- a/include/freerdp/channels/rdpgfx.h +++ b/include/freerdp/channels/rdpgfx.h @@ -165,6 +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; +}; +typedef struct _RDPGFX_SURFACE_COMMAND RDPGFX_SURFACE_COMMAND; + struct _RDPGFX_DELETE_ENCODING_CONTEXT_PDU { UINT16 surfaceId; diff --git a/include/freerdp/codec/clear.h b/include/freerdp/codec/clear.h new file mode 100644 index 000000000..dc5e81a83 --- /dev/null +++ b/include/freerdp/codec/clear.h @@ -0,0 +1,49 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * ClearCodec Bitmap Compression + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CODEC_CLEAR_H +#define FREERDP_CODEC_CLEAR_H + +#include +#include + +struct _CLEAR_CONTEXT +{ + BOOL Compressor; +}; +typedef struct _CLEAR_CONTEXT CLEAR_CONTEXT; + +#ifdef __cplusplus +extern "C" { +#endif + +FREERDP_API int clear_compress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); +FREERDP_API int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); + +FREERDP_API void clear_context_reset(CLEAR_CONTEXT* clear); + +FREERDP_API CLEAR_CONTEXT* clear_context_new(BOOL Compressor); +FREERDP_API void clear_context_free(CLEAR_CONTEXT* clear); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_CODEC_CLEAR_H */ + diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index abe48739b..ad0180e25 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -51,6 +51,7 @@ set(${MODULE_PREFIX}_SRCS xcrush.c mppc.c zgfx.c + clear.c jpeg.c) set(${MODULE_PREFIX}_SSE2_SRCS diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c new file mode 100644 index 000000000..564e5d364 --- /dev/null +++ b/libfreerdp/codec/clear.c @@ -0,0 +1,68 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * ClearCodec Bitmap Compression + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize) +{ + return 1; +} + +int clear_compress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize) +{ + return 1; +} + +void clear_context_reset(CLEAR_CONTEXT* clear) +{ + +} + +CLEAR_CONTEXT* clear_context_new(BOOL Compressor) +{ + CLEAR_CONTEXT* clear; + + clear = (CLEAR_CONTEXT*) calloc(1, sizeof(CLEAR_CONTEXT)); + + if (clear) + { + clear->Compressor = Compressor; + + clear_context_reset(clear); + } + + return clear; +} + +void clear_context_free(CLEAR_CONTEXT* clear) +{ + if (clear) + { + free(clear); + } +} + diff --git a/libfreerdp/codec/test/CMakeLists.txt b/libfreerdp/codec/test/CMakeLists.txt index fa268c270..ba158560c 100644 --- a/libfreerdp/codec/test/CMakeLists.txt +++ b/libfreerdp/codec/test/CMakeLists.txt @@ -11,6 +11,7 @@ set(${MODULE_PREFIX}_TESTS TestFreeRDPCodecXCrush.c TestFreeRDPCodecZGfx.c TestFreeRDPCodecPlanar.c + TestFreeRDPCodecClear.c TestFreeRDPCodecRemoteFX.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS diff --git a/libfreerdp/codec/test/TestFreeRDPCodecClear.c b/libfreerdp/codec/test/TestFreeRDPCodecClear.c new file mode 100644 index 000000000..6db7e6e12 --- /dev/null +++ b/libfreerdp/codec/test/TestFreeRDPCodecClear.c @@ -0,0 +1,10 @@ +#include +#include + +#include + +int TestFreeRDPCodecClear(int argc, char* argv[]) +{ + return 0; +} +