// 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;
///
/// Safe handle wrapper for GTK widget pointers.
/// Releases the widget via gtk_widget_destroy when disposed.
///
internal class SafeGtkWidgetHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libgtk-3.so.0")]
private static extern void gtk_widget_destroy(IntPtr widget);
///
/// Initializes a new that owns the handle.
///
public SafeGtkWidgetHandle() : base(ownsHandle: true)
{
}
///
/// Initializes a new wrapping an existing pointer.
///
/// The existing GTK widget pointer.
/// Whether this safe handle is responsible for releasing the resource.
public SafeGtkWidgetHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
///
protected override bool ReleaseHandle()
{
gtk_widget_destroy(handle);
return true;
}
}
///
/// Safe handle wrapper for GObject pointers.
/// Releases the object via g_object_unref when disposed.
/// Suitable for any GObject-derived type including GtkCssProvider, GdkPixbuf, etc.
///
internal class SafeGObjectHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libgobject-2.0.so.0")]
private static extern void g_object_unref(IntPtr obj);
///
/// Initializes a new that owns the handle.
///
public SafeGObjectHandle() : base(ownsHandle: true)
{
}
///
/// Initializes a new wrapping an existing pointer.
///
/// The existing GObject pointer.
/// Whether this safe handle is responsible for releasing the resource.
public SafeGObjectHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
///
protected override bool ReleaseHandle()
{
g_object_unref(handle);
return true;
}
}
///
/// Safe handle wrapper for X11 Display* pointers.
/// Releases the display connection via XCloseDisplay when disposed.
///
internal class SafeX11DisplayHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libX11.so.6")]
private static extern int XCloseDisplay(IntPtr display);
///
/// Initializes a new that owns the handle.
///
public SafeX11DisplayHandle() : base(ownsHandle: true)
{
}
///
/// Initializes a new wrapping an existing pointer.
///
/// The existing X11 Display pointer.
/// Whether this safe handle is responsible for releasing the resource.
public SafeX11DisplayHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
///
protected override bool ReleaseHandle()
{
XCloseDisplay(handle);
return true;
}
}
///
/// Safe handle wrapper for X11 Cursor resources.
/// Releases the cursor via XFreeCursor when disposed.
/// Requires the associated Display* to be provided at construction time,
/// as X11 cursor cleanup requires both the display and cursor handles.
///
internal class SafeX11CursorHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libX11.so.6")]
private static extern int XFreeCursor(IntPtr display, IntPtr cursor);
private readonly IntPtr _display;
///
/// Initializes a new that owns the handle.
///
///
/// The X11 Display pointer required for releasing the cursor.
/// The caller must ensure the display remains valid for the lifetime of this handle.
///
public SafeX11CursorHandle(IntPtr display) : base(ownsHandle: true)
{
_display = display;
}
///
/// Initializes a new wrapping an existing cursor.
///
///
/// The X11 Display pointer required for releasing the cursor.
/// The caller must ensure the display remains valid for the lifetime of this handle.
///
/// The existing X11 Cursor handle.
/// Whether this safe handle is responsible for releasing the resource.
public SafeX11CursorHandle(IntPtr display, IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
_display = display;
SetHandle(existingHandle);
}
///
protected override bool ReleaseHandle()
{
if (_display != IntPtr.Zero)
{
XFreeCursor(_display, handle);
}
return true;
}
}
///
/// Safe handle wrapper for GtkCssProvider* pointers.
/// Since GtkCssProvider is a GObject, this releases it via g_object_unref when disposed.
///
internal class SafeCssProviderHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("libgobject-2.0.so.0")]
private static extern void g_object_unref(IntPtr obj);
///
/// Initializes a new that owns the handle.
///
public SafeCssProviderHandle() : base(ownsHandle: true)
{
}
///
/// Initializes a new wrapping an existing pointer.
///
/// The existing GtkCssProvider pointer.
/// Whether this safe handle is responsible for releasing the resource.
public SafeCssProviderHandle(IntPtr existingHandle, bool ownsHandle = true) : base(ownsHandle)
{
SetHandle(existingHandle);
}
///
protected override bool ReleaseHandle()
{
g_object_unref(handle);
return true;
}
}