Beispiel #1
0
        public GraphicsState(WindowState window)
        {
            Window    = window;
            Stopwatch = window.Stopwatch;

            var syswm = new SDL_SysWMinfo();

            if (SDL_GetWindowWMInfo(window.Handle, ref syswm) == SDL_bool.SDL_FALSE)
            {
                throw new SdlException($"Could not get window wminfo: {SDL_GetError()}");
            }

            SDL_GetWindowSize(window.Handle, out var width, out var height);
            Device = GraphicsDevice.CreateVulkan(
                new GraphicsDeviceOptions(true, null, false, ResourceBindingModel.Default,
                                          true, false, false),
                VkSurfaceSource.CreateWin32(syswm.info.win.hinstance, syswm.info.win.window),
                (uint)width, (uint)height);
            Log.Debug("main swapchain color format is {format}",
                      Device.MainSwapchain.Framebuffer.ColorTargets[0].Target.Format);

            SingleRectIndexBuffer = new ResourcelessArrayBuffer <uint>(this, BufferUsage.IndexBuffer,
                                                                       new uint[] { 0, 2, 3, 0, 3, 1 }.ToImmutableArray());

            RandomnessTexture = new RandomnessTexture(this);
        }
Beispiel #2
0
        private static unsafe Veldrid.Vk.VkSurfaceSource GetSurfaceSource(SDL_SysWMinfo sysWmInfo)
        {
            switch (sysWmInfo.subsystem)
            {
            case SysWMType.Windows:
                Win32WindowInfo w32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info);
                return(Vk.VkSurfaceSource.CreateWin32(w32Info.hinstance, w32Info.Sdl2Window));

            default:
                throw new PlatformNotSupportedException("Cannot create a Vulkan surface for " + sysWmInfo.subsystem + ".");
            }
        }
Beispiel #3
0
        public IntPtr GetHWnd()
        {
            if (Window == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            var sysWmInfo = new SDL_SysWMinfo();

            SDL_GetVersion(out sysWmInfo.version);
            SDL_GetWindowWMInfo(Window, ref sysWmInfo);
            return(sysWmInfo.info.win.window);
        }
Beispiel #4
0
        static void Main(string[] args)
        {
            bool quitRequested = false;

            Core.Coocoo3DMain coocoo3DMain = new Core.Coocoo3DMain();
            IntPtr            window       = SDL_CreateWindow("Coocoo3D", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, SDL_WindowFlags.SDL_WINDOW_RESIZABLE);

            SDL_GetWindowSize(window, out int Width, out int Height);
            SDL_SysWMinfo info = new SDL_SysWMinfo();

            SDL_GetWindowWMInfo(window, ref info);
            IntPtr hwnd = info.info.win.window;

            coocoo3DMain.SetWindow(hwnd, Width, Height);
            SDL_SetWindowTitle(window, "Coocoo3D GPU: " + coocoo3DMain.statistics.DeviceDescription);
            Dictionary <SDL_Keycode, int>         sdlKeycode2ImguiKey = SDLKey();
            Dictionary <ImGuiMouseCursor, IntPtr> cursors             = CreateSDLCursor();

            var platformIO = coocoo3DMain.platformIO;

            while (!quitRequested)
            {
                quitRequested = !EventProcess(platformIO, sdlKeycode2ImguiKey);

                coocoo3DMain.RequireRender();
                var modState = SDL_GetModState();
                platformIO.KeyAlt     = (int)(modState & SDL_Keymod.KMOD_ALT) != 0;
                platformIO.KeyShift   = (int)(modState & SDL_Keymod.KMOD_SHIFT) != 0;
                platformIO.KeyControl = (int)(modState & SDL_Keymod.KMOD_CTRL) != 0;
                SDL_SetCursor(cursors[platformIO.requestCursor]);

                if (platformIO.WantTextInput)
                {
                    SDL_StartTextInput();
                }
                else
                {
                    SDL_StopTextInput();
                }
                SDL_CaptureMouse(platformIO.WantCaptureMouse ? SDL_bool.SDL_TRUE : SDL_bool.SDL_FALSE);
                try
                {
                    coocoo3DMain.UIHelper.OnFrame();
                }
                catch (Exception e)
                {
                    SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR, "error", e.Message + "\n" + e.StackTrace, window);
                }
            }
            coocoo3DMain.Dispose();
        }
        /// <summary>
        /// Fixes issues specific to the Windows platform.
        /// </summary>
        /// <param name="sysinfo">The current system information.</param>
        private void FixPlatformSpecificIssues_Windows(ref SDL_SysWMinfo sysinfo)
        {
            // NOTE: This fix prevents Windows from playing the "ding" sound when
            // a key binding involving the Alt modifier is pressed.
            wndProc = new Win32Native.WndProcDelegate((hWnd, msg, wParam, lParam) =>
            {
                const Int32 WM_SYSCOMMAND = 0x0112;
                const Int32 SC_KEYMENU    = 0xF100;
                if (msg == WM_SYSCOMMAND && (wParam.ToInt64() & 0xfff0) == SC_KEYMENU)
                {
                    return(IntPtr.Zero);
                }
                return(Win32Native.CallWindowProc(wndProcPrev, hWnd, msg, wParam, lParam));
            });

            const int GWLP_WNDPROC = -4;

            wndProcPrev = Win32Native.SetWindowLongPtr(sysinfo.info.win.window, GWLP_WNDPROC,
                                                       Marshal.GetFunctionPointerForDelegate(wndProc));
        }
