-- Iir to ortho translator. -- Copyright (C) 2002 - 2014 Tristan Gingold -- -- GHDL is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. -- -- GHDL is distributed in the hope that it will be useful, but WITHOUT ANY -- WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. -- -- You should have received a copy of the GNU General Public License -- along with GCC; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. with Name_Table; with Files_Map; with Vhdl.Errors; use Vhdl.Errors; with Vhdl.Utils; use Vhdl.Utils; with Vhdl.Configuration; with Libraries; with Trans.Chap7; with Trans; use Trans.Helpers; with Trans.Helpers2; use Trans.Helpers2; package body Trans.Rtis is -- Node for block, generate, processes. Ghdl_Rtin_Block : O_Tnode; Ghdl_Rtin_Block_Common : O_Fnode; Ghdl_Rtin_Block_Name : O_Fnode; Ghdl_Rtin_Block_Loc : O_Fnode; Ghdl_Rtin_Block_Linecol : O_Fnode; Ghdl_Rtin_Block_Parent : O_Fnode; Ghdl_Rtin_Block_Nbr_Child : O_Fnode; Ghdl_Rtin_Block_Children : O_Fnode; -- A block with a filename: for package, body, entity and architecture. Ghdl_Rtin_Block_File : O_Tnode; Ghdl_Rtin_Block_File_Block : O_Fnode; Ghdl_Rtin_Block_File_Filename : O_Fnode; -- For generate statement. Ghdl_Rtin_Generate : O_Tnode; Ghdl_Rtin_Generate_Common : O_Fnode; Ghdl_Rtin_Generate_Name : O_Fnode; Ghdl_Rtin_Generate_Loc : O_Fnode; Ghdl_Rtin_Generate_Linecol : O_Fnode; Ghdl_Rtin_Generate_Parent : O_Fnode; Ghdl_Rtin_Generate_Size : O_Fnode; Ghdl_Rtin_Generate_Child : O_Fnode; -- Node for scalar type decls. Ghdl_Rtin_Type_Scalar : O_Tnode; Ghdl_Rtin_Type_Scalar_Common : O_Fnode; Ghdl_Rtin_Type_Scalar_Name : O_Fnode; -- Node for an enumeration type definition. Ghdl_Rtin_Type_Enum : O_Tnode; Ghdl_Rtin_Type_Enum_Common : O_Fnode; Ghdl_Rtin_Type_Enum_Name : O_Fnode; Ghdl_Rtin_Type_Enum_Nbr : O_Fnode; Ghdl_Rtin_Type_Enum_Lits : O_Fnode; -- Node for an unit64. Ghdl_Rtin_Unit64 : O_Tnode; Ghdl_Rtin_Unit64_Common : O_Fnode; Ghdl_Rtin_Unit64_Name : O_Fnode; Ghdl_Rtin_Unit64_Value : O_Fnode; -- Node for an unitptr. Ghdl_Rtin_Unitptr : O_Tnode; Ghdl_Rtin_Unitptr_Common : O_Fnode; Ghdl_Rtin_Unitptr_Name : O_Fnode; Ghdl_Rtin_Unitptr_Value : O_Fnode; -- Node for a physical type Ghdl_Rtin_Type_Physical : O_Tnode; Ghdl_Rtin_Type_Physical_Common : O_Fnode; Ghdl_Rtin_Type_Physical_Name : O_Fnode; Ghdl_Rtin_Type_Physical_Nbr : O_Fnode; Ghdl_Rtin_Type_Physical_Units : O_Fnode; -- Node for a scalar subtype definition. Ghdl_Rtin_Subtype_Scalar : O_Tnode; Ghdl_Rtin_Subtype_Scalar_Common : O_Fnode; Ghdl_Rtin_Subtype_Scalar_Name : O_Fnode; Ghdl_Rtin_Subtype_Scalar_Base : O_Fnode; Ghdl_Rtin_Subtype_Scalar_Range : O_Fnode; -- Node for an access or a file type. Ghdl_Rtin_Type_Fileacc : O_Tnode; Ghdl_Rtin_Type_Fileacc_Common : O_Fnode; Ghdl_Rtin_Type_Fileacc_Name : O_Fnode; Ghdl_Rtin_Type_Fileacc_Base : O_Fnode; -- Node for an array type. Ghdl_Rtin_Type_Array : O_Tnode; Ghdl_Rtin_Type_Array_Common : O_Fnode; Ghdl_Rtin_Type_Array_Name : O_Fnode; Ghdl_Rtin_Type_Array_Element : O_Fnode; Ghdl_Rtin_Type_Array_Nbrdim : O_Fnode; Ghdl_Rtin_Type_Array_Indexes : O_Fnode; -- Node for a composite subtype. Ghdl_Rtin_Subtype_Composite : O_Tnode; Ghdl_Rtin_Subtype_Composite_Common : O_Fnode; Ghdl_Rtin_Subtype_Composite_Name : O_Fnode; Ghdl_Rtin_Subtype_Composite_Basetype : O_Fnode; Ghdl_Rtin_Subtype_Composite_Layout : O_Fnode; -- Node for a record element. Ghdl_Rtin_Element : O_Tnode; Ghdl_Rtin_Element_Common : O_Fnode; Ghdl_Rtin_Element_Name : O_Fnode; Ghdl_Rtin_Element_Type : O_Fnode; Ghdl_Rtin_Element_Valoff : O_Fnode; Ghdl_Rtin_Element_Sigoff : O_Fnode; Ghdl_Rtin_Element_Layout : O_Fnode; -- Node for a record type. Ghdl_Rtin_Type_Record : O_Tnode; Ghdl_Rtin_Type_Record_Common : O_Fnode; Ghdl_Rtin_Type_Record_Name : O_Fnode; Ghdl_Rtin_Type_Record_Nbrel : O_Fnode; Ghdl_Rtin_Type_Record_Elements : O_Fnode; Ghdl_Rtin_Type_Record_Layout : O_Fnode; -- Node for an object. Ghdl_Rtin_Object : O_Tnode; Ghdl_Rtin_Object_Common : O_Fnode; Ghdl_Rtin_Object_Name : O_Fnode; Ghdl_Rtin_Object_Loc : O_Fnode; Ghdl_Rtin_Object_Type : O_Fnode; Ghdl_Rtin_Object_Linecol : O_Fnode; -- Node for an instance. Ghdl_Rtin_Instance : O_Tnode; Ghdl_Rtin_Instance_Common : O_Fnode; Ghdl_Rtin_Instance_Name : O_Fnode; Ghdl_Rtin_Instance_Linecol : O_Fnode; Ghdl_Rtin_Instance_Loc : O_Fnode; Ghdl_Rtin_Instance_Parent : O_Fnode; Ghdl_Rtin_Instance_Type : O_Fnode; -- Node for a component. Ghdl_Rtin_Component : O_Tnode; Ghdl_Rtin_Component_Common : O_Fnode; Ghdl_Rtin_Component_Name : O_Fnode; Ghdl_Rtin_Component_Nbr_Child : O_Fnode; Ghdl_Rtin_Component_Children : O_Fnode; Null_Loc : O_Cnode; function Get_Context_Rti (Node : Iir) return O_Dnode; -- Create all the declarations for RTIs. procedure Rti_Initialize is begin -- Create type ghdl_rti_kind is (ghdl_rtik_typedef_bool, ...) declare Constr : O_Enum_List; begin Start_Enum_Type (Constr, 8); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_top"), Ghdl_Rtik_Top); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_library"), Ghdl_Rtik_Library); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_package"), Ghdl_Rtik_Package); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_package_body"), Ghdl_Rtik_Package_Body); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_entity"), Ghdl_Rtik_Entity); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_architecture"), Ghdl_Rtik_Architecture); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_process"), Ghdl_Rtik_Process); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_block"), Ghdl_Rtik_Block); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_if_generate"), Ghdl_Rtik_If_Generate); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_case_generate"), Ghdl_Rtik_Case_Generate); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_for_generate"), Ghdl_Rtik_For_Generate); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_generate_body"), Ghdl_Rtik_Generate_Body); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_instance"), Ghdl_Rtik_Instance); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_constant"), Ghdl_Rtik_Constant); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_iterator"), Ghdl_Rtik_Iterator); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_variable"), Ghdl_Rtik_Variable); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_signal"), Ghdl_Rtik_Signal); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_file"), Ghdl_Rtik_File); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_port"), Ghdl_Rtik_Port); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_generic"), Ghdl_Rtik_Generic); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_alias"), Ghdl_Rtik_Alias); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_guard"), Ghdl_Rtik_Guard); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_component"), Ghdl_Rtik_Component); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_attribute"), Ghdl_Rtik_Attribute); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_b1"), Ghdl_Rtik_Type_B1); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_e8"), Ghdl_Rtik_Type_E8); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_e32"), Ghdl_Rtik_Type_E32); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_i32"), Ghdl_Rtik_Type_I32); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_i64"), Ghdl_Rtik_Type_I64); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_f64"), Ghdl_Rtik_Type_F64); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_p32"), Ghdl_Rtik_Type_P32); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_p64"), Ghdl_Rtik_Type_P64); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_access"), Ghdl_Rtik_Type_Access); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_array"), Ghdl_Rtik_Type_Array); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_record"), Ghdl_Rtik_Type_Record); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_unbounded_record"), Ghdl_Rtik_Type_Unbounded_Record); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_file"), Ghdl_Rtik_Type_File); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_subtype_scalar"), Ghdl_Rtik_Subtype_Scalar); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_subtype_array"), Ghdl_Rtik_Subtype_Array); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_subtype_unconstrained_array"), Ghdl_Rtik_Subtype_Unconstrained_Array); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_subtype_record"), Ghdl_Rtik_Subtype_Record); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_subtype_unbounded_record"), Ghdl_Rtik_Subtype_Unbounded_Record); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_subtype_access"), Ghdl_Rtik_Subtype_Access); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_type_protected"), Ghdl_Rtik_Type_Protected); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_element"), Ghdl_Rtik_Element); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_unit64"), Ghdl_Rtik_Unit64); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_unitptr"), Ghdl_Rtik_Unitptr); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_attribute_transaction"), Ghdl_Rtik_Attribute_Transaction); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_attribute_quiet"), Ghdl_Rtik_Attribute_Quiet); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_attribute_stable"), Ghdl_Rtik_Attribute_Stable); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_psl_assert"), Ghdl_Rtik_Psl_Assert); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_psl_cover"), Ghdl_Rtik_Psl_Cover); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_psl_endpoint"), Ghdl_Rtik_Psl_Endpoint); New_Enum_Literal (Constr, Get_Identifier ("__ghdl_rtik_error"), Ghdl_Rtik_Error); Finish_Enum_Type (Constr, Ghdl_Rtik); New_Type_Decl (Get_Identifier ("__ghdl_rtik"), Ghdl_Rtik); end; -- Create type ghdl_rti_depth. Ghd
// dear imgui: Platform Binding for SDL2
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
// Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Clipboard support.
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
// [ ] Platform: Gamepad support (need to use SDL_GameController API to fill the io.NavInputs[] value when ImGuiConfigFlags_NavEnableGamepad is set).
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
// 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples.
// 2018-06-08: Misc: ImGui_ImplSDL2_InitForOpenGL() now takes a SDL_GLContext parameter.
// 2018-05-09: Misc: Fixed clipboard paste memory leak (we didn't call SDL_FreeMemory on the data returned by SDL_GetClipboardText).
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS).
// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes.
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS.
// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
#include "imgui.h"
#include "imgui_impl_sdl.h"
// SDL
// (the multi-viewports feature requires SDL features supported from SDL 2.0.5+)
#include <SDL.h>
#include <SDL_syswm.h>
#define SDL_HAS_CAPTURE_MOUSE SDL_VERSION_ATLEAST(2,0,4)
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
#define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH SDL_VERSION_ATLEAST(2,0,5)
#if !SDL_HAS_VULKAN
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
#endif
// 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] = { 0 };
static char* g_ClipboardTextData = NULL;
static const char* ImGui_ImplSDL2_GetClipboardText(void*)
{
if (g_ClipboardTextData)
SDL_free(g_ClipboardTextData);
g_ClipboardTextData = SDL_GetClipboardText();
return g_ClipboardTextData;
}
static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
{
SDL_SetClipboardText(text);
}
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
bool ImGui_ImplSDL2_ProcessEvent(SDL_Event* event)
{
ImGuiIO& io = ImGui::GetIO();
switch (event->type)
{
case SDL_MOUSEWHEEL:
{
if (event->wheel.x > 0) io.MouseWheelH += 1;
if (event->wheel.x < 0) io.MouseWheelH -= 1;
if (event->wheel.y > 0) io.MouseWheel += 1;
if (event->wheel.y < 0) io.MouseWheel -= 1;
return true;
}
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;
return true;
}
case SDL_TEXTINPUT:
{
io.AddInputCharactersUTF8(event->text.text);
return true;
}
case SDL_KEYDOWN:
case SDL_KEYUP:
{
int key = event->key.keysym.scancode;
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
io.KeysDown[key] = (event->type == SDL_KEYDOWN);
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
return true;
}
}
return false;
}
static bool ImGui_ImplSDL2_Init(SDL_Window* window)
{
g_Window = window;
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
io.ClipboardUserData = NULL;
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);
#ifdef _WIN32
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
io.ImeWindowHandle = wmInfo.info.win.window;
#else
(void)window;
#endif
return true;
}
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
{
(void)sdl_gl_context; // Viewport branch will need this.
return ImGui_ImplSDL2_Init(window);
}
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
{
#if !SDL_HAS_VULKAN
IM_ASSERT(0 && "Unsupported");
#endif
return ImGui_ImplSDL2_Init(window);
}
void ImGui_ImplSDL2_Shutdown()
{
g_Window = NULL;
// Destroy last known clipboard data
if (g_ClipboardTextData)
SDL_free(g_ClipboardTextData);
g_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));
}
static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
{
ImGuiIO& io = ImGui::GetIO();
// 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);
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;
#if SDL_HAS_CAPTURE_MOUSE && !defined(__EMSCRIPTEN__)
SDL_Window* focused_window = SDL_GetKeyboardFocus();
if (g_Window == focused_window)
{
// 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.
int wx, wy;
SDL_GetWindowPosition(focused_window, &wx, &wy);
SDL_GetGlobalMouseState(&mx, &my);
mx -= wx;
my -= wy;
io.MousePos = ImVec2((float)mx, (float)my);
}
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor.
// The function is only supported from SDL 2.0.4 (released Jan 2016)
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)
io.MousePos = ImVec2((float)mx, (float)my);
#endif
}
static void ImGui_ImplSDL2_UpdateMouseCursor()
{
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
SDL_ShowCursor(SDL_FALSE);
}
else
{
// Show OS mouse cursor
SDL_SetCursor(g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]);
SDL_ShowCursor(SDL_TRUE);
}
}
void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt()); // Font atlas needs to be built, call renderer _NewFrame() function e.g. ImGui_ImplOpenGL3_NewFrame()
// Setup display size (every frame to accommodate for window resizing)
int w, h;
int display_w, display_h;
SDL_GetWindowSize(window, &w, &h);
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
// 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;
ImGui_ImplSDL2_UpdateMousePosAndButtons();
ImGui_ImplSDL2_UpdateMouseCursor();
}