mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-03 17:24:24 +00:00 
			
		
		
		
	Backends: moved global to a data structure to facilitate support for multi-contexts. (#586, #1851, #2004, #3012, #3934, #4141)
This is NOT enable multi-contexts for any backends - in order to make this commit as harmless as possible, while containing all the cruft/renaming -
This commit is contained in:
		@@ -18,6 +18,7 @@
 | 
			
		||||
 | 
			
		||||
// CHANGELOG
 | 
			
		||||
// (minor and older changes stripped away, please see git history for details)
 | 
			
		||||
//  2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
 | 
			
		||||
//  2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
 | 
			
		||||
//  2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
 | 
			
		||||
//  2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
 | 
			
		||||
@@ -59,20 +60,32 @@
 | 
			
		||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE    SDL_VERSION_ATLEAST(2,0,4)
 | 
			
		||||
#define SDL_HAS_VULKAN                      SDL_VERSION_ATLEAST(2,0,6)
 | 
			
		||||
 | 
			
		||||
// Data
 | 
			
		||||
static SDL_Window*  g_Window = NULL;
 | 
			
		||||
static Uint64       g_Time = 0;
 | 
			
		||||
static bool         g_MousePressed[3] = { false, false, false };
 | 
			
		||||
static SDL_Cursor*  g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
 | 
			
		||||
static char*        g_ClipboardTextData = NULL;
 | 
			
		||||
static bool         g_MouseCanUseGlobalState = true;
 | 
			
		||||
struct ImGui_ImplSDL2_Data
 | 
			
		||||
{
 | 
			
		||||
    SDL_Window* Window;
 | 
			
		||||
    Uint64      Time;
 | 
			
		||||
    bool        MousePressed[3];
 | 
			
		||||
    SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
 | 
			
		||||
    char*       ClipboardTextData;
 | 
			
		||||
    bool        MouseCanUseGlobalState;
 | 
			
		||||
 | 
			
		||||
    ImGui_ImplSDL2_Data() { memset(this, 0, sizeof(*this)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Wrapping access to backend data data (to facilitate multiple-contexts stored in io.BackendPlatformUserData)
 | 
			
		||||
static ImGui_ImplSDL2_Data* g_Data;
 | 
			
		||||
static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_CreateBackendData()  { IM_ASSERT(g_Data == NULL); g_Data = IM_NEW(ImGui_ImplSDL2_Data); return g_Data; }
 | 
			
		||||
static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()     { return ImGui::GetCurrentContext() != NULL ? g_Data : NULL; }
 | 
			
		||||
static void                 ImGui_ImplSDL2_DestroyBackendData() { IM_DELETE(g_Data); g_Data = NULL; }
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
static const char* ImGui_ImplSDL2_GetClipboardText(void*)
 | 
			
		||||
{
 | 
			
		||||
    if (g_ClipboardTextData)
 | 
			
		||||
        SDL_free(g_ClipboardTextData);
 | 
			
		||||
    g_ClipboardTextData = SDL_GetClipboardText();
 | 
			
		||||
    return g_ClipboardTextData;
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
 | 
			
		||||
    if (bd->ClipboardTextData)
 | 
			
		||||
        SDL_free(bd->ClipboardTextData);
 | 
			
		||||
    bd->ClipboardTextData = SDL_GetClipboardText();
 | 
			
		||||
    return bd->ClipboardTextData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
 | 
			
		||||
@@ -88,6 +101,8 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
 | 
			
		||||
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
 | 
			
		||||
 | 
			
		||||
    switch (event->type)
 | 
			
		||||
    {
 | 
			
		||||
    case SDL_MOUSEWHEEL:
 | 
			
		||||
@@ -100,9 +115,9 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
 | 
			
		||||
        }
 | 
			
		||||
    case SDL_MOUSEBUTTONDOWN:
 | 
			
		||||
        {
 | 
			
		||||
            if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true;
 | 
			
		||||
            if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true;
 | 
			
		||||
            if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true;
 | 
			
		||||
            if (event->button.button == SDL_BUTTON_LEFT) { bd->MousePressed[0] = true; }
 | 
			
		||||
            if (event->button.button == SDL_BUTTON_RIGHT) { bd->MousePressed[1] = true; }
 | 
			
		||||
            if (event->button.button == SDL_BUTTON_MIDDLE) { bd->MousePressed[2] = true; }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    case SDL_TEXTINPUT:
 | 
			
		||||
@@ -132,13 +147,17 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
 | 
			
		||||
 | 
			
		||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window)
 | 
			
		||||
{
 | 
			
		||||
    g_Window = window;
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
 | 
			
		||||
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_CreateBackendData();
 | 
			
		||||
    bd->Window = window;
 | 
			
		||||
 | 
			
		||||
    // Setup backend capabilities flags
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    io.BackendPlatformUserData = (void*)bd;
 | 
			
		||||
    io.BackendPlatformName = "imgui_impl_sdl";
 | 
			
		||||
    io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;       // We can honor GetMouseCursor() values (optional)
 | 
			
		||||
    io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;        // We can honor io.WantSetMousePos requests (optional, rarely used)
 | 
			
		||||
    io.BackendPlatformName = "imgui_impl_sdl";
 | 
			
		||||
 | 
			
		||||
    // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
 | 
			
		||||
    io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
 | 
			
		||||
@@ -169,24 +188,24 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
 | 
			
		||||
    io.ClipboardUserData = NULL;
 | 
			
		||||
 | 
			
		||||
    // Load mouse cursors
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
 | 
			
		||||
    g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
 | 
			
		||||
    bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
 | 
			
		||||
 | 
			
		||||
    // Check and store if we are on a SDL backend that supports global mouse position
 | 
			
		||||
    // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
 | 
			
		||||
    const char* sdl_backend = SDL_GetCurrentVideoDriver();
 | 
			
		||||
    const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
 | 
			
		||||
    g_MouseCanUseGlobalState = false;
 | 
			
		||||
    bd->MouseCanUseGlobalState = false;
 | 
			
		||||
    for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
 | 
			
		||||
        if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
 | 
			
		||||
            g_MouseCanUseGlobalState = true;
 | 
			
		||||
            bd->MouseCanUseGlobalState = true;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
    SDL_SysWMinfo wmInfo;
 | 
			
		||||
@@ -202,7 +221,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
 | 
			
		||||
 | 
			
		||||
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
 | 
			
		||||
{
 | 
			
		||||
    (void)sdl_gl_context; // Viewport branch will need this.
 | 
			
		||||
    IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
 | 
			
		||||
    return ImGui_ImplSDL2_Init(window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -229,41 +248,48 @@ bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
 | 
			
		||||
 | 
			
		||||
void ImGui_ImplSDL2_Shutdown()
 | 
			
		||||
{
 | 
			
		||||
    g_Window = NULL;
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
 | 
			
		||||
    bd->Window = NULL;
 | 
			
		||||
 | 
			
		||||
    // Destroy last known clipboard data
 | 
			
		||||
    if (g_ClipboardTextData)
 | 
			
		||||
        SDL_free(g_ClipboardTextData);
 | 
			
		||||
    g_ClipboardTextData = NULL;
 | 
			
		||||
    if (bd->ClipboardTextData)
 | 
			
		||||
        SDL_free(bd->ClipboardTextData);
 | 
			
		||||
    bd->ClipboardTextData = NULL;
 | 
			
		||||
 | 
			
		||||
    // Destroy SDL mouse cursors
 | 
			
		||||
    for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
 | 
			
		||||
        SDL_FreeCursor(g_MouseCursors[cursor_n]);
 | 
			
		||||
    memset(g_MouseCursors, 0, sizeof(g_MouseCursors));
 | 
			
		||||
        SDL_FreeCursor(bd->MouseCursors[cursor_n]);
 | 
			
		||||
    memset(bd->MouseCursors, 0, sizeof(bd->MouseCursors));
 | 
			
		||||
 | 
			
		||||
    io.BackendPlatformName = NULL;
 | 
			
		||||
    io.BackendPlatformUserData = NULL;
 | 
			
		||||
    ImGui_ImplSDL2_DestroyBackendData();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
 | 
			
		||||
 | 
			
		||||
    // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
 | 
			
		||||
    if (io.WantSetMousePos)
 | 
			
		||||
        SDL_WarpMouseInWindow(g_Window, (int)io.MousePos.x, (int)io.MousePos.y);
 | 
			
		||||
        SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
 | 
			
		||||
    else
 | 
			
		||||
        io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
 | 
			
		||||
 | 
			
		||||
    int mx, my;
 | 
			
		||||
    Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my);
 | 
			
		||||
    io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;  // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
 | 
			
		||||
    io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
 | 
			
		||||
    io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
 | 
			
		||||
    g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false;
 | 
			
		||||
    io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;  // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
 | 
			
		||||
    io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
 | 
			
		||||
    io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
 | 
			
		||||
    bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false;
 | 
			
		||||
 | 
			
		||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS)
 | 
			
		||||
    SDL_Window* focused_window = SDL_GetKeyboardFocus();
 | 
			
		||||
    if (g_Window == focused_window)
 | 
			
		||||
    if (bd->Window == focused_window)
 | 
			
		||||
    {
 | 
			
		||||
        if (g_MouseCanUseGlobalState)
 | 
			
		||||
        if (bd->MouseCanUseGlobalState)
 | 
			
		||||
        {
 | 
			
		||||
            // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?)
 | 
			
		||||
            // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally.
 | 
			
		||||
@@ -282,7 +308,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
 | 
			
		||||
    bool any_mouse_button_down = ImGui::IsAnyMouseDown();
 | 
			
		||||
    SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE);
 | 
			
		||||
#else
 | 
			
		||||
    if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS)
 | 
			
		||||
    if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS)
 | 
			
		||||
        io.MousePos = ImVec2((float)mx, (float)my);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
@@ -292,6 +318,7 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
 | 
			
		||||
        return;
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
 | 
			
		||||
 | 
			
		||||
    ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
 | 
			
		||||
    if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
 | 
			
		||||
@@ -302,7 +329,7 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Show OS mouse cursor
 | 
			
		||||
        SDL_SetCursor(g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]);
 | 
			
		||||
        SDL_SetCursor(bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]);
 | 
			
		||||
        SDL_ShowCursor(SDL_TRUE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -351,6 +378,8 @@ static void ImGui_ImplSDL2_UpdateGamepads()
 | 
			
		||||
void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
 | 
			
		||||
{
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO();
 | 
			
		||||
    ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
 | 
			
		||||
    IM_ASSERT(bd->Window == window); // FIXME: Should remove parameter from ImGui_ImplSDL2_NewFrame()
 | 
			
		||||
 | 
			
		||||
    // Setup display size (every frame to accommodate for window resizing)
 | 
			
		||||
    int w, h;
 | 
			
		||||
@@ -366,8 +395,8 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
 | 
			
		||||
    // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
 | 
			
		||||
    static Uint64 frequency = SDL_GetPerformanceFrequency();
 | 
			
		||||
    Uint64 current_time = SDL_GetPerformanceCounter();
 | 
			
		||||
    io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f);
 | 
			
		||||
    g_Time = current_time;
 | 
			
		||||
    io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
 | 
			
		||||
    bd->Time = current_time;
 | 
			
		||||
 | 
			
		||||
    ImGui_ImplSDL2_UpdateMousePosAndButtons();
 | 
			
		||||
    ImGui_ImplSDL2_UpdateMouseCursor();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user