mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
feat(ffi): add graceful shutdown API (#464)
This commit is contained in:
@@ -6,9 +6,16 @@
|
||||
x:Class="Devolutions.IronRdp.AvaloniaExample.MainWindow"
|
||||
Title="Devolutions.IronRdp.AvaloniaExample">
|
||||
|
||||
<Canvas Name="MainCanvas" Width="1280" Height="800" Background="Black"
|
||||
PointerPressed="Canvas_OnPointerPressed" PointerMoved="Canvas_PointerMoved" PointerReleased="Canvas_PointerReleased"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
/>
|
||||
<DockPanel>
|
||||
<!-- Disconnect button at the top -->
|
||||
<Button Content="Disconnect" DockPanel.Dock="Top" HorizontalAlignment="Right"
|
||||
Margin="10" Click="OnDisconnectClick" />
|
||||
|
||||
<!-- Canvas adjusted to fill the remaining space -->
|
||||
<Canvas Name="MainCanvas" Width="1280" Height="800" Background="Black"
|
||||
PointerPressed="Canvas_OnPointerPressed" PointerMoved="Canvas_PointerMoved"
|
||||
PointerReleased="Canvas_PointerReleased"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</DockPanel>
|
||||
</Window>
|
||||
@@ -10,6 +10,7 @@ using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Devolutions.IronRdp.AvaloniaExample;
|
||||
|
||||
@@ -357,7 +358,7 @@ public partial class MainWindow : Window
|
||||
|
||||
IntPtr? GetWindowHandle()
|
||||
{
|
||||
var handle = this.TryGetPlatformHandle();
|
||||
var handle = TryGetPlatformHandle();
|
||||
if (handle == null)
|
||||
{
|
||||
return null;
|
||||
@@ -365,4 +366,16 @@ public partial class MainWindow : Window
|
||||
|
||||
return handle.Handle;
|
||||
}
|
||||
|
||||
public void OnDisconnectClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var output = this._activeStage!.GracefulShutdown();
|
||||
|
||||
HandleActiveStageOutput(output).ContinueWith(t=>{
|
||||
if (t.IsFaulted)
|
||||
{
|
||||
Trace.TraceError("Error processing active stage: " + t.Exception!.Message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ class Program
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
}catch(Exception e){
|
||||
Trace.TraceError(e.Message);
|
||||
Trace.TraceError(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,28 @@ public partial class ActiveStage: IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>ActiveStageOutputIterator</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public ActiveStageOutputIterator GracefulShutdown()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ActiveStage");
|
||||
}
|
||||
Raw.SessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError result = Raw.ActiveStage.GracefulShutdown(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.ActiveStageOutputIterator* retVal = result.Ok;
|
||||
return new ActiveStageOutputIterator(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
|
||||
@@ -34,6 +34,9 @@ public partial struct ActiveStage
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStage_submit_clipboard_format_data", ExactSpelling = true)]
|
||||
public static unsafe extern SessionFfiResultBoxVecU8BoxIronRdpError SubmitClipboardFormatData(ActiveStage* self, FormatDataResponse* formatDataResponse);
|
||||
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStage_graceful_shutdown", ExactSpelling = true)]
|
||||
public static unsafe extern SessionFfiResultBoxActiveStageOutputIteratorBoxIronRdpError GracefulShutdown(ActiveStage* self);
|
||||
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ActiveStage_destroy", ExactSpelling = true)]
|
||||
public static unsafe extern void Destroy(ActiveStage* self);
|
||||
}
|
||||
|
||||
@@ -121,6 +121,11 @@ pub mod ffi {
|
||||
|
||||
Ok(Box::new(VecU8(frame)))
|
||||
}
|
||||
|
||||
pub fn graceful_shutdown(&mut self) -> Result<Box<ActiveStageOutputIterator>, Box<IronRdpError>> {
|
||||
let outputs = self.0.graceful_shutdown()?;
|
||||
Ok(Box::new(ActiveStageOutputIterator(outputs)))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ActiveStageOutputType {
|
||||
|
||||
Reference in New Issue
Block a user