Beispiel #6
0
        private static unsafe VkSurfaceSource GetSurfaceSource(SDL_SysWMinfo sysWmInfo)
        {
            switch (sysWmInfo.subsystem)
            {
            case SysWMType.Windows:
                Win32WindowInfo w32Info = Unsafe.Read <Win32WindowInfo>(&sysWmInfo.info);
                return(VkSurfaceSource.CreateWin32(w32Info.hinstance, w32Info.Sdl2Window));

            case SysWMType.X11:
                X11WindowInfo x11Info = Unsafe.Read <X11WindowInfo>(&sysWmInfo.info);
                return(VkSurfaceSource.CreateXlib(
                           (Vulkan.Xlib.Display *)x11Info.display,
                           new Vulkan.Xlib.Window()
                {
                    Value = x11Info.Sdl2Window
                }));

            default:
                throw new PlatformNotSupportedException("Cannot create a Vulkan surface for " + sysWmInfo.subsystem + ".");
            }
        }
Beispiel #7
0
        public static IntPtr GetRenderSurfaceHandle()
        {
            var info = new SDL_SysWMinfo();

            SDL_GetWindowWMInfo(_window, ref info);

            switch (RunningPlatform)
            {
            case RunningPlatform.Windows:
                return(info.info.win.window);

            case RunningPlatform.Linux:
                return(info.info.x11.window);

            case RunningPlatform.Mac:
                return(info.info.cocoa.window);
            }

            throw new Exception(
                      "SDLGamePlatform [GetRenderSurfaceHandle]: " +
                      "Invalid OS, could not retrive native renderer surface handle.");
        }
Beispiel #8
0
        public override IntPtr GetRenderSurfaceHandle()
        {
            var info = new SDL_SysWMinfo();


            SDL_GetWindowWMInfo(window, ref info);

            switch (CurrentPlatform.RunningOS)
            {
            case OS.Win:
                return(info.info.win.window);

            case OS.Linux:
                return(info.info.x11.window);

            case OS.OSX:
                return(info.info.cocoa.window);
            }

            throw new Exception(
                      "SDLGamePlatform [GetRenderSurfaceHandle]: " +
                      "Invalid OS, could not retrive native renderer surface handle.");
        }
