diff --git a/src/LPUtf8StrMarshaler.cs b/src/LPUtf8StrMarshaler.cs index 3371ed0..df720c1 100644 --- a/src/LPUtf8StrMarshaler.cs +++ b/src/LPUtf8StrMarshaler.cs @@ -38,7 +38,7 @@ namespace SDL2 _leaveAllocatedInstance = new LPUtf8StrMarshaler(true), _defaultInstance = new LPUtf8StrMarshaler(false); - private static ICustomMarshaler GetInstance(string cookie) + public static ICustomMarshaler GetInstance(string cookie) { switch (cookie) { diff --git a/src/SDL2.cs b/src/SDL2.cs index 4b86982..1bdece3 100644 --- a/src/SDL2.cs +++ b/src/SDL2.cs @@ -4390,7 +4390,148 @@ namespace SDL2 #endregion + #region SDL_messagebox.h + [Flags] + public enum SDL_MessageBoxFlags + { + SDL_MESSAGEBOX_ERROR = 0x00000010, + SDL_MESSAGEBOX_WARNING = 0x00000020, + SDL_MESSAGEBOX_INFORMATION = 0x00000040 + } + + [Flags] + public enum SDL_MessageBoxButtonFlags + { + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 + } + + [StructLayout(LayoutKind.Sequential)] + internal struct INTERNAL_SDL_MessageBoxButtonData + { + public SDL_MessageBoxButtonFlags flags; + public int buttonid; + public IntPtr text; /* The UTF-8 button text */ + } + + [StructLayout(LayoutKind.Sequential)] + public struct SDL_MessageBoxButtonData + { + public SDL_MessageBoxButtonFlags flags; + public int buttonid; + public string text; /* The UTF-8 button text */ + } + + [StructLayout(LayoutKind.Sequential)] + public struct SDL_MessageBoxColor + { + public byte r, g, b; + } + + public enum SDL_MessageBoxColorType + { + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX + } + + [StructLayout(LayoutKind.Sequential)] + public struct SDL_MessageBoxColorScheme + { + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = (int)SDL_MessageBoxColorType.SDL_MESSAGEBOX_COLOR_MAX)] + public SDL_MessageBoxColor[] colors; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct INTERNAL_SDL_MessageBoxData + { + public SDL_MessageBoxFlags flags; + public IntPtr window; /* Parent window, can be NULL */ + public IntPtr title; /* UTF-8 title */ + public IntPtr message; /* UTF-8 message text */ + public int numbuttons; + public IntPtr buttons; + public IntPtr colorScheme; /* Can be NULL to use system settings */ + } + + [StructLayout(LayoutKind.Sequential)] + public struct SDL_MessageBoxData + { + public SDL_MessageBoxFlags flags; + public IntPtr window; /* Parent window, can be NULL */ + public string title; /* UTF-8 title */ + public string message; /* UTF-8 message text */ + public int numbuttons; + public SDL_MessageBoxButtonData[] buttons; + public SDL_MessageBoxColorScheme? colorScheme; /* Can be NULL to use system settings */ + } + + [DllImport(nativeLibName, EntryPoint = "SDL_ShowMessageBox", CallingConvention = CallingConvention.Cdecl)] + internal static extern int INTERNAL_SDL_ShowMessageBox([In()] ref INTERNAL_SDL_MessageBoxData messageboxdata, out int buttonid); + + public static unsafe int SDL_ShowMessageBox([In()] ref SDL_MessageBoxData messageboxdata, out int buttonid) + { + var utf8 = LPUtf8StrMarshaler.GetInstance(null); + + var data = new INTERNAL_SDL_MessageBoxData() + { + flags = messageboxdata.flags, + window = messageboxdata.window, + title = utf8.MarshalManagedToNative(messageboxdata.title), + message = utf8.MarshalManagedToNative(messageboxdata.message), + numbuttons = messageboxdata.numbuttons, + }; + + var buttons = new INTERNAL_SDL_MessageBoxButtonData[messageboxdata.numbuttons]; + for (int i = 0; i < messageboxdata.numbuttons; i++) + { + buttons[i] = new INTERNAL_SDL_MessageBoxButtonData() + { + flags = messageboxdata.buttons[i].flags, + buttonid = messageboxdata.buttons[i].buttonid, + text = utf8.MarshalManagedToNative(messageboxdata.buttons[i].text), + }; + } + + if (messageboxdata.colorScheme != null) + { + data.colorScheme = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SDL_MessageBoxColorScheme))); + Marshal.StructureToPtr(messageboxdata.colorScheme.Value, data.colorScheme, false); + } + + int result; + fixed (INTERNAL_SDL_MessageBoxButtonData* buttonsPtr = &buttons[0]) + { + data.buttons = (IntPtr)buttonsPtr; + result = INTERNAL_SDL_ShowMessageBox(ref data, out buttonid); + } + + Marshal.FreeHGlobal(data.colorScheme); + for (int i = 0; i < messageboxdata.numbuttons; i++) + { + utf8.CleanUpNativeData(buttons[i].text); + } + utf8.CleanUpNativeData(data.message); + utf8.CleanUpNativeData(data.title); + + return result; + } + + [DllImport(nativeLibName, CallingConvention = CallingConvention.Cdecl)] + public static extern int SDL_ShowSimpleMessageBox( + SDL_MessageBoxFlags flags, + [In()] [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LPUtf8StrMarshaler))] + string title, + [In()] [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LPUtf8StrMarshaler))] + string message, + IntPtr window + ); + + #endregion } }