50 lines
1.5 KiB
C#
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;
|
|
}
|
|
} |