git repos / blockattack-game

blame: source/code/Libs/imgui/backends/imgui_impl_sdl2.cpp

normal view · raw

1193b4be Poul Sander 2025-02-03 21:28 1
// dear imgui: Platform Backend for SDL2
1193b4be Poul Sander 2025-02-03 21:28 2
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
1193b4be Poul Sander 2025-02-03 21:28 3
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
1193b4be Poul Sander 2025-02-03 21:28 4
// (Prefer SDL 2.0.5+ for full feature support.)
1193b4be Poul Sander 2025-02-03 21:28 5
1193b4be Poul Sander 2025-02-03 21:28 6
// Implemented features:
1193b4be Poul Sander 2025-02-03 21:28 7
//  [X] Platform: Clipboard support.
1193b4be Poul Sander 2025-02-03 21:28 8
//  [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
4e9e2555 Poul Sander 2025-10-05 10:15 9
//  [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]
4e9e2555 Poul Sander 2025-10-05 10:15 10
//  [X] Platform: Gamepad support.
4e9e2555 Poul Sander 2025-10-05 10:15 11
//  [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
4e9e2555 Poul Sander 2025-10-05 10:15 12
//  [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
1193b4be Poul Sander 2025-02-03 21:28 13
//  [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
4e9e2555 Poul Sander 2025-10-05 10:15 14
// Missing features or Issues:
1193b4be Poul Sander 2025-02-03 21:28 15
//  [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
1193b4be Poul Sander 2025-02-03 21:28 16
//  [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
1193b4be Poul Sander 2025-02-03 21:28 17
1193b4be Poul Sander 2025-02-03 21:28 18
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1193b4be Poul Sander 2025-02-03 21:28 19
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
1193b4be Poul Sander 2025-02-03 21:28 20
// Learn about Dear ImGui:
1193b4be Poul Sander 2025-02-03 21:28 21
// - FAQ                  https://dearimgui.com/faq
1193b4be Poul Sander 2025-02-03 21:28 22
// - Getting Started      https://dearimgui.com/getting-started
1193b4be Poul Sander 2025-02-03 21:28 23
// - Documentation        https://dearimgui.com/docs (same as your local docs/ folder).
1193b4be Poul Sander 2025-02-03 21:28 24
// - Introduction, links and more at the top of imgui.cpp
1193b4be Poul Sander 2025-02-03 21:28 25
1193b4be Poul Sander 2025-02-03 21:28 26
// CHANGELOG
1193b4be Poul Sander 2025-02-03 21:28 27
// (minor and older changes stripped away, please see git history for details)
4e9e2555 Poul Sander 2025-10-05 10:15 28
//  2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
4e9e2555 Poul Sander 2025-10-05 10:15 29
//  2025-09-15: Content Scales are always reported as 1.0 on Wayland. (#8921)
4e9e2555 Poul Sander 2025-10-05 10:15 30
//  2025-07-08: Made ImGui_ImplSDL2_GetContentScaleForWindow(), ImGui_ImplSDL2_GetContentScaleForDisplay() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733)
4e9e2555 Poul Sander 2025-10-05 10:15 31
//  2025-06-11: Added ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window) and ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index) helper to facilitate making DPI-aware apps.
4e9e2555 Poul Sander 2025-10-05 10:15 32
//  2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
4e9e2555 Poul Sander 2025-10-05 10:15 33
//  2025-04-09: [Docking] Revert update monitors and work areas information every frame. Only do it on Windows. (#8415, #8558)
4e9e2555 Poul Sander 2025-10-05 10:15 34
//  2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561)
4e9e2555 Poul Sander 2025-10-05 10:15 35
//  2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
4e9e2555 Poul Sander 2025-10-05 10:15 36
//  2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
4e9e2555 Poul Sander 2025-10-05 10:15 37
//  2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g.Linux debuggers not claiming capture back. (#6410, #3650)
4e9e2555 Poul Sander 2025-10-05 10:15 38
//  2025-02-25: [Docking] Revert to use SDL_GetDisplayBounds() for WorkPos/WorkRect if SDL_GetDisplayUsableBounds() failed.
4e9e2555 Poul Sander 2025-10-05 10:15 39
//  2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
4e9e2555 Poul Sander 2025-10-05 10:15 40
//  2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415)
4e9e2555 Poul Sander 2025-10-05 10:15 41
//  2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
4e9e2555 Poul Sander 2025-10-05 10:15 42
//  2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
4e9e2555 Poul Sander 2025-10-05 10:15 43
//  2025-01-20: Made ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode_Manual) accept an empty array.
4e9e2555 Poul Sander 2025-10-05 10:15 44
//  2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
1193b4be Poul Sander 2025-02-03 21:28 45
//  2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
1193b4be Poul Sander 2025-02-03 21:28 46
//  2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
1193b4be Poul Sander 2025-02-03 21:28 47
//               - io.GetClipboardTextFn    -> platform_io.Platform_GetClipboardTextFn
1193b4be Poul Sander 2025-02-03 21:28 48
//               - io.SetClipboardTextFn    -> platform_io.Platform_SetClipboardTextFn
1193b4be Poul Sander 2025-02-03 21:28 49
//               - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
1193b4be Poul Sander 2025-02-03 21:28 50
//               - io.PlatformSetImeDataFn  -> platform_io.Platform_SetImeDataFn
1193b4be Poul Sander 2025-02-03 21:28 51
//  2024-08-19: Storing SDL's Uint32 WindowID inside ImGuiViewport::PlatformHandle instead of SDL_Window*.
1193b4be Poul Sander 2025-02-03 21:28 52
//  2024-08-19: ImGui_ImplSDL2_ProcessEvent() now ignores events intended for other SDL windows. (#7853)
1193b4be Poul Sander 2025-02-03 21:28 53
//  2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
1193b4be Poul Sander 2025-02-03 21:28 54
//  2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
1193b4be Poul Sander 2025-02-03 21:28 55
//  2024-02-14: Inputs: Handle gamepad disconnection. Added ImGui_ImplSDL2_SetGamepadMode().
1193b4be Poul Sander 2025-02-03 21:28 56
//  2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
1193b4be Poul Sander 2025-02-03 21:28 57
//  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)
1193b4be Poul Sander 2025-02-03 21:28 58
//  2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
1193b4be Poul Sander 2025-02-03 21:28 59
//  2023-02-23: Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. (#6189, #6114, #3644)
1193b4be Poul Sander 2025-02-03 21:28 60
//  2023-02-07: Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()).
1193b4be Poul Sander 2025-02-03 21:28 61
//  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.
1193b4be Poul Sander 2025-02-03 21:28 62
//  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).
1193b4be Poul Sander 2025-02-03 21:28 63
//  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)
1193b4be Poul Sander 2025-02-03 21:28 64
//  2023-02-02: Removed SDL_MOUSEWHEEL value clamping, as values seem correct in latest Emscripten. (#4019)
1193b4be Poul Sander 2025-02-03 21:28 65
//  2023-02-01: Flipping SDL_MOUSEWHEEL 'wheel.x' value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
1193b4be Poul Sander 2025-02-03 21:28 66
//  2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
1193b4be Poul Sander 2025-02-03 21:28 67
//  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)
1193b4be Poul Sander 2025-02-03 21:28 68
//  2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
1193b4be Poul Sander 2025-02-03 21:28 69
//  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.
1193b4be Poul Sander 2025-02-03 21:28 70
//  2022-03-22: Inputs: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2).
1193b4be Poul Sander 2025-02-03 21:28 71
//  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.
1193b4be Poul Sander 2025-02-03 21:28 72
//  2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
1193b4be Poul Sander 2025-02-03 21:28 73
//  2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
1193b4be Poul Sander 2025-02-03 21:28 74
//  2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
1193b4be Poul Sander 2025-02-03 21:28 75
//  2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates.
1193b4be Poul Sander 2025-02-03 21:28 76
//  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.
1193b4be Poul Sander 2025-02-03 21:28 77
//  2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
1193b4be Poul Sander 2025-02-03 21:28 78
//  2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
1193b4be Poul Sander 2025-02-03 21:28 79
//  2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
1193b4be Poul Sander 2025-02-03 21:28 80
//  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+)
1193b4be Poul Sander 2025-02-03 21:28 81
//  2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
1193b4be Poul Sander 2025-02-03 21:28 82
//  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).
1193b4be Poul Sander 2025-02-03 21:28 83
//  2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
1193b4be Poul Sander 2025-02-03 21:28 84
//  2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
1193b4be Poul Sander 2025-02-03 21:28 85
//  2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
1193b4be Poul Sander 2025-02-03 21:28 86
//  2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
1193b4be Poul Sander 2025-02-03 21:28 87
//  2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
1193b4be Poul Sander 2025-02-03 21:28 88
//  2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
1193b4be Poul Sander 2025-02-03 21:28 89
//  2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
1193b4be Poul Sander 2025-02-03 21:28 90
//  2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
1193b4be Poul Sander 2025-02-03 21:28 91
//  2018-12-21: Inputs: Workaround for Android/iOS which don't seem to handle focus related calls.
1193b4be Poul Sander 2025-02-03 21:28 92
//  2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
1193b4be Poul Sander 2025-02-03 21:28 93
//  2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'.
1193b4be Poul Sander 2025-02-03 21:28 94
//  2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
1193b4be Poul Sander 2025-02-03 21:28 95
//  2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
1193b4be Poul Sander 2025-02-03 21:28 96
//  2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples.
1193b4be Poul Sander 2025-02-03 21:28 97
//  2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter.
1193b4be Poul Sander 2025-02-03 21:28 98
//  2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText).
1193b4be Poul Sander 2025-02-03 21:28 99
//  2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
1193b4be Poul Sander 2025-02-03 21:28 100
//  2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value.
1193b4be Poul Sander 2025-02-03 21:28 101
//  2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
1193b4be Poul Sander 2025-02-03 21:28 102
//  2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
1193b4be Poul Sander 2025-02-03 21:28 103
//  2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS).
1193b4be Poul Sander 2025-02-03 21:28 104
//  2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes.
1193b4be Poul Sander 2025-02-03 21:28 105
//  2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
1193b4be Poul Sander 2025-02-03 21:28 106
//  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.
1193b4be Poul Sander 2025-02-03 21:28 107
//  2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
1193b4be Poul Sander 2025-02-03 21:28 108
//  2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
1193b4be Poul Sander 2025-02-03 21:28 109
//  2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
1193b4be Poul Sander 2025-02-03 21:28 110
1193b4be Poul Sander 2025-02-03 21:28 111
#include "imgui.h"
1193b4be Poul Sander 2025-02-03 21:28 112
#ifndef IMGUI_DISABLE
1193b4be Poul Sander 2025-02-03 21:28 113
#include "imgui_impl_sdl2.h"
1193b4be Poul Sander 2025-02-03 21:28 114
1193b4be Poul Sander 2025-02-03 21:28 115
// Clang warnings with -Weverything
1193b4be Poul Sander 2025-02-03 21:28 116
#if defined(__clang__)
1193b4be Poul Sander 2025-02-03 21:28 117
#pragma clang diagnostic push
4e9e2555 Poul Sander 2025-10-05 10:15 118
#pragma clang diagnostic ignored "-Wold-style-cast"                 // warning: use of old-style cast
1193b4be Poul Sander 2025-02-03 21:28 119
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"  // warning: implicit conversion from 'xxx' to 'float' may lose precision
1193b4be Poul Sander 2025-02-03 21:28 120
#endif
1193b4be Poul Sander 2025-02-03 21:28 121
1193b4be Poul Sander 2025-02-03 21:28 122
// SDL
1193b4be Poul Sander 2025-02-03 21:28 123
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
1193b4be Poul Sander 2025-02-03 21:28 124
#include <SDL.h>
1193b4be Poul Sander 2025-02-03 21:28 125
#include <SDL_syswm.h>
4e9e2555 Poul Sander 2025-10-05 10:15 126
#include <stdio.h>              // for snprintf()
1193b4be Poul Sander 2025-02-03 21:28 127
#ifdef __APPLE__
1193b4be Poul Sander 2025-02-03 21:28 128
#include <TargetConditionals.h>
1193b4be Poul Sander 2025-02-03 21:28 129
#endif
1193b4be Poul Sander 2025-02-03 21:28 130
#ifdef __EMSCRIPTEN__
1193b4be Poul Sander 2025-02-03 21:28 131
#include <emscripten/em_js.h>
1193b4be Poul Sander 2025-02-03 21:28 132
#endif
4e9e2555 Poul Sander 2025-10-05 10:15 133
#undef Status // X11 headers are leaking this.
1193b4be Poul Sander 2025-02-03 21:28 134
1193b4be Poul Sander 2025-02-03 21:28 135
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
1193b4be Poul Sander 2025-02-03 21:28 136
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE    1
1193b4be Poul Sander 2025-02-03 21:28 137
#else
1193b4be Poul Sander 2025-02-03 21:28 138
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE    0
1193b4be Poul Sander 2025-02-03 21:28 139
#endif
1193b4be Poul Sander 2025-02-03 21:28 140
#define SDL_HAS_WINDOW_ALPHA                SDL_VERSION_ATLEAST(2,0,5)
1193b4be Poul Sander 2025-02-03 21:28 141
#define SDL_HAS_ALWAYS_ON_TOP               SDL_VERSION_ATLEAST(2,0,5)
1193b4be Poul Sander 2025-02-03 21:28 142
#define SDL_HAS_USABLE_DISPLAY_BOUNDS       SDL_VERSION_ATLEAST(2,0,5)
1193b4be Poul Sander 2025-02-03 21:28 143
#define SDL_HAS_PER_MONITOR_DPI             SDL_VERSION_ATLEAST(2,0,4)
1193b4be Poul Sander 2025-02-03 21:28 144
#define SDL_HAS_VULKAN                      SDL_VERSION_ATLEAST(2,0,6)
1193b4be Poul Sander 2025-02-03 21:28 145
#define SDL_HAS_DISPLAY_EVENT               SDL_VERSION_ATLEAST(2,0,9)
4e9e2555 Poul Sander 2025-10-05 10:15 146
#define SDL_HAS_OPEN_URL                    SDL_VERSION_ATLEAST(2,0,14)
1193b4be Poul Sander 2025-02-03 21:28 147
#define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18)
1193b4be Poul Sander 2025-02-03 21:28 148
#if SDL_HAS_VULKAN
4e9e2555 Poul Sander 2025-10-05 10:15 149
#include <SDL_vulkan.h>
4e9e2555 Poul Sander 2025-10-05 10:15 150
#else
1193b4be Poul Sander 2025-02-03 21:28 151
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
1193b4be Poul Sander 2025-02-03 21:28 152
#endif
1193b4be Poul Sander 2025-02-03 21:28 153
1193b4be Poul Sander 2025-02-03 21:28 154
// SDL Data
1193b4be Poul Sander 2025-02-03 21:28 155
struct ImGui_ImplSDL2_Data
1193b4be Poul Sander 2025-02-03 21:28 156
{
1193b4be Poul Sander 2025-02-03 21:28 157
    SDL_Window*             Window;
4e9e2555 Poul Sander 2025-10-05 10:15 158
    Uint32                  WindowID;       // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
1193b4be Poul Sander 2025-02-03 21:28 159
    SDL_Renderer*           Renderer;
1193b4be Poul Sander 2025-02-03 21:28 160
    Uint64                  Time;
1193b4be Poul Sander 2025-02-03 21:28 161
    char*                   ClipboardTextData;
4e9e2555 Poul Sander 2025-10-05 10:15 162
    char                    BackendPlatformName[48];
1193b4be Poul Sander 2025-02-03 21:28 163
    bool                    UseVulkan;
1193b4be Poul Sander 2025-02-03 21:28 164
    bool                    WantUpdateMonitors;
1193b4be Poul Sander 2025-02-03 21:28 165
1193b4be Poul Sander 2025-02-03 21:28 166
    // Mouse handling
1193b4be Poul Sander 2025-02-03 21:28 167
    Uint32                  MouseWindowID;
1193b4be Poul Sander 2025-02-03 21:28 168
    int                     MouseButtonsDown;
1193b4be Poul Sander 2025-02-03 21:28 169
    SDL_Cursor*             MouseCursors[ImGuiMouseCursor_COUNT];
1193b4be Poul Sander 2025-02-03 21:28 170
    SDL_Cursor*             MouseLastCursor;
1193b4be Poul Sander 2025-02-03 21:28 171
    int                     MouseLastLeaveFrame;
1193b4be Poul Sander 2025-02-03 21:28 172
    bool                    MouseCanUseGlobalState;
4e9e2555 Poul Sander 2025-10-05 10:15 173
    bool                    MouseCanUseCapture;
1193b4be Poul Sander 2025-02-03 21:28 174
    bool                    MouseCanReportHoveredViewport;  // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
1193b4be Poul Sander 2025-02-03 21:28 175
1193b4be Poul Sander 2025-02-03 21:28 176
    // Gamepad handling
1193b4be Poul Sander 2025-02-03 21:28 177
    ImVector<SDL_GameController*> Gamepads;
1193b4be Poul Sander 2025-02-03 21:28 178
    ImGui_ImplSDL2_GamepadMode    GamepadMode;
1193b4be Poul Sander 2025-02-03 21:28 179
    bool                          WantUpdateGamepadsList;
1193b4be Poul Sander 2025-02-03 21:28 180
1193b4be Poul Sander 2025-02-03 21:28 181
    ImGui_ImplSDL2_Data()   { memset((void*)this, 0, sizeof(*this)); }
1193b4be Poul Sander 2025-02-03 21:28 182
};
1193b4be Poul Sander 2025-02-03 21:28 183
1193b4be Poul Sander 2025-02-03 21:28 184
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
1193b4be Poul Sander 2025-02-03 21:28 185
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
1193b4be Poul Sander 2025-02-03 21:28 186
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
1193b4be Poul Sander 2025-02-03 21:28 187
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
1193b4be Poul Sander 2025-02-03 21:28 188
static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
1193b4be Poul Sander 2025-02-03 21:28 189
{
1193b4be Poul Sander 2025-02-03 21:28 190
    return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
1193b4be Poul Sander 2025-02-03 21:28 191
}
1193b4be Poul Sander 2025-02-03 21:28 192
1193b4be Poul Sander 2025-02-03 21:28 193
// Forward Declarations
1193b4be Poul Sander 2025-02-03 21:28 194
static void ImGui_ImplSDL2_UpdateMonitors();
1193b4be Poul Sander 2025-02-03 21:28 195
static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
1193b4be Poul Sander 2025-02-03 21:28 196
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport();
1193b4be Poul Sander 2025-02-03 21:28 197
1193b4be Poul Sander 2025-02-03 21:28 198
// Functions
1193b4be Poul Sander 2025-02-03 21:28 199
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
1193b4be Poul Sander 2025-02-03 21:28 200
{
1193b4be Poul Sander 2025-02-03 21:28 201
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 202
    if (bd->ClipboardTextData)
1193b4be Poul Sander 2025-02-03 21:28 203
        SDL_free(bd->ClipboardTextData);
1193b4be Poul Sander 2025-02-03 21:28 204
    bd->ClipboardTextData = SDL_GetClipboardText();
1193b4be Poul Sander 2025-02-03 21:28 205
    return bd->ClipboardTextData;
1193b4be Poul Sander 2025-02-03 21:28 206
}
1193b4be Poul Sander 2025-02-03 21:28 207
1193b4be Poul Sander 2025-02-03 21:28 208
static void ImGui_ImplSDL2_SetClipboardText(ImGuiContext*, const char* text)
1193b4be Poul Sander 2025-02-03 21:28 209
{
1193b4be Poul Sander 2025-02-03 21:28 210
    SDL_SetClipboardText(text);
1193b4be Poul Sander 2025-02-03 21:28 211
}
1193b4be Poul Sander 2025-02-03 21:28 212
1193b4be Poul Sander 2025-02-03 21:28 213
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
1193b4be Poul Sander 2025-02-03 21:28 214
static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport* viewport, ImGuiPlatformImeData* data)
1193b4be Poul Sander 2025-02-03 21:28 215
{
1193b4be Poul Sander 2025-02-03 21:28 216
    if (data->WantVisible)
1193b4be Poul Sander 2025-02-03 21:28 217
    {
1193b4be Poul Sander 2025-02-03 21:28 218
        SDL_Rect r;
1193b4be Poul Sander 2025-02-03 21:28 219
        r.x = (int)(data->InputPos.x - viewport->Pos.x);
1193b4be Poul Sander 2025-02-03 21:28 220
        r.y = (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight);
1193b4be Poul Sander 2025-02-03 21:28 221
        r.w = 1;
1193b4be Poul Sander 2025-02-03 21:28 222
        r.h = (int)data->InputLineHeight;
1193b4be Poul Sander 2025-02-03 21:28 223
        SDL_SetTextInputRect(&r);
1193b4be Poul Sander 2025-02-03 21:28 224
    }
1193b4be Poul Sander 2025-02-03 21:28 225
}
1193b4be Poul Sander 2025-02-03 21:28 226
1193b4be Poul Sander 2025-02-03 21:28 227
// Not static to allow third-party code to use that if they want to (but undocumented)
4e9e2555 Poul Sander 2025-10-05 10:15 228
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
1193b4be Poul Sander 2025-02-03 21:28 229
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
1193b4be Poul Sander 2025-02-03 21:28 230
{
1193b4be Poul Sander 2025-02-03 21:28 231
    switch (keycode)
1193b4be Poul Sander 2025-02-03 21:28 232
    {
1193b4be Poul Sander 2025-02-03 21:28 233
        case SDLK_TAB: return ImGuiKey_Tab;
1193b4be Poul Sander 2025-02-03 21:28 234
        case SDLK_LEFT: return ImGuiKey_LeftArrow;
1193b4be Poul Sander 2025-02-03 21:28 235
        case SDLK_RIGHT: return ImGuiKey_RightArrow;
1193b4be Poul Sander 2025-02-03 21:28 236
        case SDLK_UP: return ImGuiKey_UpArrow;
1193b4be Poul Sander 2025-02-03 21:28 237
        case SDLK_DOWN: return ImGuiKey_DownArrow;
1193b4be Poul Sander 2025-02-03 21:28 238
        case SDLK_PAGEUP: return ImGuiKey_PageUp;
1193b4be Poul Sander 2025-02-03 21:28 239
        case SDLK_PAGEDOWN: return ImGuiKey_PageDown;
1193b4be Poul Sander 2025-02-03 21:28 240
        case SDLK_HOME: return ImGuiKey_Home;
1193b4be Poul Sander 2025-02-03 21:28 241
        case SDLK_END: return ImGuiKey_End;
1193b4be Poul Sander 2025-02-03 21:28 242
        case SDLK_INSERT: return ImGuiKey_Insert;
1193b4be Poul Sander 2025-02-03 21:28 243
        case SDLK_DELETE: return ImGuiKey_Delete;
1193b4be Poul Sander 2025-02-03 21:28 244
        case SDLK_BACKSPACE: return ImGuiKey_Backspace;
1193b4be Poul Sander 2025-02-03 21:28 245
        case SDLK_SPACE: return ImGuiKey_Space;
1193b4be Poul Sander 2025-02-03 21:28 246
        case SDLK_RETURN: return ImGuiKey_Enter;
1193b4be Poul Sander 2025-02-03 21:28 247
        case SDLK_ESCAPE: return ImGuiKey_Escape;
4e9e2555 Poul Sander 2025-10-05 10:15 248
        //case SDLK_QUOTE: return ImGuiKey_Apostrophe;
1193b4be Poul Sander 2025-02-03 21:28 249
        case SDLK_COMMA: return ImGuiKey_Comma;
4e9e2555 Poul Sander 2025-10-05 10:15 250
        //case SDLK_MINUS: return ImGuiKey_Minus;
1193b4be Poul Sander 2025-02-03 21:28 251
        case SDLK_PERIOD: return ImGuiKey_Period;
4e9e2555 Poul Sander 2025-10-05 10:15 252
        //case SDLK_SLASH: return ImGuiKey_Slash;
1193b4be Poul Sander 2025-02-03 21:28 253
        case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
4e9e2555 Poul Sander 2025-10-05 10:15 254
        //case SDLK_EQUALS: return ImGuiKey_Equal;
4e9e2555 Poul Sander 2025-10-05 10:15 255
        //case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
4e9e2555 Poul Sander 2025-10-05 10:15 256
        //case SDLK_BACKSLASH: return ImGuiKey_Backslash;
4e9e2555 Poul Sander 2025-10-05 10:15 257
        //case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
4e9e2555 Poul Sander 2025-10-05 10:15 258
        //case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
1193b4be Poul Sander 2025-02-03 21:28 259
        case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
1193b4be Poul Sander 2025-02-03 21:28 260
        case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
1193b4be Poul Sander 2025-02-03 21:28 261
        case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
1193b4be Poul Sander 2025-02-03 21:28 262
        case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen;
1193b4be Poul Sander 2025-02-03 21:28 263
        case SDLK_PAUSE: return ImGuiKey_Pause;
1193b4be Poul Sander 2025-02-03 21:28 264
        case SDLK_KP_0: return ImGuiKey_Keypad0;
1193b4be Poul Sander 2025-02-03 21:28 265
        case SDLK_KP_1: return ImGuiKey_Keypad1;
1193b4be Poul Sander 2025-02-03 21:28 266
        case SDLK_KP_2: return ImGuiKey_Keypad2;
1193b4be Poul Sander 2025-02-03 21:28 267
        case SDLK_KP_3: return ImGuiKey_Keypad3;
1193b4be Poul Sander 2025-02-03 21:28 268
        case SDLK_KP_4: return ImGuiKey_Keypad4;
1193b4be Poul Sander 2025-02-03 21:28 269
        case SDLK_KP_5: return ImGuiKey_Keypad5;
1193b4be Poul Sander 2025-02-03 21:28 270
        case SDLK_KP_6: return ImGuiKey_Keypad6;
1193b4be Poul Sander 2025-02-03 21:28 271
        case SDLK_KP_7: return ImGuiKey_Keypad7;
1193b4be Poul Sander 2025-02-03 21:28 272
        case SDLK_KP_8: return ImGuiKey_Keypad8;
1193b4be Poul Sander 2025-02-03 21:28 273
        case SDLK_KP_9: return ImGuiKey_Keypad9;
1193b4be Poul Sander 2025-02-03 21:28 274
        case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal;
1193b4be Poul Sander 2025-02-03 21:28 275
        case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide;
1193b4be Poul Sander 2025-02-03 21:28 276
        case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
1193b4be Poul Sander 2025-02-03 21:28 277
        case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract;
1193b4be Poul Sander 2025-02-03 21:28 278
        case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
1193b4be Poul Sander 2025-02-03 21:28 279
        case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
1193b4be Poul Sander 2025-02-03 21:28 280
        case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
1193b4be Poul Sander 2025-02-03 21:28 281
        case SDLK_LCTRL: return ImGuiKey_LeftCtrl;
1193b4be Poul Sander 2025-02-03 21:28 282
        case SDLK_LSHIFT: return ImGuiKey_LeftShift;
1193b4be Poul Sander 2025-02-03 21:28 283
        case SDLK_LALT: return ImGuiKey_LeftAlt;
1193b4be Poul Sander 2025-02-03 21:28 284
        case SDLK_LGUI: return ImGuiKey_LeftSuper;
1193b4be Poul Sander 2025-02-03 21:28 285
        case SDLK_RCTRL: return ImGuiKey_RightCtrl;
1193b4be Poul Sander 2025-02-03 21:28 286
        case SDLK_RSHIFT: return ImGuiKey_RightShift;
1193b4be Poul Sander 2025-02-03 21:28 287
        case SDLK_RALT: return ImGuiKey_RightAlt;
1193b4be Poul Sander 2025-02-03 21:28 288
        case SDLK_RGUI: return ImGuiKey_RightSuper;
1193b4be Poul Sander 2025-02-03 21:28 289
        case SDLK_APPLICATION: return ImGuiKey_Menu;
1193b4be Poul Sander 2025-02-03 21:28 290
        case SDLK_0: return ImGuiKey_0;
1193b4be Poul Sander 2025-02-03 21:28 291
        case SDLK_1: return ImGuiKey_1;
1193b4be Poul Sander 2025-02-03 21:28 292
        case SDLK_2: return ImGuiKey_2;
1193b4be Poul Sander 2025-02-03 21:28 293
        case SDLK_3: return ImGuiKey_3;
1193b4be Poul Sander 2025-02-03 21:28 294
        case SDLK_4: return ImGuiKey_4;
1193b4be Poul Sander 2025-02-03 21:28 295
        case SDLK_5: return ImGuiKey_5;
1193b4be Poul Sander 2025-02-03 21:28 296
        case SDLK_6: return ImGuiKey_6;
1193b4be Poul Sander 2025-02-03 21:28 297
        case SDLK_7: return ImGuiKey_7;
1193b4be Poul Sander 2025-02-03 21:28 298
        case SDLK_8: return ImGuiKey_8;
1193b4be Poul Sander 2025-02-03 21:28 299
        case SDLK_9: return ImGuiKey_9;
1193b4be Poul Sander 2025-02-03 21:28 300
        case SDLK_a: return ImGuiKey_A;
1193b4be Poul Sander 2025-02-03 21:28 301
        case SDLK_b: return ImGuiKey_B;
1193b4be Poul Sander 2025-02-03 21:28 302
        case SDLK_c: return ImGuiKey_C;
1193b4be Poul Sander 2025-02-03 21:28 303
        case SDLK_d: return ImGuiKey_D;
1193b4be Poul Sander 2025-02-03 21:28 304
        case SDLK_e: return ImGuiKey_E;
1193b4be Poul Sander 2025-02-03 21:28 305
        case SDLK_f: return ImGuiKey_F;
1193b4be Poul Sander 2025-02-03 21:28 306
        case SDLK_g: return ImGuiKey_G;
1193b4be Poul Sander 2025-02-03 21:28 307
        case SDLK_h: return ImGuiKey_H;
1193b4be Poul Sander 2025-02-03 21:28 308
        case SDLK_i: return ImGuiKey_I;
1193b4be Poul Sander 2025-02-03 21:28 309
        case SDLK_j: return ImGuiKey_J;
1193b4be Poul Sander 2025-02-03 21:28 310
        case SDLK_k: return ImGuiKey_K;
1193b4be Poul Sander 2025-02-03 21:28 311
        case SDLK_l: return ImGuiKey_L;
1193b4be Poul Sander 2025-02-03 21:28 312
        case SDLK_m: return ImGuiKey_M;
1193b4be Poul Sander 2025-02-03 21:28 313
        case SDLK_n: return ImGuiKey_N;
1193b4be Poul Sander 2025-02-03 21:28 314
        case SDLK_o: return ImGuiKey_O;
1193b4be Poul Sander 2025-02-03 21:28 315
        case SDLK_p: return ImGuiKey_P;
1193b4be Poul Sander 2025-02-03 21:28 316
        case SDLK_q: return ImGuiKey_Q;
1193b4be Poul Sander 2025-02-03 21:28 317
        case SDLK_r: return ImGuiKey_R;
1193b4be Poul Sander 2025-02-03 21:28 318
        case SDLK_s: return ImGuiKey_S;
1193b4be Poul Sander 2025-02-03 21:28 319
        case SDLK_t: return ImGuiKey_T;
1193b4be Poul Sander 2025-02-03 21:28 320
        case SDLK_u: return ImGuiKey_U;
1193b4be Poul Sander 2025-02-03 21:28 321
        case SDLK_v: return ImGuiKey_V;
1193b4be Poul Sander 2025-02-03 21:28 322
        case SDLK_w: return ImGuiKey_W;
1193b4be Poul Sander 2025-02-03 21:28 323
        case SDLK_x: return ImGuiKey_X;
1193b4be Poul Sander 2025-02-03 21:28 324
        case SDLK_y: return ImGuiKey_Y;
1193b4be Poul Sander 2025-02-03 21:28 325
        case SDLK_z: return ImGuiKey_Z;
1193b4be Poul Sander 2025-02-03 21:28 326
        case SDLK_F1: return ImGuiKey_F1;
1193b4be Poul Sander 2025-02-03 21:28 327
        case SDLK_F2: return ImGuiKey_F2;
1193b4be Poul Sander 2025-02-03 21:28 328
        case SDLK_F3: return ImGuiKey_F3;
1193b4be Poul Sander 2025-02-03 21:28 329
        case SDLK_F4: return ImGuiKey_F4;
1193b4be Poul Sander 2025-02-03 21:28 330
        case SDLK_F5: return ImGuiKey_F5;
1193b4be Poul Sander 2025-02-03 21:28 331
        case SDLK_F6: return ImGuiKey_F6;
1193b4be Poul Sander 2025-02-03 21:28 332
        case SDLK_F7: return ImGuiKey_F7;
1193b4be Poul Sander 2025-02-03 21:28 333
        case SDLK_F8: return ImGuiKey_F8;
1193b4be Poul Sander 2025-02-03 21:28 334
        case SDLK_F9: return ImGuiKey_F9;
1193b4be Poul Sander 2025-02-03 21:28 335
        case SDLK_F10: return ImGuiKey_F10;
1193b4be Poul Sander 2025-02-03 21:28 336
        case SDLK_F11: return ImGuiKey_F11;
1193b4be Poul Sander 2025-02-03 21:28 337
        case SDLK_F12: return ImGuiKey_F12;
1193b4be Poul Sander 2025-02-03 21:28 338
        case SDLK_F13: return ImGuiKey_F13;
1193b4be Poul Sander 2025-02-03 21:28 339
        case SDLK_F14: return ImGuiKey_F14;
1193b4be Poul Sander 2025-02-03 21:28 340
        case SDLK_F15: return ImGuiKey_F15;
1193b4be Poul Sander 2025-02-03 21:28 341
        case SDLK_F16: return ImGuiKey_F16;
1193b4be Poul Sander 2025-02-03 21:28 342
        case SDLK_F17: return ImGuiKey_F17;
1193b4be Poul Sander 2025-02-03 21:28 343
        case SDLK_F18: return ImGuiKey_F18;
1193b4be Poul Sander 2025-02-03 21:28 344
        case SDLK_F19: return ImGuiKey_F19;
1193b4be Poul Sander 2025-02-03 21:28 345
        case SDLK_F20: return ImGuiKey_F20;
1193b4be Poul Sander 2025-02-03 21:28 346
        case SDLK_F21: return ImGuiKey_F21;
1193b4be Poul Sander 2025-02-03 21:28 347
        case SDLK_F22: return ImGuiKey_F22;
1193b4be Poul Sander 2025-02-03 21:28 348
        case SDLK_F23: return ImGuiKey_F23;
1193b4be Poul Sander 2025-02-03 21:28 349
        case SDLK_F24: return ImGuiKey_F24;
1193b4be Poul Sander 2025-02-03 21:28 350
        case SDLK_AC_BACK: return ImGuiKey_AppBack;
1193b4be Poul Sander 2025-02-03 21:28 351
        case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
1193b4be Poul Sander 2025-02-03 21:28 352
        default: break;
1193b4be Poul Sander 2025-02-03 21:28 353
    }
4e9e2555 Poul Sander 2025-10-05 10:15 354
4e9e2555 Poul Sander 2025-10-05 10:15 355
    // Fallback to scancode
4e9e2555 Poul Sander 2025-10-05 10:15 356
    switch (scancode)
4e9e2555 Poul Sander 2025-10-05 10:15 357
    {
4e9e2555 Poul Sander 2025-10-05 10:15 358
    case SDL_SCANCODE_GRAVE: return ImGuiKey_GraveAccent;
4e9e2555 Poul Sander 2025-10-05 10:15 359
    case SDL_SCANCODE_MINUS: return ImGuiKey_Minus;
4e9e2555 Poul Sander 2025-10-05 10:15 360
    case SDL_SCANCODE_EQUALS: return ImGuiKey_Equal;
4e9e2555 Poul Sander 2025-10-05 10:15 361
    case SDL_SCANCODE_LEFTBRACKET: return ImGuiKey_LeftBracket;
4e9e2555 Poul Sander 2025-10-05 10:15 362
    case SDL_SCANCODE_RIGHTBRACKET: return ImGuiKey_RightBracket;
4e9e2555 Poul Sander 2025-10-05 10:15 363
    case SDL_SCANCODE_NONUSBACKSLASH: return ImGuiKey_Oem102;
4e9e2555 Poul Sander 2025-10-05 10:15 364
    case SDL_SCANCODE_BACKSLASH: return ImGuiKey_Backslash;
4e9e2555 Poul Sander 2025-10-05 10:15 365
    case SDL_SCANCODE_SEMICOLON: return ImGuiKey_Semicolon;
4e9e2555 Poul Sander 2025-10-05 10:15 366
    case SDL_SCANCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
4e9e2555 Poul Sander 2025-10-05 10:15 367
    case SDL_SCANCODE_COMMA: return ImGuiKey_Comma;
4e9e2555 Poul Sander 2025-10-05 10:15 368
    case SDL_SCANCODE_PERIOD: return ImGuiKey_Period;
4e9e2555 Poul Sander 2025-10-05 10:15 369
    case SDL_SCANCODE_SLASH: return ImGuiKey_Slash;
4e9e2555 Poul Sander 2025-10-05 10:15 370
    default: break;
4e9e2555 Poul Sander 2025-10-05 10:15 371
    }
1193b4be Poul Sander 2025-02-03 21:28 372
    return ImGuiKey_None;
1193b4be Poul Sander 2025-02-03 21:28 373
}
1193b4be Poul Sander 2025-02-03 21:28 374
1193b4be Poul Sander 2025-02-03 21:28 375
static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
1193b4be Poul Sander 2025-02-03 21:28 376
{
1193b4be Poul Sander 2025-02-03 21:28 377
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 378
    io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & KMOD_CTRL) != 0);