Beispiel #9
0
        public static bool Init(IntPtr sdlWindow)
        {
            _sdlWindow = sdlWindow;

            // Setup back-end capabilities flags
            var io = ImGui.GetIO();

            // We can honor GetMouseCursor() values (optional)
            // We can honor io.WantSetMousePos requests (optional, rarely used)
            io.BackendFlags = io.BackendFlags | (ImGuiBackendFlags.HasMouseCursors | ImGuiBackendFlags.HasSetMousePos);

            // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
            io.KeyMap[(int)ImGuiKey.Tab]         = (int)SDL_Scancode.SDL_SCANCODE_TAB;
            io.KeyMap[(int)ImGuiKey.LeftArrow]   = (int)SDL_Scancode.SDL_SCANCODE_LEFT;
            io.KeyMap[(int)ImGuiKey.RightArrow]  = (int)SDL_Scancode.SDL_SCANCODE_RIGHT;
            io.KeyMap[(int)ImGuiKey.UpArrow]     = (int)SDL_Scancode.SDL_SCANCODE_UP;
            io.KeyMap[(int)ImGuiKey.DownArrow]   = (int)SDL_Scancode.SDL_SCANCODE_DOWN;
            io.KeyMap[(int)ImGuiKey.PageUp]      = (int)SDL_Scancode.SDL_SCANCODE_PAGEUP;
            io.KeyMap[(int)ImGuiKey.PageDown]    = (int)SDL_Scancode.SDL_SCANCODE_PAGEDOWN;
            io.KeyMap[(int)ImGuiKey.Home]        = (int)SDL_Scancode.SDL_SCANCODE_HOME;
            io.KeyMap[(int)ImGuiKey.End]         = (int)SDL_Scancode.SDL_SCANCODE_END;
            io.KeyMap[(int)ImGuiKey.Insert]      = (int)SDL_Scancode.SDL_SCANCODE_INSERT;
            io.KeyMap[(int)ImGuiKey.Delete]      = (int)SDL_Scancode.SDL_SCANCODE_DELETE;
            io.KeyMap[(int)ImGuiKey.Backspace]   = (int)SDL_Scancode.SDL_SCANCODE_BACKSPACE;
            io.KeyMap[(int)ImGuiKey.Space]       = (int)SDL_Scancode.SDL_SCANCODE_SPACE;
            io.KeyMap[(int)ImGuiKey.Enter]       = (int)SDL_Scancode.SDL_SCANCODE_RETURN;
            io.KeyMap[(int)ImGuiKey.Escape]      = (int)SDL_Scancode.SDL_SCANCODE_ESCAPE;
            io.KeyMap[(int)ImGuiKey.KeyPadEnter] = (int)SDL_Scancode.SDL_SCANCODE_RETURN2;
            io.KeyMap[(int)ImGuiKey.A]           = (int)SDL_Scancode.SDL_SCANCODE_A;
            io.KeyMap[(int)ImGuiKey.C]           = (int)SDL_Scancode.SDL_SCANCODE_C;
            io.KeyMap[(int)ImGuiKey.V]           = (int)SDL_Scancode.SDL_SCANCODE_V;
            io.KeyMap[(int)ImGuiKey.X]           = (int)SDL_Scancode.SDL_SCANCODE_X;
            io.KeyMap[(int)ImGuiKey.Y]           = (int)SDL_Scancode.SDL_SCANCODE_Y;
            io.KeyMap[(int)ImGuiKey.Z]           = (int)SDL_Scancode.SDL_SCANCODE_Z;

            _setText = new SetClipboardTextDelegate(SetClipboardText);
            _getText = new GetClipboardTextDelegate(GetClipboardText);

            io.SetClipboardTextFn = Marshal.GetFunctionPointerForDelegate(_setText);
            io.GetClipboardTextFn = Marshal.GetFunctionPointerForDelegate(_getText);
            io.ClipboardUserData  = IntPtr.Zero;

            _mouseCursors[(int)ImGuiMouseCursor.Arrow]      = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW);
            _mouseCursors[(int)ImGuiMouseCursor.TextInput]  = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeAll]  = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEALL);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeNS]   = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeEW]   = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeNESW] = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeNWSE] = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE);
            _mouseCursors[(int)ImGuiMouseCursor.Hand]       = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_HAND);
            // This apparently does not exist in ImGui.NET
            // _mouseCursors[(int)ImGuiMouseCursor.NotAllowed] = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_NO);

            var sysWmInfo = new SDL_SysWMinfo();

            SDL_GetVersion(out sysWmInfo.version);
            SDL_GetWindowWMInfo(sdlWindow, ref sysWmInfo);
            io.ImeWindowHandle = sysWmInfo.info.win.window;

            return(true);
        }
Beispiel #10
0
 public static SDL_bool SDL_GetWindowWMInfo(
     IntPtr window,
     ref SDL_SysWMinfo info)
 {
     return(SDL_bool.SDL_TRUE);
 }
Beispiel #11
0
 static extern void SDL_GetWMInfo(out SDL_SysWMinfo info);
Beispiel #12
0
 public static extern bool GetWindowWMInfo(IntPtr window, ref SDL_SysWMinfo sysWMinfo);
