2020-10-12 17:34:22 +02:00
// dear imgui: Platform Backend for SDL2
2018-02-21 23:05:17 +01:00
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
2021-07-29 18:21:08 +02:00
// (Prefer SDL 2.0.5+ for full feature support.)
2016-03-24 11:00:47 +01:00
2018-02-05 20:34:11 +01:00
// Implemented features:
2018-06-11 12:33:51 +02:00
// [X] Platform: Clipboard support.
2023-04-04 19:43:51 +02:00
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
2024-11-06 16:56:51 +01:00
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
2019-04-23 12:26:14 +02:00
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
2024-12-05 12:43:04 +01:00
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
2023-02-07 18:55:10 +01:00
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
2018-06-12 16:24:24 +02:00
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
2024-12-11 12:27:25 +01:00
// Missing features or Issues:
2024-02-28 11:03:44 +01:00
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
2018-02-05 20:34:11 +01:00
2021-06-24 17:34:23 +02:00
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
2021-05-27 13:59:35 +02:00
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
2023-09-11 13:47:08 +02:00
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
2015-07-08 18:27:25 +02:00
2018-02-15 11:11:21 +01:00
// CHANGELOG
2018-02-16 17:20:18 +01:00
// (minor and older changes stripped away, please see git history for details)
2024-02-14 14:32:17 +01:00
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
2024-10-24 14:47:07 +02:00
// 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
2024-09-08 12:19:51 +02:00
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
2024-08-22 17:50:10 +02:00
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
2024-08-22 16:42:57 +02:00
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
2024-08-22 16:55:14 +02:00
// - io.PlatformSetImeDataFn -> platform_io.Platform_SetImeDataFn
2024-08-19 14:07:25 +02:00
// 2024-08-19: Storing SDL's Uint32 WindowID inside ImGuiViewport::PlatformHandle instead of SDL_Window*.
2024-08-19 13:57:08 +02:00
// 2024-08-19: ImGui_ImplSDL2_ProcessEvent() now ignores events intended for other SDL windows. (#7853)
2024-07-02 18:06:19 +02:00
// 2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
2024-07-02 15:48:32 +02:00
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
2024-02-14 11:30:43 +01:00
// 2024-02-14: Inputs: Handle gamepad disconnection. Added ImGui_ImplSDL2_SetGamepadMode().
2023-10-05 21:26:07 +02:00
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
2023-04-11 11:20:29 +02:00
// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's unclear exactly what their relation is to IME. (#6306)
2023-04-04 19:43:51 +02:00
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
2023-02-23 13:06:07 +01:00
// 2023-02-23: Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644)
2023-02-07 18:55:10 +01:00
// 2023-02-07: Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()).
2023-02-07 11:54:50 +01:00
// 2023-02-07: *BREAKING CHANGE* Renamed this backend file from imgui_impl_sdl.cpp/.h to imgui_impl_sdl2.cpp/.h in prevision for the future release of SDL3.
2023-02-02 21:28:28 +01:00
// 2023-02-02: Avoid calling SDL_SetCursor() when cursor has not changed, as the function is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version).
2023-02-02 18:33:04 +01:00
// 2023-02-02: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data for smooth scrolling + Scaling X value on Emscripten (bug?). (#4019, #6096)
2023-02-02 14:23:39 +01:00
// 2023-02-02: Removed SDL_MOUSEWHEEL value clamping, as values seem correct in latest Emscripten. (#4019)
2023-02-01 20:50:45 +01:00
// 2023-02-01: Flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
2022-10-11 12:22:29 +02:00
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
2022-09-26 14:44:26 +02:00
// 2022-09-26: Inputs: Disable SDL 2.0.22 new "auto capture" (SDL_HINT_MOUSE_AUTO_CAPTURE) which prevents drag and drop across windows for multi-viewport support + don't capture when drag and dropping. (#5710)
2022-09-22 18:58:33 +02:00
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
2022-03-22 18:06:48 +01:00
// 2022-03-22: Inputs: Fix mouse position issues when dragging outside of boundaries. SDL_CaptureMouse() erroneously still gives out LEAVE events when hovering OS decorations.
2022-03-20 00:13:31 +01:00
// 2022-03-22: Inputs: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2).
2022-01-22 14:55:03 +01:00
// 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer.
2022-02-25 17:18:40 +01:00
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
2022-01-20 17:12:28 +01:00
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
2022-01-17 17:22:37 +01:00
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
2022-01-21 17:32:35 +01:00
// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates.
2022-01-12 16:44:24 +01:00
// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
2022-01-12 16:11:10 +01:00
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
2022-01-10 16:59:31 +01:00
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
2021-08-02 20:17:26 +02:00
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
2021-07-29 18:21:08 +02:00
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
2021-06-29 19:54:25 +02:00
// 2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
2021-06-28 16:52:10 +02:00
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
2021-03-20 15:06:53 +01:00
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
2020-05-25 12:23:49 +02:00
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
2020-02-20 12:28:06 +01:00
// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
2019-12-17 14:34:18 +01:00
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
2019-12-05 15:43:05 +01:00
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
2019-07-22 03:39:50 +02:00
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
2019-04-23 12:26:14 +02:00
// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
2019-03-12 18:27:14 +01:00
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
2018-12-21 16:33:50 +01:00
// 2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls.
2018-11-30 18:18:15 +01:00
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
2018-11-23 18:12:37 +01:00
// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'.
2018-08-01 11:34:17 +02:00
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
2018-06-29 16:30:41 +02:00
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
2018-06-10 15:45:54 +02:00
// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples.
2019-01-20 17:56:17 +01:00
// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter.
2018-05-11 22:22:41 +02:00
// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText).
2018-04-06 23:34:43 +02:00
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
2018-02-16 19:55:16 +01:00
// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value.
2018-02-16 17:20:18 +01:00
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS).
2019-01-20 17:56:17 +01:00
// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes.
2018-02-16 17:20:18 +01:00
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS.
// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
2018-02-15 11:11:21 +01:00
2018-02-16 22:22:47 +01:00
# include "imgui.h"
2023-07-13 11:27:52 +02:00
# ifndef IMGUI_DISABLE
2023-02-07 11:54:50 +01:00
# include "imgui_impl_sdl2.h"
2018-02-27 23:30:39 +01:00
2023-03-23 18:17:45 +01:00
// Clang warnings with -Weverything
# if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
# endif
2018-02-27 10:29:37 +01:00
// SDL
2018-12-21 16:26:17 +01:00
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
2015-05-25 09:40:58 +02:00
# include <SDL.h>
# include <SDL_syswm.h>
2024-07-02 18:06:19 +02:00
# ifdef __APPLE__
2021-08-24 15:26:55 +02:00
# include <TargetConditionals.h>
2018-12-21 16:33:50 +01:00
# endif
2024-07-02 18:06:19 +02:00
# ifdef __EMSCRIPTEN__
# include <emscripten/em_js.h>
# endif
2018-06-08 19:37:33 +02:00
2022-04-13 20:38:45 +02:00
# if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
2021-08-18 12:00:15 +02:00
# define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
# else
# define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
# endif
2018-11-28 22:50:37 +01:00
# define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5)
2018-04-23 15:54:38 +02:00
# define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5)
# define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5)
# define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4)
# define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
2023-04-21 15:40:14 +02:00
# define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9)
2024-08-17 13:13:10 +02:00
# define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18)
2024-09-08 12:19:51 +02:00
# if SDL_HAS_VULKAN
2024-10-24 00:20:13 +02:00
# include <SDL_vulkan.h>
2024-10-24 18:15:51 +02:00
# else
2018-03-14 14:14:16 +01:00
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000 ;
# endif
2015-05-25 09:40:58 +02:00
2021-08-02 15:48:20 +02:00
// SDL Data
2021-06-28 16:52:10 +02:00
struct ImGui_ImplSDL2_Data
{
2024-02-13 15:49:49 +01:00
SDL_Window * Window ;
2024-08-19 13:57:08 +02:00
Uint32 WindowID ;
2024-02-13 15:49:49 +01:00
SDL_Renderer * Renderer ;
Uint64 Time ;
char * ClipboardTextData ;
2024-02-14 14:32:17 +01:00
bool UseVulkan ;
bool WantUpdateMonitors ;
2024-02-13 15:49:49 +01:00
// Mouse handling
Uint32 MouseWindowID ;
int MouseButtonsDown ;
SDL_Cursor * MouseCursors [ ImGuiMouseCursor_COUNT ] ;
SDL_Cursor * MouseLastCursor ;
int MouseLastLeaveFrame ;
bool MouseCanUseGlobalState ;
2024-02-14 14:32:17 +01:00
bool MouseCanReportHoveredViewport ; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
2021-06-28 16:52:10 +02:00
2024-02-13 16:24:44 +01:00
// Gamepad handling
2024-02-13 18:50:21 +01:00
ImVector < SDL_GameController * > Gamepads ;
ImGui_ImplSDL2_GamepadMode GamepadMode ;
bool WantUpdateGamepadsList ;
2021-06-28 16:52:10 +02:00
2022-03-13 07:15:32 +01:00
ImGui_ImplSDL2_Data ( ) { memset ( ( void * ) this , 0 , sizeof ( * this ) ) ; }
2021-06-28 16:52:10 +02:00
} ;
2021-06-29 16:42:13 +02:00
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
2021-06-30 15:22:15 +02:00
static ImGui_ImplSDL2_Data * ImGui_ImplSDL2_GetBackendData ( )
{
2022-10-11 12:22:29 +02:00
return ImGui : : GetCurrentContext ( ) ? ( ImGui_ImplSDL2_Data * ) ImGui : : GetIO ( ) . BackendPlatformUserData : nullptr ;
2021-06-30 15:22:15 +02:00
}
2015-05-25 09:40:58 +02:00
2018-02-27 23:30:39 +01:00
// Forward Declarations
2020-02-09 17:31:18 +01:00
static void ImGui_ImplSDL2_UpdateMonitors ( ) ;
2024-10-08 20:47:24 +02:00
static void ImGui_ImplSDL2_InitMultiViewportSupport ( SDL_Window * window , void * sdl_gl_context ) ;
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport ( ) ;
2018-02-27 23:30:39 +01:00
2021-06-28 16:52:10 +02:00
// Functions
2024-08-22 17:50:10 +02:00
static const char * ImGui_ImplSDL2_GetClipboardText ( ImGuiContext * )
2015-05-25 09:40:58 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
if ( bd - > ClipboardTextData )
SDL_free ( bd - > ClipboardTextData ) ;
bd - > ClipboardTextData = SDL_GetClipboardText ( ) ;
return bd - > ClipboardTextData ;
2015-05-25 09:40:58 +02:00
}
2024-08-22 17:50:10 +02:00
static void ImGui_ImplSDL2_SetClipboardText ( ImGuiContext * , const char * text )
2015-05-25 09:40:58 +02:00
{
SDL_SetClipboardText ( text ) ;
}
2023-02-07 18:55:10 +01:00
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
2024-07-02 17:48:38 +02:00
static void ImGui_ImplSDL2_PlatformSetImeData ( ImGuiContext * , ImGuiViewport * viewport , ImGuiPlatformImeData * data )
2023-02-07 18:55:10 +01:00
{
if ( data - > WantVisible )
{
SDL_Rect r ;
2023-04-06 19:18:15 +02:00
r . x = ( int ) ( data - > InputPos . x - viewport - > Pos . x ) ;
r . y = ( int ) ( data - > InputPos . y - viewport - > Pos . y + data - > InputLineHeight ) ;
2023-02-07 18:55:10 +01:00
r . w = 1 ;
r . h = ( int ) data - > InputLineHeight ;
SDL_SetTextInputRect ( & r ) ;
}
}
2024-09-19 14:09:45 +02:00
// Not static to allow third-party code to use that if they want to (but undocumented)
2024-10-24 17:24:47 +02:00
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey ( SDL_Keycode keycode , SDL_Scancode scancode ) ;
2024-09-19 14:09:45 +02:00
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey ( SDL_Keycode keycode , SDL_Scancode scancode )
2021-12-12 11:57:37 +01:00
{
2024-07-02 11:32:46 +02:00
IM_UNUSED ( scancode ) ;
2021-12-12 11:57:37 +01:00
switch ( keycode )
{
case SDLK_TAB : return ImGuiKey_Tab ;
case SDLK_LEFT : return ImGuiKey_LeftArrow ;
case SDLK_RIGHT : return ImGuiKey_RightArrow ;
case SDLK_UP : return ImGuiKey_UpArrow ;
case SDLK_DOWN : return ImGuiKey_DownArrow ;
case SDLK_PAGEUP : return ImGuiKey_PageUp ;
case SDLK_PAGEDOWN : return ImGuiKey_PageDown ;
case SDLK_HOME : return ImGuiKey_Home ;
case SDLK_END : return ImGuiKey_End ;
case SDLK_INSERT : return ImGuiKey_Insert ;
case SDLK_DELETE : return ImGuiKey_Delete ;
case SDLK_BACKSPACE : return ImGuiKey_Backspace ;
case SDLK_SPACE : return ImGuiKey_Space ;
case SDLK_RETURN : return ImGuiKey_Enter ;
case SDLK_ESCAPE : return ImGuiKey_Escape ;
case SDLK_QUOTE : return ImGuiKey_Apostrophe ;
case SDLK_COMMA : return ImGuiKey_Comma ;
case SDLK_MINUS : return ImGuiKey_Minus ;
case SDLK_PERIOD : return ImGuiKey_Period ;
case SDLK_SLASH : return ImGuiKey_Slash ;
case SDLK_SEMICOLON : return ImGuiKey_Semicolon ;
case SDLK_EQUALS : return ImGuiKey_Equal ;
case SDLK_LEFTBRACKET : return ImGuiKey_LeftBracket ;
case SDLK_BACKSLASH : return ImGuiKey_Backslash ;
case SDLK_RIGHTBRACKET : return ImGuiKey_RightBracket ;
case SDLK_BACKQUOTE : return ImGuiKey_GraveAccent ;
case SDLK_CAPSLOCK : return ImGuiKey_CapsLock ;
case SDLK_SCROLLLOCK : return ImGuiKey_ScrollLock ;
case SDLK_NUMLOCKCLEAR : return ImGuiKey_NumLock ;
case SDLK_PRINTSCREEN : return ImGuiKey_PrintScreen ;
case SDLK_PAUSE : return ImGuiKey_Pause ;
case SDLK_KP_0 : return ImGuiKey_Keypad0 ;
case SDLK_KP_1 : return ImGuiKey_Keypad1 ;
case SDLK_KP_2 : return ImGuiKey_Keypad2 ;
case SDLK_KP_3 : return ImGuiKey_Keypad3 ;
case SDLK_KP_4 : return ImGuiKey_Keypad4 ;
case SDLK_KP_5 : return ImGuiKey_Keypad5 ;
case SDLK_KP_6 : return ImGuiKey_Keypad6 ;
case SDLK_KP_7 : return ImGuiKey_Keypad7 ;
case SDLK_KP_8 : return ImGuiKey_Keypad8 ;
case SDLK_KP_9 : return ImGuiKey_Keypad9 ;
case SDLK_KP_PERIOD : return ImGuiKey_KeypadDecimal ;
case SDLK_KP_DIVIDE : return ImGuiKey_KeypadDivide ;
case SDLK_KP_MULTIPLY : return ImGuiKey_KeypadMultiply ;
case SDLK_KP_MINUS : return ImGuiKey_KeypadSubtract ;
case SDLK_KP_PLUS : return ImGuiKey_KeypadAdd ;
case SDLK_KP_ENTER : return ImGuiKey_KeypadEnter ;
case SDLK_KP_EQUALS : return ImGuiKey_KeypadEqual ;
2022-01-17 15:41:04 +01:00
case SDLK_LCTRL : return ImGuiKey_LeftCtrl ;
2021-12-12 11:57:37 +01:00
case SDLK_LSHIFT : return ImGuiKey_LeftShift ;
case SDLK_LALT : return ImGuiKey_LeftAlt ;
case SDLK_LGUI : return ImGuiKey_LeftSuper ;
2022-01-17 15:41:04 +01:00
case SDLK_RCTRL : return ImGuiKey_RightCtrl ;
2021-12-12 11:57:37 +01:00
case SDLK_RSHIFT : return ImGuiKey_RightShift ;
case SDLK_RALT : return ImGuiKey_RightAlt ;
case SDLK_RGUI : return ImGuiKey_RightSuper ;
2022-01-24 12:10:40 +01:00
case SDLK_APPLICATION : return ImGuiKey_Menu ;
2021-12-12 11:57:37 +01:00
case SDLK_0 : return ImGuiKey_0 ;
case SDLK_1 : return ImGuiKey_1 ;
case SDLK_2 : return ImGuiKey_2 ;
case SDLK_3 : return ImGuiKey_3 ;
case SDLK_4 : return ImGuiKey_4 ;
case SDLK_5 : return ImGuiKey_5 ;
case SDLK_6 : return ImGuiKey_6 ;
case SDLK_7 : return ImGuiKey_7 ;
case SDLK_8 : return ImGuiKey_8 ;
case SDLK_9 : return ImGuiKey_9 ;
case SDLK_a : return ImGuiKey_A ;
case SDLK_b : return ImGuiKey_B ;
case SDLK_c : return ImGuiKey_C ;
case SDLK_d : return ImGuiKey_D ;
case SDLK_e : return ImGuiKey_E ;
case SDLK_f : return ImGuiKey_F ;
case SDLK_g : return ImGuiKey_G ;
case SDLK_h : return ImGuiKey_H ;
case SDLK_i : return ImGuiKey_I ;
case SDLK_j : return ImGuiKey_J ;
case SDLK_k : return ImGuiKey_K ;
case SDLK_l : return ImGuiKey_L ;
case SDLK_m : return ImGuiKey_M ;
case SDLK_n : return ImGuiKey_N ;
case SDLK_o : return ImGuiKey_O ;
case SDLK_p : return ImGuiKey_P ;
case SDLK_q : return ImGuiKey_Q ;
case SDLK_r : return ImGuiKey_R ;
case SDLK_s : return ImGuiKey_S ;
case SDLK_t : return ImGuiKey_T ;
case SDLK_u : return ImGuiKey_U ;
case SDLK_v : return ImGuiKey_V ;
case SDLK_w : return ImGuiKey_W ;
case SDLK_x : return ImGuiKey_X ;
case SDLK_y : return ImGuiKey_Y ;
case SDLK_z : return ImGuiKey_Z ;
case SDLK_F1 : return ImGuiKey_F1 ;
case SDLK_F2 : return ImGuiKey_F2 ;
case SDLK_F3 : return ImGuiKey_F3 ;
case SDLK_F4 : return ImGuiKey_F4 ;
case SDLK_F5 : return ImGuiKey_F5 ;
case SDLK_F6 : return ImGuiKey_F6 ;
case SDLK_F7 : return ImGuiKey_F7 ;
case SDLK_F8 : return ImGuiKey_F8 ;
case SDLK_F9 : return ImGuiKey_F9 ;
case SDLK_F10 : return ImGuiKey_F10 ;
case SDLK_F11 : return ImGuiKey_F11 ;
case SDLK_F12 : return ImGuiKey_F12 ;
2023-10-05 20:39:49 +02:00
case SDLK_F13 : return ImGuiKey_F13 ;
case SDLK_F14 : return ImGuiKey_F14 ;
case SDLK_F15 : return ImGuiKey_F15 ;
case SDLK_F16 : return ImGuiKey_F16 ;
case SDLK_F17 : return ImGuiKey_F17 ;
case SDLK_F18 : return ImGuiKey_F18 ;
case SDLK_F19 : return ImGuiKey_F19 ;
case SDLK_F20 : return ImGuiKey_F20 ;
case SDLK_F21 : return ImGuiKey_F21 ;
case SDLK_F22 : return ImGuiKey_F22 ;
case SDLK_F23 : return ImGuiKey_F23 ;
case SDLK_F24 : return ImGuiKey_F24 ;
2023-10-05 21:26:07 +02:00
case SDLK_AC_BACK : return ImGuiKey_AppBack ;
case SDLK_AC_FORWARD : return ImGuiKey_AppForward ;
2024-07-02 12:12:25 +02:00
default : break ;
2021-12-12 11:57:37 +01:00
}
return ImGuiKey_None ;
}
2022-01-17 14:57:55 +01:00
static void ImGui_ImplSDL2_UpdateKeyModifiers ( SDL_Keymod sdl_key_mods )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2022-09-22 18:58:33 +02:00
io . AddKeyEvent ( ImGuiMod_Ctrl , ( sdl_key_mods & KMOD_CTRL ) ! = 0 ) ;
io . AddKeyEvent ( ImGuiMod_Shift , ( sdl_key_mods & KMOD_SHIFT ) ! = 0 ) ;
io . AddKeyEvent ( ImGuiMod_Alt , ( sdl_key_mods & KMOD_ALT ) ! = 0 ) ;
io . AddKeyEvent ( ImGuiMod_Super , ( sdl_key_mods & KMOD_GUI ) ! = 0 ) ;
2022-01-17 14:57:55 +01:00
}
2024-08-19 13:57:08 +02:00
static ImGuiViewport * ImGui_ImplSDL2_GetViewportForWindowID ( Uint32 window_id )
{
2024-08-19 14:46:53 +02:00
return ImGui : : FindViewportByPlatformHandle ( ( void * ) ( intptr_t ) window_id ) ;
2024-08-19 13:57:08 +02:00
}
Examples: Added a bunch of comments/referencs related to io.WantCaptureMouse, io.WantCaptureKeyboard (#1262, #1237, #1219, #635, #1058, #1051, #912, #533, #703, #446, #459, #364, #213, #52, and more)
2017-11-01 14:24:09 +01:00
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
2022-02-28 20:50:58 +01:00
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
Examples: Added a bunch of comments/referencs related to io.WantCaptureMouse, io.WantCaptureKeyboard (#1262, #1237, #1219, #635, #1058, #1051, #912, #533, #703, #446, #459, #364, #213, #52, and more)
2017-11-01 14:24:09 +01:00
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
2018-11-23 18:12:37 +01:00
bool ImGui_ImplSDL2_ProcessEvent ( const SDL_Event * event )
2015-05-25 09:40:58 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2024-05-07 16:53:03 +02:00
IM_ASSERT ( bd ! = nullptr & & " Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()? " ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 16:52:10 +02:00
2015-07-08 19:42:43 +02:00
switch ( event - > type )
2015-07-08 18:10:54 +02:00
{
2022-01-12 16:44:24 +01:00
case SDL_MOUSEMOTION :
{
2024-12-05 12:25:02 +01:00
if ( ImGui_ImplSDL2_GetViewportForWindowID ( event - > motion . windowID ) = = nullptr )
2024-08-02 00:05:51 +02:00
return false ;
2022-01-13 18:36:23 +01:00
ImVec2 mouse_pos ( ( float ) event - > motion . x , ( float ) event - > motion . y ) ;
if ( io . ConfigFlags & ImGuiConfigFlags_ViewportsEnable )
{
int window_x , window_y ;
SDL_GetWindowPosition ( SDL_GetWindowFromID ( event - > motion . windowID ) , & window_x , & window_y ) ;
mouse_pos . x + = window_x ;
mouse_pos . y + = window_y ;
}
2023-04-04 19:43:51 +02:00
io . AddMouseSourceEvent ( event - > motion . which = = SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse ) ;
2022-01-17 18:16:55 +01:00
io . AddMousePosEvent ( mouse_pos . x , mouse_pos . y ) ;
2022-01-12 16:44:24 +01:00
return true ;
}
2022-01-11 22:56:35 +01:00
case SDL_MOUSEWHEEL :
2015-07-08 18:10:54 +02:00
{
2024-12-05 12:25:02 +01:00
if ( ImGui_ImplSDL2_GetViewportForWindowID ( event - > wheel . windowID ) = = nullptr )
2024-08-02 00:05:51 +02:00
return false ;
2023-02-02 18:33:04 +01:00
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
# if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten!
float wheel_x = - event - > wheel . preciseX ;
float wheel_y = event - > wheel . preciseY ;
# else
2023-02-02 14:23:39 +01:00
float wheel_x = - ( float ) event - > wheel . x ;
float wheel_y = ( float ) event - > wheel . y ;
2023-02-02 18:33:04 +01:00
# endif
2024-10-24 14:47:07 +02:00
# if defined(__EMSCRIPTEN__) && !SDL_VERSION_ATLEAST(2,31,0)
2023-02-02 18:33:04 +01:00
wheel_x / = 100.0f ;
# endif
2023-04-04 19:43:51 +02:00
io . AddMouseSourceEvent ( event - > wheel . which = = SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse ) ;
2022-01-17 17:22:37 +01:00
io . AddMouseWheelEvent ( wheel_x , wheel_y ) ;
2015-07-08 18:10:54 +02:00
return true ;
}
2022-01-11 22:56:35 +01:00
case SDL_MOUSEBUTTONDOWN :
2022-01-12 16:11:10 +01:00
case SDL_MOUSEBUTTONUP :
2015-07-08 18:10:54 +02:00
{
2024-12-05 12:25:02 +01:00
if ( ImGui_ImplSDL2_GetViewportForWindowID ( event - > button . windowID ) = = nullptr )
2024-08-02 00:05:51 +02:00
return false ;
2022-01-12 16:11:10 +01:00
int mouse_button = - 1 ;
if ( event - > button . button = = SDL_BUTTON_LEFT ) { mouse_button = 0 ; }
if ( event - > button . button = = SDL_BUTTON_RIGHT ) { mouse_button = 1 ; }
if ( event - > button . button = = SDL_BUTTON_MIDDLE ) { mouse_button = 2 ; }
2022-03-20 00:13:31 +01:00
if ( event - > button . button = = SDL_BUTTON_X1 ) { mouse_button = 3 ; }
if ( event - > button . button = = SDL_BUTTON_X2 ) { mouse_button = 4 ; }
2022-01-12 16:11:10 +01:00
if ( mouse_button = = - 1 )
break ;
2023-04-04 19:43:51 +02:00
io . AddMouseSourceEvent ( event - > button . which = = SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse ) ;
2022-01-17 17:22:37 +01:00
io . AddMouseButtonEvent ( mouse_button , ( event - > type = = SDL_MOUSEBUTTONDOWN ) ) ;
2022-01-12 16:11:10 +01:00
bd - > MouseButtonsDown = ( event - > type = = SDL_MOUSEBUTTONDOWN ) ? ( bd - > MouseButtonsDown | ( 1 < < mouse_button ) ) : ( bd - > MouseButtonsDown & ~ ( 1 < < mouse_button ) ) ;
2015-07-08 18:10:54 +02:00
return true ;
}
2022-01-11 22:56:35 +01:00
case SDL_TEXTINPUT :
2015-07-08 18:10:54 +02:00
{
2024-12-05 12:25:02 +01:00
if ( ImGui_ImplSDL2_GetViewportForWindowID ( event - > text . windowID ) = = nullptr )
2024-08-02 00:05:51 +02:00
return false ;
2015-07-16 05:16:22 +02:00
io . AddInputCharactersUTF8 ( event - > text . text ) ;
2015-07-08 18:10:54 +02:00
return true ;
}
2022-01-11 22:56:35 +01:00
case SDL_KEYDOWN :
case SDL_KEYUP :
2015-07-08 18:10:54 +02:00
{
2024-12-05 12:25:02 +01:00
if ( ImGui_ImplSDL2_GetViewportForWindowID ( event - > key . windowID ) = = nullptr )
2024-08-02 00:05:51 +02:00
return false ;
2022-01-17 14:57:55 +01:00
ImGui_ImplSDL2_UpdateKeyModifiers ( ( SDL_Keymod ) event - > key . keysym . mod ) ;
2024-07-02 11:32:46 +02:00
ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey ( event - > key . keysym . sym , event - > key . keysym . scancode ) ;
2021-12-12 11:57:37 +01:00
io . AddKeyEvent ( key , ( event - > type = = SDL_KEYDOWN ) ) ;
io . SetKeyEventNativeData ( key , event - > key . keysym . sym , event - > key . keysym . scancode , event - > key . keysym . scancode ) ; // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
2015-07-08 18:10:54 +02:00
return true ;
}
2023-04-21 15:40:14 +02:00
# if SDL_HAS_DISPLAY_EVENT
case SDL_DISPLAYEVENT :
{
// 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION,
// so change of DPI/Scaling are not reflected in this event. (SDL3 has it)
bd - > WantUpdateMonitors = true ;
return true ;
}
# endif
2022-01-11 22:56:35 +01:00
case SDL_WINDOWEVENT :
2021-08-02 20:17:26 +02:00
{
2024-08-19 14:46:53 +02:00
ImGuiViewport * viewport = ImGui_ImplSDL2_GetViewportForWindowID ( event - > window . windowID ) ;
if ( viewport = = NULL )
2024-08-02 00:05:51 +02:00
return false ;
2024-08-19 14:46:53 +02:00
2022-02-25 17:18:40 +01:00
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
// - However we won't get a correct LEAVE event for a captured window.
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
// causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why
// we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details.
2022-01-13 18:36:23 +01:00
Uint8 window_event = event - > window . event ;
2022-01-18 16:59:19 +01:00
if ( window_event = = SDL_WINDOWEVENT_ENTER )
{
2022-02-25 17:18:40 +01:00
bd - > MouseWindowID = event - > window . windowID ;
2024-02-13 15:49:49 +01:00
bd - > MouseLastLeaveFrame = 0 ;
2022-01-18 16:59:19 +01:00
}
2022-02-25 17:18:40 +01:00
if ( window_event = = SDL_WINDOWEVENT_LEAVE )
2024-02-13 15:49:49 +01:00
bd - > MouseLastLeaveFrame = ImGui : : GetFrameCount ( ) + 1 ;
2022-01-13 18:36:23 +01:00
if ( window_event = = SDL_WINDOWEVENT_FOCUS_GAINED )
2021-08-02 20:17:26 +02:00
io . AddFocusEvent ( true ) ;
2022-01-13 18:36:23 +01:00
else if ( window_event = = SDL_WINDOWEVENT_FOCUS_LOST )
2021-08-02 20:17:26 +02:00
io . AddFocusEvent ( false ) ;
2024-08-19 14:46:53 +02:00
else if ( window_event = = SDL_WINDOWEVENT_CLOSE )
viewport - > PlatformRequestClose = true ;
else if ( window_event = = SDL_WINDOWEVENT_MOVED )
viewport - > PlatformRequestMove = true ;
else if ( window_event = = SDL_WINDOWEVENT_RESIZED )
viewport - > PlatformRequestResize = true ;
2021-08-02 20:17:26 +02:00
return true ;
}
2024-02-13 16:24:44 +01:00
case SDL_CONTROLLERDEVICEADDED :
case SDL_CONTROLLERDEVICEREMOVED :
{
2024-02-13 18:50:21 +01:00
bd - > WantUpdateGamepadsList = true ;
2024-02-13 16:24:44 +01:00
return true ;
}
2015-07-08 18:10:54 +02:00
}
return false ;
2015-05-25 09:40:58 +02:00
}
2024-07-02 18:06:19 +02:00
# ifdef __EMSCRIPTEN__
EM_JS ( void , ImGui_ImplSDL2_EmscriptenOpenURL , ( char const * url ) , { url = url ? UTF8ToString ( url ) : null ; if ( url ) window . open ( url , ' _blank ' ) ; } ) ;
# endif
2022-02-07 16:18:19 +01:00
static bool ImGui_ImplSDL2_Init ( SDL_Window * window , SDL_Renderer * renderer , void * sdl_gl_context )
2015-05-25 09:40:58 +02:00
{
2021-06-28 16:52:10 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2024-05-13 15:07:13 +02:00
IMGUI_CHECKVERSION ( ) ;
2022-10-11 12:22:29 +02:00
IM_ASSERT ( io . BackendPlatformUserData = = nullptr & & " Already initialized a platform backend! " ) ;
2021-06-28 16:52:10 +02:00
2021-08-02 15:04:45 +02:00
// Check and store if we are on a SDL backend that supports global mouse position
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
bool mouse_can_use_global_state = false ;
# if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
2021-08-18 12:00:15 +02:00
const char * sdl_backend = SDL_GetCurrentVideoDriver ( ) ;
const char * global_mouse_whitelist [ ] = { " windows " , " cocoa " , " x11 " , " DIVE " , " VMAN " } ;
2021-08-02 15:04:45 +02:00
for ( int n = 0 ; n < IM_ARRAYSIZE ( global_mouse_whitelist ) ; n + + )
if ( strncmp ( sdl_backend , global_mouse_whitelist [ n ] , strlen ( global_mouse_whitelist [ n ] ) ) = = 0 )
mouse_can_use_global_state = true ;
# endif
2020-10-12 17:34:22 +02:00
// Setup backend capabilities flags
2021-06-30 15:22:15 +02:00
ImGui_ImplSDL2_Data * bd = IM_NEW ( ImGui_ImplSDL2_Data ) ( ) ;
2021-06-28 16:52:10 +02:00
io . BackendPlatformUserData = ( void * ) bd ;
2023-02-07 11:54:50 +01:00
io . BackendPlatformName = " imgui_impl_sdl2 " ;
2021-08-02 15:04:45 +02:00
io . BackendFlags | = ImGuiBackendFlags_HasMouseCursors ; // We can honor GetMouseCursor() values (optional)
io . BackendFlags | = ImGuiBackendFlags_HasSetMousePos ; // We can honor io.WantSetMousePos requests (optional, rarely used)
if ( mouse_can_use_global_state )
io . BackendFlags | = ImGuiBackendFlags_PlatformHasViewports ; // We can create multi-viewports on the Platform side (optional)
2022-01-31 11:47:44 +01:00
2021-06-30 15:22:15 +02:00
bd - > Window = window ;
2024-08-19 13:57:08 +02:00
bd - > WindowID = SDL_GetWindowID ( window ) ;
2022-01-22 14:55:03 +01:00
bd - > Renderer = renderer ;
2022-11-10 16:22:34 +01:00
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
2021-08-02 15:04:45 +02:00
bd - > MouseCanUseGlobalState = mouse_can_use_global_state ;
2022-11-10 16:22:34 +01:00
# ifndef __APPLE__
bd - > MouseCanReportHoveredViewport = bd - > MouseCanUseGlobalState ;
# else
bd - > MouseCanReportHoveredViewport = false ;
# endif
2021-06-30 15:22:15 +02:00
2024-08-22 16:42:57 +02:00
ImGuiPlatformIO & platform_io = ImGui : : GetPlatformIO ( ) ;
2024-08-22 17:50:10 +02:00
platform_io . Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText ;
platform_io . Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText ;
platform_io . Platform_ClipboardUserData = nullptr ;
2024-08-22 16:55:14 +02:00
platform_io . Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData ;
2024-07-02 18:06:19 +02:00
# ifdef __EMSCRIPTEN__
2024-08-22 16:42:57 +02:00
platform_io . Platform_OpenInShellFn = [ ] ( ImGuiContext * , const char * url ) { ImGui_ImplSDL2_EmscriptenOpenURL ( url ) ; return true ; } ;
2024-07-02 18:06:19 +02:00
# endif
2016-03-26 15:43:45 +01:00
2024-09-19 14:25:01 +02:00
// Update monitor a first time during init
ImGui_ImplSDL2_UpdateMonitors ( ) ;
2024-02-13 16:24:44 +01:00
// Gamepad handling
2024-02-13 18:50:21 +01:00
bd - > GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst ;
bd - > WantUpdateGamepadsList = true ;
2024-02-13 16:24:44 +01:00
2019-12-17 14:34:18 +01:00
// Load mouse cursors
2021-06-28 16:52:10 +02:00
bd - > MouseCursors [ ImGuiMouseCursor_Arrow ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_ARROW ) ;
bd - > MouseCursors [ ImGuiMouseCursor_TextInput ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_IBEAM ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeAll ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_SIZEALL ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNS ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_SIZENS ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeEW ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_SIZEWE ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNESW ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_SIZENESW ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNWSE ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_SIZENWSE ) ;
bd - > MouseCursors [ ImGuiMouseCursor_Hand ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_HAND ) ;
bd - > MouseCursors [ ImGuiMouseCursor_NotAllowed ] = SDL_CreateSystemCursor ( SDL_SYSTEM_CURSOR_NO ) ;
2018-02-16 18:45:31 +01:00
2022-01-05 13:03:48 +01:00
// Set platform dependent data in viewport
2018-02-27 23:30:39 +01:00
// Our mouse update function expect PlatformHandle to be filled for the main viewport
ImGuiViewport * main_viewport = ImGui : : GetMainViewport ( ) ;
2024-08-19 14:07:25 +02:00
main_viewport - > PlatformHandle = ( void * ) ( intptr_t ) bd - > WindowID ;
2022-10-11 15:59:23 +02:00
main_viewport - > PlatformHandleRaw = nullptr ;
2019-06-18 23:35:48 +02:00
SDL_SysWMinfo info ;
SDL_VERSION ( & info . version ) ;
if ( SDL_GetWindowWMInfo ( window , & info ) )
2022-06-16 10:15:26 +02:00
{
2023-01-02 15:02:22 +01:00
# if defined(SDL_VIDEO_DRIVER_WINDOWS)
2022-01-05 14:28:20 +01:00
main_viewport - > PlatformHandleRaw = ( void * ) info . info . win . window ;
2022-09-09 16:45:16 +02:00
# elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
2022-06-16 10:15:26 +02:00
main_viewport - > PlatformHandleRaw = ( void * ) info . info . cocoa . window ;
2019-06-18 23:35:48 +02:00
# endif
2022-06-16 10:15:26 +02:00
}
2018-03-07 14:46:53 +01:00
2022-09-26 14:44:26 +02:00
// From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
2021-07-29 18:21:08 +02:00
// Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
// (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
// It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
// you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
2022-09-26 14:44:26 +02:00
# ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
2021-07-29 18:21:08 +02:00
SDL_SetHint ( SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH , " 1 " ) ;
# endif
2023-02-07 18:55:10 +01:00
// From 2.0.18: Enable native IME.
// IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any.
// For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow().
# ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint ( SDL_HINT_IME_SHOW_UI , " 1 " ) ;
# endif
2022-09-26 14:44:26 +02:00
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
# ifdef SDL_HINT_MOUSE_AUTO_CAPTURE
SDL_SetHint ( SDL_HINT_MOUSE_AUTO_CAPTURE , " 0 " ) ;
# endif
2018-03-07 14:46:53 +01:00
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
2024-10-08 20:47:24 +02:00
// We left the call to ImGui_ImplSDL2_InitMultiViewportSupport() outside of #ifdef to avoid unused-function warnings.
if ( io . BackendFlags & ImGuiBackendFlags_PlatformHasViewports )
ImGui_ImplSDL2_InitMultiViewportSupport ( window , sdl_gl_context ) ;
2018-02-27 23:30:39 +01:00
2015-05-25 09:40:58 +02:00
return true ;
}
2018-06-08 19:37:33 +02:00
bool ImGui_ImplSDL2_InitForOpenGL ( SDL_Window * window , void * sdl_gl_context )
{
2022-10-11 15:59:23 +02:00
return ImGui_ImplSDL2_Init ( window , nullptr , sdl_gl_context ) ;
2018-06-08 19:37:33 +02:00
}
bool ImGui_ImplSDL2_InitForVulkan ( SDL_Window * window )
{
2018-12-21 16:26:17 +01:00
# if !SDL_HAS_VULKAN
2018-06-08 19:37:33 +02:00
IM_ASSERT ( 0 & & " Unsupported " ) ;
2018-12-21 16:26:17 +01:00
# endif
2022-10-11 15:59:23 +02:00
if ( ! ImGui_ImplSDL2_Init ( window , nullptr , nullptr ) )
2021-06-29 14:53:25 +02:00
return false ;
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
bd - > UseVulkan = true ;
return true ;
2018-06-08 19:37:33 +02:00
}
2019-06-17 01:11:32 +02:00
bool ImGui_ImplSDL2_InitForD3D ( SDL_Window * window )
{
# if !defined(_WIN32)
IM_ASSERT ( 0 & & " Unsupported " ) ;
# endif
2022-10-11 15:59:23 +02:00
return ImGui_ImplSDL2_Init ( window , nullptr , nullptr ) ;
2019-06-17 01:11:32 +02:00
}
2020-02-07 21:48:59 +01:00
bool ImGui_ImplSDL2_InitForMetal ( SDL_Window * window )
{
2022-10-11 15:59:23 +02:00
return ImGui_ImplSDL2_Init ( window , nullptr , nullptr ) ;
2020-02-07 21:48:59 +01:00
}
2022-01-22 14:55:03 +01:00
bool ImGui_ImplSDL2_InitForSDLRenderer ( SDL_Window * window , SDL_Renderer * renderer )
2021-09-21 19:29:39 +02:00
{
2022-10-11 15:59:23 +02:00
return ImGui_ImplSDL2_Init ( window , renderer , nullptr ) ;
2021-09-21 19:29:39 +02:00
}
2023-08-15 12:48:46 +02:00
bool ImGui_ImplSDL2_InitForOther ( SDL_Window * window )
{
2023-08-26 11:45:21 +02:00
return ImGui_ImplSDL2_Init ( window , nullptr , nullptr ) ;
2023-08-15 12:48:46 +02:00
}
2024-02-13 18:50:21 +01:00
static void ImGui_ImplSDL2_CloseGamepads ( ) ;
2018-02-16 22:22:47 +01:00
void ImGui_ImplSDL2_Shutdown ( )
2015-05-25 09:40:58 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2022-10-11 12:22:29 +02:00
IM_ASSERT ( bd ! = nullptr & & " No platform backend to shutdown, or already shutdown? " ) ;
2021-09-20 18:43:05 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-06-08 19:37:33 +02:00
2024-10-08 20:47:24 +02:00
ImGui_ImplSDL2_ShutdownMultiViewportSupport ( ) ;
2018-02-27 23:30:39 +01:00
2021-06-28 16:52:10 +02:00
if ( bd - > ClipboardTextData )
SDL_free ( bd - > ClipboardTextData ) ;
2018-06-20 11:06:29 +02:00
for ( ImGuiMouseCursor cursor_n = 0 ; cursor_n < ImGuiMouseCursor_COUNT ; cursor_n + + )
2021-06-28 16:52:10 +02:00
SDL_FreeCursor ( bd - > MouseCursors [ cursor_n ] ) ;
2024-02-13 18:50:21 +01:00
ImGui_ImplSDL2_CloseGamepads ( ) ;
2021-06-28 16:52:10 +02:00
2022-10-11 12:22:29 +02:00
io . BackendPlatformName = nullptr ;
io . BackendPlatformUserData = nullptr ;
2023-04-19 16:40:18 +02:00
io . BackendFlags & = ~ ( ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport ) ;
2021-06-30 15:22:15 +02:00
IM_DELETE ( bd ) ;
2015-05-25 09:40:58 +02:00
}
2019-09-17 16:35:50 +02:00
// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
2022-01-12 16:44:24 +01:00
static void ImGui_ImplSDL2_UpdateMouseData ( )
2018-02-27 23:30:39 +01:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2021-08-02 15:48:20 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-06-08 19:37:33 +02:00
2022-01-12 16:44:24 +01:00
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
2021-08-02 15:04:45 +02:00
# if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
2022-11-10 16:22:34 +01:00
SDL_CaptureMouse ( ( bd - > MouseButtonsDown ! = 0 ) ? SDL_TRUE : SDL_FALSE ) ;
2022-01-12 16:44:24 +01:00
SDL_Window * focused_window = SDL_GetKeyboardFocus ( ) ;
2024-08-19 14:46:53 +02:00
const bool is_app_focused = ( focused_window & & ( bd - > Window = = focused_window | | ImGui_ImplSDL2_GetViewportForWindowID ( SDL_GetWindowID ( focused_window ) ) ! = NULL ) ) ;
2021-07-29 18:21:08 +02:00
# else
2022-01-13 18:52:19 +01:00
SDL_Window * focused_window = bd - > Window ;
2022-01-12 16:44:24 +01:00
const bool is_app_focused = ( SDL_GetWindowFlags ( bd - > Window ) & SDL_WINDOW_INPUT_FOCUS ) ! = 0 ; // SDL 2.0.3 and non-windowed systems: single-viewport only
2021-07-29 18:21:08 +02:00
# endif
2021-08-02 15:04:45 +02:00
2022-01-12 16:44:24 +01:00
if ( is_app_focused )
2018-06-08 19:37:33 +02:00
{
2024-10-14 15:28:00 +02:00
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
2022-01-12 16:44:24 +01:00
if ( io . WantSetMousePos )
2022-01-13 18:36:23 +01:00
{
2021-08-02 15:04:45 +02:00
# if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
2022-01-13 18:36:23 +01:00
if ( io . ConfigFlags & ImGuiConfigFlags_ViewportsEnable )
SDL_WarpMouseGlobal ( ( int ) io . MousePos . x , ( int ) io . MousePos . y ) ;
else
2021-08-02 15:04:45 +02:00
# endif
2022-01-13 18:36:23 +01:00
SDL_WarpMouseInWindow ( bd - > Window , ( int ) io . MousePos . x , ( int ) io . MousePos . y ) ;
2019-09-24 19:44:29 +02:00
}
2022-01-12 16:44:24 +01:00
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
if ( bd - > MouseCanUseGlobalState & & bd - > MouseButtonsDown = = 0 )
2019-12-18 20:49:41 +01:00
{
2021-08-02 15:04:45 +02:00
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
2022-01-13 18:36:23 +01:00
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
int mouse_x , mouse_y , window_x , window_y ;
SDL_GetGlobalMouseState ( & mouse_x , & mouse_y ) ;
if ( ! ( io . ConfigFlags & ImGuiConfigFlags_ViewportsEnable ) )
{
SDL_GetWindowPosition ( focused_window , & window_x , & window_y ) ;
mouse_x - = window_x ;
mouse_y - = window_y ;
}
2022-01-17 18:16:55 +01:00
io . AddMousePosEvent ( ( float ) mouse_x , ( float ) mouse_y ) ;
2019-12-18 20:49:41 +01:00
}
2018-12-20 22:28:31 +01:00
}
2022-01-12 16:44:24 +01:00
2022-01-18 17:24:59 +01:00
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
2022-01-18 16:59:19 +01:00
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
// by the backend, and use its flawed heuristic to guess the viewport behind.
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
2022-01-31 11:47:44 +01:00
if ( io . BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport )
{
ImGuiID mouse_viewport_id = 0 ;
2024-08-19 14:46:53 +02:00
if ( ImGuiViewport * mouse_viewport = ImGui_ImplSDL2_GetViewportForWindowID ( bd - > MouseWindowID ) )
mouse_viewport_id = mouse_viewport - > ID ;
2022-01-31 11:47:44 +01:00
io . AddMouseViewportEvent ( mouse_viewport_id ) ;
}
2018-05-11 16:41:32 +02:00
}
static void ImGui_ImplSDL2_UpdateMouseCursor ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
if ( io . ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange )
return ;
2021-06-28 16:52:10 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2018-02-27 23:30:39 +01:00
2018-05-11 16:41:32 +02:00
ImGuiMouseCursor imgui_cursor = ImGui : : GetMouseCursor ( ) ;
if ( io . MouseDrawCursor | | imgui_cursor = = ImGuiMouseCursor_None )
2018-02-27 23:30:39 +01:00
{
2018-05-11 16:41:32 +02:00
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
SDL_ShowCursor ( SDL_FALSE ) ;
}
else
{
// Show OS mouse cursor
2023-02-02 21:28:28 +01:00
SDL_Cursor * expected_cursor = bd - > MouseCursors [ imgui_cursor ] ? bd - > MouseCursors [ imgui_cursor ] : bd - > MouseCursors [ ImGuiMouseCursor_Arrow ] ;
2024-02-13 15:49:49 +01:00
if ( bd - > MouseLastCursor ! = expected_cursor )
2023-02-02 21:28:28 +01:00
{
SDL_SetCursor ( expected_cursor ) ; // SDL function doesn't have an early out (see #6113)
2024-02-13 15:49:49 +01:00
bd - > MouseLastCursor = expected_cursor ;
2023-02-02 21:28:28 +01:00
}
2018-05-11 16:41:32 +02:00
SDL_ShowCursor ( SDL_TRUE ) ;
2018-02-27 23:30:39 +01:00
}
}
2024-02-13 18:50:21 +01:00
static void ImGui_ImplSDL2_CloseGamepads ( )
{
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
if ( bd - > GamepadMode ! = ImGui_ImplSDL2_GamepadMode_Manual )
for ( SDL_GameController * gamepad : bd - > Gamepads )
SDL_GameControllerClose ( gamepad ) ;
bd - > Gamepads . resize ( 0 ) ;
}
2024-02-14 11:30:43 +01:00
void ImGui_ImplSDL2_SetGamepadMode ( ImGui_ImplSDL2_GamepadMode mode , struct _SDL_GameController * * manual_gamepads_array , int manual_gamepads_count )
2024-02-13 18:50:21 +01:00
{
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
ImGui_ImplSDL2_CloseGamepads ( ) ;
2024-02-14 11:30:43 +01:00
if ( mode = = ImGui_ImplSDL2_GamepadMode_Manual )
{
IM_ASSERT ( manual_gamepads_array ! = nullptr & & manual_gamepads_count > 0 ) ;
for ( int n = 0 ; n < manual_gamepads_count ; n + + )
bd - > Gamepads . push_back ( manual_gamepads_array [ n ] ) ;
}
else
{
IM_ASSERT ( manual_gamepads_array = = nullptr & & manual_gamepads_count < = 0 ) ;
bd - > WantUpdateGamepadsList = true ;
}
bd - > GamepadMode = mode ;
2024-02-13 18:50:21 +01:00
}
static void ImGui_ImplSDL2_UpdateGamepadButton ( ImGui_ImplSDL2_Data * bd , ImGuiIO & io , ImGuiKey key , SDL_GameControllerButton button_no )
{
bool merged_value = false ;
for ( SDL_GameController * gamepad : bd - > Gamepads )
merged_value | = SDL_GameControllerGetButton ( gamepad , button_no ) ! = 0 ;
io . AddKeyEvent ( key , merged_value ) ;
}
2024-02-14 11:30:43 +01:00
static inline float Saturate ( float v ) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v ; }
2024-02-13 18:50:21 +01:00
static void ImGui_ImplSDL2_UpdateGamepadAnalog ( ImGui_ImplSDL2_Data * bd , ImGuiIO & io , ImGuiKey key , SDL_GameControllerAxis axis_no , float v0 , float v1 )
{
float merged_value = 0.0f ;
for ( SDL_GameController * gamepad : bd - > Gamepads )
{
2024-02-14 11:30:43 +01:00
float vn = Saturate ( ( float ) ( SDL_GameControllerGetAxis ( gamepad , axis_no ) - v0 ) / ( float ) ( v1 - v0 ) ) ;
2024-02-13 18:50:21 +01:00
if ( merged_value < vn )
merged_value = vn ;
}
io . AddKeyAnalogEvent ( key , merged_value > 0.1f , merged_value ) ;
}
2019-04-22 14:34:34 +02:00
static void ImGui_ImplSDL2_UpdateGamepads ( )
{
2024-02-13 16:24:44 +01:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2019-04-22 14:34:34 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2019-04-23 12:26:14 +02:00
2024-02-13 18:50:21 +01:00
// Update list of controller(s) to use
if ( bd - > WantUpdateGamepadsList & & bd - > GamepadMode ! = ImGui_ImplSDL2_GamepadMode_Manual )
2024-02-13 16:24:44 +01:00
{
2024-02-13 18:50:21 +01:00
ImGui_ImplSDL2_CloseGamepads ( ) ;
2024-02-13 16:24:44 +01:00
int joystick_count = SDL_NumJoysticks ( ) ;
for ( int n = 0 ; n < joystick_count ; n + + )
if ( SDL_IsGameController ( n ) )
if ( SDL_GameController * gamepad = SDL_GameControllerOpen ( n ) )
{
2024-02-13 18:50:21 +01:00
bd - > Gamepads . push_back ( gamepad ) ;
if ( bd - > GamepadMode = = ImGui_ImplSDL2_GamepadMode_AutoFirst )
break ;
2024-02-13 16:24:44 +01:00
}
2024-02-13 18:50:21 +01:00
bd - > WantUpdateGamepadsList = false ;
2024-02-13 16:24:44 +01:00
}
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 )
2019-04-22 14:34:34 +02:00
return ;
2022-01-20 17:12:28 +01:00
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
2024-02-13 18:50:21 +01:00
if ( bd - > Gamepads . Size = = 0 )
2019-04-23 12:26:14 +02:00
return ;
2022-01-20 17:12:28 +01:00
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
2019-04-23 12:26:14 +02:00
// Update gamepad inputs
2024-02-13 18:50:21 +01:00
const int thumb_dead_zone = 8000 ; // SDL_gamecontroller.h suggests using this value.
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadStart , SDL_CONTROLLER_BUTTON_START ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadBack , SDL_CONTROLLER_BUTTON_BACK ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadFaceLeft , SDL_CONTROLLER_BUTTON_X ) ; // Xbox X, PS Square
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadFaceRight , SDL_CONTROLLER_BUTTON_B ) ; // Xbox B, PS Circle
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadFaceUp , SDL_CONTROLLER_BUTTON_Y ) ; // Xbox Y, PS Triangle
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadFaceDown , SDL_CONTROLLER_BUTTON_A ) ; // Xbox A, PS Cross
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadDpadLeft , SDL_CONTROLLER_BUTTON_DPAD_LEFT ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadDpadRight , SDL_CONTROLLER_BUTTON_DPAD_RIGHT ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadDpadUp , SDL_CONTROLLER_BUTTON_DPAD_UP ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadDpadDown , SDL_CONTROLLER_BUTTON_DPAD_DOWN ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadL1 , SDL_CONTROLLER_BUTTON_LEFTSHOULDER ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadR1 , SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadL2 , SDL_CONTROLLER_AXIS_TRIGGERLEFT , 0.0f , 32767 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadR2 , SDL_CONTROLLER_AXIS_TRIGGERRIGHT , 0.0f , 32767 ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadL3 , SDL_CONTROLLER_BUTTON_LEFTSTICK ) ;
ImGui_ImplSDL2_UpdateGamepadButton ( bd , io , ImGuiKey_GamepadR3 , SDL_CONTROLLER_BUTTON_RIGHTSTICK ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadLStickLeft , SDL_CONTROLLER_AXIS_LEFTX , - thumb_dead_zone , - 32768 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadLStickRight , SDL_CONTROLLER_AXIS_LEFTX , + thumb_dead_zone , + 32767 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadLStickUp , SDL_CONTROLLER_AXIS_LEFTY , - thumb_dead_zone , - 32768 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadLStickDown , SDL_CONTROLLER_AXIS_LEFTY , + thumb_dead_zone , + 32767 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadRStickLeft , SDL_CONTROLLER_AXIS_RIGHTX , - thumb_dead_zone , - 32768 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadRStickRight , SDL_CONTROLLER_AXIS_RIGHTX , + thumb_dead_zone , + 32767 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadRStickUp , SDL_CONTROLLER_AXIS_RIGHTY , - thumb_dead_zone , - 32768 ) ;
ImGui_ImplSDL2_UpdateGamepadAnalog ( bd , io , ImGuiKey_GamepadRStickDown , SDL_CONTROLLER_AXIS_RIGHTY , + thumb_dead_zone , + 32767 ) ;
2019-04-22 14:34:34 +02:00
}
2023-04-21 15:40:14 +02:00
// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has).
2020-02-09 17:31:18 +01:00
static void ImGui_ImplSDL2_UpdateMonitors ( )
{
2023-04-21 15:40:14 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2020-02-09 17:31:18 +01:00
ImGuiPlatformIO & platform_io = ImGui : : GetPlatformIO ( ) ;
platform_io . Monitors . resize ( 0 ) ;
2023-04-21 15:40:14 +02:00
bd - > WantUpdateMonitors = false ;
2020-02-09 17:31:18 +01:00
int display_count = SDL_GetNumVideoDisplays ( ) ;
for ( int n = 0 ; n < display_count ; n + + )
{
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
ImGuiPlatformMonitor monitor ;
SDL_Rect r ;
SDL_GetDisplayBounds ( n , & r ) ;
monitor . MainPos = monitor . WorkPos = ImVec2 ( ( float ) r . x , ( float ) r . y ) ;
monitor . MainSize = monitor . WorkSize = ImVec2 ( ( float ) r . w , ( float ) r . h ) ;
# if SDL_HAS_USABLE_DISPLAY_BOUNDS
SDL_GetDisplayUsableBounds ( n , & r ) ;
monitor . WorkPos = ImVec2 ( ( float ) r . x , ( float ) r . y ) ;
monitor . WorkSize = ImVec2 ( ( float ) r . w , ( float ) r . h ) ;
# endif
# if SDL_HAS_PER_MONITOR_DPI
2022-06-16 10:15:26 +02:00
// FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
// DpiScale to cocoa_window.backingScaleFactor here.
2020-02-09 17:31:18 +01:00
float dpi = 0.0f ;
2022-10-11 15:59:23 +02:00
if ( ! SDL_GetDisplayDPI ( n , & dpi , nullptr , nullptr ) )
2024-08-19 12:18:47 +02:00
{
if ( dpi < = 0.0f )
continue ; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
2020-02-09 17:31:18 +01:00
monitor . DpiScale = dpi / 96.0f ;
2024-08-19 12:18:47 +02:00
}
2020-02-09 17:31:18 +01:00
# endif
2023-04-21 15:10:44 +02:00
monitor . PlatformHandle = ( void * ) ( intptr_t ) n ;
2020-02-09 17:31:18 +01:00
platform_io . Monitors . push_back ( monitor ) ;
}
}
2021-06-29 19:54:25 +02:00
void ImGui_ImplSDL2_NewFrame ( )
2015-05-25 09:40:58 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2024-05-07 16:53:03 +02:00
IM_ASSERT ( bd ! = nullptr & & " Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()? " ) ;
2021-07-09 20:16:19 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2015-05-25 09:40:58 +02:00
// Setup display size (every frame to accommodate for window resizing)
int w , h ;
2016-03-25 22:25:20 +01:00
int display_w , display_h ;
2021-06-29 19:54:25 +02:00
SDL_GetWindowSize ( bd - > Window , & w , & h ) ;
if ( SDL_GetWindowFlags ( bd - > Window ) & SDL_WINDOW_MINIMIZED )
2020-05-25 12:23:49 +02:00
w = h = 0 ;
2022-10-11 12:22:29 +02:00
if ( bd - > Renderer ! = nullptr )
2022-01-22 14:55:03 +01:00
SDL_GetRendererOutputSize ( bd - > Renderer , & display_w , & display_h ) ;
2024-09-08 12:19:51 +02:00
# if SDL_HAS_VULKAN
else if ( SDL_GetWindowFlags ( bd - > Window ) & SDL_WINDOW_VULKAN )
SDL_Vulkan_GetDrawableSize ( bd - > Window , & display_w , & display_h ) ;
# endif
2022-01-22 14:55:03 +01:00
else
SDL_GL_GetDrawableSize ( bd - > Window , & display_w , & display_h ) ;
2015-05-25 09:40:58 +02:00
io . DisplaySize = ImVec2 ( ( float ) w , ( float ) h ) ;
2019-03-12 18:27:14 +01:00
if ( w > 0 & & h > 0 )
io . DisplayFramebufferScale = ImVec2 ( ( float ) display_w / w , ( float ) display_h / h ) ;
2016-01-20 15:06:31 +01:00
2023-04-21 15:40:14 +02:00
// Update monitors
if ( bd - > WantUpdateMonitors )
ImGui_ImplSDL2_UpdateMonitors ( ) ;
2018-02-05 23:09:14 +01:00
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
2023-02-23 13:06:07 +01:00
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
2018-02-05 23:09:14 +01:00
static Uint64 frequency = SDL_GetPerformanceFrequency ( ) ;
Uint64 current_time = SDL_GetPerformanceCounter ( ) ;
2023-02-23 13:06:07 +01:00
if ( current_time < = bd - > Time )
current_time = bd - > Time + 1 ;
2021-06-28 16:52:10 +02:00
io . DeltaTime = bd - > Time > 0 ? ( float ) ( ( double ) ( current_time - bd - > Time ) / frequency ) : ( float ) ( 1.0f / 60.0f ) ;
bd - > Time = current_time ;
2015-05-25 09:40:58 +02:00
2024-02-13 15:49:49 +01:00
if ( bd - > MouseLastLeaveFrame & & bd - > MouseLastLeaveFrame > = ImGui : : GetFrameCount ( ) & & bd - > MouseButtonsDown = = 0 )
2022-02-25 17:18:40 +01:00
{
bd - > MouseWindowID = 0 ;
2024-02-13 15:49:49 +01:00
bd - > MouseLastLeaveFrame = 0 ;
2022-02-25 17:18:40 +01:00
io . AddMousePosEvent ( - FLT_MAX , - FLT_MAX ) ;
}
2022-11-10 16:22:34 +01:00
// Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
2024-06-21 02:45:47 +02:00
// Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rigorous, but testing for payload reduces noise and potential side-effects.
2022-11-10 16:22:34 +01:00
if ( bd - > MouseCanReportHoveredViewport & & ImGui : : GetDragDropPayload ( ) = = nullptr )
io . BackendFlags | = ImGuiBackendFlags_HasMouseHoveredViewport ;
else
io . BackendFlags & = ~ ImGuiBackendFlags_HasMouseHoveredViewport ;
2022-01-12 16:44:24 +01:00
ImGui_ImplSDL2_UpdateMouseData ( ) ;
2018-05-11 16:41:32 +02:00
ImGui_ImplSDL2_UpdateMouseCursor ( ) ;
2019-04-22 14:34:34 +02:00
2019-04-23 12:26:14 +02:00
// Update game controllers (if enabled and available)
2019-04-22 14:34:34 +02:00
ImGui_ImplSDL2_UpdateGamepads ( ) ;
2018-02-27 23:30:39 +01:00
}
2018-01-19 10:46:54 +01:00
2018-03-18 18:44:57 +01:00
//--------------------------------------------------------------------------------------------------------
2018-04-24 17:09:50 +02:00
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
2020-10-14 14:43:45 +02:00
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
2018-04-24 17:09:50 +02:00
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
2018-03-18 18:44:57 +01:00
//--------------------------------------------------------------------------------------------------------
2018-02-27 23:30:39 +01:00
2023-04-11 16:19:59 +02:00
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
2021-06-29 15:34:54 +02:00
struct ImGui_ImplSDL2_ViewportData
2018-02-27 23:30:39 +01:00
{
SDL_Window * Window ;
Uint32 WindowID ;
2018-04-09 22:01:24 +02:00
bool WindowOwned ;
2018-02-27 23:30:39 +01:00
SDL_GLContext GLContext ;
2022-10-11 15:59:23 +02:00
ImGui_ImplSDL2_ViewportData ( ) { Window = nullptr ; WindowID = 0 ; WindowOwned = false ; GLContext = nullptr ; }
~ ImGui_ImplSDL2_ViewportData ( ) { IM_ASSERT ( Window = = nullptr & & GLContext = = nullptr ) ; }
2018-02-27 23:30:39 +01:00
} ;
2018-03-18 18:44:57 +01:00
static void ImGui_ImplSDL2_CreateWindow ( ImGuiViewport * viewport )
2018-02-27 23:30:39 +01:00
{
2021-06-29 14:53:25 +02:00
ImGui_ImplSDL2_Data * bd = ImGui_ImplSDL2_GetBackendData ( ) ;
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = IM_NEW ( ImGui_ImplSDL2_ViewportData ) ( ) ;
viewport - > PlatformUserData = vd ;
2018-02-27 23:30:39 +01:00
ImGuiViewport * main_viewport = ImGui : : GetMainViewport ( ) ;
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * main_viewport_data = ( ImGui_ImplSDL2_ViewportData * ) main_viewport - > PlatformUserData ;
2018-03-15 19:25:23 +01:00
2018-04-23 15:54:38 +02:00
// Share GL resources with main context
2022-10-11 15:59:23 +02:00
bool use_opengl = ( main_viewport_data - > GLContext ! = nullptr ) ;
SDL_GLContext backup_context = nullptr ;
2018-03-15 19:25:23 +01:00
if ( use_opengl )
{
backup_context = SDL_GL_GetCurrentContext ( ) ;
SDL_GL_SetAttribute ( SDL_GL_SHARE_WITH_CURRENT_CONTEXT , 1 ) ;
SDL_GL_MakeCurrent ( main_viewport_data - > Window , main_viewport_data - > GLContext ) ;
}
2018-02-27 23:30:39 +01:00
Uint32 sdl_flags = 0 ;
2021-06-29 14:53:25 +02:00
sdl_flags | = use_opengl ? SDL_WINDOW_OPENGL : ( bd - > UseVulkan ? SDL_WINDOW_VULKAN : 0 ) ;
sdl_flags | = SDL_GetWindowFlags ( bd - > Window ) & SDL_WINDOW_ALLOW_HIGHDPI ;
2018-02-27 23:30:39 +01:00
sdl_flags | = SDL_WINDOW_HIDDEN ;
sdl_flags | = ( viewport - > Flags & ImGuiViewportFlags_NoDecoration ) ? SDL_WINDOW_BORDERLESS : 0 ;
sdl_flags | = ( viewport - > Flags & ImGuiViewportFlags_NoDecoration ) ? 0 : SDL_WINDOW_RESIZABLE ;
2020-01-06 08:49:36 +01:00
# if !defined(_WIN32)
// See SDL hack in ImGui_ImplSDL2_ShowWindow().
sdl_flags | = ( viewport - > Flags & ImGuiViewportFlags_NoTaskBarIcon ) ? SDL_WINDOW_SKIP_TASKBAR : 0 ;
# endif
2018-04-11 21:27:19 +02:00
# if SDL_HAS_ALWAYS_ON_TOP
2018-05-10 12:10:10 +02:00
sdl_flags | = ( viewport - > Flags & ImGuiViewportFlags_TopMost ) ? SDL_WINDOW_ALWAYS_ON_TOP : 0 ;
2018-04-11 21:27:19 +02:00
# endif
2021-06-29 15:34:54 +02:00
vd - > Window = SDL_CreateWindow ( " No Title Yet " , ( int ) viewport - > Pos . x , ( int ) viewport - > Pos . y , ( int ) viewport - > Size . x , ( int ) viewport - > Size . y , sdl_flags ) ;
vd - > WindowOwned = true ;
2018-03-15 19:25:23 +01:00
if ( use_opengl )
2018-08-25 20:15:18 +02:00
{
2021-06-29 15:34:54 +02:00
vd - > GLContext = SDL_GL_CreateContext ( vd - > Window ) ;
2018-08-25 20:15:18 +02:00
SDL_GL_SetSwapInterval ( 0 ) ;
}
2018-03-15 19:25:23 +01:00
if ( use_opengl & & backup_context )
2021-06-29 15:34:54 +02:00
SDL_GL_MakeCurrent ( vd - > Window , backup_context ) ;
2019-06-18 06:03:00 +02:00
2024-08-19 14:46:53 +02:00
viewport - > PlatformHandle = ( void * ) ( intptr_t ) SDL_GetWindowID ( vd - > Window ) ;
2022-10-11 15:59:23 +02:00
viewport - > PlatformHandleRaw = nullptr ;
2019-06-18 06:03:00 +02:00
SDL_SysWMinfo info ;
SDL_VERSION ( & info . version ) ;
2021-06-29 15:34:54 +02:00
if ( SDL_GetWindowWMInfo ( vd - > Window , & info ) )
2022-06-16 10:15:26 +02:00
{
2023-01-02 15:02:22 +01:00
# if defined(SDL_VIDEO_DRIVER_WINDOWS)
2019-06-18 06:03:00 +02:00
viewport - > PlatformHandleRaw = info . info . win . window ;
2022-09-09 16:45:16 +02:00
# elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
2022-06-16 10:15:26 +02:00
viewport - > PlatformHandleRaw = ( void * ) info . info . cocoa . window ;
2019-06-18 06:03:00 +02:00
# endif
2022-06-16 10:15:26 +02:00
}
2018-02-27 23:30:39 +01:00
}
2018-03-18 18:44:57 +01:00
static void ImGui_ImplSDL2_DestroyWindow ( ImGuiViewport * viewport )
2018-02-27 23:30:39 +01:00
{
2021-06-29 15:34:54 +02:00
if ( ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData )
2018-02-16 19:55:16 +01:00
{
2021-06-29 15:34:54 +02:00
if ( vd - > GLContext & & vd - > WindowOwned )
SDL_GL_DeleteContext ( vd - > GLContext ) ;
if ( vd - > Window & & vd - > WindowOwned )
SDL_DestroyWindow ( vd - > Window ) ;
2022-10-11 15:59:23 +02:00
vd - > GLContext = nullptr ;
vd - > Window = nullptr ;
2021-06-29 15:34:54 +02:00
IM_DELETE ( vd ) ;
2018-02-16 19:55:16 +01:00
}
2022-10-11 15:59:23 +02:00
viewport - > PlatformUserData = viewport - > PlatformHandle = nullptr ;
2018-02-27 23:30:39 +01:00
}
static void ImGui_ImplSDL2_ShowWindow ( ImGuiViewport * viewport )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
2024-09-23 14:03:36 +02:00
# if defined(_WIN32) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
2019-06-18 23:35:48 +02:00
HWND hwnd = ( HWND ) viewport - > PlatformHandleRaw ;
2018-02-27 23:30:39 +01:00
2019-06-18 23:35:48 +02:00
// SDL hack: Hide icon from task bar
// Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition.
if ( viewport - > Flags & ImGuiViewportFlags_NoTaskBarIcon )
{
LONG ex_style = : : GetWindowLong ( hwnd , GWL_EXSTYLE ) ;
ex_style & = ~ WS_EX_APPWINDOW ;
ex_style | = WS_EX_TOOLWINDOW ;
: : SetWindowLong ( hwnd , GWL_EXSTYLE , ex_style ) ;
}
2024-08-17 13:13:10 +02:00
# endif
2015-05-25 09:40:58 +02:00
2024-08-17 13:13:10 +02:00
# if SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT
SDL_SetHint ( SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN , ( viewport - > Flags & ImGuiViewportFlags_NoFocusOnAppearing ) ? " 1 " : " 0 " ) ;
# elif defined(_WIN32)
2019-06-18 23:35:48 +02:00
// SDL hack: SDL always activate/focus windows :/
if ( viewport - > Flags & ImGuiViewportFlags_NoFocusOnAppearing )
{
: : ShowWindow ( hwnd , SW_SHOWNA ) ;
return ;
2018-03-15 10:54:27 +01:00
}
2018-02-27 23:30:39 +01:00
# endif
2021-06-29 15:34:54 +02:00
SDL_ShowWindow ( vd - > Window ) ;
2018-02-27 23:30:39 +01:00
}
static ImVec2 ImGui_ImplSDL2_GetWindowPos ( ImGuiViewport * viewport )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
2018-02-27 23:30:39 +01:00
int x = 0 , y = 0 ;
2021-06-29 15:34:54 +02:00
SDL_GetWindowPosition ( vd - > Window , & x , & y ) ;
2018-02-27 23:30:39 +01:00
return ImVec2 ( ( float ) x , ( float ) y ) ;
}
static void ImGui_ImplSDL2_SetWindowPos ( ImGuiViewport * viewport , ImVec2 pos )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
SDL_SetWindowPosition ( vd - > Window , ( int ) pos . x , ( int ) pos . y ) ;
2018-02-27 23:30:39 +01:00
}
static ImVec2 ImGui_ImplSDL2_GetWindowSize ( ImGuiViewport * viewport )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
2018-02-27 23:30:39 +01:00
int w = 0 , h = 0 ;
2021-06-29 15:34:54 +02:00
SDL_GetWindowSize ( vd - > Window , & w , & h ) ;
2018-02-27 23:30:39 +01:00
return ImVec2 ( ( float ) w , ( float ) h ) ;
}
static void ImGui_ImplSDL2_SetWindowSize ( ImGuiViewport * viewport , ImVec2 size )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
SDL_SetWindowSize ( vd - > Window , ( int ) size . x , ( int ) size . y ) ;
2018-02-27 23:30:39 +01:00
}
static void ImGui_ImplSDL2_SetWindowTitle ( ImGuiViewport * viewport , const char * title )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
SDL_SetWindowTitle ( vd - > Window , title ) ;
2018-02-27 23:30:39 +01:00
}
2018-11-28 22:50:37 +01:00
# if SDL_HAS_WINDOW_ALPHA
static void ImGui_ImplSDL2_SetWindowAlpha ( ImGuiViewport * viewport , float alpha )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
SDL_SetWindowOpacity ( vd - > Window , alpha ) ;
2018-11-28 22:50:37 +01:00
}
# endif
2018-04-25 15:15:14 +02:00
static void ImGui_ImplSDL2_SetWindowFocus ( ImGuiViewport * viewport )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
SDL_RaiseWindow ( vd - > Window ) ;
2018-04-25 15:15:14 +02:00
}
static bool ImGui_ImplSDL2_GetWindowFocus ( ImGuiViewport * viewport )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
return ( SDL_GetWindowFlags ( vd - > Window ) & SDL_WINDOW_INPUT_FOCUS ) ! = 0 ;
2018-04-25 15:15:14 +02:00
}
2018-11-23 16:18:30 +01:00
static bool ImGui_ImplSDL2_GetWindowMinimized ( ImGuiViewport * viewport )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
return ( SDL_GetWindowFlags ( vd - > Window ) & SDL_WINDOW_MINIMIZED ) ! = 0 ;
2018-11-23 16:18:30 +01:00
}
2018-03-19 15:20:47 +01:00
static void ImGui_ImplSDL2_RenderWindow ( ImGuiViewport * viewport , void * )
2018-02-27 23:30:39 +01:00
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
if ( vd - > GLContext )
SDL_GL_MakeCurrent ( vd - > Window , vd - > GLContext ) ;
2018-02-27 23:30:39 +01:00
}
2018-03-19 15:20:47 +01:00
static void ImGui_ImplSDL2_SwapBuffers ( ImGuiViewport * viewport , void * )
2018-02-27 23:30:39 +01:00
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
if ( vd - > GLContext )
2018-03-13 23:16:15 +01:00
{
2021-06-29 15:34:54 +02:00
SDL_GL_MakeCurrent ( vd - > Window , vd - > GLContext ) ;
SDL_GL_SwapWindow ( vd - > Window ) ;
2018-03-13 23:16:15 +01:00
}
}
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
# if SDL_HAS_VULKAN
# include <SDL_vulkan.h>
static int ImGui_ImplSDL2_CreateVkSurface ( ImGuiViewport * viewport , ImU64 vk_instance , const void * vk_allocator , ImU64 * out_vk_surface )
{
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = ( ImGui_ImplSDL2_ViewportData * ) viewport - > PlatformUserData ;
2018-03-13 23:16:15 +01:00
( void ) vk_allocator ;
2021-06-29 15:34:54 +02:00
SDL_bool ret = SDL_Vulkan_CreateSurface ( vd - > Window , ( VkInstance ) vk_instance , ( VkSurfaceKHR * ) out_vk_surface ) ;
2019-09-17 16:35:50 +02:00
return ret ? 0 : 1 ; // ret ? VK_SUCCESS : VK_NOT_READY
2018-02-27 23:30:39 +01:00
}
2018-03-13 23:16:15 +01:00
# endif // SDL_HAS_VULKAN
2018-02-27 23:30:39 +01:00
2024-10-08 20:47:24 +02:00
static void ImGui_ImplSDL2_InitMultiViewportSupport ( SDL_Window * window , void * sdl_gl_context )
2018-02-27 23:30:39 +01:00
{
// Register platform interface (will be coupled with a renderer interface)
2018-03-18 18:44:57 +01:00
ImGuiPlatformIO & platform_io = ImGui : : GetPlatformIO ( ) ;
platform_io . Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow ;
platform_io . Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow ;
platform_io . Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow ;
platform_io . Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos ;
platform_io . Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos ;
platform_io . Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize ;
platform_io . Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize ;
2018-04-25 15:15:14 +02:00
platform_io . Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus ;
platform_io . Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus ;
2018-11-23 16:18:30 +01:00
platform_io . Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized ;
2018-03-18 18:44:57 +01:00
platform_io . Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle ;
platform_io . Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow ;
platform_io . Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers ;
2018-11-28 22:50:37 +01:00
# if SDL_HAS_WINDOW_ALPHA
platform_io . Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha ;
# endif
2018-03-13 23:16:15 +01:00
# if SDL_HAS_VULKAN
2018-03-18 18:44:57 +01:00
platform_io . Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface ;
2018-03-13 23:16:15 +01:00
# endif
2018-02-27 23:30:39 +01:00
2018-04-09 22:01:24 +02:00
// Register main window handle (which is owned by the main application, not by us)
2020-01-20 19:33:46 +01:00
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
2018-02-27 23:30:39 +01:00
ImGuiViewport * main_viewport = ImGui : : GetMainViewport ( ) ;
2021-06-29 15:34:54 +02:00
ImGui_ImplSDL2_ViewportData * vd = IM_NEW ( ImGui_ImplSDL2_ViewportData ) ( ) ;
vd - > Window = window ;
vd - > WindowID = SDL_GetWindowID ( window ) ;
vd - > WindowOwned = false ;
vd - > GLContext = sdl_gl_context ;
main_viewport - > PlatformUserData = vd ;
2024-08-19 14:46:53 +02:00
main_viewport - > PlatformHandle = ( void * ) ( intptr_t ) vd - > WindowID ;
2018-02-27 23:30:39 +01:00
}
2024-10-08 20:47:24 +02:00
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport ( )
2018-02-27 23:30:39 +01:00
{
2021-10-15 17:16:26 +02:00
ImGui : : DestroyPlatformWindows ( ) ;
2015-05-25 09:40:58 +02:00
}
2023-03-29 18:41:41 +02:00
2023-07-13 11:27:52 +02:00
//-----------------------------------------------------------------------------
2023-03-23 18:17:45 +01:00
# if defined(__clang__)
# pragma clang diagnostic pop
# endif
2023-07-13 11:27:52 +02:00
# endif // #ifndef IMGUI_DISABLE