1193b4be Poul Sander 2025-02-03 21:28 379
    io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & KMOD_SHIFT) != 0);
1193b4be Poul Sander 2025-02-03 21:28 380
    io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & KMOD_ALT) != 0);
1193b4be Poul Sander 2025-02-03 21:28 381
    io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0);
1193b4be Poul Sander 2025-02-03 21:28 382
}
1193b4be Poul Sander 2025-02-03 21:28 383
1193b4be Poul Sander 2025-02-03 21:28 384
static ImGuiViewport* ImGui_ImplSDL2_GetViewportForWindowID(Uint32 window_id)
1193b4be Poul Sander 2025-02-03 21:28 385
{
1193b4be Poul Sander 2025-02-03 21:28 386
    return ImGui::FindViewportByPlatformHandle((void*)(intptr_t)window_id);
1193b4be Poul Sander 2025-02-03 21:28 387
}
1193b4be Poul Sander 2025-02-03 21:28 388
1193b4be Poul Sander 2025-02-03 21:28 389
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
1193b4be Poul Sander 2025-02-03 21:28 390
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
1193b4be Poul Sander 2025-02-03 21:28 391
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
1193b4be Poul Sander 2025-02-03 21:28 392
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
1193b4be Poul Sander 2025-02-03 21:28 393
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
1193b4be Poul Sander 2025-02-03 21:28 394
{
1193b4be Poul Sander 2025-02-03 21:28 395
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 396
    IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?");
1193b4be Poul Sander 2025-02-03 21:28 397
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 398
1193b4be Poul Sander 2025-02-03 21:28 399
    switch (event->type)
1193b4be Poul Sander 2025-02-03 21:28 400
    {
1193b4be Poul Sander 2025-02-03 21:28 401
        case SDL_MOUSEMOTION:
1193b4be Poul Sander 2025-02-03 21:28 402
        {
4e9e2555 Poul Sander 2025-10-05 10:15 403
            if (ImGui_ImplSDL2_GetViewportForWindowID(event->motion.windowID) == nullptr)
1193b4be Poul Sander 2025-02-03 21:28 404
                return false;
1193b4be Poul Sander 2025-02-03 21:28 405
            ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
1193b4be Poul Sander 2025-02-03 21:28 406
            if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
1193b4be Poul Sander 2025-02-03 21:28 407
            {
1193b4be Poul Sander 2025-02-03 21:28 408
                int window_x, window_y;
1193b4be Poul Sander 2025-02-03 21:28 409
                SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
1193b4be Poul Sander 2025-02-03 21:28 410
                mouse_pos.x += window_x;
1193b4be Poul Sander 2025-02-03 21:28 411
                mouse_pos.y += window_y;
1193b4be Poul Sander 2025-02-03 21:28 412
            }
1193b4be Poul Sander 2025-02-03 21:28 413
            io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
1193b4be Poul Sander 2025-02-03 21:28 414
            io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
1193b4be Poul Sander 2025-02-03 21:28 415
            return true;
1193b4be Poul Sander 2025-02-03 21:28 416
        }
1193b4be Poul Sander 2025-02-03 21:28 417
        case SDL_MOUSEWHEEL:
1193b4be Poul Sander 2025-02-03 21:28 418
        {
4e9e2555 Poul Sander 2025-10-05 10:15 419
            if (ImGui_ImplSDL2_GetViewportForWindowID(event->wheel.windowID) == nullptr)
1193b4be Poul Sander 2025-02-03 21:28 420
                return false;
1193b4be Poul Sander 2025-02-03 21:28 421
            //IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
1193b4be Poul Sander 2025-02-03 21:28 422
#if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten!
1193b4be Poul Sander 2025-02-03 21:28 423
            float wheel_x = -event->wheel.preciseX;
1193b4be Poul Sander 2025-02-03 21:28 424
            float wheel_y = event->wheel.preciseY;
1193b4be Poul Sander 2025-02-03 21:28 425
#else
1193b4be Poul Sander 2025-02-03 21:28 426
            float wheel_x = -(float)event->wheel.x;
1193b4be Poul Sander 2025-02-03 21:28 427
            float wheel_y = (float)event->wheel.y;
1193b4be Poul Sander 2025-02-03 21:28 428
#endif
4e9e2555 Poul Sander 2025-10-05 10:15 429
#if defined(__EMSCRIPTEN__) && !SDL_VERSION_ATLEAST(2,31,0)
1193b4be Poul Sander 2025-02-03 21:28 430
            wheel_x /= 100.0f;
1193b4be Poul Sander 2025-02-03 21:28 431
#endif
1193b4be Poul Sander 2025-02-03 21:28 432
            io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
1193b4be Poul Sander 2025-02-03 21:28 433
            io.AddMouseWheelEvent(wheel_x, wheel_y);
1193b4be Poul Sander 2025-02-03 21:28 434
            return true;
1193b4be Poul Sander 2025-02-03 21:28 435
        }
1193b4be Poul Sander 2025-02-03 21:28 436
        case SDL_MOUSEBUTTONDOWN:
1193b4be Poul Sander 2025-02-03 21:28 437
        case SDL_MOUSEBUTTONUP:
1193b4be Poul Sander 2025-02-03 21:28 438
        {
4e9e2555 Poul Sander 2025-10-05 10:15 439
            if (ImGui_ImplSDL2_GetViewportForWindowID(event->button.windowID) == nullptr)
1193b4be Poul Sander 2025-02-03 21:28 440
                return false;
1193b4be Poul Sander 2025-02-03 21:28 441
            int mouse_button = -1;
1193b4be Poul Sander 2025-02-03 21:28 442
            if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
1193b4be Poul Sander 2025-02-03 21:28 443
            if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
1193b4be Poul Sander 2025-02-03 21:28 444
            if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
1193b4be Poul Sander 2025-02-03 21:28 445
            if (event->button.button == SDL_BUTTON_X1) { mouse_button = 3; }
1193b4be Poul Sander 2025-02-03 21:28 446
            if (event->button.button == SDL_BUTTON_X2) { mouse_button = 4; }
1193b4be Poul Sander 2025-02-03 21:28 447
            if (mouse_button == -1)
1193b4be Poul Sander 2025-02-03 21:28 448
                break;
1193b4be Poul Sander 2025-02-03 21:28 449
            io.AddMouseSourceEvent(event->button.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
1193b4be Poul Sander 2025-02-03 21:28 450
            io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN));
1193b4be Poul Sander 2025-02-03 21:28 451
            bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
1193b4be Poul Sander 2025-02-03 21:28 452
            return true;
1193b4be Poul Sander 2025-02-03 21:28 453
        }
1193b4be Poul Sander 2025-02-03 21:28 454
        case SDL_TEXTINPUT:
1193b4be Poul Sander 2025-02-03 21:28 455
        {
4e9e2555 Poul Sander 2025-10-05 10:15 456
            if (ImGui_ImplSDL2_GetViewportForWindowID(event->text.windowID) == nullptr)
1193b4be Poul Sander 2025-02-03 21:28 457
                return false;
1193b4be Poul Sander 2025-02-03 21:28 458
            io.AddInputCharactersUTF8(event->text.text);
1193b4be Poul Sander 2025-02-03 21:28 459
            return true;
1193b4be Poul Sander 2025-02-03 21:28 460
        }
1193b4be Poul Sander 2025-02-03 21:28 461
        case SDL_KEYDOWN:
1193b4be Poul Sander 2025-02-03 21:28 462
        case SDL_KEYUP:
1193b4be Poul Sander 2025-02-03 21:28 463
        {
4e9e2555 Poul Sander 2025-10-05 10:15 464
            ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID);
4e9e2555 Poul Sander 2025-10-05 10:15 465
            if (viewport == nullptr)
1193b4be Poul Sander 2025-02-03 21:28 466
                return false;
4e9e2555 Poul Sander 2025-10-05 10:15 467
            //IMGUI_DEBUG_LOG("SDL_KEY%s : key=0x%08X ('%s'), scancode=%d ('%s'), mod=%X, windowID=%d, viewport=%08X\n",
4e9e2555 Poul Sander 2025-10-05 10:15 468
            //    (event->type == SDL_KEYDOWN) ? "DOWN" : "UP  ", event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.mod, event->key.windowID, viewport ? viewport->ID : 0);
1193b4be Poul Sander 2025-02-03 21:28 469
            ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
1193b4be Poul Sander 2025-02-03 21:28 470
            ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey(event->key.keysym.sym, event->key.keysym.scancode);
1193b4be Poul Sander 2025-02-03 21:28 471
            io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
4e9e2555 Poul Sander 2025-10-05 10:15 472
            io.SetKeyEventNativeData(key, (int)event->key.keysym.sym, (int)event->key.keysym.scancode, (int)event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
1193b4be Poul Sander 2025-02-03 21:28 473
            return true;
1193b4be Poul Sander 2025-02-03 21:28 474
        }
1193b4be Poul Sander 2025-02-03 21:28 475
#if SDL_HAS_DISPLAY_EVENT
1193b4be Poul Sander 2025-02-03 21:28 476
        case SDL_DISPLAYEVENT:
1193b4be Poul Sander 2025-02-03 21:28 477
        {
1193b4be Poul Sander 2025-02-03 21:28 478
            // 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION,
1193b4be Poul Sander 2025-02-03 21:28 479
            // so change of DPI/Scaling are not reflected in this event. (SDL3 has it)
1193b4be Poul Sander 2025-02-03 21:28 480
            bd->WantUpdateMonitors = true;
1193b4be Poul Sander 2025-02-03 21:28 481
            return true;
1193b4be Poul Sander 2025-02-03 21:28 482
        }
1193b4be Poul Sander 2025-02-03 21:28 483
#endif
1193b4be Poul Sander 2025-02-03 21:28 484
        case SDL_WINDOWEVENT:
1193b4be Poul Sander 2025-02-03 21:28 485
        {
1193b4be Poul Sander 2025-02-03 21:28 486
            ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->window.windowID);
1193b4be Poul Sander 2025-02-03 21:28 487
            if (viewport == NULL)
1193b4be Poul Sander 2025-02-03 21:28 488
                return false;
1193b4be Poul Sander 2025-02-03 21:28 489
1193b4be Poul Sander 2025-02-03 21:28 490
            // - 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.
1193b4be Poul Sander 2025-02-03 21:28 491
            // - However we won't get a correct LEAVE event for a captured window.
1193b4be Poul Sander 2025-02-03 21:28 492
            // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
1193b4be Poul Sander 2025-02-03 21:28 493
            //   causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why
1193b4be Poul Sander 2025-02-03 21:28 494
            //   we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details.
1193b4be Poul Sander 2025-02-03 21:28 495
            Uint8 window_event = event->window.event;
1193b4be Poul Sander 2025-02-03 21:28 496
            if (window_event == SDL_WINDOWEVENT_ENTER)
1193b4be Poul Sander 2025-02-03 21:28 497
            {
1193b4be Poul Sander 2025-02-03 21:28 498
                bd->MouseWindowID = event->window.windowID;
1193b4be Poul Sander 2025-02-03 21:28 499
                bd->MouseLastLeaveFrame = 0;
1193b4be Poul Sander 2025-02-03 21:28 500
            }
1193b4be Poul Sander 2025-02-03 21:28 501
            if (window_event == SDL_WINDOWEVENT_LEAVE)
1193b4be Poul Sander 2025-02-03 21:28 502
                bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1;
4e9e2555 Poul Sander 2025-10-05 10:15 503
            //if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) { IMGUI_DEBUG_LOG("SDL_WINDOWEVENT_FOCUS_GAINED: windowId %d, viewport: %08X\n", event->window.windowID, viewport ? viewport->ID : 0); }
4e9e2555 Poul Sander 2025-10-05 10:15 504
            //if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) { IMGUI_DEBUG_LOG("SDL_WINDOWEVENT_FOCUS_LOST: windowId %d, viewport: %08X\n", event->window.windowID, viewport ? viewport->ID : 0); }
1193b4be Poul Sander 2025-02-03 21:28 505
            if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
1193b4be Poul Sander 2025-02-03 21:28 506
                io.AddFocusEvent(true);
4e9e2555 Poul Sander 2025-10-05 10:15 507
            if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
1193b4be Poul Sander 2025-02-03 21:28 508
                io.AddFocusEvent(false);
4e9e2555 Poul Sander 2025-10-05 10:15 509
            if (window_event == SDL_WINDOWEVENT_CLOSE)
1193b4be Poul Sander 2025-02-03 21:28 510
                viewport->PlatformRequestClose = true;
4e9e2555 Poul Sander 2025-10-05 10:15 511
            if (window_event == SDL_WINDOWEVENT_MOVED)
1193b4be Poul Sander 2025-02-03 21:28 512
                viewport->PlatformRequestMove = true;
4e9e2555 Poul Sander 2025-10-05 10:15 513
            if (window_event == SDL_WINDOWEVENT_RESIZED)
1193b4be Poul Sander 2025-02-03 21:28 514
                viewport->PlatformRequestResize = true;
1193b4be Poul Sander 2025-02-03 21:28 515
            return true;
1193b4be Poul Sander 2025-02-03 21:28 516
        }
