diff --git a/include/freerdp/constants.h b/include/freerdp/constants.h index 05abbf565..26e7423d8 100644 --- a/include/freerdp/constants.h +++ b/include/freerdp/constants.h @@ -20,6 +20,15 @@ #ifndef __FREERDP_CONSTANTS #define __FREERDP_CONSTANTS +/** + * Codec IDs + */ +enum RDP_CODEC_ID +{ + CODEC_ID_NSCODEC = 0x01, + CODEC_ID_REMOTEFX = 0x02 +}; + /** * Static Virtual Channel Flags */ @@ -35,8 +44,6 @@ enum RDP_SVC_CHANNEL_FLAG CHANNEL_FLAG_FAIL = 0x100 }; -//#define CHANNEL_FLAG_ONLY (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST) - /** * Static Virtual Channel Options */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index b79e200d4..8257f4423 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -260,13 +260,12 @@ struct rdp_settings boolean desktop_composition; + boolean rfx_decode; boolean frame_acknowledge; uint8* app_name; boolean remote_app; - int rfx_flags; - int ui_decode_flags; boolean mouse_motion; }; typedef struct rdp_settings rdpSettings; diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index 15c2d1fee..f476b031f 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -131,7 +131,7 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings) header = rdp_capability_set_start(s); - extraFlags = LONG_CREDENTIALS_SUPPORTED | NO_BITMAP_COMPRESSION_HDR; + extraFlags = LONG_CREDENTIALS_SUPPORTED; /* | NO_BITMAP_COMPRESSION_HDR; */ if (settings->auto_reconnection) extraFlags |= AUTORECONNECT_SUPPORTED; @@ -144,7 +144,7 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings) stream_write_uint16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */ stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */ stream_write_uint16(s, 0); /* generalCompressionTypes (2 bytes) */ - stream_write_uint16(s, 0); /* extraFlags (2 bytes) */ + stream_write_uint16(s, extraFlags); /* extraFlags (2 bytes) */ stream_write_uint16(s, 0); /* updateCapabilityFlag (2 bytes) */ stream_write_uint16(s, 0); /* remoteUnshareFlag (2 bytes) */ stream_write_uint16(s, 0); /* generalCompressionLevel (2 bytes) */ @@ -1338,10 +1338,57 @@ void rdp_read_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) { uint8* header; + uint8 bitmapCodecCount; header = rdp_capability_set_start(s); + bitmapCodecCount = 0; + if (settings->rfx_decode) + bitmapCodecCount++; + stream_write_uint8(s, bitmapCodecCount); + + if (settings->rfx_decode) + { + /* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */ + stream_write(s, "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86", 16); /* codecGUID */ + stream_write_uint8(s, CODEC_ID_REMOTEFX); /* codecID */ + stream_write_uint16(s, 49); /* codecPropertiesLength */ + + /* TS_RFX_CLNT_CAPS_CONTAINER */ + stream_write_uint32(s, 49); /* length */ + stream_write_uint32(s, CARDP_CAPS_CAPTURE_NON_CAC); /* captureFlags */ + stream_write_uint32(s, 37); /* capsLength */ + + /* TS_RFX_CAPS */ + stream_write_uint16(s, CBY_CAPS); /* blockType */ + stream_write_uint32(s, 8); /* blockLen */ + stream_write_uint16(s, 1); /* numCapsets */ + + /* TS_RFX_CAPSET */ + stream_write_uint16(s, CBY_CAPSET); /* blockType */ + stream_write_uint32(s, 29); /* blockLen */ + stream_write_uint8(s, 0x01); /* codecId (MUST be set to 0x01) */ + stream_write_uint16(s, CLY_CAPSET); /* capsetType */ + stream_write_uint16(s, 2); /* numIcaps */ + stream_write_uint16(s, 8); /* icapLen */ + + /* TS_RFX_ICAP (RLGR1) */ + stream_write_uint16(s, CLW_VERSION_1_0); /* version */ + stream_write_uint16(s, CT_TILE_64x64); /* tileSize */ + stream_write_uint8(s, 0); /* flags */ + stream_write_uint8(s, CLW_COL_CONV_ICT); /* colConvBits */ + stream_write_uint8(s, CLW_XFORM_DWT_53_A); /* transformBits */ + stream_write_uint8(s, CLW_ENTROPY_RLGR1); /* entropyBits */ + + /* TS_RFX_ICAP (RLGR3) */ + stream_write_uint16(s, CLW_VERSION_1_0); /* version */ + stream_write_uint16(s, CT_TILE_64x64); /* tileSize */ + stream_write_uint8(s, 0); /* flags */ + stream_write_uint8(s, CLW_COL_CONV_ICT); /* colConvBits */ + stream_write_uint8(s, CLW_XFORM_DWT_53_A); /* transformBits */ + stream_write_uint8(s, CLW_ENTROPY_RLGR3); /* entropyBits */ + } rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS); } @@ -1609,15 +1656,12 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) rdp_write_surface_commands_capability_set(s, settings); } -#if 0 if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS]) { numberCapabilities++; rdp_write_bitmap_codecs_capability_set(s, settings); } -#endif - if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE]) { if (settings->frame_acknowledge) diff --git a/libfreerdp-core/capabilities.h b/libfreerdp-core/capabilities.h index ddf84f540..975799a8e 100644 --- a/libfreerdp-core/capabilities.h +++ b/libfreerdp-core/capabilities.h @@ -23,6 +23,7 @@ #include "rdp.h" #include +#include #include #include @@ -156,6 +157,18 @@ #define SURFCMDS_FRAME_MARKER 0x00000010 #define SURFCMDS_STREAM_SURFACE_BITS 0x00000040 +/* Bitmap Codec Constants */ +#define CARDP_CAPS_CAPTURE_NON_CAC 0x00000001 +#define CBY_CAPS 0xCBC0 +#define CBY_CAPSET 0xCBC1 +#define CLY_CAPSET 0xCFC0 +#define CLW_VERSION_1_0 0x0100 +#define CT_TILE_64x64 0x0040 +#define CLW_COL_CONV_ICT 0x1 +#define CLW_XFORM_DWT_53_A 0x1 +#define CLW_ENTROPY_RLGR1 0x01 +#define CLW_ENTROPY_RLGR3 0x04 + void rdp_read_demand_active(STREAM* s, rdpSettings* settings); void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings); void rdp_write_confirm_active(STREAM* s, rdpSettings* settings); diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c index 648989241..edddb0dc7 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp-utils/args.c @@ -175,11 +175,12 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, } else if (strcmp("--rfx", argv[index]) == 0) { - settings->rfx_flags = 1; - settings->ui_decode_flags = 1; + settings->rfx_decode = True; + settings->fast_path_input = True; settings->color_depth = 32; settings->frame_acknowledge = False; settings->performance_flags = PERF_FLAG_NONE; + settings->large_pointer = True; } else if (strcmp("-m", argv[index]) == 0) {