Files
maui-linux/Native/SafeHandles.cs

197 lines
6.5 KiB
C#
Raw Permalink Normal View History

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace Microsoft.Maui.Platform.Linux.Native;
/// <summary>
/// Safe handle wrapper for GTK widget pointers.
/// Releases the widget via <c>gtk_widget_destroy</c> when disposed.
/// </summary>
internal class SafeGtkWidgetHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libgtk-3.so.0")]
private static extern void gtk_widget_destroy(IntPtr widget);
/// <summary>
/// Initializes a new <see cref="SafeGtkWidgetHandle"/> that owns the handle.
/// </summary>
public SafeGtkWidgetHandle() : base(ownsHandle: true)
{
}
/// <summary>
/// Initializes a new <see cref="SafeGtkWidgetHandle"/> wrapping an existing pointer.
/// </summary>
/// <param name="existingHandle">The existing GTK widget pointer.</param>
/// <param name="ownsHandle">Whether this safe handle is responsible for releasing the resource.</param>
public SafeGtkWidgetHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
/// <inheritdoc />
protected override bool ReleaseHandle()
{
gtk_widget_destroy(handle);
return true;
}
}
/// <summary>
/// Safe handle wrapper for GObject pointers.
/// Releases the object via <c>g_object_unref</c> when disposed.
/// Suitable for any GObject-derived type including GtkCssProvider, GdkPixbuf, etc.
/// </summary>
internal class SafeGObjectHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libgobject-2.0.so.0")]
private static extern void g_object_unref(IntPtr obj);
/// <summary>
/// Initializes a new <see cref="SafeGObjectHandle"/> that owns the handle.
/// </summary>
public SafeGObjectHandle() : base(ownsHandle: true)
{
}
/// <summary>
/// Initializes a new <see cref="SafeGObjectHandle"/> wrapping an existing pointer.
/// </summary>
/// <param name="existingHandle">The existing GObject pointer.</param>
/// <param name="ownsHandle">Whether this safe handle is responsible for releasing the resource.</param>
public SafeGObjectHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
/// <inheritdoc />
protected override bool ReleaseHandle()
{
g_object_unref(handle);
return true;
}
}
/// <summary>
/// Safe handle wrapper for X11 <c>Display*</c> pointers.
/// Releases the display connection via <c>XCloseDisplay</c> when disposed.
/// </summary>
internal class SafeX11DisplayHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libX11.so.6")]
private static extern int XCloseDisplay(IntPtr display);
/// <summary>
/// Initializes a new <see cref="SafeX11DisplayHandle"/> that owns the handle.
/// </summary>
public SafeX11DisplayHandle() : base(ownsHandle: true)
{
}
/// <summary>
/// Initializes a new <see cref="SafeX11DisplayHandle"/> wrapping an existing pointer.
/// </summary>
/// <param name="existingHandle">The existing X11 Display pointer.</param>
/// <param name="ownsHandle">Whether this safe handle is responsible for releasing the resource.</param>
public SafeX11DisplayHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
/// <inheritdoc />
protected override bool ReleaseHandle()
{
XCloseDisplay(handle);
return true;
}
}
/// <summary>
/// Safe handle wrapper for X11 Cursor resources.
/// Releases the cursor via <c>XFreeCursor</c> when disposed.
/// Requires the associated <c>Display*</c> to be provided at construction time,
/// as X11 cursor cleanup requires both the display and cursor handles.
/// </summary>
internal class SafeX11CursorHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libX11.so.6")]
private static extern int XFreeCursor(IntPtr display, IntPtr cursor);
private readonly IntPtr _display;
/// <summary>
/// Initializes a new <see cref="SafeX11CursorHandle"/> that owns the handle.
/// </summary>
/// <param name="display">
/// The X11 Display pointer required for releasing the cursor.
/// The caller must ensure the display remains valid for the lifetime of this handle.
/// </param>
public SafeX11CursorHandle(IntPtr display) : base(ownsHandle: true)
{
_display = display;
}
/// <summary>
/// Initializes a new <see cref="SafeX11CursorHandle"/> wrapping an existing cursor.
/// </summary>
/// <param name="display">
/// The X11 Display pointer required for releasing the cursor.
/// The caller must ensure the display remains valid for the lifetime of this handle.
/// </param>
/// <param name="existingHandle">The existing X11 Cursor handle.</param>
/// <param name="ownsHandle">Whether this safe handle is responsible for releasing the resource.</param>
public SafeX11CursorHandle(IntPtr display, IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
_display = display;
SetHandle(existingHandle);
}
/// <inheritdoc />
protected override bool ReleaseHandle()
{
if (_display != IntPtr.Zero)
{
XFreeCursor(_display, handle);
}
return true;
}
}
/// <summary>
/// Safe handle wrapper for <c>GtkCssProvider*</c> pointers.
/// Since GtkCssProvider is a GObject, this releases it via <c>g_object_unref</c> when disposed.
/// </summary>
internal class SafeCssProviderHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libgobject-2.0.so.0")]
private static extern void g_object_unref(IntPtr obj);
/// <summary>
/// Initializes a new <see cref="SafeCssProviderHandle"/> that owns the handle.
/// </summary>
public SafeCssProviderHandle() : base(ownsHandle: true)
{
}
/// <summary>
/// Initializes a new <see cref="SafeCssProviderHandle"/> wrapping an existing pointer.
/// </summary>
/// <param name="existingHandle">The existing GtkCssProvider pointer.</param>
/// <param name="ownsHandle">Whether this safe handle is responsible for releasing the resource.</param>
public SafeCssProviderHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
/// <inheritdoc />
protected override bool ReleaseHandle()
{
g_object_unref(handle);
return true;
}
}