1193b4be Poul Sander 2025-02-03 21:28 517
        case SDL_CONTROLLERDEVICEADDED:
1193b4be Poul Sander 2025-02-03 21:28 518
        case SDL_CONTROLLERDEVICEREMOVED:
1193b4be Poul Sander 2025-02-03 21:28 519
        {
1193b4be Poul Sander 2025-02-03 21:28 520
            bd->WantUpdateGamepadsList = true;
1193b4be Poul Sander 2025-02-03 21:28 521
            return true;
1193b4be Poul Sander 2025-02-03 21:28 522
        }
4e9e2555 Poul Sander 2025-10-05 10:15 523
        default:
4e9e2555 Poul Sander 2025-10-05 10:15 524
            break;
1193b4be Poul Sander 2025-02-03 21:28 525
    }
1193b4be Poul Sander 2025-02-03 21:28 526
    return false;
1193b4be Poul Sander 2025-02-03 21:28 527
}
1193b4be Poul Sander 2025-02-03 21:28 528
1193b4be Poul Sander 2025-02-03 21:28 529
#ifdef __EMSCRIPTEN__
1193b4be Poul Sander 2025-02-03 21:28 530
EM_JS(void, ImGui_ImplSDL2_EmscriptenOpenURL, (char const* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); });
1193b4be Poul Sander 2025-02-03 21:28 531
#endif
1193b4be Poul Sander 2025-02-03 21:28 532
1193b4be Poul Sander 2025-02-03 21:28 533
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
1193b4be Poul Sander 2025-02-03 21:28 534
{
1193b4be Poul Sander 2025-02-03 21:28 535
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 536
    IMGUI_CHECKVERSION();
1193b4be Poul Sander 2025-02-03 21:28 537
    IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
4e9e2555 Poul Sander 2025-10-05 10:15 538
    //SDL_SetHint(SDL_HINT_EVENT_LOGGING, "2");
1193b4be Poul Sander 2025-02-03 21:28 539
4e9e2555 Poul Sander 2025-10-05 10:15 540
    // Obtain compiled and runtime versions
4e9e2555 Poul Sander 2025-10-05 10:15 541
    SDL_version ver_compiled;
4e9e2555 Poul Sander 2025-10-05 10:15 542
    SDL_version ver_runtime;
4e9e2555 Poul Sander 2025-10-05 10:15 543
    SDL_VERSION(&ver_compiled);
4e9e2555 Poul Sander 2025-10-05 10:15 544
    SDL_GetVersion(&ver_runtime);
1193b4be Poul Sander 2025-02-03 21:28 545
1193b4be Poul Sander 2025-02-03 21:28 546
    // Setup backend capabilities flags
1193b4be Poul Sander 2025-02-03 21:28 547
    ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
4e9e2555 Poul Sander 2025-10-05 10:15 548
    snprintf(bd->BackendPlatformName, sizeof(bd->BackendPlatformName), "imgui_impl_sdl2 (%u.%u.%u, %u.%u.%u)",
4e9e2555 Poul Sander 2025-10-05 10:15 549
        ver_compiled.major, ver_compiled.minor, ver_compiled.patch, ver_runtime.major, ver_runtime.minor, ver_runtime.patch);
1193b4be Poul Sander 2025-02-03 21:28 550
    io.BackendPlatformUserData = (void*)bd;
4e9e2555 Poul Sander 2025-10-05 10:15 551
    io.BackendPlatformName = bd->BackendPlatformName;
1193b4be Poul Sander 2025-02-03 21:28 552
    io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;           // We can honor GetMouseCursor() values (optional)
1193b4be Poul Sander 2025-02-03 21:28 553
    io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;            // We can honor io.WantSetMousePos requests (optional, rarely used)
4e9e2555 Poul Sander 2025-10-05 10:15 554
    // (ImGuiBackendFlags_PlatformHasViewports may be set just below)
1193b4be Poul Sander 2025-02-03 21:28 555
1193b4be Poul Sander 2025-02-03 21:28 556
    bd->Window = window;
1193b4be Poul Sander 2025-02-03 21:28 557
    bd->WindowID = SDL_GetWindowID(window);
1193b4be Poul Sander 2025-02-03 21:28 558
    bd->Renderer = renderer;
1193b4be Poul Sander 2025-02-03 21:28 559
1193b4be Poul Sander 2025-02-03 21:28 560
    // SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
1193b4be Poul Sander 2025-02-03 21:28 561
    // We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
1193b4be Poul Sander 2025-02-03 21:28 562
#ifndef __APPLE__
1193b4be Poul Sander 2025-02-03 21:28 563
    bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
1193b4be Poul Sander 2025-02-03 21:28 564
#else
1193b4be Poul Sander 2025-02-03 21:28 565
    bd->MouseCanReportHoveredViewport = false;
1193b4be Poul Sander 2025-02-03 21:28 566
#endif
1193b4be Poul Sander 2025-02-03 21:28 567
4e9e2555 Poul Sander 2025-10-05 10:15 568
    // Check and store if we are on a SDL backend that supports SDL_GetGlobalMouseState() and SDL_CaptureMouse()
4e9e2555 Poul Sander 2025-10-05 10:15 569
    // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
4e9e2555 Poul Sander 2025-10-05 10:15 570
    bd->MouseCanUseGlobalState = false;
4e9e2555 Poul Sander 2025-10-05 10:15 571
    bd->MouseCanUseCapture = false;
4e9e2555 Poul Sander 2025-10-05 10:15 572
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
4e9e2555 Poul Sander 2025-10-05 10:15 573
    const char* sdl_backend = SDL_GetCurrentVideoDriver();
4e9e2555 Poul Sander 2025-10-05 10:15 574
    const char* capture_and_global_state_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
4e9e2555 Poul Sander 2025-10-05 10:15 575
    for (const char* item : capture_and_global_state_whitelist)
4e9e2555 Poul Sander 2025-10-05 10:15 576
        if (strncmp(sdl_backend, item, strlen(item)) == 0)
4e9e2555 Poul Sander 2025-10-05 10:15 577
            bd->MouseCanUseGlobalState = bd->MouseCanUseCapture = true;
4e9e2555 Poul Sander 2025-10-05 10:15 578
#endif
4e9e2555 Poul Sander 2025-10-05 10:15 579
    if (bd->MouseCanUseGlobalState)
4e9e2555 Poul Sander 2025-10-05 10:15 580
        io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports;  // We can create multi-viewports on the Platform side (optional)
4e9e2555 Poul Sander 2025-10-05 10:15 581
1193b4be Poul Sander 2025-02-03 21:28 582
    ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
1193b4be Poul Sander 2025-02-03 21:28 583
    platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
1193b4be Poul Sander 2025-02-03 21:28 584
    platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
1193b4be Poul Sander 2025-02-03 21:28 585
    platform_io.Platform_ClipboardUserData = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 586
    platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData;
1193b4be Poul Sander 2025-02-03 21:28 587
#ifdef __EMSCRIPTEN__
1193b4be Poul Sander 2025-02-03 21:28 588
    platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
4e9e2555 Poul Sander 2025-10-05 10:15 589
#elif SDL_HAS_OPEN_URL
4e9e2555 Poul Sander 2025-10-05 10:15 590
    platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
1193b4be Poul Sander 2025-02-03 21:28 591
#endif
1193b4be Poul Sander 2025-02-03 21:28 592
1193b4be Poul Sander 2025-02-03 21:28 593
    // Update monitor a first time during init
1193b4be Poul Sander 2025-02-03 21:28 594
    ImGui_ImplSDL2_UpdateMonitors();
1193b4be Poul Sander 2025-02-03 21:28 595
1193b4be Poul Sander 2025-02-03 21:28 596
    // Gamepad handling
1193b4be Poul Sander 2025-02-03 21:28 597
    bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
1193b4be Poul Sander 2025-02-03 21:28 598
    bd->WantUpdateGamepadsList = true;
1193b4be Poul Sander 2025-02-03 21:28 599
1193b4be Poul Sander 2025-02-03 21:28 600
    // Load mouse cursors
1193b4be Poul Sander 2025-02-03 21:28 601
    bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
1193b4be Poul Sander 2025-02-03 21:28 602
    bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
1193b4be Poul Sander 2025-02-03 21:28 603
    bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
1193b4be Poul Sander 2025-02-03 21:28 604
    bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
1193b4be Poul Sander 2025-02-03 21:28 605
    bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
1193b4be Poul Sander 2025-02-03 21:28 606
    bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
1193b4be Poul Sander 2025-02-03 21:28 607
    bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
1193b4be Poul Sander 2025-02-03 21:28 608
    bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
4e9e2555 Poul Sander 2025-10-05 10:15 609
    bd->MouseCursors[ImGuiMouseCursor_Wait] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
4e9e2555 Poul Sander 2025-10-05 10:15 610
    bd->MouseCursors[ImGuiMouseCursor_Progress] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAITARROW);