Beispiel #13
0
 private static extern int SDL_GetWindowWMInfo(IntPtr window, out SDL_SysWMinfo info);
Beispiel #14
0
        public unsafe NativeWindow(
            GraphicsService graphicsService,
            string title,
            int x, int y,
            int width, int height,
            SDL_WindowFlags flags
            )
        {
            _width           = width;
            _height          = height;
            _graphicsService = graphicsService;
            _handle          = SDL2Native.SDL_CreateWindow(
                title,
                x, y,
                width, height,
                flags
                );

            //get sdl version
            var sysWindowInfo = new SDL_SysWMinfo();

            SDL2Native.SDL_GetVersion(&sysWindowInfo.version);
            _version = sysWindowInfo.version;
            if (SDL2Native.SDL_GetWMWindowInfo(
                    _handle,
                    &sysWindowInfo
                    ) == 0)
            {
                throw new Exception("couldn't retrive sdl window information");
            }

            VkResult     error;
            VkSurfaceKHR surface;

            if (sysWindowInfo.subsystem == SysWMType.Windows)
            {
                var processHandle = (
                    Process
                    .GetCurrentProcess()
                    .SafeHandle
                    .DangerousGetHandle()
                    );
                var win32Info   = Unsafe.Read <Win32WindowInfo>(&sysWindowInfo.info);
                var surfaceInfo = new VkWin32SurfaceCreateInfoKHR
                {
                    sType     = VkStructureType.Win32SurfaceCreateInfoKHR,
                    hinstance = processHandle,
                    hwnd      = win32Info.window
                };
                error = VulkanNative.vkCreateWin32SurfaceKHR(
                    graphicsService.Handle,
                    &surfaceInfo,
                    null,
                    &surface
                    );
            }
            else if (sysWindowInfo.subsystem == SysWMType.X11)
            {
                var x11Info     = Unsafe.Read <X11WindowInfo>(&sysWindowInfo.info);
                var surfaceInfo = new VkXlibSurfaceCreateInfoKHR
                {
                    sType  = VkStructureType.XlibSurfaceCreateInfoKHR,
                    dpy    = (Vulkan.Xlib.Display *)x11Info.display,
                    window = new Vulkan.Xlib.Window
                    {
                        Value = x11Info.window
                    }
                };
                error = VulkanNative.vkCreateXlibSurfaceKHR(
                    graphicsService.Handle,
                    &surfaceInfo,
                    null,
                    &surface
                    );
            }
            else if (sysWindowInfo.subsystem == SysWMType.Wayland)
            {
                var waylandINfo = Unsafe.Read <WaylandWindowInfo>(&sysWindowInfo.info);
                var surfaceInfo = new VkWaylandSurfaceCreateInfoKHR
                {
                    sType   = VkStructureType.WaylandSurfaceCreateInfoKHR,
                    display = (Vulkan.Wayland.wl_display *)waylandINfo.display,
                    surface = (Vulkan.Wayland.wl_surface *)waylandINfo.surface
                };
                error = VulkanNative.vkCreateWaylandSurfaceKHR(
                    graphicsService.Handle,
                    &surfaceInfo,
                    null,
                    &surface
                    );
            }
            else if (sysWindowInfo.subsystem == SysWMType.Android)
            {
                var androidInfo = Unsafe.Read <AndroidWindowInfo>(&sysWindowInfo.info);
                var surfaceInfo = new VkAndroidSurfaceCreateInfoKHR
                {
                    sType  = VkStructureType.AndroidSurfaceCreateInfoKHR,
                    window = (Vulkan.Android.ANativeWindow *)androidInfo.window
                };
                error = VulkanNative.vkCreateAndroidSurfaceKHR(
                    graphicsService.Handle,
                    &surfaceInfo,
                    null,
                    &surface
                    );
            }
            else if (sysWindowInfo.subsystem == SysWMType.Mir)
            {
                var mirInfo     = Unsafe.Read <MirWindowInfo>(&sysWindowInfo.info);
                var surfaceInfo = new VkMirSurfaceCreateInfoKHR
                {
                    sType      = VkStructureType.MirSurfaceCreateInfoKHR,
                    connection = (Vulkan.Mir.MirConnection *)mirInfo.connection,
                    mirSurface = (Vulkan.Mir.MirSurface *)mirInfo.mirSurface
                };
                error = VulkanNative.vkCreateMirSurfaceKHR(
                    graphicsService.Handle,
                    &surfaceInfo,
                    null,
                    &surface
                    );
            }
            else if (sysWindowInfo.subsystem == SysWMType.Cocoa)
            {
                var cocaInfo = Unsafe.Read <CocoaWindowInfo>(&sysWindowInfo.info);

                var nsWindow    = new NSWindow(cocaInfo.Window);
                var contentView = nsWindow.contentView;
                contentView.wantsLayer = true;
                contentView.layer      = CAMetalLayer.New().NativePtr;

                var surfaceInfo = new VkMacOSSurfaceCreateInfoMVK
                {
                    sType = VkStructureType.MacosSurfaceCreateInfoMvk,
                    pView = nsWindow.contentView.NativePtr.ToPointer()
                };
                error = VulkanNative.vkCreateMacOSSurfaceMVK(
                    graphicsService.Handle,
                    &surfaceInfo,
                    null,
                    &surface
                    );
            }
            else
            {
                throw new PlatformNotSupportedException("this platform is currently not supported");
            }

            if (error != VkResult.Success)
            {
                throw new Exception("failed to create window surface");
            }

            _surface = surface;
        }
