Skip to content

Commit

Permalink
[bindings] fix authentication handling
Browse files Browse the repository at this point in the history
Clean up the C API usage a little, too.
  • Loading branch information
nil4 committed Nov 11, 2024
1 parent 89cb5ce commit d8facaa
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 61 deletions.
27 changes: 14 additions & 13 deletions Bindings/dotnet/RoyalApps.RoyalVNCKit/VncConnection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using static RoyalApps.RoyalVNCKit.RoyalVNCKit;

namespace RoyalApps.RoyalVNCKit;

Expand All @@ -24,7 +25,7 @@ public VncConnection(VncSettings settings) : this(CreateInstance(settings))
var context = new VncContext();
var logger = new VncLogger(context);
context.Logger = logger;
return RoyalVNCKit.rvnc_connection_create(settings.Instance, logger.Instance, context.Instance);
return rvnc_connection_create(settings.Instance, logger.Instance, context.Instance);
}

VncContext? Context
Expand All @@ -33,7 +34,7 @@ public VncConnection(VncSettings settings) : this(CreateInstance(settings))
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

var contextInstance = RoyalVNCKit.rvnc_connection_context_get(_instance);
var contextInstance = rvnc_connection_context_get(_instance);

if (contextInstance is null)
return null;
Expand All @@ -50,7 +51,7 @@ public ConnectionStatus Status
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

void* nativeState = RoyalVNCKit.rvnc_connection_state_get_copy(_instance);
void* nativeState = rvnc_connection_state_get_copy(_instance);
using var holder = new VncConnectionState(nativeState);

return holder.Status;
Expand All @@ -70,36 +71,36 @@ public VncConnectionDelegate? Delegate
if (context is not null)
context.ConnectionDelegate = value;

RoyalVNCKit.rvnc_connection_delegate_set(_instance, val);
rvnc_connection_delegate_set(_instance, val);
}
}

public void Connect()
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

RoyalVNCKit.rvnc_connection_connect(_instance);
rvnc_connection_connect(_instance);
}

public void Disconnect()
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

RoyalVNCKit.rvnc_connection_disconnect(_instance);
rvnc_connection_disconnect(_instance);
}

public void SendKeyDown(KeySymbol key)
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

RoyalVNCKit.rvnc_connection_key_down(_instance, key);
rvnc_connection_key_down(_instance, key);
}

public void SendKeyUp(KeySymbol key)
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

RoyalVNCKit.rvnc_connection_key_up(_instance, key);
rvnc_connection_key_up(_instance, key);
}

public void SendMouseButtonDown(ushort x, ushort y, MouseButton button)
Expand All @@ -110,7 +111,7 @@ public void SendMouseButtonDown(ushort x, ushort y, MouseButton button)
throw new ArgumentOutOfRangeException(nameof(button));
}

RoyalVNCKit.rvnc_connection_mouse_down(_instance, button, x, y);
rvnc_connection_mouse_down(_instance, button, x, y);
}

public void SendMouseButtonUp(ushort x, ushort y, MouseButton button)
Expand All @@ -121,14 +122,14 @@ public void SendMouseButtonUp(ushort x, ushort y, MouseButton button)
throw new ArgumentOutOfRangeException(nameof(button));
}

RoyalVNCKit.rvnc_connection_mouse_up(_instance, button, x, y);
rvnc_connection_mouse_up(_instance, button, x, y);
}

public void SendMouseMove(ushort x, ushort y)
{
ObjectDisposedException.ThrowIf(_isDisposed || _instance is null, this);

RoyalVNCKit.rvnc_connection_mouse_move(_instance, x, y);
rvnc_connection_mouse_move(_instance, x, y);
}

public void SendMouseScroll(ushort x, ushort y, double scrollWheelDeltaX, double scrollWheelDeltaY)
Expand All @@ -139,7 +140,7 @@ public void SendMouseScroll(ushort x, ushort y, double scrollWheelDeltaX, double
MouseWheel direction = MouseWheel.Down;
uint steps = 1;

RoyalVNCKit.rvnc_connection_mouse_wheel(_instance, direction, x, y, steps);
rvnc_connection_mouse_wheel(_instance, direction, x, y, steps);
}

public void Dispose()
Expand All @@ -156,7 +157,7 @@ public void Dispose()
if (_instance is null)
return;