1193b4be Poul Sander 2025-02-03 21:28 611
    bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
1193b4be Poul Sander 2025-02-03 21:28 612
1193b4be Poul Sander 2025-02-03 21:28 613
    // Set platform dependent data in viewport
1193b4be Poul Sander 2025-02-03 21:28 614
    // Our mouse update function expect PlatformHandle to be filled for the main viewport
1193b4be Poul Sander 2025-02-03 21:28 615
    ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1193b4be Poul Sander 2025-02-03 21:28 616
    main_viewport->PlatformHandle = (void*)(intptr_t)bd->WindowID;
1193b4be Poul Sander 2025-02-03 21:28 617
    main_viewport->PlatformHandleRaw = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 618
    SDL_SysWMinfo info;
1193b4be Poul Sander 2025-02-03 21:28 619
    SDL_VERSION(&info.version);
1193b4be Poul Sander 2025-02-03 21:28 620
    if (SDL_GetWindowWMInfo(window, &info))
1193b4be Poul Sander 2025-02-03 21:28 621
    {
1193b4be Poul Sander 2025-02-03 21:28 622
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
1193b4be Poul Sander 2025-02-03 21:28 623
        main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
1193b4be Poul Sander 2025-02-03 21:28 624
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
1193b4be Poul Sander 2025-02-03 21:28 625
        main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
1193b4be Poul Sander 2025-02-03 21:28 626
#endif
1193b4be Poul Sander 2025-02-03 21:28 627
    }
