using System.Runtime.InteropServices; using System.Text; namespace Nerfed.Runtime.Gui; public static unsafe class GuiClipboard { private static IntPtr clipboard; private static readonly Dictionary pinned = new Dictionary(); 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(bytes, length)); bytes[length] = 0; return bytes; } // Stops the delegate pointer from being collected private static IntPtr GetPointerTo(T fn) where T : Delegate { if (pinned.TryGetValue(fn, out nint ptr)) { return ptr; } ptr = Marshal.GetFunctionPointerForDelegate(fn); pinned.Add(fn, ptr); return ptr; } }