RoyalVNCKit.rvnc_connection_destroy(_instance);
rvnc_connection_destroy(_instance);
_instance = null;
}
}
48 changes: 26 additions & 22 deletions Bindings/dotnet/RoyalApps.RoyalVNCKit/VncConnectionDelegate.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using static RoyalApps.RoyalVNCKit.RoyalVNCKit;

namespace RoyalApps.RoyalVNCKit;

Expand Down Expand Up @@ -53,7 +55,7 @@ public sealed unsafe class VncConnectionDelegate: IDisposable
}

public VncConnectionDelegate() : this(
RoyalVNCKit.rvnc_connection_delegate_create(
rvnc_connection_delegate_create(
connectionStateDidChange: ConnectionStateDidChangeHandler,
authenticate: AuthenticateHandler,
didCreateFramebuffer: DidCreateFramebufferHandler,
Expand All @@ -74,7 +76,7 @@ public void Dispose()
if (Instance is null)
return;

RoyalVNCKit.rvnc_connection_delegate_destroy(Instance);
rvnc_connection_delegate_destroy(Instance);
Instance = null;
}

Expand All @@ -100,99 +102,101 @@ static bool TryGetConnectionAndDelegate(
return connection is not null && connectionDelegate is not null;
}

static readonly RoyalVNCKit.ConnectionStateDidChangeDelegate ConnectionStateDidChangeHandler = ConnectionStateDidChange;
static readonly ConnectionStateDidChangeDelegate ConnectionStateDidChangeHandler = ConnectionStateDidChange;
static void ConnectionStateDidChange(
void* connection,
void* context,
void* connectionState
)
{
if (!TryGetConnectionAndDelegate(context, out VncConnection? vncConnection, out VncConnectionDelegate? vncConnectionDelegate)
if (!TryGetConnectionAndDelegate(context, out var vncConnection, out var vncConnectionDelegate)
|| vncConnectionDelegate is not { ConnectionStateChanged: {} handler })
return;

var state = new VncConnectionState(connectionState);
handler.Invoke(vncConnection, state);
}

static readonly RoyalVNCKit.AuthenticateDelegate AuthenticateHandler = Authenticate;
static readonly AuthenticateDelegate AuthenticateHandler = Authenticate;
static void Authenticate(
void* connection,
void* context,
void* authenticationRequest
)
{
if (!TryGetConnectionAndDelegate(context, out VncConnection? vncConnection, out VncConnectionDelegate? vncConnectionDelegate)
if (!TryGetConnectionAndDelegate(context, out var vncConnection, out var vncConnectionDelegate)
|| vncConnectionDelegate is not { AuthenticationRequested: { } handler })
{
RoyalVNCKit.rvnc_authentication_request_cancel(authenticationRequest);
rvnc_authentication_request_cancel(authenticationRequest);
return;
}

var authType = RoyalVNCKit.rvnc_authentication_request_authentication_type_get(authenticationRequest);
bool requiresUsername = RoyalVNCKit.rvnc_authentication_type_requires_username(authType).FromNativeBool();
bool requiresPassword = RoyalVNCKit.rvnc_authentication_type_requires_password(authType).FromNativeBool();
var authType = rvnc_authentication_request_authentication_type_get(authenticationRequest);
bool requiresUsername = rvnc_authentication_type_requires_username(authType).FromNativeBool();
bool requiresPassword = rvnc_authentication_type_requires_password(authType).FromNativeBool();

var request = new AuthenticationRequest(authType, requiresUsername, requiresPassword);

if (!handler.Invoke(vncConnection, request) || (request.Username is null && request.Password is null))
{
RoyalVNCKit.rvnc_authentication_request_cancel(authenticationRequest);
rvnc_authentication_request_cancel(authenticationRequest);
return;
}

if (request is { Username: string username, Password: string password })
RoyalVNCKit.rvnc_authentication_request_complete_with_username_password(authenticationRequest, username, password);
Debug.Assert(request.RequiresPassword);

if (request.RequiresUsername)
rvnc_authentication_request_complete_with_username_password(authenticationRequest, request.Username ?? "", request.Password ?? "");
else
RoyalVNCKit.rvnc_authentication_request_complete_with_password(authenticationRequest, request.Password!);
rvnc_authentication_request_complete_with_password(authenticationRequest, request.Password ?? "");
}

static readonly RoyalVNCKit.DidUpdateCursorDelegate DidUpdateCursorHandler = DidUpdateCursor;
static readonly DidUpdateCursorDelegate DidUpdateCursorHandler = DidUpdateCursor;
static void DidUpdateCursor(
void* connection,
void* context,
void* cursor
)
{
if (!TryGetConnectionAndDelegate(context, out VncConnection? vncConnection, out VncConnectionDelegate? vncConnectionDelegate)
if (!TryGetConnectionAndDelegate(context, out var vncConnection, out var vncConnectionDelegate)
|| vncConnectionDelegate is not { CursorUpdated: { } handler })
return;

var vncCursor = new VncCursor(cursor);
handler.Invoke(vncConnection, vncCursor);
}

static readonly RoyalVNCKit.DidCreateFramebufferDelegate DidCreateFramebufferHandler = DidCreateFramebuffer;
static readonly DidCreateFramebufferDelegate DidCreateFramebufferHandler = DidCreateFramebuffer;
static void DidCreateFramebuffer(
void* connection,
void* context,
void* framebuffer
)
{
if (!TryGetConnectionAndDelegate(context, out VncConnection? vncConnection, out VncConnectionDelegate? vncConnectionDelegate)
if (!TryGetConnectionAndDelegate(context, out var vncConnection, out var vncConnectionDelegate)
|| vncConnectionDelegate is not { FramebufferCreated: { } handler })
return;

var vncFramebuffer = new VncFramebuffer(framebuffer);
handler.Invoke(vncConnection, vncFramebuffer);
}

static readonly RoyalVNCKit.DidResizeFramebufferDelegate DidResizeFramebufferHandler = DidResizeFramebuffer;
static readonly DidResizeFramebufferDelegate DidResizeFramebufferHandler = DidResizeFramebuffer;
static void DidResizeFramebuffer(
void* connection,
void* context,
void* framebuffer
)
{
if (!TryGetConnectionAndDelegate(context, out VncConnection? vncConnection, out VncConnectionDelegate? vncConnectionDelegate)
if (!TryGetConnectionAndDelegate(context, out var vncConnection, out var vncConnectionDelegate)
|| vncConnectionDelegate is not { FramebufferResized: { } handler })
return;

var vncFramebuffer = new VncFramebuffer(framebuffer);
handler.Invoke(vncConnection, vncFramebuffer);
}

static readonly RoyalVNCKit.DidUpdateFramebufferDelegate DidUpdateFramebufferHandler = DidUpdateFramebuffer;
static readonly DidUpdateFramebufferDelegate DidUpdateFramebufferHandler = DidUpdateFramebuffer;
static void DidUpdateFramebuffer(
void* connection,
void* context,
Expand All @@ -203,7 +207,7 @@ static void DidUpdateFramebuffer(
ushort height
)
{
if (!TryGetConnectionAndDelegate(context, out VncConnection? vncConnection, out VncConnectionDelegate? vncConnectionDelegate)
if (!TryGetConnectionAndDelegate(context, out var vncConnection, out var vncConnectionDelegate)
|| vncConnectionDelegate is not { FramebufferUpdated: { } handler })
return;

Expand Down
11 changes: 6 additions & 5 deletions Bindings/dotnet/RoyalApps.RoyalVNCKit/VncConnectionState.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using static RoyalApps.RoyalVNCKit.RoyalVNCKit;

namespace RoyalApps.RoyalVNCKit;

Expand All @@ -14,10 +15,10 @@ internal VncConnectionState(void* instance)
_instance = instance;
}

public ConnectionStatus Status => RoyalVNCKit.rvnc_connection_state_status_get(_instance);
public string? ErrorDescription => RoyalVNCKit.rvnc_connection_state_error_description_get_copy(_instance);
public bool DisplayErrorToUser => RoyalVNCKit.rvnc_connection_state_error_should_display_to_user_get(_instance).FromNativeBool();
public bool IsAuthenticationError => RoyalVNCKit.rvnc_connection_state_error_is_authentication_error_get(_instance).FromNativeBool();
public ConnectionStatus Status => rvnc_connection_state_status_get(_instance);
public string? ErrorDescription => rvnc_connection_state_error_description_get_copy(_instance);
public bool DisplayErrorToUser => rvnc_connection_state_error_should_display_to_user_get(_instance).FromNativeBool();
public bool IsAuthenticationError => rvnc_connection_state_error_is_authentication_error_get(_instance).FromNativeBool();

internal void Dispose() => RoyalVNCKit.rvnc_connection_state_destroy(_instance);
internal void Dispose() => rvnc_connection_state_destroy(_instance);
}
25 changes: 13 additions & 12 deletions Bindings/dotnet/RoyalApps.RoyalVNCKit/VncCursor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using static RoyalApps.RoyalVNCKit.RoyalVNCKit;

namespace RoyalApps.RoyalVNCKit;

Expand All @@ -15,26 +16,26 @@ internal VncCursor(void* instance)
_instance = instance;
}

public bool IsEmpty => RoyalVNCKit.rvnc_cursor_is_empty_get(_instance).FromNativeBool();
public ushort Width => RoyalVNCKit.rvnc_cursor_size_width_get(_instance);
public ushort Height => RoyalVNCKit.rvnc_cursor_size_height_get(_instance);
public ushort HotspotX => RoyalVNCKit.rvnc_cursor_hotspot_x_get(_instance);
public ushort HotspotY => RoyalVNCKit.rvnc_cursor_hotspot_y_get(_instance);
public long BitsPerComponent => RoyalVNCKit.rvnc_cursor_bits_per_component_get(_instance);
public long BitsPerPixel => RoyalVNCKit.rvnc_cursor_bits_per_pixel_get(_instance);
public long BytesPerPixel => RoyalVNCKit.rvnc_cursor_bytes_per_pixel_get(_instance);
public long BytesPerRow => RoyalVNCKit.rvnc_cursor_bytes_per_row_get(_instance);
public bool IsEmpty => rvnc_cursor_is_empty_get(_instance).FromNativeBool();
public ushort Width => rvnc_cursor_size_width_get(_instance);
public ushort Height => rvnc_cursor_size_height_get(_instance);
public ushort HotspotX => rvnc_cursor_hotspot_x_get(_instance);
public ushort HotspotY => rvnc_cursor_hotspot_y_get(_instance);
public long BitsPerComponent => rvnc_cursor_bits_per_component_get(_instance);
public long BitsPerPixel => rvnc_cursor_bits_per_pixel_get(_instance);
public long BytesPerPixel => rvnc_cursor_bytes_per_pixel_get(_instance);
public long BytesPerRow => rvnc_cursor_bytes_per_row_get(_instance);

public ReadOnlySpan<byte> PixelData
{
get
{
var length = checked((int)RoyalVNCKit.rvnc_cursor_pixel_data_size_get(_instance));
var length = checked((int)rvnc_cursor_pixel_data_size_get(_instance));
if (length is 0)
return ReadOnlySpan<byte>.Empty;

if (_pixelData is null)
_pixelData = RoyalVNCKit.rvnc_cursor_pixel_data_get_copy(_instance);
_pixelData = rvnc_cursor_pixel_data_get_copy(_instance);

Debug.Assert(_pixelData is not null);
return new(_pixelData, length);
Expand All @@ -50,7 +51,7 @@ public void Dispose()

if (_pixelData is not null)
{
RoyalVNCKit.rvnc_cursor_pixel_data_destroy(_pixelData);
rvnc_cursor_pixel_data_destroy(_pixelData);
_pixelData = null;
}

Expand Down
9 changes: 5 additions & 4 deletions Bindings/dotnet/RoyalApps.RoyalVNCKit/VncFramebuffer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static RoyalApps.RoyalVNCKit.RoyalVNCKit;

namespace RoyalApps.RoyalVNCKit;

Expand All @@ -15,18 +16,18 @@ internal VncFramebuffer(void* instance)
_instance = instance;
}

public ushort Width => RoyalVNCKit.rvnc_framebuffer_size_width_get(_instance);
public ushort Height => RoyalVNCKit.rvnc_framebuffer_size_height_get(_instance);
public ushort Width => rvnc_framebuffer_size_width_get(_instance);
public ushort Height => rvnc_framebuffer_size_height_get(_instance);

public ReadOnlySpan<byte> PixelData
{
get
{
var length = checked((int)RoyalVNCKit.rvnc_framebuffer_pixel_data_size_get(_instance));
var length = checked((int)rvnc_framebuffer_pixel_data_size_get(_instance));
if (length is 0)
return ReadOnlySpan<byte>.Empty;

var pixelData = RoyalVNCKit.rvnc_framebuffer_pixel_data_get(_instance);
var pixelData = rvnc_framebuffer_pixel_data_get(_instance);

Debug.Assert(pixelData is not null);
return new(pixelData, length);
Expand Down
Loading

0 comments on commit d8facaa

Please sign in to comment.