1193b4be Poul Sander 2025-02-03 21:28 628
1193b4be Poul Sander 2025-02-03 21:28 629
    // From 2.0.5: Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
1193b4be Poul Sander 2025-02-03 21:28 630
    // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
1193b4be Poul Sander 2025-02-03 21:28 631
    // (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
1193b4be Poul Sander 2025-02-03 21:28 632
    // It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
1193b4be Poul Sander 2025-02-03 21:28 633
    // you can ignore SDL_MOUSEBUTTONDOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
1193b4be Poul Sander 2025-02-03 21:28 634
#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
1193b4be Poul Sander 2025-02-03 21:28 635
    SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
1193b4be Poul Sander 2025-02-03 21:28 636
#endif
1193b4be Poul Sander 2025-02-03 21:28 637
1193b4be Poul Sander 2025-02-03 21:28 638
    // From 2.0.18: Enable native IME.
1193b4be Poul Sander 2025-02-03 21:28 639
    // IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any.
1193b4be Poul Sander 2025-02-03 21:28 640
    // For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow().
1193b4be Poul Sander 2025-02-03 21:28 641
#ifdef SDL_HINT_IME_SHOW_UI
1193b4be Poul Sander 2025-02-03 21:28 642
    SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
1193b4be Poul Sander 2025-02-03 21:28 643
#endif
1193b4be Poul Sander 2025-02-03 21:28 644
1193b4be Poul Sander 2025-02-03 21:28 645
    // From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
1193b4be Poul Sander 2025-02-03 21:28 646
#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE
1193b4be Poul Sander 2025-02-03 21:28 647
    SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
1193b4be Poul Sander 2025-02-03 21:28 648
#endif
1193b4be Poul Sander 2025-02-03 21:28 649
1193b4be Poul Sander 2025-02-03 21:28 650
    // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
1193b4be Poul Sander 2025-02-03 21:28 651
    // We left the call to ImGui_ImplSDL2_InitMultiViewportSupport() outside of #ifdef to avoid unused-function warnings.
1193b4be Poul Sander 2025-02-03 21:28 652
    if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
1193b4be Poul Sander 2025-02-03 21:28 653
        ImGui_ImplSDL2_InitMultiViewportSupport(window, sdl_gl_context);
1193b4be Poul Sander 2025-02-03 21:28 654
1193b4be Poul Sander 2025-02-03 21:28 655
    return true;
1193b4be Poul Sander 2025-02-03 21:28 656
}
1193b4be Poul Sander 2025-02-03 21:28 657
1193b4be Poul Sander 2025-02-03 21:28 658
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
1193b4be Poul Sander 2025-02-03 21:28 659
{
1193b4be Poul Sander 2025-02-03 21:28 660
    return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context);
1193b4be Poul Sander 2025-02-03 21:28 661
}
1193b4be Poul Sander 2025-02-03 21:28 662
1193b4be Poul Sander 2025-02-03 21:28 663
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
1193b4be Poul Sander 2025-02-03 21:28 664
{
1193b4be Poul Sander 2025-02-03 21:28 665
#if !SDL_HAS_VULKAN
1193b4be Poul Sander 2025-02-03 21:28 666
    IM_ASSERT(0 && "Unsupported");
1193b4be Poul Sander 2025-02-03 21:28 667
#endif
1193b4be Poul Sander 2025-02-03 21:28 668
    if (!ImGui_ImplSDL2_Init(window, nullptr, nullptr))
1193b4be Poul Sander 2025-02-03 21:28 669
        return false;
1193b4be Poul Sander 2025-02-03 21:28 670
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 671
    bd->UseVulkan = true;
1193b4be Poul Sander 2025-02-03 21:28 672
    return true;
1193b4be Poul Sander 2025-02-03 21:28 673
}
1193b4be Poul Sander 2025-02-03 21:28 674
1193b4be Poul Sander 2025-02-03 21:28 675
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
1193b4be Poul Sander 2025-02-03 21:28 676
{
1193b4be Poul Sander 2025-02-03 21:28 677
#if !defined(_WIN32)
1193b4be Poul Sander 2025-02-03 21:28 678
    IM_ASSERT(0 && "Unsupported");
1193b4be Poul Sander 2025-02-03 21:28 679
#endif
1193b4be Poul Sander 2025-02-03 21:28 680
    return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
1193b4be Poul Sander 2025-02-03 21:28 681
}
1193b4be Poul Sander 2025-02-03 21:28 682
1193b4be Poul Sander 2025-02-03 21:28 683
bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
1193b4be Poul Sander 2025-02-03 21:28 684
{
1193b4be Poul Sander 2025-02-03 21:28 685
    return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
1193b4be Poul Sander 2025-02-03 21:28 686
}
1193b4be Poul Sander 2025-02-03 21:28 687
1193b4be Poul Sander 2025-02-03 21:28 688
bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
1193b4be Poul Sander 2025-02-03 21:28 689
{
1193b4be Poul Sander 2025-02-03 21:28 690
    return ImGui_ImplSDL2_Init(window, renderer, nullptr);
1193b4be Poul Sander 2025-02-03 21:28 691
}
1193b4be Poul Sander 2025-02-03 21:28 692
1193b4be Poul Sander 2025-02-03 21:28 693
bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
1193b4be Poul Sander 2025-02-03 21:28 694
{
1193b4be Poul Sander 2025-02-03 21:28 695
    return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
1193b4be Poul Sander 2025-02-03 21:28 696
}
1193b4be Poul Sander 2025-02-03 21:28 697
1193b4be Poul Sander 2025-02-03 21:28 698
static void ImGui_ImplSDL2_CloseGamepads();
1193b4be Poul Sander 2025-02-03 21:28 699
1193b4be Poul Sander 2025-02-03 21:28 700
void ImGui_ImplSDL2_Shutdown()
1193b4be Poul Sander 2025-02-03 21:28 701
{
1193b4be Poul Sander 2025-02-03 21:28 702
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 703
    IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
1193b4be Poul Sander 2025-02-03 21:28 704
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 705
1193b4be Poul Sander 2025-02-03 21:28 706
    ImGui_ImplSDL2_ShutdownMultiViewportSupport();
1193b4be Poul Sander 2025-02-03 21:28 707
1193b4be Poul Sander 2025-02-03 21:28 708
    if (bd->ClipboardTextData)
1193b4be Poul Sander 2025-02-03 21:28 709
        SDL_free(bd->ClipboardTextData);
1193b4be Poul Sander 2025-02-03 21:28 710
    for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
1193b4be Poul Sander 2025-02-03 21:28 711
        SDL_FreeCursor(bd->MouseCursors[cursor_n]);
1193b4be Poul Sander 2025-02-03 21:28 712
    ImGui_ImplSDL2_CloseGamepads();
1193b4be Poul Sander 2025-02-03 21:28 713
1193b4be Poul Sander 2025-02-03 21:28 714
    io.BackendPlatformName = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 715
    io.BackendPlatformUserData = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 716
    io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
1193b4be Poul Sander 2025-02-03 21:28 717
    IM_DELETE(bd);
1193b4be Poul Sander 2025-02-03 21:28 718
}
1193b4be Poul Sander 2025-02-03 21:28 719
1193b4be Poul Sander 2025-02-03 21:28 720
// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
1193b4be Poul Sander 2025-02-03 21:28 721
static void ImGui_ImplSDL2_UpdateMouseData()
1193b4be Poul Sander 2025-02-03 21:28 722
{
1193b4be Poul Sander 2025-02-03 21:28 723
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 724
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 725
1193b4be Poul Sander 2025-02-03 21:28 726
    // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
1193b4be Poul Sander 2025-02-03 21:28 727
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
4e9e2555 Poul Sander 2025-10-05 10:15 728
    // - SDL_CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
4e9e2555 Poul Sander 2025-10-05 10:15 729
    // - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to mitigate the issue we wait until mouse has moved to begin capture.
4e9e2555 Poul Sander 2025-10-05 10:15 730
    if (bd->MouseCanUseCapture)
4e9e2555 Poul Sander 2025-10-05 10:15 731
    {
4e9e2555 Poul Sander 2025-10-05 10:15 732
        bool want_capture = false;
4e9e2555 Poul Sander 2025-10-05 10:15 733
        for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++)
4e9e2555 Poul Sander 2025-10-05 10:15 734
            if (ImGui::IsMouseDragging(button_n, 1.0f))
4e9e2555 Poul Sander 2025-10-05 10:15 735
                want_capture = true;
4e9e2555 Poul Sander 2025-10-05 10:15 736
        SDL_CaptureMouse(want_capture ? SDL_TRUE : SDL_FALSE);
4e9e2555 Poul Sander 2025-10-05 10:15 737
    }
4e9e2555 Poul Sander 2025-10-05 10:15 738
1193b4be Poul Sander 2025-02-03 21:28 739
    SDL_Window* focused_window = SDL_GetKeyboardFocus();
1193b4be Poul Sander 2025-02-03 21:28 740
    const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL2_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
1193b4be Poul Sander 2025-02-03 21:28 741
#else
1193b4be Poul Sander 2025-02-03 21:28 742
    SDL_Window* focused_window = bd->Window;
1193b4be Poul Sander 2025-02-03 21:28 743
    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
1193b4be Poul Sander 2025-02-03 21:28 744
#endif
1193b4be Poul Sander 2025-02-03 21:28 745
1193b4be Poul Sander 2025-02-03 21:28 746
    if (is_app_focused)
1193b4be Poul Sander 2025-02-03 21:28 747
    {
1193b4be Poul Sander 2025-02-03 21:28 748
        // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
1193b4be Poul Sander 2025-02-03 21:28 749
        if (io.WantSetMousePos)
1193b4be Poul Sander 2025-02-03 21:28 750
        {
1193b4be Poul Sander 2025-02-03 21:28 751
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
1193b4be Poul Sander 2025-02-03 21:28 752
            if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
1193b4be Poul Sander 2025-02-03 21:28 753
                SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y);
1193b4be Poul Sander 2025-02-03 21:28 754
            else
1193b4be Poul Sander 2025-02-03 21:28 755
#endif
1193b4be Poul Sander 2025-02-03 21:28 756
                SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
1193b4be Poul Sander 2025-02-03 21:28 757
        }
1193b4be Poul Sander 2025-02-03 21:28 758
1193b4be Poul Sander 2025-02-03 21:28 759
        // (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
4e9e2555 Poul Sander 2025-10-05 10:15 760
        const bool is_relative_mouse_mode = SDL_GetRelativeMouseMode() != 0;
4e9e2555 Poul Sander 2025-10-05 10:15 761
        if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
1193b4be Poul Sander 2025-02-03 21:28 762
        {
1193b4be Poul Sander 2025-02-03 21:28 763
            // 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)
1193b4be Poul Sander 2025-02-03 21:28 764
            // 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)
1193b4be Poul Sander 2025-02-03 21:28 765
            int mouse_x, mouse_y, window_x, window_y;
1193b4be Poul Sander 2025-02-03 21:28 766
            SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
1193b4be Poul Sander 2025-02-03 21:28 767
            if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
1193b4be Poul Sander 2025-02-03 21:28 768
            {
1193b4be Poul Sander 2025-02-03 21:28 769
                SDL_GetWindowPosition(focused_window, &window_x, &window_y);
1193b4be Poul Sander 2025-02-03 21:28 770
                mouse_x -= window_x;
1193b4be Poul Sander 2025-02-03 21:28 771
                mouse_y -= window_y;
1193b4be Poul Sander 2025-02-03 21:28 772
            }
1193b4be Poul Sander 2025-02-03 21:28 773
            io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
1193b4be Poul Sander 2025-02-03 21:28 774
        }
1193b4be Poul Sander 2025-02-03 21:28 775
    }
1193b4be Poul Sander 2025-02-03 21:28 776
1193b4be Poul Sander 2025-02-03 21:28 777
    // (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
1193b4be Poul Sander 2025-02-03 21:28 778
    // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
1193b4be Poul Sander 2025-02-03 21:28 779
    // - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
1193b4be Poul Sander 2025-02-03 21:28 780
    //       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
1193b4be Poul Sander 2025-02-03 21:28 781
    //       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
1193b4be Poul Sander 2025-02-03 21:28 782
    //       by the backend, and use its flawed heuristic to guess the viewport behind.
1193b4be Poul Sander 2025-02-03 21:28 783
    // - [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).
1193b4be Poul Sander 2025-02-03 21:28 784
    if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
1193b4be Poul Sander 2025-02-03 21:28 785
    {
1193b4be Poul Sander 2025-02-03 21:28 786
        ImGuiID mouse_viewport_id = 0;
1193b4be Poul Sander 2025-02-03 21:28 787
        if (ImGuiViewport* mouse_viewport = ImGui_ImplSDL2_GetViewportForWindowID(bd->MouseWindowID))
1193b4be Poul Sander 2025-02-03 21:28 788
            mouse_viewport_id = mouse_viewport->ID;
1193b4be Poul Sander 2025-02-03 21:28 789
        io.AddMouseViewportEvent(mouse_viewport_id);
1193b4be Poul Sander 2025-02-03 21:28 790
    }