Beispiel #15
0
        unsafe static void Main(string[] args)
        {
            int width  = 640;
            int height = 480;

            var renderer = new Renderer();

            renderer.CreateSDL(width, height, string.Format("OpenLSR v{0}", Assembly.GetEntryAssembly().GetName().Version.ToString()));

            var wmi = new SDL_SysWMinfo();

            SDL_VERSION(out wmi.version);
            SDL_GetWindowWMInfo(renderer.window, ref wmi);

            var pd = new PlatformData();

            pd.WindowHandle = wmi.info.win.window;

            var init = new InitSettings();

            init.PlatformData = pd;

            Bgfx.Init(init);
            Bgfx.Reset(width, height, ResetFlags.Vsync);

            SDL_ShowWindow(renderer.window);

            // enable debug text
            Bgfx.SetDebugFeatures(DebugFeatures.DisplayText);

            // set view 0 clear state
            Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff);

            bool      quit = false;
            SDL_Event Event;

            // start the frame clock
            var clock = new GameClock();

            clock.Start();

            // main loop
            while (!quit)
            {
                while (SDL_PollEvent(out Event) != 0)
                {
                    switch (Event.type)
                    {
                    case SDL_EventType.SDL_QUIT:
                        quit = true;
                        break;

                    default:
                        break;
                    }
                }

                // set view 0 viewport
                Bgfx.SetViewRect(0, 0, 0, width, height);

                //  make sure view 0 is cleared if no other draw calls are submitted
                Bgfx.Touch(0);

                // tick the clock
                var elapsed = clock.Frame();
                var time    = clock.TotalTime();

                // write some debug text
                Bgfx.DebugTextClear();

                Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Magenta, "OpenLSR Test");
                Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Magenta, "Frame: {0:F3} ms", elapsed * 1000);


                // advance to the next frame. Rendering thread will be kicked to
                // process submitted rendering primitives.
                Bgfx.Frame();
            }

            // clean up
            Bgfx.Shutdown();

            SDL_DestroyRenderer(renderer.renderer);
            SDL_DestroyWindow(renderer.window);

            SDL_Quit();
        }
Beispiel #16
0
 static extern void SDL_GetWMInfo(out SDL_SysWMinfo info);
