Nerfed/Nerfed.Runtime/Gui/GuiClipboard.cs

50 lines
1.5 KiB
C#

using System.Runtime.InteropServices;
using System.Text;
namespace Nerfed.Runtime.Gui;
public static unsafe class GuiClipboard
{
private static IntPtr clipboard;
private static readonly Dictionary<Delegate, IntPtr> pinned = new Dictionary<Delegate, IntPtr>();
public static readonly IntPtr GetFnPtr = GetPointerTo(Get);
public static readonly IntPtr SetFnPtr = GetPointerTo(Set);
private static unsafe void Set(void* userdata, byte* text)
{
int len = 0; while (text[len] != 0) len++;
string str = Encoding.UTF8.GetString(text, len);
SDL2.SDL.SDL_SetClipboardText(str);
}
private static unsafe byte* Get(void* userdata)
{
if (clipboard != IntPtr.Zero)
{
NativeMemory.Free((void*) clipboard);
clipboard = IntPtr.Zero;
}
string str = SDL2.SDL.SDL_GetClipboardText();
int length = Encoding.UTF8.GetByteCount(str);
byte* bytes = (byte*)(clipboard = (nint)NativeMemory.Alloc((nuint)(length + 1)));
Encoding.UTF8.GetBytes(str, new Span<byte>(bytes, length));
bytes[length] = 0;
return bytes;
}
// Stops the delegate pointer from being collected
private static IntPtr GetPointerTo<T>(T fn) where T : Delegate
{
if (pinned.TryGetValue(fn, out nint ptr))
{
return ptr;
}
ptr = Marshal.GetFunctionPointerForDelegate(fn);
pinned.Add(fn, ptr);
return ptr;
}
}