2020-10-12 23:34:22 +08:00
// dear imgui: Platform Backend for GLFW
2021-01-28 19:11:26 +08:00
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
2018-06-09 01:37:33 +08:00
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
2023-02-07 19:24:42 +08:00
// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ or GLFW 3.4+ for full feature support.)
2018-06-09 01:37:33 +08:00
// Implemented features:
2018-06-11 18:33:51 +08:00
// [X] Platform: Clipboard support.
2023-04-05 01:43:51 +08:00
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
2021-12-12 19:00:31 +08:00
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
2018-09-20 16:37:55 +08:00
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
2019-12-05 22:43:05 +08:00
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
2018-06-09 01:37:33 +08:00
2021-06-28 22:52:10 +08:00
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
2021-05-27 19:59:35 +08:00
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
2023-09-11 19:47:08 +08:00
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
2018-06-09 01:37:33 +08:00
2024-09-08 01:22:45 +08:00
// About Emscripten support:
// - Emscripten provides its own GLFW (3.2.1) implementation (syntax: "-sUSE_GLFW=3"), but Joystick is broken and several features are not supported (multiple windows, clipboard, timer, etc.)
// - A third-party Emscripten GLFW (3.4.0) implementation (syntax: "--use-port=contrib.glfw3") fixes the Joystick issue and implements all relevant features for the browser.
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Comparison.md for details.
2018-06-09 01:37:33 +08:00
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
2024-08-22 23:50:10 +08:00
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
2024-08-22 22:42:57 +08:00
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
2024-07-31 23:33:24 +08:00
// 2024-07-31: Added ImGui_ImplGlfw_Sleep() helper function for usage by our examples app, since GLFW doesn't provide one.
2024-07-08 21:53:23 +08:00
// 2024-07-08: *BREAKING* Renamed ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback to ImGui_ImplGlfw_InstallEmscriptenCallbacks(), added GLFWWindow* parameter.
2024-07-09 04:04:27 +08:00
// 2024-07-08: Emscripten: Added support for GLFW3 contrib port (GLFW 3.4.0 features + bug fixes): to enable, replace -sUSE_GLFW=3 with --use-port=contrib.glfw3 (requires emscripten 3.1.59+) (https://github.com/pongasoft/emscripten-glfw)
2024-07-03 00:06:19 +08:00
// 2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
2023-12-19 22:57:00 +08:00
// 2023-12-19: Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to register canvas selector and auto-resize GLFW window.
2023-10-06 02:39:49 +08:00
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
2023-07-18 17:45:52 +08:00
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
2023-06-12 17:58:17 +08:00
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
2023-04-05 01:43:51 +08:00
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702)
2023-03-16 18:58:32 +08:00
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
2023-03-14 22:56:38 +08:00
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
2023-02-03 22:00:41 +08:00
// 2023-02-03: Emscripten: Registering custom low-level mouse wheel handler to get more accurate scrolling impulses on Emscripten. (#4019, #6096)
2023-01-04 22:42:20 +08:00
// 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty.
2022-11-23 01:08:25 +08:00
// 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908)
2022-10-18 18:17:59 +08:00
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
2022-10-11 18:22:29 +08:00
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
2022-09-23 00:58:33 +08:00
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
2023-07-18 17:45:52 +08:00
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position *EDIT* Reverted 2023-07-18.
2022-04-30 15:21:04 +08:00
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
2022-03-23 21:01:57 +08:00
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
2022-09-23 00:58:33 +08:00
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
2022-01-21 00:12:22 +08:00
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
2022-01-18 00:22:37 +08:00
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
2022-01-22 00:32:35 +08:00
// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates.
2022-01-13 00:08:37 +08:00
// 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback().
2022-01-10 23:59:31 +08:00
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
2022-01-05 23:54:03 +08:00
// 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API.
2021-08-03 02:17:26 +08:00
// 2021-08-17: *BREAKING CHANGE*: Now using glfwSetWindowFocusCallback() to calling io.AddFocusEvent(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() and forward it to the backend via ImGui_ImplGlfw_WindowFocusCallback().
// 2021-07-29: *BREAKING CHANGE*: Now using glfwSetCursorEnterCallback(). MousePos is correctly reported when the host platform window is hovered but not focused. If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() callback and forward it to the backend via ImGui_ImplGlfw_CursorEnterCallback().
2021-06-28 22:52:10 +08:00
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
2020-01-17 18:36:56 +08:00
// 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and it generates errors.
2019-12-05 22:43:05 +08:00
// 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, not allowed cursor).
2019-10-18 22:25:18 +08:00
// 2019-10-18: Misc: Previously installed user callbacks are now restored on shutdown.
2019-07-22 09:39:50 +08:00
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
2019-05-11 16:33:56 +08:00
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
2019-03-13 01:27:14 +08:00
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
2018-12-01 01:18:15 +08:00
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
2018-11-08 23:24:41 +08:00
// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them.
2018-08-01 17:34:17 +08:00
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
2018-06-29 22:30:41 +08:00
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
2018-06-09 01:37:33 +08:00
// 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples.
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value, passed to glfwSetCursor()).
// 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-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set.
// 2018-01-25: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
// 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"
2023-07-13 17:27:52 +08:00
# ifndef IMGUI_DISABLE
2018-06-09 01:37:33 +08:00
# include "imgui_impl_glfw.h"
2021-12-29 19:41:34 +08:00
// Clang warnings with -Weverything
# if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
# pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
# endif
2018-06-09 01:37:33 +08:00
// GLFW
# include <GLFW/glfw3.h>
2023-02-07 19:24:42 +08:00
2018-06-09 01:37:33 +08:00
# ifdef _WIN32
# undef APIENTRY
2024-04-30 01:24:17 +08:00
# ifndef GLFW_EXPOSE_NATIVE_WIN32
2018-06-09 01:37:33 +08:00
# define GLFW_EXPOSE_NATIVE_WIN32
2024-04-30 01:24:17 +08:00
# endif
2023-02-07 19:24:42 +08:00
# include <GLFW/glfw3native.h> // for glfwGetWin32Window()
# endif
# ifdef __APPLE__
2024-04-30 01:24:17 +08:00
# ifndef GLFW_EXPOSE_NATIVE_COCOA
2023-02-07 19:24:42 +08:00
# define GLFW_EXPOSE_NATIVE_COCOA
2024-04-30 01:24:17 +08:00
# endif
2023-02-07 19:24:42 +08:00
# include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
2018-06-09 01:37:33 +08:00
# endif
2024-07-31 23:33:24 +08:00
# ifndef _WIN32
# include <unistd.h> // for usleep()
# endif
2022-10-18 18:17:59 +08:00
2023-02-03 22:00:41 +08:00
# ifdef __EMSCRIPTEN__
# include <emscripten.h>
# include <emscripten/html5.h>
2024-07-09 04:04:27 +08:00
# ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
# include <GLFW/emscripten_glfw3.h>
# else
# define EMSCRIPTEN_USE_EMBEDDED_GLFW3
# endif
2023-02-03 22:00:41 +08:00
# endif
2022-10-18 18:17:59 +08:00
// We gather version tests as define in order to easily see which features are version-dependent.
# define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION)
# ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
# define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
2019-12-06 22:08:04 +08:00
# else
2022-10-18 18:17:59 +08:00
# define GLFW_HAS_NEW_CURSORS (0)
2019-12-06 22:08:04 +08:00
# endif
2022-10-18 18:17:59 +08:00
# define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
# define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
2023-03-14 22:56:38 +08:00
# define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
2018-06-09 01:37:33 +08:00
2021-06-28 22:52:10 +08:00
// GLFW data
2018-06-09 01:37:33 +08:00
enum GlfwClientApi
{
GlfwClientApi_Unknown ,
GlfwClientApi_OpenGL ,
2024-01-24 22:15:15 +08:00
GlfwClientApi_Vulkan ,
2018-06-09 01:37:33 +08:00
} ;
2021-06-28 22:52:10 +08:00
struct ImGui_ImplGlfw_Data
{
GLFWwindow * Window ;
GlfwClientApi ClientApi ;
double Time ;
2021-07-30 00:59:45 +08:00
GLFWwindow * MouseWindow ;
2021-06-28 22:52:10 +08:00
GLFWcursor * MouseCursors [ ImGuiMouseCursor_COUNT ] ;
2022-02-07 23:00:13 +08:00
ImVec2 LastValidMousePos ;
2021-06-28 22:52:10 +08:00
bool InstalledCallbacks ;
2023-02-04 00:53:53 +08:00
bool CallbacksChainForAllWindows ;
2024-07-09 04:23:26 +08:00
# ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
2023-12-19 22:52:44 +08:00
const char * CanvasSelector ;
# endif
2021-06-28 22:52:10 +08:00
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
2021-08-03 02:17:26 +08:00
GLFWwindowfocusfun PrevUserCallbackWindowFocus ;
2022-01-13 00:08:37 +08:00
GLFWcursorposfun PrevUserCallbackCursorPos ;
2021-07-30 00:59:45 +08:00
GLFWcursorenterfun PrevUserCallbackCursorEnter ;
2021-06-28 22:52:10 +08:00
GLFWmousebuttonfun PrevUserCallbackMousebutton ;
GLFWscrollfun PrevUserCallbackScroll ;
GLFWkeyfun PrevUserCallbackKey ;
GLFWcharfun PrevUserCallbackChar ;
2021-07-07 20:12:48 +08:00
GLFWmonitorfun PrevUserCallbackMonitor ;
2023-04-05 01:43:51 +08:00
# ifdef _WIN32
2024-06-26 20:32:48 +08:00
WNDPROC PrevWndProc ;
2023-04-05 01:43:51 +08:00
# endif
2021-06-28 22:52:10 +08:00
2022-03-13 14:15:32 +08:00
ImGui_ImplGlfw_Data ( ) { memset ( ( void * ) this , 0 , sizeof ( * this ) ) ; }
2021-06-28 22:52:10 +08:00
} ;
2021-06-29 22:42:13 +08:00
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
2021-07-07 20:12:48 +08:00
// - Because glfwPollEvents() process all windows and some events may be called outside of it, you will need to register your own callbacks
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
2021-06-29 22:42:13 +08:00
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
2021-06-30 21:22:15 +08:00
static ImGui_ImplGlfw_Data * ImGui_ImplGlfw_GetBackendData ( )
{
2022-10-11 18:22:29 +08:00
return ImGui : : GetCurrentContext ( ) ? ( ImGui_ImplGlfw_Data * ) ImGui : : GetIO ( ) . BackendPlatformUserData : nullptr ;
2021-06-30 21:22:15 +08:00
}
2021-06-28 22:52:10 +08:00
// Functions
2024-09-19 20:09:45 +08:00
// Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey ( int keycode , int scancode )
2021-12-12 19:00:31 +08:00
{
2024-09-19 20:09:45 +08:00
IM_UNUSED ( scancode ) ;
switch ( keycode )
2021-12-12 19:00:31 +08:00
{
case GLFW_KEY_TAB : return ImGuiKey_Tab ;
case GLFW_KEY_LEFT : return ImGuiKey_LeftArrow ;
case GLFW_KEY_RIGHT : return ImGuiKey_RightArrow ;
case GLFW_KEY_UP : return ImGuiKey_UpArrow ;
case GLFW_KEY_DOWN : return ImGuiKey_DownArrow ;
case GLFW_KEY_PAGE_UP : return ImGuiKey_PageUp ;
case GLFW_KEY_PAGE_DOWN : return ImGuiKey_PageDown ;
case GLFW_KEY_HOME : return ImGuiKey_Home ;
case GLFW_KEY_END : return ImGuiKey_End ;
case GLFW_KEY_INSERT : return ImGuiKey_Insert ;
case GLFW_KEY_DELETE : return ImGuiKey_Delete ;
case GLFW_KEY_BACKSPACE : return ImGuiKey_Backspace ;
case GLFW_KEY_SPACE : return ImGuiKey_Space ;
case GLFW_KEY_ENTER : return ImGuiKey_Enter ;
case GLFW_KEY_ESCAPE : return ImGuiKey_Escape ;
case GLFW_KEY_APOSTROPHE : return ImGuiKey_Apostrophe ;
case GLFW_KEY_COMMA : return ImGuiKey_Comma ;
case GLFW_KEY_MINUS : return ImGuiKey_Minus ;
case GLFW_KEY_PERIOD : return ImGuiKey_Period ;
case GLFW_KEY_SLASH : return ImGuiKey_Slash ;
case GLFW_KEY_SEMICOLON : return ImGuiKey_Semicolon ;
case GLFW_KEY_EQUAL : return ImGuiKey_Equal ;
case GLFW_KEY_LEFT_BRACKET : return ImGuiKey_LeftBracket ;
case GLFW_KEY_BACKSLASH : return ImGuiKey_Backslash ;
case GLFW_KEY_RIGHT_BRACKET : return ImGuiKey_RightBracket ;
case GLFW_KEY_GRAVE_ACCENT : return ImGuiKey_GraveAccent ;
case GLFW_KEY_CAPS_LOCK : return ImGuiKey_CapsLock ;
case GLFW_KEY_SCROLL_LOCK : return ImGuiKey_ScrollLock ;
case GLFW_KEY_NUM_LOCK : return ImGuiKey_NumLock ;
case GLFW_KEY_PRINT_SCREEN : return ImGuiKey_PrintScreen ;
case GLFW_KEY_PAUSE : return ImGuiKey_Pause ;
case GLFW_KEY_KP_0 : return ImGuiKey_Keypad0 ;
case GLFW_KEY_KP_1 : return ImGuiKey_Keypad1 ;
case GLFW_KEY_KP_2 : return ImGuiKey_Keypad2 ;
case GLFW_KEY_KP_3 : return ImGuiKey_Keypad3 ;
case GLFW_KEY_KP_4 : return ImGuiKey_Keypad4 ;
case GLFW_KEY_KP_5 : return ImGuiKey_Keypad5 ;
case GLFW_KEY_KP_6 : return ImGuiKey_Keypad6 ;
case GLFW_KEY_KP_7 : return ImGuiKey_Keypad7 ;
case GLFW_KEY_KP_8 : return ImGuiKey_Keypad8 ;
case GLFW_KEY_KP_9 : return ImGuiKey_Keypad9 ;
case GLFW_KEY_KP_DECIMAL : return ImGuiKey_KeypadDecimal ;
case GLFW_KEY_KP_DIVIDE : return ImGuiKey_KeypadDivide ;
case GLFW_KEY_KP_MULTIPLY : return ImGuiKey_KeypadMultiply ;
case GLFW_KEY_KP_SUBTRACT : return ImGuiKey_KeypadSubtract ;
case GLFW_KEY_KP_ADD : return ImGuiKey_KeypadAdd ;
case GLFW_KEY_KP_ENTER : return ImGuiKey_KeypadEnter ;
case GLFW_KEY_KP_EQUAL : return ImGuiKey_KeypadEqual ;
case GLFW_KEY_LEFT_SHIFT : return ImGuiKey_LeftShift ;
2022-01-17 22:41:04 +08:00
case GLFW_KEY_LEFT_CONTROL : return ImGuiKey_LeftCtrl ;
2021-12-12 19:00:31 +08:00
case GLFW_KEY_LEFT_ALT : return ImGuiKey_LeftAlt ;
case GLFW_KEY_LEFT_SUPER : return ImGuiKey_LeftSuper ;
case GLFW_KEY_RIGHT_SHIFT : return ImGuiKey_RightShift ;
2022-01-17 22:41:04 +08:00
case GLFW_KEY_RIGHT_CONTROL : return ImGuiKey_RightCtrl ;
2021-12-12 19:00:31 +08:00
case GLFW_KEY_RIGHT_ALT : return ImGuiKey_RightAlt ;
case GLFW_KEY_RIGHT_SUPER : return ImGuiKey_RightSuper ;
case GLFW_KEY_MENU : return ImGuiKey_Menu ;
case GLFW_KEY_0 : return ImGuiKey_0 ;
case GLFW_KEY_1 : return ImGuiKey_1 ;
case GLFW_KEY_2 : return ImGuiKey_2 ;
case GLFW_KEY_3 : return ImGuiKey_3 ;
case GLFW_KEY_4 : return ImGuiKey_4 ;
case GLFW_KEY_5 : return ImGuiKey_5 ;
case GLFW_KEY_6 : return ImGuiKey_6 ;
case GLFW_KEY_7 : return ImGuiKey_7 ;
case GLFW_KEY_8 : return ImGuiKey_8 ;
case GLFW_KEY_9 : return ImGuiKey_9 ;
case GLFW_KEY_A : return ImGuiKey_A ;
case GLFW_KEY_B : return ImGuiKey_B ;
case GLFW_KEY_C : return ImGuiKey_C ;
case GLFW_KEY_D : return ImGuiKey_D ;
case GLFW_KEY_E : return ImGuiKey_E ;
case GLFW_KEY_F : return ImGuiKey_F ;
case GLFW_KEY_G : return ImGuiKey_G ;
case GLFW_KEY_H : return ImGuiKey_H ;
case GLFW_KEY_I : return ImGuiKey_I ;
case GLFW_KEY_J : return ImGuiKey_J ;
case GLFW_KEY_K : return ImGuiKey_K ;
case GLFW_KEY_L : return ImGuiKey_L ;
case GLFW_KEY_M : return ImGuiKey_M ;
case GLFW_KEY_N : return ImGuiKey_N ;
case GLFW_KEY_O : return ImGuiKey_O ;
case GLFW_KEY_P : return ImGuiKey_P ;
case GLFW_KEY_Q : return ImGuiKey_Q ;
case GLFW_KEY_R : return ImGuiKey_R ;
case GLFW_KEY_S : return ImGuiKey_S ;
case GLFW_KEY_T : return ImGuiKey_T ;
case GLFW_KEY_U : return ImGuiKey_U ;
case GLFW_KEY_V : return ImGuiKey_V ;
case GLFW_KEY_W : return ImGuiKey_W ;
case GLFW_KEY_X : return ImGuiKey_X ;
case GLFW_KEY_Y : return ImGuiKey_Y ;
case GLFW_KEY_Z : return ImGuiKey_Z ;
case GLFW_KEY_F1 : return ImGuiKey_F1 ;
case GLFW_KEY_F2 : return ImGuiKey_F2 ;
case GLFW_KEY_F3 : return ImGuiKey_F3 ;
case GLFW_KEY_F4 : return ImGuiKey_F4 ;
case GLFW_KEY_F5 : return ImGuiKey_F5 ;
case GLFW_KEY_F6 : return ImGuiKey_F6 ;
case GLFW_KEY_F7 : return ImGuiKey_F7 ;
case GLFW_KEY_F8 : return ImGuiKey_F8 ;
case GLFW_KEY_F9 : return ImGuiKey_F9 ;
case GLFW_KEY_F10 : return ImGuiKey_F10 ;
case GLFW_KEY_F11 : return ImGuiKey_F11 ;
case GLFW_KEY_F12 : return ImGuiKey_F12 ;
2023-10-06 02:39:49 +08:00
case GLFW_KEY_F13 : return ImGuiKey_F13 ;
case GLFW_KEY_F14 : return ImGuiKey_F14 ;
case GLFW_KEY_F15 : return ImGuiKey_F15 ;
case GLFW_KEY_F16 : return ImGuiKey_F16 ;
case GLFW_KEY_F17 : return ImGuiKey_F17 ;
case GLFW_KEY_F18 : return ImGuiKey_F18 ;
case GLFW_KEY_F19 : return ImGuiKey_F19 ;
case GLFW_KEY_F20 : return ImGuiKey_F20 ;
case GLFW_KEY_F21 : return ImGuiKey_F21 ;
case GLFW_KEY_F22 : return ImGuiKey_F22 ;
case GLFW_KEY_F23 : return ImGuiKey_F23 ;
case GLFW_KEY_F24 : return ImGuiKey_F24 ;
2021-12-12 19:00:31 +08:00
default : return ImGuiKey_None ;
}
}
2023-01-04 22:42:20 +08:00
// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
2023-03-16 18:58:32 +08:00
static void ImGui_ImplGlfw_UpdateKeyModifiers ( GLFWwindow * window )
2022-01-17 21:57:55 +08:00
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2023-03-16 18:58:32 +08:00
io . AddKeyEvent ( ImGuiMod_Ctrl , ( glfwGetKey ( window , GLFW_KEY_LEFT_CONTROL ) = = GLFW_PRESS ) | | ( glfwGetKey ( window , GLFW_KEY_RIGHT_CONTROL ) = = GLFW_PRESS ) ) ;
io . AddKeyEvent ( ImGuiMod_Shift , ( glfwGetKey ( window , GLFW_KEY_LEFT_SHIFT ) = = GLFW_PRESS ) | | ( glfwGetKey ( window , GLFW_KEY_RIGHT_SHIFT ) = = GLFW_PRESS ) ) ;
io . AddKeyEvent ( ImGuiMod_Alt , ( glfwGetKey ( window , GLFW_KEY_LEFT_ALT ) = = GLFW_PRESS ) | | ( glfwGetKey ( window , GLFW_KEY_RIGHT_ALT ) = = GLFW_PRESS ) ) ;
io . AddKeyEvent ( ImGuiMod_Super , ( glfwGetKey ( window , GLFW_KEY_LEFT_SUPER ) = = GLFW_PRESS ) | | ( glfwGetKey ( window , GLFW_KEY_RIGHT_SUPER ) = = GLFW_PRESS ) ) ;
2022-01-17 21:57:55 +08:00
}
2023-02-04 00:53:53 +08:00
static bool ImGui_ImplGlfw_ShouldChainCallback ( GLFWwindow * window )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
return bd - > CallbacksChainForAllWindows ? true : ( window = = bd - > Window ) ;
}
2018-11-08 23:24:41 +08:00
void ImGui_ImplGlfw_MouseButtonCallback ( GLFWwindow * window , int button , int action , int mods )
2018-06-09 01:37:33 +08:00
{
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackMousebutton ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2021-06-28 22:52:10 +08:00
bd - > PrevUserCallbackMousebutton ( window , button , action , mods ) ;
2018-11-08 23:24:41 +08:00
2023-03-16 18:58:32 +08:00
ImGui_ImplGlfw_UpdateKeyModifiers ( window ) ;
2022-01-18 00:22:37 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
if ( button > = 0 & & button < ImGuiMouseButton_COUNT )
io . AddMouseButtonEvent ( button , action = = GLFW_PRESS ) ;
2018-06-09 01:37:33 +08:00
}
2018-11-08 23:24:41 +08:00
void ImGui_ImplGlfw_ScrollCallback ( GLFWwindow * window , double xoffset , double yoffset )
2018-06-09 01:37:33 +08:00
{
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackScroll ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2021-06-28 22:52:10 +08:00
bd - > PrevUserCallbackScroll ( window , xoffset , yoffset ) ;
2018-11-08 23:24:41 +08:00
2024-07-09 04:04:27 +08:00
# ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
2023-02-03 22:00:41 +08:00
// Ignore GLFW events: will be processed in ImGui_ImplEmscripten_WheelCallback().
return ;
2023-02-03 01:33:04 +08:00
# endif
2018-06-09 01:37:33 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2022-01-18 00:22:37 +08:00
io . AddMouseWheelEvent ( ( float ) xoffset , ( float ) yoffset ) ;
2018-06-09 01:37:33 +08:00
}
2024-09-19 20:09:45 +08:00
// FIXME: should this be baked into ImGui_ImplGlfw_KeyToImGuiKey()? then what about the values passed to io.SetKeyEventNativeData()?
2021-12-12 19:00:31 +08:00
static int ImGui_ImplGlfw_TranslateUntranslatedKey ( int key , int scancode )
2018-06-09 01:37:33 +08:00
{
2024-07-09 04:04:27 +08:00
# if GLFW_HAS_GETKEYNAME && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
2022-01-05 23:54:03 +08:00
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
// See https://github.com/glfw/glfw/issues/1502 for details.
// Adding a workaround to undo this (so our keys are translated->untranslated->translated, likely a lossy process).
// This won't cover edge cases but this is at least going to cover common cases.
2022-02-01 22:27:10 +08:00
if ( key > = GLFW_KEY_KP_0 & & key < = GLFW_KEY_KP_EQUAL )
return key ;
2022-11-23 01:08:25 +08:00
GLFWerrorfun prev_error_callback = glfwSetErrorCallback ( nullptr ) ;
2022-01-05 23:54:03 +08:00
const char * key_name = glfwGetKeyName ( key , scancode ) ;
2022-11-23 01:08:25 +08:00
glfwSetErrorCallback ( prev_error_callback ) ;
2024-07-09 04:04:27 +08:00
# if GLFW_HAS_GETERROR && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) // Eat errors (see #5908)
2023-04-11 17:25:14 +08:00
( void ) glfwGetError ( nullptr ) ;
2022-11-23 01:08:25 +08:00
# endif
2022-01-05 23:54:03 +08:00
if ( key_name & & key_name [ 0 ] ! = 0 & & key_name [ 1 ] = = 0 )
{
2022-01-24 20:45:47 +08:00
const char char_names [ ] = " `-=[] \\ ,; \' ./ " ;
2022-01-05 23:54:03 +08:00
const int char_keys [ ] = { GLFW_KEY_GRAVE_ACCENT , GLFW_KEY_MINUS , GLFW_KEY_EQUAL , GLFW_KEY_LEFT_BRACKET , GLFW_KEY_RIGHT_BRACKET , GLFW_KEY_BACKSLASH , GLFW_KEY_COMMA , GLFW_KEY_SEMICOLON , GLFW_KEY_APOSTROPHE , GLFW_KEY_PERIOD , GLFW_KEY_SLASH , 0 } ;
IM_ASSERT ( IM_ARRAYSIZE ( char_names ) = = IM_ARRAYSIZE ( char_keys ) ) ;
if ( key_name [ 0 ] > = ' 0 ' & & key_name [ 0 ] < = ' 9 ' ) { key = GLFW_KEY_0 + ( key_name [ 0 ] - ' 0 ' ) ; }
else if ( key_name [ 0 ] > = ' A ' & & key_name [ 0 ] < = ' Z ' ) { key = GLFW_KEY_A + ( key_name [ 0 ] - ' A ' ) ; }
2022-04-30 15:21:04 +08:00
else if ( key_name [ 0 ] > = ' a ' & & key_name [ 0 ] < = ' z ' ) { key = GLFW_KEY_A + ( key_name [ 0 ] - ' a ' ) ; }
2022-01-05 23:54:03 +08:00
else if ( const char * p = strchr ( char_names , key_name [ 0 ] ) ) { key = char_keys [ p - char_names ] ; }
}
// if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name);
2022-01-14 12:47:53 +08:00
# else
IM_UNUSED ( scancode ) ;
2022-01-05 23:54:03 +08:00
# endif
2021-12-12 19:00:31 +08:00
return key ;
}
2022-01-05 23:54:03 +08:00
2021-12-12 19:00:31 +08:00
void ImGui_ImplGlfw_KeyCallback ( GLFWwindow * window , int keycode , int scancode , int action , int mods )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackKey ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2021-12-12 19:00:31 +08:00
bd - > PrevUserCallbackKey ( window , keycode , scancode , action , mods ) ;
2018-06-09 01:37:33 +08:00
2021-12-12 19:00:31 +08:00
if ( action ! = GLFW_PRESS & & action ! = GLFW_RELEASE )
return ;
2023-03-16 18:58:32 +08:00
ImGui_ImplGlfw_UpdateKeyModifiers ( window ) ;
2022-01-17 21:57:55 +08:00
2021-12-12 19:00:31 +08:00
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey ( keycode , scancode ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
2024-09-19 20:09:45 +08:00
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey ( keycode , scancode ) ;
2021-12-12 19:00:31 +08:00
io . AddKeyEvent ( imgui_key , ( action = = GLFW_PRESS ) ) ;
io . SetKeyEventNativeData ( imgui_key , keycode , scancode ) ; // To support legacy indexing (<1.87 user code)
2018-06-09 01:37:33 +08:00
}
2021-08-03 02:17:26 +08:00
void ImGui_ImplGlfw_WindowFocusCallback ( GLFWwindow * window , int focused )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackWindowFocus ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2021-08-03 02:17:26 +08:00
bd - > PrevUserCallbackWindowFocus ( window , focused ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . AddFocusEvent ( focused ! = 0 ) ;
}
2022-01-13 00:08:37 +08:00
void ImGui_ImplGlfw_CursorPosCallback ( GLFWwindow * window , double x , double y )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackCursorPos ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2022-01-13 00:08:37 +08:00
bd - > PrevUserCallbackCursorPos ( window , x , y ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
2022-01-18 00:22:37 +08:00
io . AddMousePosEvent ( ( float ) x , ( float ) y ) ;
2022-02-07 23:00:13 +08:00
bd - > LastValidMousePos = ImVec2 ( ( float ) x , ( float ) y ) ;
2022-01-13 00:08:37 +08:00
}
2022-02-07 22:59:28 +08:00
// Workaround: X11 seems to send spurious Leave/Enter events which would make us lose our position,
// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984)
2021-07-30 00:59:45 +08:00
void ImGui_ImplGlfw_CursorEnterCallback ( GLFWwindow * window , int entered )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackCursorEnter ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2021-07-30 00:59:45 +08:00
bd - > PrevUserCallbackCursorEnter ( window , entered ) ;
2021-08-03 02:17:26 +08:00
2022-01-13 00:08:37 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-07-30 00:59:45 +08:00
if ( entered )
2022-02-07 22:59:28 +08:00
{
2021-07-30 00:59:45 +08:00
bd - > MouseWindow = window ;
2022-02-07 23:00:13 +08:00
io . AddMousePosEvent ( bd - > LastValidMousePos . x , bd - > LastValidMousePos . y ) ;
2022-02-07 22:59:28 +08:00
}
else if ( ! entered & & bd - > MouseWindow = = window )
2022-01-13 00:08:37 +08:00
{
2022-02-07 23:00:13 +08:00
bd - > LastValidMousePos = io . MousePos ;
2022-10-11 18:22:29 +08:00
bd - > MouseWindow = nullptr ;
2022-01-18 00:22:37 +08:00
io . AddMousePosEvent ( - FLT_MAX , - FLT_MAX ) ;
2022-01-13 00:08:37 +08:00
}
2021-07-30 00:59:45 +08:00
}
2018-11-08 23:24:41 +08:00
void ImGui_ImplGlfw_CharCallback ( GLFWwindow * window , unsigned int c )
2018-06-09 01:37:33 +08:00
{
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2023-02-04 00:53:53 +08:00
if ( bd - > PrevUserCallbackChar ! = nullptr & & ImGui_ImplGlfw_ShouldChainCallback ( window ) )
2021-06-28 22:52:10 +08:00
bd - > PrevUserCallbackChar ( window , c ) ;
2018-11-08 23:24:41 +08:00
2018-06-09 01:37:33 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2019-05-11 16:33:56 +08:00
io . AddInputCharacter ( c ) ;
2018-06-09 01:37:33 +08:00
}
2021-07-07 20:12:48 +08:00
void ImGui_ImplGlfw_MonitorCallback ( GLFWmonitor * , int )
{
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
}
2024-07-09 04:04:27 +08:00
# ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
2023-02-03 22:00:41 +08:00
static EM_BOOL ImGui_ImplEmscripten_WheelCallback ( int , const EmscriptenWheelEvent * ev , void * )
{
// Mimic Emscripten_HandleWheel() in SDL.
// Corresponding equivalent in GLFW JS emulation layer has incorrect quantizing preventing small values. See #6096
float multiplier = 0.0f ;
if ( ev - > deltaMode = = DOM_DELTA_PIXEL ) { multiplier = 1.0f / 100.0f ; } // 100 pixels make up a step.
else if ( ev - > deltaMode = = DOM_DELTA_LINE ) { multiplier = 1.0f / 3.0f ; } // 3 lines make up a step.
else if ( ev - > deltaMode = = DOM_DELTA_PAGE ) { multiplier = 80.0f ; } // A page makes up 80 steps.
float wheel_x = ev - > deltaX * - multiplier ;
float wheel_y = ev - > deltaY * - multiplier ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . AddMouseWheelEvent ( wheel_x , wheel_y ) ;
//IMGUI_DEBUG_LOG("[Emsc] mode %d dx: %.2f, dy: %.2f, dz: %.2f --> feed %.2f %.2f\n", (int)ev->deltaMode, ev->deltaX, ev->deltaY, ev->deltaZ, wheel_x, wheel_y);
return EM_TRUE ;
}
# endif
2023-04-05 01:43:51 +08:00
# ifdef _WIN32
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo ( )
{
LPARAM extra_info = : : GetMessageExtraInfo ( ) ;
if ( ( extra_info & 0xFFFFFF80 ) = = 0xFF515700 )
return ImGuiMouseSource_Pen ;
if ( ( extra_info & 0xFFFFFF80 ) = = 0xFF515780 )
return ImGuiMouseSource_TouchScreen ;
return ImGuiMouseSource_Mouse ;
}
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc ( HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
switch ( msg )
{
case WM_MOUSEMOVE : case WM_NCMOUSEMOVE :
case WM_LBUTTONDOWN : case WM_LBUTTONDBLCLK : case WM_LBUTTONUP :
case WM_RBUTTONDOWN : case WM_RBUTTONDBLCLK : case WM_RBUTTONUP :
case WM_MBUTTONDOWN : case WM_MBUTTONDBLCLK : case WM_MBUTTONUP :
case WM_XBUTTONDOWN : case WM_XBUTTONDBLCLK : case WM_XBUTTONUP :
ImGui : : GetIO ( ) . AddMouseSourceEvent ( GetMouseSourceFromMessageExtraInfo ( ) ) ;
break ;
}
2024-06-26 20:32:48 +08:00
return : : CallWindowProcW ( bd - > PrevWndProc , hWnd , msg , wParam , lParam ) ;
2023-04-05 01:43:51 +08:00
}
# endif
2022-02-07 23:00:13 +08:00
void ImGui_ImplGlfw_InstallCallbacks ( GLFWwindow * window )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
IM_ASSERT ( bd - > InstalledCallbacks = = false & & " Callbacks already installed! " ) ;
IM_ASSERT ( bd - > Window = = window ) ;
bd - > PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback ( window , ImGui_ImplGlfw_WindowFocusCallback ) ;
bd - > PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback ( window , ImGui_ImplGlfw_CursorEnterCallback ) ;
bd - > PrevUserCallbackCursorPos = glfwSetCursorPosCallback ( window , ImGui_ImplGlfw_CursorPosCallback ) ;
bd - > PrevUserCallbackMousebutton = glfwSetMouseButtonCallback ( window , ImGui_ImplGlfw_MouseButtonCallback ) ;
bd - > PrevUserCallbackScroll = glfwSetScrollCallback ( window , ImGui_ImplGlfw_ScrollCallback ) ;
bd - > PrevUserCallbackKey = glfwSetKeyCallback ( window , ImGui_ImplGlfw_KeyCallback ) ;
bd - > PrevUserCallbackChar = glfwSetCharCallback ( window , ImGui_ImplGlfw_CharCallback ) ;
bd - > PrevUserCallbackMonitor = glfwSetMonitorCallback ( ImGui_ImplGlfw_MonitorCallback ) ;
bd - > InstalledCallbacks = true ;
}
void ImGui_ImplGlfw_RestoreCallbacks ( GLFWwindow * window )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
IM_ASSERT ( bd - > InstalledCallbacks = = true & & " Callbacks not installed! " ) ;
IM_ASSERT ( bd - > Window = = window ) ;
glfwSetWindowFocusCallback ( window , bd - > PrevUserCallbackWindowFocus ) ;
glfwSetCursorEnterCallback ( window , bd - > PrevUserCallbackCursorEnter ) ;
glfwSetCursorPosCallback ( window , bd - > PrevUserCallbackCursorPos ) ;
glfwSetMouseButtonCallback ( window , bd - > PrevUserCallbackMousebutton ) ;
glfwSetScrollCallback ( window , bd - > PrevUserCallbackScroll ) ;
glfwSetKeyCallback ( window , bd - > PrevUserCallbackKey ) ;
glfwSetCharCallback ( window , bd - > PrevUserCallbackChar ) ;
glfwSetMonitorCallback ( bd - > PrevUserCallbackMonitor ) ;
bd - > InstalledCallbacks = false ;
2022-10-11 18:22:29 +08:00
bd - > PrevUserCallbackWindowFocus = nullptr ;
bd - > PrevUserCallbackCursorEnter = nullptr ;
bd - > PrevUserCallbackCursorPos = nullptr ;
bd - > PrevUserCallbackMousebutton = nullptr ;
bd - > PrevUserCallbackScroll = nullptr ;
bd - > PrevUserCallbackKey = nullptr ;
bd - > PrevUserCallbackChar = nullptr ;
bd - > PrevUserCallbackMonitor = nullptr ;
2022-02-07 23:00:13 +08:00
}
2023-02-04 00:53:53 +08:00
// Set to 'true' to enable chaining installed callbacks for all windows (including secondary viewports created by backends or by user.
// This is 'false' by default meaning we only chain callbacks for the main viewport.
// We cannot set this to 'true' by default because user callbacks code may be not testing the 'window' parameter of their callback.
// If you set this to 'true' your user callback code will need to make sure you are testing the 'window' parameter.
void ImGui_ImplGlfw_SetCallbacksChainForAllWindows ( bool chain_for_all_windows )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
bd - > CallbacksChainForAllWindows = chain_for_all_windows ;
}
2024-07-03 00:06:19 +08:00
# ifdef __EMSCRIPTEN__
2024-09-08 01:22:45 +08:00
# if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
2024-08-24 00:56:02 +08:00
void ImGui_ImplGlfw_EmscriptenOpenURL ( const char * url ) { if ( url ) emscripten : : glfw3 : : OpenURL ( url ) ; }
# else
EM_JS ( void , ImGui_ImplGlfw_EmscriptenOpenURL , ( const char * url ) , { url = url ? UTF8ToString ( url ) : null ; if ( url ) window . open ( url , ' _blank ' ) ; } ) ;
# endif
2024-07-03 00:06:19 +08:00
# endif
2018-06-09 01:37:33 +08:00
static bool ImGui_ImplGlfw_Init ( GLFWwindow * window , bool install_callbacks , GlfwClientApi client_api )
{
2021-06-28 22:52:10 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2024-05-13 21:07:13 +08:00
IMGUI_CHECKVERSION ( ) ;
2022-10-11 18:22:29 +08:00
IM_ASSERT ( io . BackendPlatformUserData = = nullptr & & " Already initialized a platform backend! " ) ;
2022-10-18 18:17:59 +08:00
//printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED);
2021-06-28 22:52:10 +08:00
2020-10-12 23:34:22 +08:00
// Setup backend capabilities flags
2021-06-30 21:22:15 +08:00
ImGui_ImplGlfw_Data * bd = IM_NEW ( ImGui_ImplGlfw_Data ) ( ) ;
2021-06-28 22:52:10 +08:00
io . BackendPlatformUserData = ( void * ) bd ;
io . BackendPlatformName = " imgui_impl_glfw " ;
2018-06-09 01:37:33 +08:00
io . BackendFlags | = ImGuiBackendFlags_HasMouseCursors ; // We can honor GetMouseCursor() values (optional)
io . BackendFlags | = ImGuiBackendFlags_HasSetMousePos ; // We can honor io.WantSetMousePos requests (optional, rarely used)
2021-06-30 21:22:15 +08:00
bd - > Window = window ;
bd - > Time = 0.0 ;
2024-08-22 22:42:57 +08:00
ImGuiPlatformIO & platform_io = ImGui : : GetPlatformIO ( ) ;
2024-08-23 02:27:50 +08:00
platform_io . Platform_SetClipboardTextFn = [ ] ( ImGuiContext * , const char * text ) { glfwSetClipboardString ( NULL , text ) ; } ;
platform_io . Platform_GetClipboardTextFn = [ ] ( ImGuiContext * ) { return glfwGetClipboardString ( NULL ) ; } ;
2024-07-03 00:06:19 +08:00
# ifdef __EMSCRIPTEN__
2024-08-22 22:42:57 +08:00
platform_io . Platform_OpenInShellFn = [ ] ( ImGuiContext * , const char * url ) { ImGui_ImplGlfw_EmscriptenOpenURL ( url ) ; return true ; } ;
2024-07-03 00:06:19 +08:00
# endif
2022-01-05 20:03:48 +08:00
2020-01-17 18:36:56 +08:00
// Create mouse cursors
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
// GLFW will emit an error which will often be printed by the app, so we temporarily disable error reporting.
2022-10-11 18:22:29 +08:00
// Missing cursors will return nullptr and our _UpdateMouseCursor() function will use the Arrow cursor instead.)
GLFWerrorfun prev_error_callback = glfwSetErrorCallback ( nullptr ) ;
2021-06-28 22:52:10 +08:00
bd - > MouseCursors [ ImGuiMouseCursor_Arrow ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_TextInput ] = glfwCreateStandardCursor ( GLFW_IBEAM_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNS ] = glfwCreateStandardCursor ( GLFW_VRESIZE_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeEW ] = glfwCreateStandardCursor ( GLFW_HRESIZE_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_Hand ] = glfwCreateStandardCursor ( GLFW_HAND_CURSOR ) ;
2019-12-02 16:36:59 +08:00
# if GLFW_HAS_NEW_CURSORS
2021-06-28 22:52:10 +08:00
bd - > MouseCursors [ ImGuiMouseCursor_ResizeAll ] = glfwCreateStandardCursor ( GLFW_RESIZE_ALL_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNESW ] = glfwCreateStandardCursor ( GLFW_RESIZE_NESW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNWSE ] = glfwCreateStandardCursor ( GLFW_RESIZE_NWSE_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_NotAllowed ] = glfwCreateStandardCursor ( GLFW_NOT_ALLOWED_CURSOR ) ;
2019-12-02 16:36:59 +08:00
# else
2021-06-28 22:52:10 +08:00
bd - > MouseCursors [ ImGuiMouseCursor_ResizeAll ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNESW ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNWSE ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_NotAllowed ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
2022-10-18 18:17:59 +08:00
# endif
2022-11-23 01:08:25 +08:00
glfwSetErrorCallback ( prev_error_callback ) ;
2023-03-14 22:56:38 +08:00
# if GLFW_HAS_GETERROR && !defined(__EMSCRIPTEN__) // Eat errors (see #5908)
2023-04-11 17:25:14 +08:00
( void ) glfwGetError ( nullptr ) ;
2019-12-02 16:36:59 +08:00
# endif
2019-01-21 00:56:17 +08:00
2018-11-08 23:24:41 +08:00
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
2018-06-09 01:37:33 +08:00
if ( install_callbacks )
2022-02-07 23:00:13 +08:00
ImGui_ImplGlfw_InstallCallbacks ( window ) ;
2023-02-03 22:00:41 +08:00
2023-02-07 19:24:42 +08:00
// Set platform dependent data in viewport
ImGuiViewport * main_viewport = ImGui : : GetMainViewport ( ) ;
2024-06-26 20:32:48 +08:00
main_viewport - > PlatformHandle = ( void * ) bd - > Window ;
2023-02-07 19:24:42 +08:00
# ifdef _WIN32
main_viewport - > PlatformHandleRaw = glfwGetWin32Window ( bd - > Window ) ;
# elif defined(__APPLE__)
main_viewport - > PlatformHandleRaw = ( void * ) glfwGetCocoaWindow ( bd - > Window ) ;
2023-02-08 03:17:18 +08:00
# else
IM_UNUSED ( main_viewport ) ;
2023-02-07 19:24:42 +08:00
# endif
2023-04-05 01:43:51 +08:00
// Windows: register a WndProc hook so we can intercept some messages.
# ifdef _WIN32
2024-06-26 20:32:48 +08:00
bd - > PrevWndProc = ( WNDPROC ) : : GetWindowLongPtrW ( ( HWND ) main_viewport - > PlatformHandleRaw , GWLP_WNDPROC ) ;
IM_ASSERT ( bd - > PrevWndProc ! = nullptr ) ;
2023-12-28 12:17:28 +08:00
: : SetWindowLongPtrW ( ( HWND ) main_viewport - > PlatformHandleRaw , GWLP_WNDPROC , ( LONG_PTR ) ImGui_ImplGlfw_WndProc ) ;
2023-04-05 01:43:51 +08:00
# endif
2024-09-08 01:22:45 +08:00
// Emscripten: the same application can run on various platforms, so we detect the Apple platform at runtime
// to override io.ConfigMacOSXBehaviors from its default (which is always false in Emscripten).
2024-09-08 01:23:20 +08:00
# ifdef __EMSCRIPTEN__
2024-09-08 01:22:45 +08:00
# if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
if ( emscripten : : glfw3 : : IsRuntimePlatformApple ( ) )
{
ImGui : : GetIO ( ) . ConfigMacOSXBehaviors = true ;
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
// This means that Meta + V only registers a single key-press, even if the keys are held.
// This is a compromise for dealing with this issue in ImGui since ImGui implements key repeat itself.
// See https://github.com/pongasoft/emscripten-glfw/blob/v3.4.0.20240817/docs/Usage.md#the-problem-of-the-super-key
emscripten : : glfw3 : : SetSuperPlusKeyTimeouts ( 10 , 10 ) ;
}
2024-09-08 01:23:20 +08:00
# endif
2024-09-08 01:22:45 +08:00
# endif
2021-06-28 22:52:10 +08:00
bd - > ClientApi = client_api ;
2018-06-09 01:37:33 +08:00
return true ;
}
bool ImGui_ImplGlfw_InitForOpenGL ( GLFWwindow * window , bool install_callbacks )
{
return ImGui_ImplGlfw_Init ( window , install_callbacks , GlfwClientApi_OpenGL ) ;
}
bool ImGui_ImplGlfw_InitForVulkan ( GLFWwindow * window , bool install_callbacks )
{
return ImGui_ImplGlfw_Init ( window , install_callbacks , GlfwClientApi_Vulkan ) ;
}
2021-02-11 00:27:33 +08:00
bool ImGui_ImplGlfw_InitForOther ( GLFWwindow * window , bool install_callbacks )
2021-01-28 19:11:26 +08:00
{
2021-02-11 00:27:33 +08:00
return ImGui_ImplGlfw_Init ( window , install_callbacks , GlfwClientApi_Unknown ) ;
2021-01-28 19:11:26 +08:00
}
2018-06-09 01:37:33 +08:00
void ImGui_ImplGlfw_Shutdown ( )
{
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2022-10-11 18:22:29 +08:00
IM_ASSERT ( bd ! = nullptr & & " No platform backend to shutdown, or already shutdown? " ) ;
2021-09-21 00:43:05 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 22:52:10 +08:00
if ( bd - > InstalledCallbacks )
2022-02-07 23:00:13 +08:00
ImGui_ImplGlfw_RestoreCallbacks ( bd - > Window ) ;
2024-07-09 04:04:27 +08:00
# ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
2024-07-08 21:53:23 +08:00
if ( bd - > CanvasSelector )
emscripten_set_wheel_callback ( bd - > CanvasSelector , nullptr , false , nullptr ) ;
2023-09-06 17:41:19 +08:00
# endif
2019-10-18 22:25:18 +08:00
2018-06-20 17:06:29 +08:00
for ( ImGuiMouseCursor cursor_n = 0 ; cursor_n < ImGuiMouseCursor_COUNT ; cursor_n + + )
2021-06-28 22:52:10 +08:00
glfwDestroyCursor ( bd - > MouseCursors [ cursor_n ] ) ;
2024-06-26 20:32:48 +08:00
// Windows: restore our WndProc hook
2023-04-05 01:43:51 +08:00
# ifdef _WIN32
ImGuiViewport * main_viewport = ImGui : : GetMainViewport ( ) ;
2024-06-26 20:32:48 +08:00
: : SetWindowLongPtrW ( ( HWND ) main_viewport - > PlatformHandleRaw , GWLP_WNDPROC , ( LONG_PTR ) bd - > PrevWndProc ) ;
bd - > PrevWndProc = nullptr ;
2023-04-05 01:43:51 +08:00
# endif
2022-10-11 18:22:29 +08:00
io . BackendPlatformName = nullptr ;
io . BackendPlatformUserData = nullptr ;
2023-04-17 20:47:15 +08:00
io . BackendFlags & = ~ ( ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad ) ;
2021-06-30 21:22:15 +08:00
IM_DELETE ( bd ) ;
2018-06-09 01:37:33 +08:00
}
2022-01-13 00:08:37 +08:00
static void ImGui_ImplGlfw_UpdateMouseData ( )
2018-06-09 01:37:33 +08:00
{
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2018-06-09 01:37:33 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-08-02 21:48:20 +08:00
2023-02-07 19:24:42 +08:00
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
{
GLFWwindow * window = bd - > Window ;
2024-07-09 04:04:27 +08:00
# ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
2023-02-07 19:24:42 +08:00
const bool is_window_focused = true ;
2018-08-01 17:34:17 +08:00
# else
2023-02-07 19:24:42 +08:00
const bool is_window_focused = glfwGetWindowAttrib ( window , GLFW_FOCUSED ) ! = 0 ;
2018-08-01 17:34:17 +08:00
# endif
2023-02-07 19:24:42 +08:00
if ( is_window_focused )
2022-01-13 00:08:37 +08:00
{
2023-02-07 19:24:42 +08:00
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if ( io . WantSetMousePos )
glfwSetCursorPos ( window , ( double ) io . MousePos . x , ( double ) io . MousePos . y ) ;
// (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
if ( bd - > MouseWindow = = nullptr )
{
double mouse_x , mouse_y ;
glfwGetCursorPos ( window , & mouse_x , & mouse_y ) ;
bd - > LastValidMousePos = ImVec2 ( ( float ) mouse_x , ( float ) mouse_y ) ;
io . AddMousePosEvent ( ( float ) mouse_x , ( float ) mouse_y ) ;
}
2022-01-13 00:08:37 +08:00
}
}
2018-06-09 01:37:33 +08:00
}
static void ImGui_ImplGlfw_UpdateMouseCursor ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
if ( ( io . ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange ) | | glfwGetInputMode ( bd - > Window , GLFW_CURSOR ) = = GLFW_CURSOR_DISABLED )
2018-06-09 01:37:33 +08:00
return ;
ImGuiMouseCursor imgui_cursor = ImGui : : GetMouseCursor ( ) ;
2023-02-07 19:24:42 +08:00
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
2018-06-09 01:37:33 +08:00
{
2023-02-07 19:24:42 +08:00
GLFWwindow * window = bd - > Window ;
if ( imgui_cursor = = ImGuiMouseCursor_None | | io . MouseDrawCursor )
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
glfwSetInputMode ( window , GLFW_CURSOR , GLFW_CURSOR_HIDDEN ) ;
}
else
{
// Show OS mouse cursor
// FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
glfwSetCursor ( window , bd - > MouseCursors [ imgui_cursor ] ? bd - > MouseCursors [ imgui_cursor ] : bd - > MouseCursors [ ImGuiMouseCursor_Arrow ] ) ;
glfwSetInputMode ( window , GLFW_CURSOR , GLFW_CURSOR_NORMAL ) ;
}
2018-06-09 01:37:33 +08:00
}
}
2022-01-21 00:12:22 +08:00
// Update gamepad inputs
static inline float Saturate ( float v ) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v ; }
2019-02-15 01:55:08 +08:00
static void ImGui_ImplGlfw_UpdateGamepads ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2022-07-25 23:16:01 +08:00
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 ) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
2019-02-15 01:55:08 +08:00
return ;
2022-01-21 00:12:22 +08:00
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
2024-07-09 04:04:27 +08:00
# if GLFW_HAS_GAMEPAD_API && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
2022-01-21 00:12:22 +08:00
GLFWgamepadstate gamepad ;
if ( ! glfwGetGamepadState ( GLFW_JOYSTICK_1 , & gamepad ) )
return ;
2022-01-21 00:39:25 +08:00
# define MAP_BUTTON(KEY_NO, BUTTON_NO, _UNUSED) do { io.AddKeyEvent(KEY_NO, gamepad.buttons[BUTTON_NO] != 0); } while (0)
# define MAP_ANALOG(KEY_NO, AXIS_NO, _UNUSED, V0, V1) do { float v = gamepad.axes[AXIS_NO]; v = (v - V0) / (V1 - V0); io.AddKeyAnalogEvent(KEY_NO, v > 0.10f, Saturate(v)); } while (0)
2022-01-21 00:12:22 +08:00
# else
2019-02-15 01:55:08 +08:00
int axes_count = 0 , buttons_count = 0 ;
const float * axes = glfwGetJoystickAxes ( GLFW_JOYSTICK_1 , & axes_count ) ;
const unsigned char * buttons = glfwGetJoystickButtons ( GLFW_JOYSTICK_1 , & buttons_count ) ;
2022-01-21 00:12:22 +08:00
if ( axes_count = = 0 | | buttons_count = = 0 )
return ;
2022-01-21 00:39:25 +08:00
# define MAP_BUTTON(KEY_NO, _UNUSED, BUTTON_NO) do { io.AddKeyEvent(KEY_NO, (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS)); } while (0)
# define MAP_ANALOG(KEY_NO, _UNUSED, AXIS_NO, V0, V1) do { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); io.AddKeyAnalogEvent(KEY_NO, v > 0.10f, Saturate(v)); } while (0)
2022-01-21 00:12:22 +08:00
# endif
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
MAP_BUTTON ( ImGuiKey_GamepadStart , GLFW_GAMEPAD_BUTTON_START , 7 ) ;
MAP_BUTTON ( ImGuiKey_GamepadBack , GLFW_GAMEPAD_BUTTON_BACK , 6 ) ;
MAP_BUTTON ( ImGuiKey_GamepadFaceLeft , GLFW_GAMEPAD_BUTTON_X , 2 ) ; // Xbox X, PS Square
2022-07-06 23:13:10 +08:00
MAP_BUTTON ( ImGuiKey_GamepadFaceRight , GLFW_GAMEPAD_BUTTON_B , 1 ) ; // Xbox B, PS Circle
2022-01-21 00:12:22 +08:00
MAP_BUTTON ( ImGuiKey_GamepadFaceUp , GLFW_GAMEPAD_BUTTON_Y , 3 ) ; // Xbox Y, PS Triangle
2022-07-06 23:13:10 +08:00
MAP_BUTTON ( ImGuiKey_GamepadFaceDown , GLFW_GAMEPAD_BUTTON_A , 0 ) ; // Xbox A, PS Cross
2022-01-21 00:12:22 +08:00
MAP_BUTTON ( ImGuiKey_GamepadDpadLeft , GLFW_GAMEPAD_BUTTON_DPAD_LEFT , 13 ) ;
MAP_BUTTON ( ImGuiKey_GamepadDpadRight , GLFW_GAMEPAD_BUTTON_DPAD_RIGHT , 11 ) ;
MAP_BUTTON ( ImGuiKey_GamepadDpadUp , GLFW_GAMEPAD_BUTTON_DPAD_UP , 10 ) ;
MAP_BUTTON ( ImGuiKey_GamepadDpadDown , GLFW_GAMEPAD_BUTTON_DPAD_DOWN , 12 ) ;
MAP_BUTTON ( ImGuiKey_GamepadL1 , GLFW_GAMEPAD_BUTTON_LEFT_BUMPER , 4 ) ;
MAP_BUTTON ( ImGuiKey_GamepadR1 , GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER , 5 ) ;
MAP_ANALOG ( ImGuiKey_GamepadL2 , GLFW_GAMEPAD_AXIS_LEFT_TRIGGER , 4 , - 0.75f , + 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadR2 , GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER , 5 , - 0.75f , + 1.0f ) ;
MAP_BUTTON ( ImGuiKey_GamepadL3 , GLFW_GAMEPAD_BUTTON_LEFT_THUMB , 8 ) ;
MAP_BUTTON ( ImGuiKey_GamepadR3 , GLFW_GAMEPAD_BUTTON_RIGHT_THUMB , 9 ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickLeft , GLFW_GAMEPAD_AXIS_LEFT_X , 0 , - 0.25f , - 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickRight , GLFW_GAMEPAD_AXIS_LEFT_X , 0 , + 0.25f , + 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickUp , GLFW_GAMEPAD_AXIS_LEFT_Y , 1 , - 0.25f , - 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadLStickDown , GLFW_GAMEPAD_AXIS_LEFT_Y , 1 , + 0.25f , + 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickLeft , GLFW_GAMEPAD_AXIS_RIGHT_X , 2 , - 0.25f , - 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickRight , GLFW_GAMEPAD_AXIS_RIGHT_X , 2 , + 0.25f , + 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickUp , GLFW_GAMEPAD_AXIS_RIGHT_Y , 3 , - 0.25f , - 1.0f ) ;
MAP_ANALOG ( ImGuiKey_GamepadRStickDown , GLFW_GAMEPAD_AXIS_RIGHT_Y , 3 , + 0.25f , + 1.0f ) ;
2019-02-15 01:55:08 +08:00
# undef MAP_BUTTON
# undef MAP_ANALOG
}
2018-06-09 01:37:33 +08:00
void ImGui_ImplGlfw_NewFrame ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 22:52:10 +08:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2024-05-07 22:53:03 +08:00
IM_ASSERT ( bd ! = nullptr & & " Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()? " ) ;
2018-06-09 01:37:33 +08:00
2018-12-24 00:39:04 +08:00
// Setup display size (every frame to accommodate for window resizing)
2018-06-09 01:37:33 +08:00
int w , h ;
int display_w , display_h ;
2021-06-28 22:52:10 +08:00
glfwGetWindowSize ( bd - > Window , & w , & h ) ;
glfwGetFramebufferSize ( bd - > Window , & display_w , & display_h ) ;
2018-06-09 01:37:33 +08:00
io . DisplaySize = ImVec2 ( ( float ) w , ( float ) h ) ;
2019-03-13 01:27:14 +08:00
if ( w > 0 & & h > 0 )
2021-12-29 19:41:34 +08:00
io . DisplayFramebufferScale = ImVec2 ( ( float ) display_w / ( float ) w , ( float ) display_h / ( float ) h ) ;
2018-06-09 01:37:33 +08:00
// Setup time step
2023-06-12 17:58:17 +08:00
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
2018-06-09 01:37:33 +08:00
double current_time = glfwGetTime ( ) ;
2023-06-12 17:58:17 +08:00
if ( current_time < = bd - > Time )
current_time = bd - > Time + 0.00001f ;
2021-06-28 22:52:10 +08:00
io . DeltaTime = bd - > Time > 0.0 ? ( float ) ( current_time - bd - > Time ) : ( float ) ( 1.0f / 60.0f ) ;
bd - > Time = current_time ;
2018-06-09 01:37:33 +08:00
2022-01-13 00:08:37 +08:00
ImGui_ImplGlfw_UpdateMouseData ( ) ;
2018-06-09 01:37:33 +08:00
ImGui_ImplGlfw_UpdateMouseCursor ( ) ;
2019-04-23 18:26:14 +08:00
// Update game controllers (if enabled and available)
2019-02-15 01:55:08 +08:00
ImGui_ImplGlfw_UpdateGamepads ( ) ;
2018-06-09 01:37:33 +08:00
}
2021-12-29 19:41:34 +08:00
2024-07-31 23:33:24 +08:00
// GLFW doesn't provide a portable sleep function
void ImGui_ImplGlfw_Sleep ( int milliseconds )
{
# ifdef _WIN32
: : Sleep ( milliseconds ) ;
# else
usleep ( milliseconds * 1000 ) ;
# endif
}
2024-07-09 04:04:27 +08:00
# ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
2023-12-19 22:52:44 +08:00
static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange ( int event_type , const EmscriptenUiEvent * event , void * user_data )
{
2023-12-19 22:57:00 +08:00
ImGui_ImplGlfw_Data * bd = ( ImGui_ImplGlfw_Data * ) user_data ;
2023-12-19 22:52:44 +08:00
double canvas_width , canvas_height ;
emscripten_get_element_css_size ( bd - > CanvasSelector , & canvas_width , & canvas_height ) ;
glfwSetWindowSize ( bd - > Window , ( int ) canvas_width , ( int ) canvas_height ) ;
return true ;
}
2023-12-19 22:57:00 +08:00
static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback ( int event_type , const EmscriptenFullscreenChangeEvent * event , void * user_data )
2023-12-19 22:52:44 +08:00
{
2023-12-19 22:57:00 +08:00
ImGui_ImplGlfw_Data * bd = ( ImGui_ImplGlfw_Data * ) user_data ;
2023-12-19 22:52:44 +08:00
double canvas_width , canvas_height ;
emscripten_get_element_css_size ( bd - > CanvasSelector , & canvas_width , & canvas_height ) ;
glfwSetWindowSize ( bd - > Window , ( int ) canvas_width , ( int ) canvas_height ) ;
return true ;
}
2023-12-19 22:57:00 +08:00
// 'canvas_selector' is a CSS selector. The event listener is applied to the first element that matches the query.
// STRING MUST PERSIST FOR THE APPLICATION DURATION. PLEASE USE A STRING LITERAL OR ENSURE POINTER WILL STAY VALID.
2024-07-08 21:53:23 +08:00
void ImGui_ImplGlfw_InstallEmscriptenCallbacks ( GLFWwindow * , const char * canvas_selector )
2023-12-19 22:52:44 +08:00
{
IM_ASSERT ( canvas_selector ! = nullptr ) ;
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2024-05-07 22:53:03 +08:00
IM_ASSERT ( bd ! = nullptr & & " Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()? " ) ;
2023-12-19 22:52:44 +08:00
2023-12-19 22:57:00 +08:00
bd - > CanvasSelector = canvas_selector ;
2023-12-19 22:52:44 +08:00
emscripten_set_resize_callback ( EMSCRIPTEN_EVENT_TARGET_WINDOW , bd , false , ImGui_ImplGlfw_OnCanvasSizeChange ) ;
2023-12-19 22:57:00 +08:00
emscripten_set_fullscreenchange_callback ( EMSCRIPTEN_EVENT_TARGET_DOCUMENT , bd , false , ImGui_ImplEmscripten_FullscreenChangeCallback ) ;
2023-12-19 22:52:44 +08:00
// Change the size of the GLFW window according to the size of the canvas
ImGui_ImplGlfw_OnCanvasSizeChange ( EMSCRIPTEN_EVENT_RESIZE , { } , bd ) ;
2024-07-08 21:53:23 +08:00
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
// FIXME: May break chaining in case user registered their own Emscripten callback?
emscripten_set_wheel_callback ( bd - > CanvasSelector , nullptr , false , ImGui_ImplEmscripten_WheelCallback ) ;
2023-12-19 22:52:44 +08:00
}
2024-07-09 04:04:27 +08:00
# elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
// by invoking emscripten_glfw_make_canvas_resizable afterward.
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Usage.md#how-to-make-the-canvas-resizable-by-the-user for an explanation
void ImGui_ImplGlfw_InstallEmscriptenCallbacks ( GLFWwindow * window , const char * canvas_selector )
{
GLFWwindow * w = ( GLFWwindow * ) ( EM_ASM_INT ( { return Module . glfwGetWindow ( UTF8ToString ( $ 0 ) ) ; } , canvas_selector ) ) ;
IM_ASSERT ( window = = w ) ; // Sanity check
IM_UNUSED ( w ) ;
emscripten_glfw_make_canvas_resizable ( window , " window " , nullptr ) ;
}
# endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
2023-12-19 22:52:44 +08:00
2023-07-13 17:27:52 +08:00
//-----------------------------------------------------------------------------
2021-12-29 19:41:34 +08:00
# if defined(__clang__)
# pragma clang diagnostic pop
# endif
2023-07-13 17:27:52 +08:00
# endif // #ifndef IMGUI_DISABLE