1193b4be Poul Sander 2025-02-03 21:28 791
}
1193b4be Poul Sander 2025-02-03 21:28 792
1193b4be Poul Sander 2025-02-03 21:28 793
static void ImGui_ImplSDL2_UpdateMouseCursor()
1193b4be Poul Sander 2025-02-03 21:28 794
{
1193b4be Poul Sander 2025-02-03 21:28 795
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 796
    if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
1193b4be Poul Sander 2025-02-03 21:28 797
        return;
1193b4be Poul Sander 2025-02-03 21:28 798
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 799
1193b4be Poul Sander 2025-02-03 21:28 800
    ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
1193b4be Poul Sander 2025-02-03 21:28 801
    if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
1193b4be Poul Sander 2025-02-03 21:28 802
    {
1193b4be Poul Sander 2025-02-03 21:28 803
        // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
1193b4be Poul Sander 2025-02-03 21:28 804
        SDL_ShowCursor(SDL_FALSE);
1193b4be Poul Sander 2025-02-03 21:28 805
    }
1193b4be Poul Sander 2025-02-03 21:28 806
    else
1193b4be Poul Sander 2025-02-03 21:28 807
    {
1193b4be Poul Sander 2025-02-03 21:28 808
        // Show OS mouse cursor
1193b4be Poul Sander 2025-02-03 21:28 809
        SDL_Cursor* expected_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
1193b4be Poul Sander 2025-02-03 21:28 810
        if (bd->MouseLastCursor != expected_cursor)
1193b4be Poul Sander 2025-02-03 21:28 811
        {
1193b4be Poul Sander 2025-02-03 21:28 812
            SDL_SetCursor(expected_cursor); // SDL function doesn't have an early out (see #6113)
1193b4be Poul Sander 2025-02-03 21:28 813
            bd->MouseLastCursor = expected_cursor;
1193b4be Poul Sander 2025-02-03 21:28 814
        }
1193b4be Poul Sander 2025-02-03 21:28 815
        SDL_ShowCursor(SDL_TRUE);
1193b4be Poul Sander 2025-02-03 21:28 816
    }
1193b4be Poul Sander 2025-02-03 21:28 817
}
1193b4be Poul Sander 2025-02-03 21:28 818
4e9e2555 Poul Sander 2025-10-05 10:15 819
// - On Windows the process needs to be marked DPI-aware!! SDL2 doesn't do it by default. You can call ::SetProcessDPIAware() or call ImGui_ImplWin32_EnableDpiAwareness() from Win32 backend.
4e9e2555 Poul Sander 2025-10-05 10:15 820
// - Apple platforms use FramebufferScale so we always return 1.0f.
4e9e2555 Poul Sander 2025-10-05 10:15 821
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
4e9e2555 Poul Sander 2025-10-05 10:15 822
float ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window)
4e9e2555 Poul Sander 2025-10-05 10:15 823
{
4e9e2555 Poul Sander 2025-10-05 10:15 824
    return ImGui_ImplSDL2_GetContentScaleForDisplay(SDL_GetWindowDisplayIndex(window));
4e9e2555 Poul Sander 2025-10-05 10:15 825
}
4e9e2555 Poul Sander 2025-10-05 10:15 826
4e9e2555 Poul Sander 2025-10-05 10:15 827
float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index)
4e9e2555 Poul Sander 2025-10-05 10:15 828
{
4e9e2555 Poul Sander 2025-10-05 10:15 829
    const char* sdl_driver = SDL_GetCurrentVideoDriver();
4e9e2555 Poul Sander 2025-10-05 10:15 830
    if (sdl_driver && strcmp(sdl_driver, "wayland") == 0)
4e9e2555 Poul Sander 2025-10-05 10:15 831
        return 1.0f;
4e9e2555 Poul Sander 2025-10-05 10:15 832
#if SDL_HAS_PER_MONITOR_DPI
4e9e2555 Poul Sander 2025-10-05 10:15 833
#if !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
4e9e2555 Poul Sander 2025-10-05 10:15 834
    float dpi = 0.0f;
4e9e2555 Poul Sander 2025-10-05 10:15 835
    if (SDL_GetDisplayDPI(display_index, &dpi, nullptr, nullptr) == 0)
4e9e2555 Poul Sander 2025-10-05 10:15 836
        return dpi / 96.0f;
4e9e2555 Poul Sander 2025-10-05 10:15 837
#endif
4e9e2555 Poul Sander 2025-10-05 10:15 838
#endif
4e9e2555 Poul Sander 2025-10-05 10:15 839
    IM_UNUSED(display_index);
4e9e2555 Poul Sander 2025-10-05 10:15 840
    return 1.0f;
4e9e2555 Poul Sander 2025-10-05 10:15 841
}
4e9e2555 Poul Sander 2025-10-05 10:15 842
1193b4be Poul Sander 2025-02-03 21:28 843
static void ImGui_ImplSDL2_CloseGamepads()
1193b4be Poul Sander 2025-02-03 21:28 844
{
1193b4be Poul Sander 2025-02-03 21:28 845
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 846
    if (bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
1193b4be Poul Sander 2025-02-03 21:28 847
        for (SDL_GameController* gamepad : bd->Gamepads)
1193b4be Poul Sander 2025-02-03 21:28 848
            SDL_GameControllerClose(gamepad);
1193b4be Poul Sander 2025-02-03 21:28 849
    bd->Gamepads.resize(0);
1193b4be Poul Sander 2025-02-03 21:28 850
}
1193b4be Poul Sander 2025-02-03 21:28 851
1193b4be Poul Sander 2025-02-03 21:28 852
void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array, int manual_gamepads_count)
1193b4be Poul Sander 2025-02-03 21:28 853
{
1193b4be Poul Sander 2025-02-03 21:28 854
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 855
    ImGui_ImplSDL2_CloseGamepads();
1193b4be Poul Sander 2025-02-03 21:28 856
    if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
1193b4be Poul Sander 2025-02-03 21:28 857
    {
4e9e2555 Poul Sander 2025-10-05 10:15 858
        IM_ASSERT(manual_gamepads_array != nullptr || manual_gamepads_count <= 0);
1193b4be Poul Sander 2025-02-03 21:28 859
        for (int n = 0; n < manual_gamepads_count; n++)
1193b4be Poul Sander 2025-02-03 21:28 860
            bd->Gamepads.push_back(manual_gamepads_array[n]);
1193b4be Poul Sander 2025-02-03 21:28 861
    }
1193b4be Poul Sander 2025-02-03 21:28 862
    else
1193b4be Poul Sander 2025-02-03 21:28 863
    {
1193b4be Poul Sander 2025-02-03 21:28 864
        IM_ASSERT(manual_gamepads_array == nullptr && manual_gamepads_count <= 0);
1193b4be Poul Sander 2025-02-03 21:28 865
        bd->WantUpdateGamepadsList = true;
1193b4be Poul Sander 2025-02-03 21:28 866
    }
1193b4be Poul Sander 2025-02-03 21:28 867
    bd->GamepadMode = mode;
1193b4be Poul Sander 2025-02-03 21:28 868
}
1193b4be Poul Sander 2025-02-03 21:28 869
1193b4be Poul Sander 2025-02-03 21:28 870
static void ImGui_ImplSDL2_UpdateGamepadButton(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerButton button_no)
1193b4be Poul Sander 2025-02-03 21:28 871
{
1193b4be Poul Sander 2025-02-03 21:28 872
    bool merged_value = false;
1193b4be Poul Sander 2025-02-03 21:28 873
    for (SDL_GameController* gamepad : bd->Gamepads)
1193b4be Poul Sander 2025-02-03 21:28 874
        merged_value |= SDL_GameControllerGetButton(gamepad, button_no) != 0;
1193b4be Poul Sander 2025-02-03 21:28 875
    io.AddKeyEvent(key, merged_value);
1193b4be Poul Sander 2025-02-03 21:28 876
}
1193b4be Poul Sander 2025-02-03 21:28 877
1193b4be Poul Sander 2025-02-03 21:28 878
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v  > 1.0f ? 1.0f : v; }
1193b4be Poul Sander 2025-02-03 21:28 879
static void ImGui_ImplSDL2_UpdateGamepadAnalog(ImGui_ImplSDL2_Data* bd, ImGuiIO& io, ImGuiKey key, SDL_GameControllerAxis axis_no, float v0, float v1)
1193b4be Poul Sander 2025-02-03 21:28 880
{
1193b4be Poul Sander 2025-02-03 21:28 881
    float merged_value = 0.0f;
1193b4be Poul Sander 2025-02-03 21:28 882
    for (SDL_GameController* gamepad : bd->Gamepads)
1193b4be Poul Sander 2025-02-03 21:28 883
    {
1193b4be Poul Sander 2025-02-03 21:28 884
        float vn = Saturate((float)(SDL_GameControllerGetAxis(gamepad, axis_no) - v0) / (float)(v1 - v0));
1193b4be Poul Sander 2025-02-03 21:28 885
        if (merged_value < vn)
1193b4be Poul Sander 2025-02-03 21:28 886
            merged_value = vn;
1193b4be Poul Sander 2025-02-03 21:28 887
    }
1193b4be Poul Sander 2025-02-03 21:28 888
    io.AddKeyAnalogEvent(key, merged_value > 0.1f, merged_value);
1193b4be Poul Sander 2025-02-03 21:28 889
}
1193b4be Poul Sander 2025-02-03 21:28 890
1193b4be Poul Sander 2025-02-03 21:28 891
static void ImGui_ImplSDL2_UpdateGamepads()
1193b4be Poul Sander 2025-02-03 21:28 892
{
1193b4be Poul Sander 2025-02-03 21:28 893
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 894
    ImGuiIO& io = ImGui::GetIO();
1193b4be Poul Sander 2025-02-03 21:28 895
1193b4be Poul Sander 2025-02-03 21:28 896
    // Update list of controller(s) to use
1193b4be Poul Sander 2025-02-03 21:28 897
    if (bd->WantUpdateGamepadsList && bd->GamepadMode != ImGui_ImplSDL2_GamepadMode_Manual)
1193b4be Poul Sander 2025-02-03 21:28 898
    {
1193b4be Poul Sander 2025-02-03 21:28 899
        ImGui_ImplSDL2_CloseGamepads();
1193b4be Poul Sander 2025-02-03 21:28 900
        int joystick_count = SDL_NumJoysticks();
1193b4be Poul Sander 2025-02-03 21:28 901
        for (int n = 0; n < joystick_count; n++)
1193b4be Poul Sander 2025-02-03 21:28 902
            if (SDL_IsGameController(n))
1193b4be Poul Sander 2025-02-03 21:28 903
                if (SDL_GameController* gamepad = SDL_GameControllerOpen(n))
1193b4be Poul Sander 2025-02-03 21:28 904
                {
1193b4be Poul Sander 2025-02-03 21:28 905
                    bd->Gamepads.push_back(gamepad);
1193b4be Poul Sander 2025-02-03 21:28 906
                    if (bd->GamepadMode == ImGui_ImplSDL2_GamepadMode_AutoFirst)
1193b4be Poul Sander 2025-02-03 21:28 907
                        break;
1193b4be Poul Sander 2025-02-03 21:28 908
                }
1193b4be Poul Sander 2025-02-03 21:28 909
        bd->WantUpdateGamepadsList = false;
1193b4be Poul Sander 2025-02-03 21:28 910
    }
1193b4be Poul Sander 2025-02-03 21:28 911
1193b4be Poul Sander 2025-02-03 21:28 912
    io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
1193b4be Poul Sander 2025-02-03 21:28 913
    if (bd->Gamepads.Size == 0)
1193b4be Poul Sander 2025-02-03 21:28 914
        return;
1193b4be Poul Sander 2025-02-03 21:28 915
    io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
1193b4be Poul Sander 2025-02-03 21:28 916
1193b4be Poul Sander 2025-02-03 21:28 917
    // Update gamepad inputs
1193b4be Poul Sander 2025-02-03 21:28 918
    const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
1193b4be Poul Sander 2025-02-03 21:28 919
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadStart,       SDL_CONTROLLER_BUTTON_START);
1193b4be Poul Sander 2025-02-03 21:28 920
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadBack,        SDL_CONTROLLER_BUTTON_BACK);
1193b4be Poul Sander 2025-02-03 21:28 921
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceLeft,    SDL_CONTROLLER_BUTTON_X);              // Xbox X, PS Square
1193b4be Poul Sander 2025-02-03 21:28 922
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceRight,   SDL_CONTROLLER_BUTTON_B);              // Xbox B, PS Circle
1193b4be Poul Sander 2025-02-03 21:28 923
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceUp,      SDL_CONTROLLER_BUTTON_Y);              // Xbox Y, PS Triangle
1193b4be Poul Sander 2025-02-03 21:28 924
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadFaceDown,    SDL_CONTROLLER_BUTTON_A);              // Xbox A, PS Cross
1193b4be Poul Sander 2025-02-03 21:28 925
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadLeft,    SDL_CONTROLLER_BUTTON_DPAD_LEFT);
1193b4be Poul Sander 2025-02-03 21:28 926
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadRight,   SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
1193b4be Poul Sander 2025-02-03 21:28 927
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadUp,      SDL_CONTROLLER_BUTTON_DPAD_UP);
1193b4be Poul Sander 2025-02-03 21:28 928
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadDpadDown,    SDL_CONTROLLER_BUTTON_DPAD_DOWN);
1193b4be Poul Sander 2025-02-03 21:28 929
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL1,          SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
1193b4be Poul Sander 2025-02-03 21:28 930
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR1,          SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
1193b4be Poul Sander 2025-02-03 21:28 931
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadL2,          SDL_CONTROLLER_AXIS_TRIGGERLEFT,  0.0f, 32767);
1193b4be Poul Sander 2025-02-03 21:28 932
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadR2,          SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767);
1193b4be Poul Sander 2025-02-03 21:28 933
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadL3,          SDL_CONTROLLER_BUTTON_LEFTSTICK);
1193b4be Poul Sander 2025-02-03 21:28 934
    ImGui_ImplSDL2_UpdateGamepadButton(bd, io, ImGuiKey_GamepadR3,          SDL_CONTROLLER_BUTTON_RIGHTSTICK);
1193b4be Poul Sander 2025-02-03 21:28 935
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickLeft,  SDL_CONTROLLER_AXIS_LEFTX,  -thumb_dead_zone, -32768);
1193b4be Poul Sander 2025-02-03 21:28 936
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX,  +thumb_dead_zone, +32767);
1193b4be Poul Sander 2025-02-03 21:28 937
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickUp,    SDL_CONTROLLER_AXIS_LEFTY,  -thumb_dead_zone, -32768);
1193b4be Poul Sander 2025-02-03 21:28 938
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadLStickDown,  SDL_CONTROLLER_AXIS_LEFTY,  +thumb_dead_zone, +32767);
1193b4be Poul Sander 2025-02-03 21:28 939
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickLeft,  SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768);
1193b4be Poul Sander 2025-02-03 21:28 940
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767);
1193b4be Poul Sander 2025-02-03 21:28 941
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickUp,    SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768);
1193b4be Poul Sander 2025-02-03 21:28 942
    ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown,  SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
