diff --git a/crates/ironrdp-client/src/config.rs b/crates/ironrdp-client/src/config.rs index 5d86d0c42..3e7f889a8 100644 --- a/crates/ironrdp-client/src/config.rs +++ b/crates/ironrdp-client/src/config.rs @@ -749,6 +749,7 @@ impl PartialConfig { request_data: None, pointer_software_rendering: false, multitransport_flags: None, + support_dyn_vc_gfx_protocol: false, compression_type, performance_flags: PerformanceFlags::default(), timezone_info: TimezoneInfo::default(), diff --git a/crates/ironrdp-connector/src/connection.rs b/crates/ironrdp-connector/src/connection.rs index b5c6a65ae..abf0112eb 100644 --- a/crates/ironrdp-connector/src/connection.rs +++ b/crates/ironrdp-connector/src/connection.rs @@ -706,6 +706,11 @@ fn create_gcc_blocks<'a>( early_capability_flags |= ClientEarlyCapabilityFlags::WANT_32_BPP_SESSION; } + if config.support_dyn_vc_gfx_protocol { + early_capability_flags |= + ClientEarlyCapabilityFlags::SUPPORT_DYN_VC_GFX_PROTOCOL; + } + Some(early_capability_flags) }, dig_product_id: Some(config.dig_product_id.clone()), diff --git a/crates/ironrdp-connector/src/lib.rs b/crates/ironrdp-connector/src/lib.rs index e59874040..f325301d3 100644 --- a/crates/ironrdp-connector/src/lib.rs +++ b/crates/ironrdp-connector/src/lib.rs @@ -261,6 +261,34 @@ pub struct Config { /// [\[MS-RDPBCGR\] 2.2.1.3.7]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/861f2bbb-6ca2-4c5a-8c44-0714fa901e70 /// [`MultiTransportChannelData`]: ironrdp_pdu::gcc::MultiTransportChannelData pub multitransport_flags: Option, + + /// Advertise client support for the Graphics Pipeline Extension + /// (MS-RDPEGFX) over the Dynamic Virtual Channel. + /// + /// When `true`, the `SUPPORT_DYN_VC_GFX_PROTOCOL` flag is set in + /// [`ClientEarlyCapabilityFlags`], telling the server it may + /// negotiate the `Microsoft::Windows::RDS::Graphics` channel for + /// surface-based graphics updates instead of (or in addition to) + /// the legacy slow-path bitmap protocol. + /// + /// Setting this **without** wiring an EGFX-capable + /// [`DvcClientProcessor`] for that channel will cause modern + /// Windows servers to stop sending legacy bitmap updates and + /// route everything over EGFX — which the connector consumer + /// can't decode, leaving the desktop blank. To enable EGFX: + /// + /// 1. Set this field to `true`. + /// 2. Attach a [`DvcClientProcessor`] for + /// `Microsoft::Windows::RDS::Graphics` via + /// [`ClientConnector::with_static_channel`] + + /// [`ironrdp_dvc::DrdynvcClient::with_dynamic_channel`]. + /// 3. Decode `ironrdp_pdu::rdp::vc::dvc::gfx::ServerPdu` and + /// paint the surfaces. + /// + /// Default: `false` (legacy slow-path bitmap only). + /// + /// [`DvcClientProcessor`]: https://docs.rs/ironrdp-dvc/latest/ironrdp_dvc/trait.DvcClientProcessor.html + pub support_dyn_vc_gfx_protocol: bool, } ironrdp_core::assert_impl!(Config: Send, Sync); diff --git a/crates/ironrdp-testsuite-core/tests/session/autodetect.rs b/crates/ironrdp-testsuite-core/tests/session/autodetect.rs index 9e931deae..dd6b31556 100644 --- a/crates/ironrdp-testsuite-core/tests/session/autodetect.rs +++ b/crates/ironrdp-testsuite-core/tests/session/autodetect.rs @@ -53,6 +53,7 @@ fn test_config() -> ironrdp_connector::Config { enable_server_pointer: false, pointer_software_rendering: false, multitransport_flags: None, + support_dyn_vc_gfx_protocol: false, performance_flags: Default::default(), timezone_info: Default::default(), alternate_shell: String::new(), diff --git a/crates/ironrdp-testsuite-extra/tests/main.rs b/crates/ironrdp-testsuite-extra/tests/main.rs index 8c6f66dc3..f47fb8f02 100644 --- a/crates/ironrdp-testsuite-extra/tests/main.rs +++ b/crates/ironrdp-testsuite-extra/tests/main.rs @@ -392,6 +392,7 @@ fn default_client_config() -> connector::Config { enable_server_pointer: true, pointer_software_rendering: true, multitransport_flags: None, + support_dyn_vc_gfx_protocol: false, performance_flags: Default::default(), timezone_info: Default::default(), alternate_shell: String::new(), diff --git a/crates/ironrdp-web/src/session.rs b/crates/ironrdp-web/src/session.rs index f9a1d90a1..681b9d0bf 100644 --- a/crates/ironrdp-web/src/session.rs +++ b/crates/ironrdp-web/src/session.rs @@ -1286,6 +1286,7 @@ fn build_config( request_data: None, pointer_software_rendering: false, multitransport_flags: None, + support_dyn_vc_gfx_protocol: false, performance_flags: PerformanceFlags::default(), desktop_scale_factor: 0, hardware_id: None, diff --git a/crates/ironrdp/examples/screenshot.rs b/crates/ironrdp/examples/screenshot.rs index d25333690..5ce6c0a7b 100644 --- a/crates/ironrdp/examples/screenshot.rs +++ b/crates/ironrdp/examples/screenshot.rs @@ -265,6 +265,7 @@ fn build_config( compression_type, pointer_software_rendering: true, multitransport_flags: None, + support_dyn_vc_gfx_protocol: false, performance_flags: PerformanceFlags::default(), desktop_scale_factor: 0, hardware_id: None, diff --git a/ffi/src/connector/config.rs b/ffi/src/connector/config.rs index 3ec0e1777..f48f26123 100644 --- a/ffi/src/connector/config.rs +++ b/ffi/src/connector/config.rs @@ -216,6 +216,7 @@ pub mod ffi { compression_type: None, pointer_software_rendering: self.pointer_software_rendering.unwrap_or(false), multitransport_flags: None, + support_dyn_vc_gfx_protocol: false, performance_flags: self.performance_flags.ok_or("performance flag is missing")?, desktop_scale_factor: 0, hardware_id: None,