Beispiel #17
0
        public ImGui_Impl_SDL(IntPtr sdlWindow)
        {
            _sdlWindow = sdlWindow;

            // Setup back-end capabilities flags
            var io = ImGui.GetIO();

            // We can honor GetMouseCursor() values (optional)
            // We can honor io.WantSetMousePos requests (optional, rarely used)
            io.BackendFlags = io.BackendFlags | ImGuiBackendFlags.HasMouseCursors | ImGuiBackendFlags.HasSetMousePos;

            // BackendPlatformName is readonly (and null) in ImGui.NET for some reason, but we can hack it via its internal pointer
            _platformNamePtr = Marshal.StringToHGlobalAnsi("imgui_impl_sdl_c#");
            unsafe
            {
                io.NativePtr->BackendPlatformName = (byte *)_platformNamePtr.ToPointer();
            }

            // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
            io.KeyMap[(int)ImGuiKey.Tab]         = (int)SDL_Scancode.SDL_SCANCODE_TAB;
            io.KeyMap[(int)ImGuiKey.LeftArrow]   = (int)SDL_Scancode.SDL_SCANCODE_LEFT;
            io.KeyMap[(int)ImGuiKey.RightArrow]  = (int)SDL_Scancode.SDL_SCANCODE_RIGHT;
            io.KeyMap[(int)ImGuiKey.UpArrow]     = (int)SDL_Scancode.SDL_SCANCODE_UP;
            io.KeyMap[(int)ImGuiKey.DownArrow]   = (int)SDL_Scancode.SDL_SCANCODE_DOWN;
            io.KeyMap[(int)ImGuiKey.PageUp]      = (int)SDL_Scancode.SDL_SCANCODE_PAGEUP;
            io.KeyMap[(int)ImGuiKey.PageDown]    = (int)SDL_Scancode.SDL_SCANCODE_PAGEDOWN;
            io.KeyMap[(int)ImGuiKey.Home]        = (int)SDL_Scancode.SDL_SCANCODE_HOME;
            io.KeyMap[(int)ImGuiKey.End]         = (int)SDL_Scancode.SDL_SCANCODE_END;
            io.KeyMap[(int)ImGuiKey.Insert]      = (int)SDL_Scancode.SDL_SCANCODE_INSERT;
            io.KeyMap[(int)ImGuiKey.Delete]      = (int)SDL_Scancode.SDL_SCANCODE_DELETE;
            io.KeyMap[(int)ImGuiKey.Backspace]   = (int)SDL_Scancode.SDL_SCANCODE_BACKSPACE;
            io.KeyMap[(int)ImGuiKey.Space]       = (int)SDL_Scancode.SDL_SCANCODE_SPACE;
            io.KeyMap[(int)ImGuiKey.Enter]       = (int)SDL_Scancode.SDL_SCANCODE_RETURN;
            io.KeyMap[(int)ImGuiKey.Escape]      = (int)SDL_Scancode.SDL_SCANCODE_ESCAPE;
            io.KeyMap[(int)ImGuiKey.KeyPadEnter] = (int)SDL_Scancode.SDL_SCANCODE_RETURN2;
            io.KeyMap[(int)ImGuiKey.A]           = (int)SDL_Scancode.SDL_SCANCODE_A;
            io.KeyMap[(int)ImGuiKey.C]           = (int)SDL_Scancode.SDL_SCANCODE_C;
            io.KeyMap[(int)ImGuiKey.V]           = (int)SDL_Scancode.SDL_SCANCODE_V;
            io.KeyMap[(int)ImGuiKey.X]           = (int)SDL_Scancode.SDL_SCANCODE_X;
            io.KeyMap[(int)ImGuiKey.Y]           = (int)SDL_Scancode.SDL_SCANCODE_Y;
            io.KeyMap[(int)ImGuiKey.Z]           = (int)SDL_Scancode.SDL_SCANCODE_Z;

            _setText = new SetClipboardTextDelegate(SetClipboardText);
            _getText = new GetClipboardTextDelegate(GetClipboardText);

            io.SetClipboardTextFn = Marshal.GetFunctionPointerForDelegate(_setText);
            io.GetClipboardTextFn = Marshal.GetFunctionPointerForDelegate(_getText);
            io.ClipboardUserData  = IntPtr.Zero;

            _mouseCursors[(int)ImGuiMouseCursor.Arrow]      = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW);
            _mouseCursors[(int)ImGuiMouseCursor.TextInput]  = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeAll]  = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEALL);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeNS]   = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeEW]   = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeNESW] = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW);
            _mouseCursors[(int)ImGuiMouseCursor.ResizeNWSE] = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE);
            _mouseCursors[(int)ImGuiMouseCursor.Hand]       = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_HAND);
            _mouseCursors[(int)ImGuiMouseCursor.NotAllowed] = SDL_CreateSystemCursor(SDL_SystemCursor.SDL_SYSTEM_CURSOR_NO);

            var sysWmInfo = new SDL_SysWMinfo();

            SDL_GetVersion(out sysWmInfo.version);
            SDL_GetWindowWMInfo(_sdlWindow, ref sysWmInfo);

            // TODO: This does not exist in newer ImGui versions
            //io.ImeWindowHandle = sysWmInfo.info.win.window;
        }