1193b4be Poul Sander 2025-02-03 21:28 943
}
1193b4be Poul Sander 2025-02-03 21:28 944
1193b4be Poul Sander 2025-02-03 21:28 945
// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has).
1193b4be Poul Sander 2025-02-03 21:28 946
static void ImGui_ImplSDL2_UpdateMonitors()
1193b4be Poul Sander 2025-02-03 21:28 947
{
1193b4be Poul Sander 2025-02-03 21:28 948
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 949
    ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
1193b4be Poul Sander 2025-02-03 21:28 950
    platform_io.Monitors.resize(0);
1193b4be Poul Sander 2025-02-03 21:28 951
    bd->WantUpdateMonitors = false;
1193b4be Poul Sander 2025-02-03 21:28 952
    int display_count = SDL_GetNumVideoDisplays();
1193b4be Poul Sander 2025-02-03 21:28 953
    for (int n = 0; n < display_count; n++)
1193b4be Poul Sander 2025-02-03 21:28 954
    {
1193b4be Poul Sander 2025-02-03 21:28 955
        // 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.
1193b4be Poul Sander 2025-02-03 21:28 956
        ImGuiPlatformMonitor monitor;
1193b4be Poul Sander 2025-02-03 21:28 957
        SDL_Rect r;
1193b4be Poul Sander 2025-02-03 21:28 958
        SDL_GetDisplayBounds(n, &r);
1193b4be Poul Sander 2025-02-03 21:28 959
        monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
1193b4be Poul Sander 2025-02-03 21:28 960
        monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
1193b4be Poul Sander 2025-02-03 21:28 961
#if SDL_HAS_USABLE_DISPLAY_BOUNDS
4e9e2555 Poul Sander 2025-10-05 10:15 962
        if (SDL_GetDisplayUsableBounds(n, &r) == 0 && r.w > 0 && r.h > 0)
1193b4be Poul Sander 2025-02-03 21:28 963
        {
4e9e2555 Poul Sander 2025-10-05 10:15 964
            monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
4e9e2555 Poul Sander 2025-10-05 10:15 965
            monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
1193b4be Poul Sander 2025-02-03 21:28 966
        }
1193b4be Poul Sander 2025-02-03 21:28 967
#endif
4e9e2555 Poul Sander 2025-10-05 10:15 968
        float dpi_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(n);
4e9e2555 Poul Sander 2025-10-05 10:15 969
        if (dpi_scale <= 0.0f)
4e9e2555 Poul Sander 2025-10-05 10:15 970
            continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
4e9e2555 Poul Sander 2025-10-05 10:15 971
        monitor.DpiScale = dpi_scale;
1193b4be Poul Sander 2025-02-03 21:28 972
        monitor.PlatformHandle = (void*)(intptr_t)n;
1193b4be Poul Sander 2025-02-03 21:28 973
        platform_io.Monitors.push_back(monitor);
1193b4be Poul Sander 2025-02-03 21:28 974
    }
1193b4be Poul Sander 2025-02-03 21:28 975
}
1193b4be Poul Sander 2025-02-03 21:28 976
4e9e2555 Poul Sander 2025-10-05 10:15 977
static void ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(SDL_Window* window, SDL_Renderer* renderer, ImVec2* out_size, ImVec2* out_framebuffer_scale)
1193b4be Poul Sander 2025-02-03 21:28 978
{
1193b4be Poul Sander 2025-02-03 21:28 979
    int w, h;
1193b4be Poul Sander 2025-02-03 21:28 980
    int display_w, display_h;
4e9e2555 Poul Sander 2025-10-05 10:15 981
    SDL_GetWindowSize(window, &w, &h);
4e9e2555 Poul Sander 2025-10-05 10:15 982
    if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
1193b4be Poul Sander 2025-02-03 21:28 983
        w = h = 0;
4e9e2555 Poul Sander 2025-10-05 10:15 984
    if (renderer != nullptr)
4e9e2555 Poul Sander 2025-10-05 10:15 985
        SDL_GetRendererOutputSize(renderer, &display_w, &display_h);
1193b4be Poul Sander 2025-02-03 21:28 986
#if SDL_HAS_VULKAN
4e9e2555 Poul Sander 2025-10-05 10:15 987
    else if (SDL_GetWindowFlags(window) & SDL_WINDOW_VULKAN)
4e9e2555 Poul Sander 2025-10-05 10:15 988
        SDL_Vulkan_GetDrawableSize(window, &display_w, &display_h);
1193b4be Poul Sander 2025-02-03 21:28 989
#endif
1193b4be Poul Sander 2025-02-03 21:28 990
    else
4e9e2555 Poul Sander 2025-10-05 10:15 991
        SDL_GL_GetDrawableSize(window, &display_w, &display_h);
4e9e2555 Poul Sander 2025-10-05 10:15 992
    if (out_size != nullptr)
4e9e2555 Poul Sander 2025-10-05 10:15 993
        *out_size = ImVec2((float)w, (float)h);
4e9e2555 Poul Sander 2025-10-05 10:15 994
    if (out_framebuffer_scale != nullptr)
4e9e2555 Poul Sander 2025-10-05 10:15 995
        *out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
4e9e2555 Poul Sander 2025-10-05 10:15 996
}
4e9e2555 Poul Sander 2025-10-05 10:15 997
4e9e2555 Poul Sander 2025-10-05 10:15 998
void ImGui_ImplSDL2_NewFrame()
4e9e2555 Poul Sander 2025-10-05 10:15 999
{
4e9e2555 Poul Sander 2025-10-05 10:15 1000
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
4e9e2555 Poul Sander 2025-10-05 10:15 1001
    IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?");
4e9e2555 Poul Sander 2025-10-05 10:15 1002
    ImGuiIO& io = ImGui::GetIO();
4e9e2555 Poul Sander 2025-10-05 10:15 1003
4e9e2555 Poul Sander 2025-10-05 10:15 1004
    // Setup main viewport size (every frame to accommodate for window resizing)
4e9e2555 Poul Sander 2025-10-05 10:15 1005
    ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(bd->Window, bd->Renderer, &io.DisplaySize, &io.DisplayFramebufferScale);
1193b4be Poul Sander 2025-02-03 21:28 1006
1193b4be Poul Sander 2025-02-03 21:28 1007
    // Update monitors
4e9e2555 Poul Sander 2025-10-05 10:15 1008
#ifdef WIN32
4e9e2555 Poul Sander 2025-10-05 10:15 1009
    bd->WantUpdateMonitors = true; // Keep polling under Windows to handle changes of work area when resizing task-bar (#8415)
4e9e2555 Poul Sander 2025-10-05 10:15 1010
#endif
1193b4be Poul Sander 2025-02-03 21:28 1011
    if (bd->WantUpdateMonitors)
1193b4be Poul Sander 2025-02-03 21:28 1012
        ImGui_ImplSDL2_UpdateMonitors();
1193b4be Poul Sander 2025-02-03 21:28 1013
1193b4be Poul Sander 2025-02-03 21:28 1014
    // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
1193b4be Poul Sander 2025-02-03 21:28 1015
    // (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
1193b4be Poul Sander 2025-02-03 21:28 1016
    static Uint64 frequency = SDL_GetPerformanceFrequency();
1193b4be Poul Sander 2025-02-03 21:28 1017
    Uint64 current_time = SDL_GetPerformanceCounter();
1193b4be Poul Sander 2025-02-03 21:28 1018
    if (current_time <= bd->Time)
1193b4be Poul Sander 2025-02-03 21:28 1019
        current_time = bd->Time + 1;
1193b4be Poul Sander 2025-02-03 21:28 1020
    io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
1193b4be Poul Sander 2025-02-03 21:28 1021
    bd->Time = current_time;
1193b4be Poul Sander 2025-02-03 21:28 1022
1193b4be Poul Sander 2025-02-03 21:28 1023
    if (bd->MouseLastLeaveFrame && bd->MouseLastLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0)
1193b4be Poul Sander 2025-02-03 21:28 1024
    {
1193b4be Poul Sander 2025-02-03 21:28 1025
        bd->MouseWindowID = 0;
1193b4be Poul Sander 2025-02-03 21:28 1026
        bd->MouseLastLeaveFrame = 0;
1193b4be Poul Sander 2025-02-03 21:28 1027
        io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
1193b4be Poul Sander 2025-02-03 21:28 1028
    }
1193b4be Poul Sander 2025-02-03 21:28 1029
1193b4be Poul Sander 2025-02-03 21:28 1030
    // Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
1193b4be Poul Sander 2025-02-03 21:28 1031
    // Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rigorous, but testing for payload reduces noise and potential side-effects.
1193b4be Poul Sander 2025-02-03 21:28 1032
    if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
1193b4be Poul Sander 2025-02-03 21:28 1033
        io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
1193b4be Poul Sander 2025-02-03 21:28 1034
    else
1193b4be Poul Sander 2025-02-03 21:28 1035
        io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
1193b4be Poul Sander 2025-02-03 21:28 1036
1193b4be Poul Sander 2025-02-03 21:28 1037
    ImGui_ImplSDL2_UpdateMouseData();
1193b4be Poul Sander 2025-02-03 21:28 1038
    ImGui_ImplSDL2_UpdateMouseCursor();
1193b4be Poul Sander 2025-02-03 21:28 1039
1193b4be Poul Sander 2025-02-03 21:28 1040
    // Update game controllers (if enabled and available)
1193b4be Poul Sander 2025-02-03 21:28 1041
    ImGui_ImplSDL2_UpdateGamepads();
1193b4be Poul Sander 2025-02-03 21:28 1042
}
1193b4be Poul Sander 2025-02-03 21:28 1043
1193b4be Poul Sander 2025-02-03 21:28 1044
//--------------------------------------------------------------------------------------------------------
1193b4be Poul Sander 2025-02-03 21:28 1045
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
1193b4be Poul Sander 2025-02-03 21:28 1046
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
1193b4be Poul Sander 2025-02-03 21:28 1047
// 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..
1193b4be Poul Sander 2025-02-03 21:28 1048
//--------------------------------------------------------------------------------------------------------
1193b4be Poul Sander 2025-02-03 21:28 1049
4e9e2555 Poul Sander 2025-10-05 10:15 1050
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
1193b4be Poul Sander 2025-02-03 21:28 1051
struct ImGui_ImplSDL2_ViewportData
1193b4be Poul Sander 2025-02-03 21:28 1052
{
1193b4be Poul Sander 2025-02-03 21:28 1053
    SDL_Window*     Window;
4e9e2555 Poul Sander 2025-10-05 10:15 1054
    Uint32          WindowID;       // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
1193b4be Poul Sander 2025-02-03 21:28 1055
    bool            WindowOwned;
1193b4be Poul Sander 2025-02-03 21:28 1056
    SDL_GLContext   GLContext;
1193b4be Poul Sander 2025-02-03 21:28 1057
4e9e2555 Poul Sander 2025-10-05 10:15 1058
    ImGui_ImplSDL2_ViewportData()   { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
4e9e2555 Poul Sander 2025-10-05 10:15 1059
    ~ImGui_ImplSDL2_ViewportData()  { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
1193b4be Poul Sander 2025-02-03 21:28 1060
};
1193b4be Poul Sander 2025-02-03 21:28 1061
1193b4be Poul Sander 2025-02-03 21:28 1062
static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1063
{
1193b4be Poul Sander 2025-02-03 21:28 1064
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
1193b4be Poul Sander 2025-02-03 21:28 1065
    ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
1193b4be Poul Sander 2025-02-03 21:28 1066
    viewport->PlatformUserData = vd;
1193b4be Poul Sander 2025-02-03 21:28 1067
1193b4be Poul Sander 2025-02-03 21:28 1068
    ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1193b4be Poul Sander 2025-02-03 21:28 1069
    ImGui_ImplSDL2_ViewportData* main_viewport_data = (ImGui_ImplSDL2_ViewportData*)main_viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1070
1193b4be Poul Sander 2025-02-03 21:28 1071
    // Share GL resources with main context
1193b4be Poul Sander 2025-02-03 21:28 1072
    bool use_opengl = (main_viewport_data->GLContext != nullptr);
1193b4be Poul Sander 2025-02-03 21:28 1073
    SDL_GLContext backup_context = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 1074
    if (use_opengl)
1193b4be Poul Sander 2025-02-03 21:28 1075
    {
1193b4be Poul Sander 2025-02-03 21:28 1076
        backup_context = SDL_GL_GetCurrentContext();
1193b4be Poul Sander 2025-02-03 21:28 1077
        SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
1193b4be Poul Sander 2025-02-03 21:28 1078
        SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
1193b4be Poul Sander 2025-02-03 21:28 1079
    }
1193b4be Poul Sander 2025-02-03 21:28 1080
1193b4be Poul Sander 2025-02-03 21:28 1081
    Uint32 sdl_flags = 0;
1193b4be Poul Sander 2025-02-03 21:28 1082
    sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
1193b4be Poul Sander 2025-02-03 21:28 1083
    sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI;
1193b4be Poul Sander 2025-02-03 21:28 1084
    sdl_flags |= SDL_WINDOW_HIDDEN;
1193b4be Poul Sander 2025-02-03 21:28 1085
    sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
1193b4be Poul Sander 2025-02-03 21:28 1086
    sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
1193b4be Poul Sander 2025-02-03 21:28 1087
#if !defined(_WIN32)
1193b4be Poul Sander 2025-02-03 21:28 1088
    // See SDL hack in ImGui_ImplSDL2_ShowWindow().
1193b4be Poul Sander 2025-02-03 21:28 1089
    sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0;
1193b4be Poul Sander 2025-02-03 21:28 1090
#endif
1193b4be Poul Sander 2025-02-03 21:28 1091
#if SDL_HAS_ALWAYS_ON_TOP
1193b4be Poul Sander 2025-02-03 21:28 1092
    sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
1193b4be Poul Sander 2025-02-03 21:28 1093
#endif
1193b4be Poul Sander 2025-02-03 21:28 1094
    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);
1193b4be Poul Sander 2025-02-03 21:28 1095
    vd->WindowOwned = true;
1193b4be Poul Sander 2025-02-03 21:28 1096
    if (use_opengl)
1193b4be Poul Sander 2025-02-03 21:28 1097
    {
1193b4be Poul Sander 2025-02-03 21:28 1098
        vd->GLContext = SDL_GL_CreateContext(vd->Window);
1193b4be Poul Sander 2025-02-03 21:28 1099
        SDL_GL_SetSwapInterval(0);
1193b4be Poul Sander 2025-02-03 21:28 1100
    }
1193b4be Poul Sander 2025-02-03 21:28 1101
    if (use_opengl && backup_context)
1193b4be Poul Sander 2025-02-03 21:28 1102
        SDL_GL_MakeCurrent(vd->Window, backup_context);
1193b4be Poul Sander 2025-02-03 21:28 1103
1193b4be Poul Sander 2025-02-03 21:28 1104
    viewport->PlatformHandle = (void*)(intptr_t)SDL_GetWindowID(vd->Window);
1193b4be Poul Sander 2025-02-03 21:28 1105
    viewport->PlatformHandleRaw = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 1106
    SDL_SysWMinfo info;
1193b4be Poul Sander 2025-02-03 21:28 1107
    SDL_VERSION(&info.version);
1193b4be Poul Sander 2025-02-03 21:28 1108
    if (SDL_GetWindowWMInfo(vd->Window, &info))
1193b4be Poul Sander 2025-02-03 21:28 1109
    {
1193b4be Poul Sander 2025-02-03 21:28 1110
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
1193b4be Poul Sander 2025-02-03 21:28 1111
        viewport->PlatformHandleRaw = info.info.win.window;
1193b4be Poul Sander 2025-02-03 21:28 1112
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
1193b4be Poul Sander 2025-02-03 21:28 1113
        viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
1193b4be Poul Sander 2025-02-03 21:28 1114
#endif
1193b4be Poul Sander 2025-02-03 21:28 1115
    }
1193b4be Poul Sander 2025-02-03 21:28 1116
}
1193b4be Poul Sander 2025-02-03 21:28 1117
1193b4be Poul Sander 2025-02-03 21:28 1118
static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1119
{
1193b4be Poul Sander 2025-02-03 21:28 1120
    if (ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData)
1193b4be Poul Sander 2025-02-03 21:28 1121
    {
1193b4be Poul Sander 2025-02-03 21:28 1122
        if (vd->GLContext && vd->WindowOwned)
1193b4be Poul Sander 2025-02-03 21:28 1123
            SDL_GL_DeleteContext(vd->GLContext);
1193b4be Poul Sander 2025-02-03 21:28 1124
        if (vd->Window && vd->WindowOwned)
1193b4be Poul Sander 2025-02-03 21:28 1125
            SDL_DestroyWindow(vd->Window);
1193b4be Poul Sander 2025-02-03 21:28 1126
        vd->GLContext = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 1127
        vd->Window = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 1128
        IM_DELETE(vd);
1193b4be Poul Sander 2025-02-03 21:28 1129
    }
1193b4be Poul Sander 2025-02-03 21:28 1130
    viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
1193b4be Poul Sander 2025-02-03 21:28 1131
}
1193b4be Poul Sander 2025-02-03 21:28 1132
1193b4be Poul Sander 2025-02-03 21:28 1133
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1134
{
1193b4be Poul Sander 2025-02-03 21:28 1135
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
4e9e2555 Poul Sander 2025-10-05 10:15 1136
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP) || (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)))
1193b4be Poul Sander 2025-02-03 21:28 1137
    HWND hwnd = (HWND)viewport->PlatformHandleRaw;
1193b4be Poul Sander 2025-02-03 21:28 1138
1193b4be Poul Sander 2025-02-03 21:28 1139
    // SDL hack: Hide icon from task bar
1193b4be Poul Sander 2025-02-03 21:28 1140
    // 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.
1193b4be Poul Sander 2025-02-03 21:28 1141
    if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
1193b4be Poul Sander 2025-02-03 21:28 1142
    {
1193b4be Poul Sander 2025-02-03 21:28 1143
        LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
1193b4be Poul Sander 2025-02-03 21:28 1144
        ex_style &= ~WS_EX_APPWINDOW;
1193b4be Poul Sander 2025-02-03 21:28 1145
        ex_style |= WS_EX_TOOLWINDOW;
1193b4be Poul Sander 2025-02-03 21:28 1146
        ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
1193b4be Poul Sander 2025-02-03 21:28 1147
    }
1193b4be Poul Sander 2025-02-03 21:28 1148
#endif
1193b4be Poul Sander 2025-02-03 21:28 1149
1193b4be Poul Sander 2025-02-03 21:28 1150
#if SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT
1193b4be Poul Sander 2025-02-03 21:28 1151
    SDL_SetHint(SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN, (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) ? "1" : "0");
1193b4be Poul Sander 2025-02-03 21:28 1152
#elif defined(_WIN32)
1193b4be Poul Sander 2025-02-03 21:28 1153
    // SDL hack: SDL always activate/focus windows :/
1193b4be Poul Sander 2025-02-03 21:28 1154
    if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
1193b4be Poul Sander 2025-02-03 21:28 1155
    {
1193b4be Poul Sander 2025-02-03 21:28 1156
        ::ShowWindow(hwnd, SW_SHOWNA);
1193b4be Poul Sander 2025-02-03 21:28 1157
        return;
1193b4be Poul Sander 2025-02-03 21:28 1158
    }
1193b4be Poul Sander 2025-02-03 21:28 1159
#endif
1193b4be Poul Sander 2025-02-03 21:28 1160
    SDL_ShowWindow(vd->Window);
1193b4be Poul Sander 2025-02-03 21:28 1161
}
1193b4be Poul Sander 2025-02-03 21:28 1162
1193b4be Poul Sander 2025-02-03 21:28 1163
static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1164
{
1193b4be Poul Sander 2025-02-03 21:28 1165
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1166
    int x = 0, y = 0;
1193b4be Poul Sander 2025-02-03 21:28 1167
    SDL_GetWindowPosition(vd->Window, &x, &y);
1193b4be Poul Sander 2025-02-03 21:28 1168
    return ImVec2((float)x, (float)y);
1193b4be Poul Sander 2025-02-03 21:28 1169
}
1193b4be Poul Sander 2025-02-03 21:28 1170
1193b4be Poul Sander 2025-02-03 21:28 1171
static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
1193b4be Poul Sander 2025-02-03 21:28 1172
{
1193b4be Poul Sander 2025-02-03 21:28 1173
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1174
    SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y);
1193b4be Poul Sander 2025-02-03 21:28 1175
}
1193b4be Poul Sander 2025-02-03 21:28 1176
1193b4be Poul Sander 2025-02-03 21:28 1177
static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1178
{
1193b4be Poul Sander 2025-02-03 21:28 1179
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1180
    int w = 0, h = 0;
1193b4be Poul Sander 2025-02-03 21:28 1181
    SDL_GetWindowSize(vd->Window, &w, &h);
1193b4be Poul Sander 2025-02-03 21:28 1182
    return ImVec2((float)w, (float)h);
1193b4be Poul Sander 2025-02-03 21:28 1183
}
1193b4be Poul Sander 2025-02-03 21:28 1184
1193b4be Poul Sander 2025-02-03 21:28 1185
static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
1193b4be Poul Sander 2025-02-03 21:28 1186
{
1193b4be Poul Sander 2025-02-03 21:28 1187
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1188
    SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
1193b4be Poul Sander 2025-02-03 21:28 1189
}
1193b4be Poul Sander 2025-02-03 21:28 1190
4e9e2555 Poul Sander 2025-10-05 10:15 1191
static ImVec2 ImGui_ImplSDL2_GetWindowFramebufferScale(ImGuiViewport* viewport)
4e9e2555 Poul Sander 2025-10-05 10:15 1192
{
4e9e2555 Poul Sander 2025-10-05 10:15 1193
    // FIXME: SDL_Renderer does not support multi-viewport.
4e9e2555 Poul Sander 2025-10-05 10:15 1194
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
4e9e2555 Poul Sander 2025-10-05 10:15 1195
    ImVec2 framebuffer_scale;
4e9e2555 Poul Sander 2025-10-05 10:15 1196
    ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, nullptr, &framebuffer_scale);
4e9e2555 Poul Sander 2025-10-05 10:15 1197
    return framebuffer_scale;
4e9e2555 Poul Sander 2025-10-05 10:15 1198
}
4e9e2555 Poul Sander 2025-10-05 10:15 1199
1193b4be Poul Sander 2025-02-03 21:28 1200
static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title)
1193b4be Poul Sander 2025-02-03 21:28 1201
{
1193b4be Poul Sander 2025-02-03 21:28 1202
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1203
    SDL_SetWindowTitle(vd->Window, title);
1193b4be Poul Sander 2025-02-03 21:28 1204
}
1193b4be Poul Sander 2025-02-03 21:28 1205
1193b4be Poul Sander 2025-02-03 21:28 1206
#if SDL_HAS_WINDOW_ALPHA
1193b4be Poul Sander 2025-02-03 21:28 1207
static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
1193b4be Poul Sander 2025-02-03 21:28 1208
{
1193b4be Poul Sander 2025-02-03 21:28 1209
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1210
    SDL_SetWindowOpacity(vd->Window, alpha);
1193b4be Poul Sander 2025-02-03 21:28 1211
}
1193b4be Poul Sander 2025-02-03 21:28 1212
#endif
1193b4be Poul Sander 2025-02-03 21:28 1213
1193b4be Poul Sander 2025-02-03 21:28 1214
static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1215
{
1193b4be Poul Sander 2025-02-03 21:28 1216
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1217
    SDL_RaiseWindow(vd->Window);
1193b4be Poul Sander 2025-02-03 21:28 1218
}
1193b4be Poul Sander 2025-02-03 21:28 1219
1193b4be Poul Sander 2025-02-03 21:28 1220
static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1221
{
1193b4be Poul Sander 2025-02-03 21:28 1222
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1223
    return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0;
1193b4be Poul Sander 2025-02-03 21:28 1224
}
1193b4be Poul Sander 2025-02-03 21:28 1225
1193b4be Poul Sander 2025-02-03 21:28 1226
static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport)
1193b4be Poul Sander 2025-02-03 21:28 1227
{
1193b4be Poul Sander 2025-02-03 21:28 1228
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1229
    return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0;
1193b4be Poul Sander 2025-02-03 21:28 1230
}
1193b4be Poul Sander 2025-02-03 21:28 1231
1193b4be Poul Sander 2025-02-03 21:28 1232
static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*)
1193b4be Poul Sander 2025-02-03 21:28 1233
{
1193b4be Poul Sander 2025-02-03 21:28 1234
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1235
    if (vd->GLContext)
1193b4be Poul Sander 2025-02-03 21:28 1236
        SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
1193b4be Poul Sander 2025-02-03 21:28 1237
}
1193b4be Poul Sander 2025-02-03 21:28 1238
1193b4be Poul Sander 2025-02-03 21:28 1239
static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*)
1193b4be Poul Sander 2025-02-03 21:28 1240
{
1193b4be Poul Sander 2025-02-03 21:28 1241
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1242
    if (vd->GLContext)
1193b4be Poul Sander 2025-02-03 21:28 1243
    {
1193b4be Poul Sander 2025-02-03 21:28 1244
        SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
1193b4be Poul Sander 2025-02-03 21:28 1245
        SDL_GL_SwapWindow(vd->Window);
1193b4be Poul Sander 2025-02-03 21:28 1246
    }
1193b4be Poul Sander 2025-02-03 21:28 1247
}
1193b4be Poul Sander 2025-02-03 21:28 1248
1193b4be Poul Sander 2025-02-03 21:28 1249
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
1193b4be Poul Sander 2025-02-03 21:28 1250
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
1193b4be Poul Sander 2025-02-03 21:28 1251
#if SDL_HAS_VULKAN
1193b4be Poul Sander 2025-02-03 21:28 1252
#include <SDL_vulkan.h>
1193b4be Poul Sander 2025-02-03 21:28 1253
static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
1193b4be Poul Sander 2025-02-03 21:28 1254
{
1193b4be Poul Sander 2025-02-03 21:28 1255
    ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
1193b4be Poul Sander 2025-02-03 21:28 1256
    (void)vk_allocator;
1193b4be Poul Sander 2025-02-03 21:28 1257
    SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR*)out_vk_surface);
1193b4be Poul Sander 2025-02-03 21:28 1258
    return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
1193b4be Poul Sander 2025-02-03 21:28 1259
}
1193b4be Poul Sander 2025-02-03 21:28 1260
#endif // SDL_HAS_VULKAN
1193b4be Poul Sander 2025-02-03 21:28 1261
1193b4be Poul Sander 2025-02-03 21:28 1262
static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
1193b4be Poul Sander 2025-02-03 21:28 1263
{
1193b4be Poul Sander 2025-02-03 21:28 1264
    // Register platform interface (will be coupled with a renderer interface)
1193b4be Poul Sander 2025-02-03 21:28 1265
    ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
1193b4be Poul Sander 2025-02-03 21:28 1266
    platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow;
1193b4be Poul Sander 2025-02-03 21:28 1267
    platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow;
1193b4be Poul Sander 2025-02-03 21:28 1268
    platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow;
1193b4be Poul Sander 2025-02-03 21:28 1269
    platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos;
1193b4be Poul Sander 2025-02-03 21:28 1270
    platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
1193b4be Poul Sander 2025-02-03 21:28 1271
    platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
1193b4be Poul Sander 2025-02-03 21:28 1272
    platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
4e9e2555 Poul Sander 2025-10-05 10:15 1273
    platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplSDL2_GetWindowFramebufferScale;
1193b4be Poul Sander 2025-02-03 21:28 1274
    platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
1193b4be Poul Sander 2025-02-03 21:28 1275
    platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
1193b4be Poul Sander 2025-02-03 21:28 1276
    platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;
1193b4be Poul Sander 2025-02-03 21:28 1277
    platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle;
1193b4be Poul Sander 2025-02-03 21:28 1278
    platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow;
1193b4be Poul Sander 2025-02-03 21:28 1279
    platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers;
1193b4be Poul Sander 2025-02-03 21:28 1280
#if SDL_HAS_WINDOW_ALPHA
1193b4be Poul Sander 2025-02-03 21:28 1281
    platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha;
1193b4be Poul Sander 2025-02-03 21:28 1282
#endif
1193b4be Poul Sander 2025-02-03 21:28 1283
#if SDL_HAS_VULKAN
1193b4be Poul Sander 2025-02-03 21:28 1284
    platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface;
1193b4be Poul Sander 2025-02-03 21:28 1285
#endif
1193b4be Poul Sander 2025-02-03 21:28 1286
1193b4be Poul Sander 2025-02-03 21:28 1287
    // Register main window handle (which is owned by the main application, not by us)
1193b4be Poul Sander 2025-02-03 21:28 1288
    // 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.
1193b4be Poul Sander 2025-02-03 21:28 1289
    ImGuiViewport* main_viewport = ImGui::GetMainViewport();
1193b4be Poul Sander 2025-02-03 21:28 1290
    ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
1193b4be Poul Sander 2025-02-03 21:28 1291
    vd->Window = window;
1193b4be Poul Sander 2025-02-03 21:28 1292
    vd->WindowID = SDL_GetWindowID(window);
1193b4be Poul Sander 2025-02-03 21:28 1293
    vd->WindowOwned = false;
1193b4be Poul Sander 2025-02-03 21:28 1294
    vd->GLContext = sdl_gl_context;
1193b4be Poul Sander 2025-02-03 21:28 1295
    main_viewport->PlatformUserData = vd;
1193b4be Poul Sander 2025-02-03 21:28 1296
    main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
1193b4be Poul Sander 2025-02-03 21:28 1297
}
1193b4be Poul Sander 2025-02-03 21:28 1298
1193b4be Poul Sander 2025-02-03 21:28 1299
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport()
1193b4be Poul Sander 2025-02-03 21:28 1300
{
1193b4be Poul Sander 2025-02-03 21:28 1301
    ImGui::DestroyPlatformWindows();
1193b4be Poul Sander 2025-02-03 21:28 1302
}
1193b4be Poul Sander 2025-02-03 21:28 1303
1193b4be Poul Sander 2025-02-03 21:28 1304
//-----------------------------------------------------------------------------
1193b4be Poul Sander 2025-02-03 21:28 1305
1193b4be Poul Sander 2025-02-03 21:28 1306
#if defined(__clang__)
1193b4be Poul Sander 2025-02-03 21:28 1307
#pragma clang diagnostic pop
1193b4be Poul Sander 2025-02-03 21:28 1308
#endif
1193b4be Poul Sander 2025-02-03 21:28 1309
1193b4be Poul Sander 2025-02-03 21:28 1310
#endif // #ifndef IMGUI_DISABLE
1970-01-01 00:00 1311