| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 | |
| 45 | |
| 46 | |
| 47 | |
| 48 | |
| 49 | |
| 50 | |
| 51 | |
| 52 | |
| 53 | |
| 54 | |
| 55 | |
| 56 | |
| 57 | |
| 58 | |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | |
| 71 | |
| 72 | |
| 73 | |
| 74 | |
| 75 | |
| 76 | |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 | |
| 82 | |
| 83 | |
| 84 | |
| 85 | |
| 86 | |
| 87 | |
| 88 | |
| 89 | |
| 90 | |
| 91 | |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | |
| 97 | |
| 98 | |
| 99 | |
| 100 | |
| 101 | |
| 102 | |
| 103 | |
| 104 | |
| 105 | |
| 106 | |
| 107 | |
| 108 | |
| 109 | |
| 110 | |
| 111 | |
| 112 | |
| 113 | #include "imgui.h" |
| 114 | #ifndef IMGUI_DISABLE |
| 115 | #include "imgui_impl_glfw.h" |
| 116 | |
| 117 | |
| 118 | #if defined(__clang__) |
| 119 | #pragma clang diagnostic push |
| 120 | #pragma clang diagnostic ignored "-Wold-style-cast" |
| 121 | #pragma clang diagnostic ignored "-Wsign-conversion" |
| 122 | #pragma clang diagnostic ignored "-Wexit-time-destructors" |
| 123 | #pragma clang diagnostic ignored "-Wglobal-constructors" |
| 124 | #elif defined(__GNUC__) |
| 125 | #pragma GCC diagnostic ignored "-Wfloat-equal" |
| 126 | #endif |
| 127 | |
| 128 | #if defined(__has_include) |
| 129 | #if !__has_include(<X11/Xlib.h>) || !__has_include(<X11/extensions/Xrandr.h>) |
| 130 | #define IMGUI_IMPL_GLFW_DISABLE_X11 |
| 131 | #endif |
| 132 | #if !__has_include(<wayland-client.h>) |
| 133 | #define IMGUI_IMPL_GLFW_DISABLE_WAYLAND |
| 134 | #endif |
| 135 | #endif |
| 136 | |
| 137 | |
| 138 | #if !defined(IMGUI_IMPL_GLFW_DISABLE_X11) && (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)) |
| 139 | #define GLFW_HAS_X11 1 |
| 140 | #else |
| 141 | #define GLFW_HAS_X11 0 |
| 142 | #endif |
| 143 | #if !defined(IMGUI_IMPL_GLFW_DISABLE_WAYLAND) && (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)) |
| 144 | #define GLFW_HAS_WAYLAND 1 |
| 145 | #else |
| 146 | #define GLFW_HAS_WAYLAND 0 |
| 147 | #endif |
| 148 | #include <GLFW/glfw3.h> |
| 149 | #ifdef _WIN32 |
| 150 | #undef APIENTRY |
| 151 | #ifndef GLFW_EXPOSE_NATIVE_WIN32 |
| 152 | #define GLFW_EXPOSE_NATIVE_WIN32 |
| 153 | #endif |
| 154 | #include <GLFW/glfw3native.h> |
| 155 | #elif defined(__APPLE__) |
| 156 | #ifndef GLFW_EXPOSE_NATIVE_COCOA |
| 157 | #define GLFW_EXPOSE_NATIVE_COCOA |
| 158 | #endif |
| 159 | #include <GLFW/glfw3native.h> |
| 160 | #elif GLFW_HAS_X11 |
| 161 | #ifndef GLFW_EXPOSE_NATIVE_X11 |
| 162 | #define GLFW_EXPOSE_NATIVE_X11 |
| 163 | #include <X11/Xatom.h> |
| 164 | #include <dlfcn.h> |
| 165 | #endif |
| 166 | #include <GLFW/glfw3native.h> |
| 167 | #undef Status |
| 168 | #endif |
| 169 | |
| 170 | #ifndef _WIN32 |
| 171 | #include <unistd.h> |
| 172 | #endif |
| 173 | #include <stdio.h> |
| 174 | |
| 175 | #ifdef __EMSCRIPTEN__ |
| 176 | #include <emscripten.h> |
| 177 | #include <emscripten/html5.h> |
| 178 | #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 |
| 179 | #include <GLFW/emscripten_glfw3.h> |
| 180 | #else |
| 181 | #define EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 182 | #endif |
| 183 | #endif |
| 184 | |
| 185 | |
| 186 | #define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION) |
| 187 | #define GLFW_HAS_CREATECURSOR (GLFW_VERSION_COMBINED >= 3100) |
| 188 | #define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_COMBINED >= 3200) |
| 189 | #define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_COMBINED >= 3300) |
| 190 | #define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_COMBINED >= 3300) |
| 191 | #define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) |
| 192 | #if defined(__EMSCRIPTEN__) || defined(__SWITCH__) |
| 193 | #define GLFW_HAS_VULKAN (0) |
| 194 | #else |
| 195 | #define GLFW_HAS_VULKAN (GLFW_VERSION_COMBINED >= 3200) |
| 196 | #endif |
| 197 | #define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_COMBINED >= 3200) |
| 198 | #define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_COMBINED >= 3300) |
| 199 | #define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_COMBINED >= 3300) |
| 200 | #define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_COMBINED >= 3301) |
| 201 | #ifdef GLFW_RESIZE_NESW_CURSOR |
| 202 | #define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) |
| 203 | #else |
| 204 | #define GLFW_HAS_NEW_CURSORS (0) |
| 205 | #endif |
| 206 | #ifdef GLFW_MOUSE_PASSTHROUGH |
| 207 | #define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_COMBINED >= 3400) |
| 208 | #else |
| 209 | #define GLFW_HAS_MOUSE_PASSTHROUGH (0) |
| 210 | #endif |
| 211 | #define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) |
| 212 | #define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) |
| 213 | #define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) |
| 214 | #define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) |
| 215 | |
| 216 | |
| 217 | |
| 218 | |
| 219 | |
| 220 | struct ImGui_ImplGlfw_WindowToContext { GLFWwindow* Window; ImGuiContext* Context; }; |
| 221 | static ImVector<ImGui_ImplGlfw_WindowToContext> g_ContextMap; |
| 222 | static void ImGui_ImplGlfw_ContextMap_Add(GLFWwindow* window, ImGuiContext* ctx) { g_ContextMap.push_back(ImGui_ImplGlfw_WindowToContext{ window, ctx }); } |
| 223 | static void ImGui_ImplGlfw_ContextMap_Remove(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) { g_ContextMap.erase_unsorted(&entry); if (g_ContextMap.empty()) g_ContextMap.clear(); return; } } |
| 224 | static ImGuiContext* ImGui_ImplGlfw_ContextMap_Get(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) return entry.Context; return nullptr; } |
| 225 | |
| 226 | enum GlfwClientApi |
| 227 | { |
| 228 | GlfwClientApi_OpenGL, |
| 229 | GlfwClientApi_Vulkan, |
| 230 | GlfwClientApi_Unknown, |
| 231 | }; |
| 232 | |
| 233 | #if GLFW_HAS_X11 |
| 234 | typedef Atom (*PFN_XInternAtom)(Display*, const char* ,Bool); |
| 235 | typedef int (*PFN_XChangeProperty)(Display*, Window, Atom, Atom, int, int, const unsigned char*, int); |
| 236 | typedef int (*PFN_XChangeWindowAttributes)(Display*, Window, unsigned long, XSetWindowAttributes*); |
| 237 | typedef int (*PFN_XFlush)(Display*); |
| 238 | #endif |
| 239 | |
| 240 | |
| 241 | struct ImGui_ImplGlfw_Data |
| 242 | { |
| 243 | ImGuiContext* Context; |
| 244 | GLFWwindow* Window; |
| 245 | GlfwClientApi ClientApi; |
| 246 | double Time; |
| 247 | GLFWwindow* MouseWindow; |
| 248 | #if GLFW_HAS_CREATECURSOR |
| 249 | GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; |
| 250 | GLFWcursor* LastMouseCursor; |
| 251 | #endif |
| 252 | bool MouseIgnoreButtonUpWaitForFocusLoss; |
| 253 | bool MouseIgnoreButtonUp; |
| 254 | ImVec2 LastValidMousePos; |
| 255 | GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; |
| 256 | bool IsWayland; |
| 257 | bool InstalledCallbacks; |
| 258 | bool CallbacksChainForAllWindows; |
| 259 | char BackendPlatformName[32]; |
| 260 | #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 261 | const char* CanvasSelector; |
| 262 | #endif |
| 263 | |
| 264 | |
| 265 | GLFWwindowfocusfun PrevUserCallbackWindowFocus; |
| 266 | GLFWcursorposfun PrevUserCallbackCursorPos; |
| 267 | GLFWcursorenterfun PrevUserCallbackCursorEnter; |
| 268 | GLFWmousebuttonfun PrevUserCallbackMousebutton; |
| 269 | GLFWscrollfun PrevUserCallbackScroll; |
| 270 | GLFWkeyfun PrevUserCallbackKey; |
| 271 | GLFWcharfun PrevUserCallbackChar; |
| 272 | GLFWmonitorfun PrevUserCallbackMonitor; |
| 273 | #ifdef _WIN32 |
| 274 | WNDPROC PrevWndProc; |
| 275 | #endif |
| 276 | |
| 277 | #if GLFW_HAS_X11 |
| 278 | |
| 279 | void* X11Module; |
| 280 | PFN_XInternAtom XInternAtom; |
| 281 | PFN_XChangeProperty XChangeProperty; |
| 282 | PFN_XChangeWindowAttributes XChangeWindowAttributes; |
| 283 | PFN_XFlush XFlush; |
| 284 | #endif |
| 285 | |
| 286 | ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); } |
| 287 | }; |
| 288 | |
| 289 | |
| 290 | |
| 291 | |
| 292 | |
| 293 | |
| 294 | |
| 295 | |
| 296 | namespace ImGui { extern ImGuiIO& GetIO(ImGuiContext*); } |
| 297 | static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData() |
| 298 | { |
| 299 | |
| 300 | return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr; |
| 301 | } |
| 302 | static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData(GLFWwindow* window) |
| 303 | { |
| 304 | |
| 305 | ImGuiContext* ctx = ImGui_ImplGlfw_ContextMap_Get(window); |
| 306 | return (ImGui_ImplGlfw_Data*)ImGui::GetIO(ctx).BackendPlatformUserData; |
| 307 | } |
| 308 | |
| 309 | |
| 310 | static void ImGui_ImplGlfw_UpdateMonitors(); |
| 311 | static void ImGui_ImplGlfw_InitMultiViewportSupport(); |
| 312 | static void ImGui_ImplGlfw_ShutdownMultiViewportSupport(); |
| 313 | |
| 314 | |
| 315 | static bool ImGui_ImplGlfw_IsWayland() |
| 316 | { |
| 317 | #if !GLFW_HAS_WAYLAND |
| 318 | return false; |
| 319 | #elif GLFW_HAS_GETPLATFORM |
| 320 | return glfwGetPlatform() == GLFW_PLATFORM_WAYLAND; |
| 321 | #else |
| 322 | const char* version = glfwGetVersionString(); |
| 323 | if (strstr(version, "Wayland") == nullptr) |
| 324 | return false; |
| 325 | #ifdef GLFW_EXPOSE_NATIVE_X11 |
| 326 | if (glfwGetX11Display() != nullptr) |
| 327 | return false; |
| 328 | #endif |
| 329 | return true; |
| 330 | #endif |
| 331 | } |
| 332 | |
| 333 | |
| 334 | ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode); |
| 335 | ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode) |
| 336 | { |
| 337 | IM_UNUSED(scancode); |
| 338 | switch (keycode) |
| 339 | { |
| 340 | case GLFW_KEY_TAB: return ImGuiKey_Tab; |
| 341 | case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow; |
| 342 | case GLFW_KEY_RIGHT: return ImGuiKey_RightArrow; |
| 343 | case GLFW_KEY_UP: return ImGuiKey_UpArrow; |
| 344 | case GLFW_KEY_DOWN: return ImGuiKey_DownArrow; |
| 345 | case GLFW_KEY_PAGE_UP: return ImGuiKey_PageUp; |
| 346 | case GLFW_KEY_PAGE_DOWN: return ImGuiKey_PageDown; |
| 347 | case GLFW_KEY_HOME: return ImGuiKey_Home; |
| 348 | case GLFW_KEY_END: return ImGuiKey_End; |
| 349 | case GLFW_KEY_INSERT: return ImGuiKey_Insert; |
| 350 | case GLFW_KEY_DELETE: return ImGuiKey_Delete; |
| 351 | case GLFW_KEY_BACKSPACE: return ImGuiKey_Backspace; |
| 352 | case GLFW_KEY_SPACE: return ImGuiKey_Space; |
| 353 | case GLFW_KEY_ENTER: return ImGuiKey_Enter; |
| 354 | case GLFW_KEY_ESCAPE: return ImGuiKey_Escape; |
| 355 | case GLFW_KEY_APOSTROPHE: return ImGuiKey_Apostrophe; |
| 356 | case GLFW_KEY_COMMA: return ImGuiKey_Comma; |
| 357 | case GLFW_KEY_MINUS: return ImGuiKey_Minus; |
| 358 | case GLFW_KEY_PERIOD: return ImGuiKey_Period; |
| 359 | case GLFW_KEY_SLASH: return ImGuiKey_Slash; |
| 360 | case GLFW_KEY_SEMICOLON: return ImGuiKey_Semicolon; |
| 361 | case GLFW_KEY_EQUAL: return ImGuiKey_Equal; |
| 362 | case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket; |
| 363 | case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash; |
| 364 | case GLFW_KEY_WORLD_1: return ImGuiKey_Oem102; |
| 365 | case GLFW_KEY_WORLD_2: return ImGuiKey_Oem102; |
| 366 | case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket; |
| 367 | case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent; |
| 368 | case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock; |
| 369 | case GLFW_KEY_SCROLL_LOCK: return ImGuiKey_ScrollLock; |
| 370 | case GLFW_KEY_NUM_LOCK: return ImGuiKey_NumLock; |
| 371 | case GLFW_KEY_PRINT_SCREEN: return ImGuiKey_PrintScreen; |
| 372 | case GLFW_KEY_PAUSE: return ImGuiKey_Pause; |
| 373 | case GLFW_KEY_KP_0: return ImGuiKey_Keypad0; |
| 374 | case GLFW_KEY_KP_1: return ImGuiKey_Keypad1; |
| 375 | case GLFW_KEY_KP_2: return ImGuiKey_Keypad2; |
| 376 | case GLFW_KEY_KP_3: return ImGuiKey_Keypad3; |
| 377 | case GLFW_KEY_KP_4: return ImGuiKey_Keypad4; |
| 378 | case GLFW_KEY_KP_5: return ImGuiKey_Keypad5; |
| 379 | case GLFW_KEY_KP_6: return ImGuiKey_Keypad6; |
| 380 | case GLFW_KEY_KP_7: return ImGuiKey_Keypad7; |
| 381 | case GLFW_KEY_KP_8: return ImGuiKey_Keypad8; |
| 382 | case GLFW_KEY_KP_9: return ImGuiKey_Keypad9; |
| 383 | case GLFW_KEY_KP_DECIMAL: return ImGuiKey_KeypadDecimal; |
| 384 | case GLFW_KEY_KP_DIVIDE: return ImGuiKey_KeypadDivide; |
| 385 | case GLFW_KEY_KP_MULTIPLY: return ImGuiKey_KeypadMultiply; |
| 386 | case GLFW_KEY_KP_SUBTRACT: return ImGuiKey_KeypadSubtract; |
| 387 | case GLFW_KEY_KP_ADD: return ImGuiKey_KeypadAdd; |
| 388 | case GLFW_KEY_KP_ENTER: return ImGuiKey_KeypadEnter; |
| 389 | case GLFW_KEY_KP_EQUAL: return ImGuiKey_KeypadEqual; |
| 390 | case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift; |
| 391 | case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftCtrl; |
| 392 | case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt; |
| 393 | case GLFW_KEY_LEFT_SUPER: return ImGuiKey_LeftSuper; |
| 394 | case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift; |
| 395 | case GLFW_KEY_RIGHT_CONTROL: return ImGuiKey_RightCtrl; |
| 396 | case GLFW_KEY_RIGHT_ALT: return ImGuiKey_RightAlt; |
| 397 | case GLFW_KEY_RIGHT_SUPER: return ImGuiKey_RightSuper; |
| 398 | case GLFW_KEY_MENU: return ImGuiKey_Menu; |
| 399 | case GLFW_KEY_0: return ImGuiKey_0; |
| 400 | case GLFW_KEY_1: return ImGuiKey_1; |
| 401 | case GLFW_KEY_2: return ImGuiKey_2; |
| 402 | case GLFW_KEY_3: return ImGuiKey_3; |
| 403 | case GLFW_KEY_4: return ImGuiKey_4; |
| 404 | case GLFW_KEY_5: return ImGuiKey_5; |
| 405 | case GLFW_KEY_6: return ImGuiKey_6; |
| 406 | case GLFW_KEY_7: return ImGuiKey_7; |
| 407 | case GLFW_KEY_8: return ImGuiKey_8; |
| 408 | case GLFW_KEY_9: return ImGuiKey_9; |
| 409 | case GLFW_KEY_A: return ImGuiKey_A; |
| 410 | case GLFW_KEY_B: return ImGuiKey_B; |
| 411 | case GLFW_KEY_C: return ImGuiKey_C; |
| 412 | case GLFW_KEY_D: return ImGuiKey_D; |
| 413 | case GLFW_KEY_E: return ImGuiKey_E; |
| 414 | case GLFW_KEY_F: return ImGuiKey_F; |
| 415 | case GLFW_KEY_G: return ImGuiKey_G; |
| 416 | case GLFW_KEY_H: return ImGuiKey_H; |
| 417 | case GLFW_KEY_I: return ImGuiKey_I; |
| 418 | case GLFW_KEY_J: return ImGuiKey_J; |
| 419 | case GLFW_KEY_K: return ImGuiKey_K; |
| 420 | case GLFW_KEY_L: return ImGuiKey_L; |
| 421 | case GLFW_KEY_M: return ImGuiKey_M; |
| 422 | case GLFW_KEY_N: return ImGuiKey_N; |
| 423 | case GLFW_KEY_O: return ImGuiKey_O; |
| 424 | case GLFW_KEY_P: return ImGuiKey_P; |
| 425 | case GLFW_KEY_Q: return ImGuiKey_Q; |
| 426 | case GLFW_KEY_R: return ImGuiKey_R; |
| 427 | case GLFW_KEY_S: return ImGuiKey_S; |
| 428 | case GLFW_KEY_T: return ImGuiKey_T; |
| 429 | case GLFW_KEY_U: return ImGuiKey_U; |
| 430 | case GLFW_KEY_V: return ImGuiKey_V; |
| 431 | case GLFW_KEY_W: return ImGuiKey_W; |
| 432 | case GLFW_KEY_X: return ImGuiKey_X; |
| 433 | case GLFW_KEY_Y: return ImGuiKey_Y; |
| 434 | case GLFW_KEY_Z: return ImGuiKey_Z; |
| 435 | case GLFW_KEY_F1: return ImGuiKey_F1; |
| 436 | case GLFW_KEY_F2: return ImGuiKey_F2; |
| 437 | case GLFW_KEY_F3: return ImGuiKey_F3; |
| 438 | case GLFW_KEY_F4: return ImGuiKey_F4; |
| 439 | case GLFW_KEY_F5: return ImGuiKey_F5; |
| 440 | case GLFW_KEY_F6: return ImGuiKey_F6; |
| 441 | case GLFW_KEY_F7: return ImGuiKey_F7; |
| 442 | case GLFW_KEY_F8: return ImGuiKey_F8; |
| 443 | case GLFW_KEY_F9: return ImGuiKey_F9; |
| 444 | case GLFW_KEY_F10: return ImGuiKey_F10; |
| 445 | case GLFW_KEY_F11: return ImGuiKey_F11; |
| 446 | case GLFW_KEY_F12: return ImGuiKey_F12; |
| 447 | case GLFW_KEY_F13: return ImGuiKey_F13; |
| 448 | case GLFW_KEY_F14: return ImGuiKey_F14; |
| 449 | case GLFW_KEY_F15: return ImGuiKey_F15; |
| 450 | case GLFW_KEY_F16: return ImGuiKey_F16; |
| 451 | case GLFW_KEY_F17: return ImGuiKey_F17; |
| 452 | case GLFW_KEY_F18: return ImGuiKey_F18; |
| 453 | case GLFW_KEY_F19: return ImGuiKey_F19; |
| 454 | case GLFW_KEY_F20: return ImGuiKey_F20; |
| 455 | case GLFW_KEY_F21: return ImGuiKey_F21; |
| 456 | case GLFW_KEY_F22: return ImGuiKey_F22; |
| 457 | case GLFW_KEY_F23: return ImGuiKey_F23; |
| 458 | case GLFW_KEY_F24: return ImGuiKey_F24; |
| 459 | default: return ImGuiKey_None; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | |
| 464 | |
| 465 | static void ImGui_ImplGlfw_UpdateKeyModifiers(ImGuiIO& io, GLFWwindow* window) |
| 466 | { |
| 467 | io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS)); |
| 468 | io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS)); |
| 469 | io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS)); |
| 470 | io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS)); |
| 471 | } |
| 472 | |
| 473 | static bool ImGui_ImplGlfw_ShouldChainCallback(ImGui_ImplGlfw_Data* bd, GLFWwindow* window) |
| 474 | { |
| 475 | return bd->CallbacksChainForAllWindows ? true : (window == bd->Window); |
| 476 | } |
| 477 | |
| 478 | void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) |
| 479 | { |
| 480 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 481 | if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 482 | bd->PrevUserCallbackMousebutton(window, button, action, mods); |
| 483 | |
| 484 | |
| 485 | if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE) |
| 486 | return; |
| 487 | |
| 488 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 489 | ImGui_ImplGlfw_UpdateKeyModifiers(io, window); |
| 490 | if (button >= 0 && button < ImGuiMouseButton_COUNT) |
| 491 | io.AddMouseButtonEvent(button, action == GLFW_PRESS); |
| 492 | } |
| 493 | |
| 494 | void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) |
| 495 | { |
| 496 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 497 | if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 498 | bd->PrevUserCallbackScroll(window, xoffset, yoffset); |
| 499 | |
| 500 | #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 501 | |
| 502 | return; |
| 503 | #endif |
| 504 | |
| 505 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 506 | io.AddMouseWheelEvent((float)xoffset, (float)yoffset); |
| 507 | } |
| 508 | |
| 509 | |
| 510 | static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode) |
| 511 | { |
| 512 | #if GLFW_HAS_GETKEYNAME && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) |
| 513 | |
| 514 | |
| 515 | |
| 516 | |
| 517 | |
| 518 | if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_EQUAL) |
| 519 | return key; |
| 520 | GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr); |
| 521 | const char* key_name = glfwGetKeyName(key, scancode); |
| 522 | glfwSetErrorCallback(prev_error_callback); |
| 523 | #if GLFW_HAS_GETERROR && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) |
| 524 | (void)glfwGetError(nullptr); |
| 525 | #endif |
| 526 | if (key_name && key_name[0] != 0 && key_name[1] == 0) |
| 527 | { |
| 528 | const char char_names[] = "`-=[]\\,;\'./"; |
| 529 | 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 }; |
| 530 | IM_ASSERT(IM_COUNTOF(char_names) == IM_COUNTOF(char_keys)); |
| 531 | if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); } |
| 532 | else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); } |
| 533 | else if (key_name[0] >= 'a' && key_name[0] <= 'z') { key = GLFW_KEY_A + (key_name[0] - 'a'); } |
| 534 | else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; } |
| 535 | } |
| 536 | |
| 537 | #else |
| 538 | IM_UNUSED(scancode); |
| 539 | #endif |
| 540 | return key; |
| 541 | } |
| 542 | |
| 543 | void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods) |
| 544 | { |
| 545 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 546 | if (bd->PrevUserCallbackKey != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 547 | bd->PrevUserCallbackKey(window, keycode, scancode, action, mods); |
| 548 | |
| 549 | if (action != GLFW_PRESS && action != GLFW_RELEASE) |
| 550 | return; |
| 551 | |
| 552 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 553 | ImGui_ImplGlfw_UpdateKeyModifiers(io, window); |
| 554 | |
| 555 | if (keycode >= 0 && keycode < IM_COUNTOF(bd->KeyOwnerWindows)) |
| 556 | bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr; |
| 557 | |
| 558 | keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode); |
| 559 | |
| 560 | ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode); |
| 561 | io.AddKeyEvent(imgui_key, (action == GLFW_PRESS)); |
| 562 | io.SetKeyEventNativeData(imgui_key, keycode, scancode); |
| 563 | } |
| 564 | |
| 565 | void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused) |
| 566 | { |
| 567 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 568 | if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 569 | bd->PrevUserCallbackWindowFocus(window, focused); |
| 570 | |
| 571 | |
| 572 | bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0); |
| 573 | bd->MouseIgnoreButtonUpWaitForFocusLoss = false; |
| 574 | |
| 575 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 576 | io.AddFocusEvent(focused != 0); |
| 577 | } |
| 578 | |
| 579 | void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y) |
| 580 | { |
| 581 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 582 | if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 583 | bd->PrevUserCallbackCursorPos(window, x, y); |
| 584 | |
| 585 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 586 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) |
| 587 | { |
| 588 | int window_x, window_y; |
| 589 | glfwGetWindowPos(window, &window_x, &window_y); |
| 590 | x += window_x; |
| 591 | y += window_y; |
| 592 | } |
| 593 | io.AddMousePosEvent((float)x, (float)y); |
| 594 | bd->LastValidMousePos = ImVec2((float)x, (float)y); |
| 595 | } |
| 596 | |
| 597 | |
| 598 | |
| 599 | void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) |
| 600 | { |
| 601 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 602 | if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 603 | bd->PrevUserCallbackCursorEnter(window, entered); |
| 604 | |
| 605 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 606 | if (entered) |
| 607 | { |
| 608 | bd->MouseWindow = window; |
| 609 | io.AddMousePosEvent(bd->LastValidMousePos.x, bd->LastValidMousePos.y); |
| 610 | } |
| 611 | else if (!entered && bd->MouseWindow == window) |
| 612 | { |
| 613 | bd->LastValidMousePos = io.MousePos; |
| 614 | bd->MouseWindow = nullptr; |
| 615 | io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) |
| 620 | { |
| 621 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 622 | if (bd->PrevUserCallbackChar != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window)) |
| 623 | bd->PrevUserCallbackChar(window, c); |
| 624 | |
| 625 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 626 | io.AddInputCharacter(c); |
| 627 | } |
| 628 | |
| 629 | void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int) |
| 630 | { |
| 631 | |
| 632 | } |
| 633 | |
| 634 | #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 635 | static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void* user_data) |
| 636 | { |
| 637 | |
| 638 | |
| 639 | ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data; |
| 640 | float multiplier = 0.0f; |
| 641 | if (ev->deltaMode == DOM_DELTA_PIXEL) { multiplier = 1.0f / 100.0f; } |
| 642 | else if (ev->deltaMode == DOM_DELTA_LINE) { multiplier = 1.0f / 3.0f; } |
| 643 | else if (ev->deltaMode == DOM_DELTA_PAGE) { multiplier = 80.0f; } |
| 644 | float wheel_x = ev->deltaX * -multiplier; |
| 645 | float wheel_y = ev->deltaY * -multiplier; |
| 646 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 647 | io.AddMouseWheelEvent(wheel_x, wheel_y); |
| 648 | |
| 649 | return EM_TRUE; |
| 650 | } |
| 651 | #endif |
| 652 | |
| 653 | #ifdef _WIN32 |
| 654 | static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); |
| 655 | #endif |
| 656 | |
| 657 | void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) |
| 658 | { |
| 659 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 660 | IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!"); |
| 661 | IM_ASSERT(bd->Window == window); |
| 662 | |
| 663 | bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback); |
| 664 | bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback); |
| 665 | bd->PrevUserCallbackCursorPos = glfwSetCursorPosCallback(window, ImGui_ImplGlfw_CursorPosCallback); |
| 666 | bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); |
| 667 | bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); |
| 668 | bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); |
| 669 | bd->PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); |
| 670 | bd->PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback); |
| 671 | bd->InstalledCallbacks = true; |
| 672 | } |
| 673 | |
| 674 | void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window) |
| 675 | { |
| 676 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 677 | IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!"); |
| 678 | IM_ASSERT(bd->Window == window); |
| 679 | |
| 680 | glfwSetWindowFocusCallback(window, bd->PrevUserCallbackWindowFocus); |
| 681 | glfwSetCursorEnterCallback(window, bd->PrevUserCallbackCursorEnter); |
| 682 | glfwSetCursorPosCallback(window, bd->PrevUserCallbackCursorPos); |
| 683 | glfwSetMouseButtonCallback(window, bd->PrevUserCallbackMousebutton); |
| 684 | glfwSetScrollCallback(window, bd->PrevUserCallbackScroll); |
| 685 | glfwSetKeyCallback(window, bd->PrevUserCallbackKey); |
| 686 | glfwSetCharCallback(window, bd->PrevUserCallbackChar); |
| 687 | glfwSetMonitorCallback(bd->PrevUserCallbackMonitor); |
| 688 | bd->InstalledCallbacks = false; |
| 689 | bd->PrevUserCallbackWindowFocus = nullptr; |
| 690 | bd->PrevUserCallbackCursorEnter = nullptr; |
| 691 | bd->PrevUserCallbackCursorPos = nullptr; |
| 692 | bd->PrevUserCallbackMousebutton = nullptr; |
| 693 | bd->PrevUserCallbackScroll = nullptr; |
| 694 | bd->PrevUserCallbackKey = nullptr; |
| 695 | bd->PrevUserCallbackChar = nullptr; |
| 696 | bd->PrevUserCallbackMonitor = nullptr; |
| 697 | } |
| 698 | |
| 699 | |
| 700 | |
| 701 | |
| 702 | |
| 703 | void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows) |
| 704 | { |
| 705 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 706 | bd->CallbacksChainForAllWindows = chain_for_all_windows; |
| 707 | } |
| 708 | |
| 709 | #ifdef __EMSCRIPTEN__ |
| 710 | #if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817 |
| 711 | void ImGui_ImplGlfw_EmscriptenOpenURL(const char* url) { if (url) emscripten::glfw3::OpenURL(url); } |
| 712 | #else |
| 713 | EM_JS(void, ImGui_ImplGlfw_EmscriptenOpenURL, (const char* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); }); |
| 714 | #endif |
| 715 | #endif |
| 716 | |
| 717 | static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) |
| 718 | { |
| 719 | ImGuiIO& io = ImGui::GetIO(); |
| 720 | IMGUI_CHECKVERSION(); |
| 721 | IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); |
| 722 | |
| 723 | |
| 724 | |
| 725 | ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)(); |
| 726 | snprintf(bd->BackendPlatformName, sizeof(bd->BackendPlatformName), "imgui_impl_glfw (%d)", GLFW_VERSION_COMBINED); |
| 727 | io.BackendPlatformUserData = (void*)bd; |
| 728 | io.BackendPlatformName = bd->BackendPlatformName; |
| 729 | #if GLFW_HAS_CREATECURSOR |
| 730 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; |
| 731 | #endif |
| 732 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; |
| 733 | |
| 734 | bool has_viewports = false; |
| 735 | #ifndef __EMSCRIPTEN__ |
| 736 | has_viewports = true; |
| 737 | #if GLFW_HAS_GETPLATFORM |
| 738 | if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) |
| 739 | has_viewports = false; |
| 740 | #endif |
| 741 | if (has_viewports) |
| 742 | io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; |
| 743 | #endif |
| 744 | #if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED |
| 745 | io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; |
| 746 | #endif |
| 747 | |
| 748 | bd->Context = ImGui::GetCurrentContext(); |
| 749 | bd->Window = window; |
| 750 | bd->Time = 0.0; |
| 751 | bd->IsWayland = ImGui_ImplGlfw_IsWayland(); |
| 752 | ImGui_ImplGlfw_ContextMap_Add(window, bd->Context); |
| 753 | |
| 754 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); |
| 755 | #if GLFW_VERSION_COMBINED < 3300 |
| 756 | platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window, text); }; |
| 757 | platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window); }; |
| 758 | #else |
| 759 | platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); }; |
| 760 | platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(nullptr); }; |
| 761 | #endif |
| 762 | |
| 763 | #ifdef __EMSCRIPTEN__ |
| 764 | platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplGlfw_EmscriptenOpenURL(url); return true; }; |
| 765 | #endif |
| 766 | |
| 767 | |
| 768 | |
| 769 | |
| 770 | |
| 771 | #if GLFW_HAS_CREATECURSOR |
| 772 | GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr); |
| 773 | bd->MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); |
| 774 | bd->MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); |
| 775 | bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); |
| 776 | bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); |
| 777 | bd->MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR); |
| 778 | #if GLFW_HAS_NEW_CURSORS |
| 779 | bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_RESIZE_ALL_CURSOR); |
| 780 | bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_RESIZE_NESW_CURSOR); |
| 781 | bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_RESIZE_NWSE_CURSOR); |
| 782 | bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_NOT_ALLOWED_CURSOR); |
| 783 | #else |
| 784 | bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); |
| 785 | bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); |
| 786 | bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); |
| 787 | bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); |
| 788 | #endif |
| 789 | glfwSetErrorCallback(prev_error_callback); |
| 790 | #endif |
| 791 | #if GLFW_HAS_GETERROR && !defined(__EMSCRIPTEN__) |
| 792 | (void)glfwGetError(nullptr); |
| 793 | #endif |
| 794 | |
| 795 | |
| 796 | if (install_callbacks) |
| 797 | ImGui_ImplGlfw_InstallCallbacks(window); |
| 798 | |
| 799 | |
| 800 | |
| 801 | ImGui_ImplGlfw_UpdateMonitors(); |
| 802 | glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback); |
| 803 | |
| 804 | |
| 805 | ImGuiViewport* main_viewport = ImGui::GetMainViewport(); |
| 806 | main_viewport->PlatformHandle = (void*)bd->Window; |
| 807 | #ifdef _WIN32 |
| 808 | main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window); |
| 809 | #elif defined(__APPLE__) |
| 810 | main_viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(bd->Window); |
| 811 | #else |
| 812 | IM_UNUSED(main_viewport); |
| 813 | #endif |
| 814 | if (has_viewports) |
| 815 | ImGui_ImplGlfw_InitMultiViewportSupport(); |
| 816 | |
| 817 | |
| 818 | #ifdef _WIN32 |
| 819 | HWND hwnd = (HWND)main_viewport->PlatformHandleRaw; |
| 820 | ::SetPropA(hwnd, "IMGUI_BACKEND_DATA", bd); |
| 821 | bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC); |
| 822 | IM_ASSERT(bd->PrevWndProc != nullptr); |
| 823 | ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc); |
| 824 | #endif |
| 825 | |
| 826 | #if GLFW_HAS_X11 |
| 827 | if (!bd->IsWayland) |
| 828 | { |
| 829 | |
| 830 | #if defined(__CYGWIN__) |
| 831 | const char* x11_module_path = "libX11-6.so"; |
| 832 | #elif defined(__OpenBSD__) || defined(__NetBSD__) |
| 833 | const char* x11_module_path = "libX11.so"; |
| 834 | #else |
| 835 | const char* x11_module_path = "libX11.so.6"; |
| 836 | #endif |
| 837 | bd->X11Module = dlopen(x11_module_path, RTLD_LAZY | RTLD_LOCAL); |
| 838 | bd->XInternAtom = (PFN_XInternAtom)dlsym(bd->X11Module, "XInternAtom"); |
| 839 | bd->XChangeProperty = (PFN_XChangeProperty)dlsym(bd->X11Module, "XChangeProperty"); |
| 840 | bd->XChangeWindowAttributes = (PFN_XChangeWindowAttributes)dlsym(bd->X11Module, "XChangeWindowAttributes"); |
| 841 | bd->XFlush = (PFN_XFlush)dlsym(bd->X11Module, "XFlush"); |
| 842 | IM_ASSERT(bd->XInternAtom != nullptr && bd->XChangeProperty != nullptr && bd->XChangeWindowAttributes != nullptr && bd->XFlush != nullptr); |
| 843 | } |
| 844 | #endif |
| 845 | |
| 846 | |
| 847 | |
| 848 | #ifdef __EMSCRIPTEN__ |
| 849 | #if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817 |
| 850 | if (emscripten::glfw3::IsRuntimePlatformApple()) |
| 851 | { |
| 852 | io.ConfigMacOSXBehaviors = true; |
| 853 | |
| 854 | |
| 855 | |
| 856 | |
| 857 | |
| 858 | emscripten::glfw3::SetSuperPlusKeyTimeouts(10, 10); |
| 859 | } |
| 860 | #endif |
| 861 | #endif |
| 862 | |
| 863 | bd->ClientApi = client_api; |
| 864 | return true; |
| 865 | } |
| 866 | |
| 867 | bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks) |
| 868 | { |
| 869 | return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_OpenGL); |
| 870 | } |
| 871 | |
| 872 | bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks) |
| 873 | { |
| 874 | return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan); |
| 875 | } |
| 876 | |
| 877 | bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks) |
| 878 | { |
| 879 | return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Unknown); |
| 880 | } |
| 881 | |
| 882 | void ImGui_ImplGlfw_Shutdown() |
| 883 | { |
| 884 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 885 | IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); |
| 886 | |
| 887 | ImGuiIO& io = ImGui::GetIO(); |
| 888 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); |
| 889 | |
| 890 | ImGui_ImplGlfw_ShutdownMultiViewportSupport(); |
| 891 | if (bd->InstalledCallbacks) |
| 892 | ImGui_ImplGlfw_RestoreCallbacks(bd->Window); |
| 893 | #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 894 | if (bd->CanvasSelector) |
| 895 | emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, nullptr); |
| 896 | #endif |
| 897 | #if GLFW_HAS_CREATECURSOR |
| 898 | for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) |
| 899 | glfwDestroyCursor(bd->MouseCursors[cursor_n]); |
| 900 | #endif |
| 901 | |
| 902 | #ifdef _WIN32 |
| 903 | ImGuiViewport* main_viewport = ImGui::GetMainViewport(); |
| 904 | ::SetPropA((HWND)main_viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", nullptr); |
| 905 | ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc); |
| 906 | bd->PrevWndProc = nullptr; |
| 907 | #endif |
| 908 | |
| 909 | #if GLFW_HAS_X11 |
| 910 | if (bd->X11Module != nullptr) |
| 911 | dlclose(bd->X11Module); |
| 912 | #endif |
| 913 | |
| 914 | io.BackendPlatformName = nullptr; |
| 915 | io.BackendPlatformUserData = nullptr; |
| 916 | io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport); |
| 917 | platform_io.ClearPlatformHandlers(); |
| 918 | ImGui_ImplGlfw_ContextMap_Remove(bd->Window); |
| 919 | IM_DELETE(bd); |
| 920 | } |
| 921 | |
| 922 | static void ImGui_ImplGlfw_UpdateMouseData() |
| 923 | { |
| 924 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 925 | ImGuiIO& io = ImGui::GetIO(); |
| 926 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); |
| 927 | |
| 928 | ImGuiID mouse_viewport_id = 0; |
| 929 | const ImVec2 mouse_pos_prev = io.MousePos; |
| 930 | for (int n = 0; n < platform_io.Viewports.Size; n++) |
| 931 | { |
| 932 | ImGuiViewport* viewport = platform_io.Viewports[n]; |
| 933 | GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle; |
| 934 | |
| 935 | #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 936 | const bool is_window_focused = true; |
| 937 | #else |
| 938 | const bool is_window_focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0; |
| 939 | #endif |
| 940 | if (is_window_focused) |
| 941 | { |
| 942 | |
| 943 | |
| 944 | if (io.WantSetMousePos) |
| 945 | glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y)); |
| 946 | |
| 947 | |
| 948 | if (bd->MouseWindow == nullptr) |
| 949 | { |
| 950 | double mouse_x, mouse_y; |
| 951 | glfwGetCursorPos(window, &mouse_x, &mouse_y); |
| 952 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) |
| 953 | { |
| 954 | |
| 955 | |
| 956 | int window_x, window_y; |
| 957 | glfwGetWindowPos(window, &window_x, &window_y); |
| 958 | mouse_x += window_x; |
| 959 | mouse_y += window_y; |
| 960 | } |
| 961 | bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y); |
| 962 | io.AddMousePosEvent((float)mouse_x, (float)mouse_y); |
| 963 | } |
| 964 | } |
| 965 | |
| 966 | |
| 967 | |
| 968 | |
| 969 | |
| 970 | |
| 971 | |
| 972 | |
| 973 | |
| 974 | |
| 975 | |
| 976 | |
| 977 | #if GLFW_HAS_MOUSE_PASSTHROUGH |
| 978 | const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0; |
| 979 | glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input); |
| 980 | #endif |
| 981 | #if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED |
| 982 | if (glfwGetWindowAttrib(window, GLFW_HOVERED)) |
| 983 | mouse_viewport_id = viewport->ID; |
| 984 | #else |
| 985 | |
| 986 | #endif |
| 987 | } |
| 988 | |
| 989 | if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) |
| 990 | io.AddMouseViewportEvent(mouse_viewport_id); |
| 991 | } |
| 992 | |
| 993 | static void ImGui_ImplGlfw_UpdateMouseCursor() |
| 994 | { |
| 995 | ImGuiIO& io = ImGui::GetIO(); |
| 996 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 997 | if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) || glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) |
| 998 | { |
| 999 | bd->LastMouseCursor = nullptr; |
| 1000 | return; |
| 1001 | } |
| 1002 | |
| 1003 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); |
| 1004 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); |
| 1005 | for (int n = 0; n < platform_io.Viewports.Size; n++) |
| 1006 | { |
| 1007 | GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle; |
| 1008 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) |
| 1009 | { |
| 1010 | if (bd->LastMouseCursor != nullptr) |
| 1011 | { |
| 1012 | |
| 1013 | glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); |
| 1014 | bd->LastMouseCursor = nullptr; |
| 1015 | } |
| 1016 | } |
| 1017 | else |
| 1018 | { |
| 1019 | |
| 1020 | |
| 1021 | #if GLFW_HAS_CREATECURSOR |
| 1022 | GLFWcursor* cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]; |
| 1023 | if (bd->LastMouseCursor != cursor) |
| 1024 | { |
| 1025 | glfwSetCursor(window, cursor); |
| 1026 | bd->LastMouseCursor = cursor; |
| 1027 | } |
| 1028 | #endif |
| 1029 | glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); |
| 1030 | } |
| 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | |
| 1035 | static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; } |
| 1036 | static void ImGui_ImplGlfw_UpdateGamepads() |
| 1037 | { |
| 1038 | ImGuiIO& io = ImGui::GetIO(); |
| 1039 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) |
| 1040 | return; |
| 1041 | |
| 1042 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; |
| 1043 | #if GLFW_HAS_GAMEPAD_API && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) |
| 1044 | GLFWgamepadstate gamepad; |
| 1045 | if (!glfwGetGamepadState(GLFW_JOYSTICK_1, &gamepad)) |
| 1046 | return; |
| 1047 | #define MAP_BUTTON(KEY_NO, BUTTON_NO, _UNUSED) do { io.AddKeyEvent(KEY_NO, gamepad.buttons[BUTTON_NO] != 0); } while (0) |
| 1048 | #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) |
| 1049 | #else |
| 1050 | int axes_count = 0, buttons_count = 0; |
| 1051 | const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axes_count); |
| 1052 | const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &buttons_count); |
| 1053 | if (axes_count == 0 || buttons_count == 0) |
| 1054 | return; |
| 1055 | #define MAP_BUTTON(KEY_NO, _UNUSED, BUTTON_NO) do { io.AddKeyEvent(KEY_NO, (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS)); } while (0) |
| 1056 | #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) |
| 1057 | #endif |
| 1058 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; |
| 1059 | MAP_BUTTON(ImGuiKey_GamepadStart, GLFW_GAMEPAD_BUTTON_START, 7); |
| 1060 | MAP_BUTTON(ImGuiKey_GamepadBack, GLFW_GAMEPAD_BUTTON_BACK, 6); |
| 1061 | MAP_BUTTON(ImGuiKey_GamepadFaceLeft, GLFW_GAMEPAD_BUTTON_X, 2); |
| 1062 | MAP_BUTTON(ImGuiKey_GamepadFaceRight, GLFW_GAMEPAD_BUTTON_B, 1); |
| 1063 | MAP_BUTTON(ImGuiKey_GamepadFaceUp, GLFW_GAMEPAD_BUTTON_Y, 3); |
| 1064 | MAP_BUTTON(ImGuiKey_GamepadFaceDown, GLFW_GAMEPAD_BUTTON_A, 0); |
| 1065 | MAP_BUTTON(ImGuiKey_GamepadDpadLeft, GLFW_GAMEPAD_BUTTON_DPAD_LEFT, 13); |
| 1066 | MAP_BUTTON(ImGuiKey_GamepadDpadRight, GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, 11); |
| 1067 | MAP_BUTTON(ImGuiKey_GamepadDpadUp, GLFW_GAMEPAD_BUTTON_DPAD_UP, 10); |
| 1068 | MAP_BUTTON(ImGuiKey_GamepadDpadDown, GLFW_GAMEPAD_BUTTON_DPAD_DOWN, 12); |
| 1069 | MAP_BUTTON(ImGuiKey_GamepadL1, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, 4); |
| 1070 | MAP_BUTTON(ImGuiKey_GamepadR1, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, 5); |
| 1071 | MAP_ANALOG(ImGuiKey_GamepadL2, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, 4, -0.75f, +1.0f); |
| 1072 | MAP_ANALOG(ImGuiKey_GamepadR2, GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, 5, -0.75f, +1.0f); |
| 1073 | MAP_BUTTON(ImGuiKey_GamepadL3, GLFW_GAMEPAD_BUTTON_LEFT_THUMB, 8); |
| 1074 | MAP_BUTTON(ImGuiKey_GamepadR3, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, 9); |
| 1075 | MAP_ANALOG(ImGuiKey_GamepadLStickLeft, GLFW_GAMEPAD_AXIS_LEFT_X, 0, -0.25f, -1.0f); |
| 1076 | MAP_ANALOG(ImGuiKey_GamepadLStickRight, GLFW_GAMEPAD_AXIS_LEFT_X, 0, +0.25f, +1.0f); |
| 1077 | MAP_ANALOG(ImGuiKey_GamepadLStickUp, GLFW_GAMEPAD_AXIS_LEFT_Y, 1, -0.25f, -1.0f); |
| 1078 | MAP_ANALOG(ImGuiKey_GamepadLStickDown, GLFW_GAMEPAD_AXIS_LEFT_Y, 1, +0.25f, +1.0f); |
| 1079 | MAP_ANALOG(ImGuiKey_GamepadRStickLeft, GLFW_GAMEPAD_AXIS_RIGHT_X, 2, -0.25f, -1.0f); |
| 1080 | MAP_ANALOG(ImGuiKey_GamepadRStickRight, GLFW_GAMEPAD_AXIS_RIGHT_X, 2, +0.25f, +1.0f); |
| 1081 | MAP_ANALOG(ImGuiKey_GamepadRStickUp, GLFW_GAMEPAD_AXIS_RIGHT_Y, 3, -0.25f, -1.0f); |
| 1082 | MAP_ANALOG(ImGuiKey_GamepadRStickDown, GLFW_GAMEPAD_AXIS_RIGHT_Y, 3, +0.25f, +1.0f); |
| 1083 | #undef MAP_BUTTON |
| 1084 | #undef MAP_ANALOG |
| 1085 | } |
| 1086 | |
| 1087 | static void ImGui_ImplGlfw_UpdateMonitors() |
| 1088 | { |
| 1089 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); |
| 1090 | int monitors_count = 0; |
| 1091 | GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count); |
| 1092 | |
| 1093 | bool updated_monitors = false; |
| 1094 | for (int n = 0; n < monitors_count; n++) |
| 1095 | { |
| 1096 | ImGuiPlatformMonitor monitor; |
| 1097 | int x, y; |
| 1098 | glfwGetMonitorPos(glfw_monitors[n], &x, &y); |
| 1099 | const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]); |
| 1100 | if (vid_mode == nullptr) |
| 1101 | continue; |
| 1102 | if (vid_mode->width <= 0 || vid_mode->height <= 0) |
| 1103 | continue; |
| 1104 | monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y); |
| 1105 | monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height); |
| 1106 | #if GLFW_HAS_MONITOR_WORK_AREA |
| 1107 | int w, h; |
| 1108 | glfwGetMonitorWorkarea(glfw_monitors[n], &x, &y, &w, &h); |
| 1109 | if (w > 0 && h > 0) |
| 1110 | { |
| 1111 | monitor.WorkPos = ImVec2((float)x, (float)y); |
| 1112 | monitor.WorkSize = ImVec2((float)w, (float)h); |
| 1113 | } |
| 1114 | #endif |
| 1115 | float scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfw_monitors[n]); |
| 1116 | if (scale == 0.0f) |
| 1117 | continue; |
| 1118 | monitor.DpiScale = scale; |
| 1119 | monitor.PlatformHandle = (void*)glfw_monitors[n]; |
| 1120 | |
| 1121 | |
| 1122 | |
| 1123 | if (!updated_monitors) |
| 1124 | platform_io.Monitors.resize(0); |
| 1125 | updated_monitors = true; |
| 1126 | platform_io.Monitors.push_back(monitor); |
| 1127 | } |
| 1128 | } |
| 1129 | |
| 1130 | |
| 1131 | |
| 1132 | #if !GLFW_HAS_PER_MONITOR_DPI && defined(_WIN32) && !defined(NOGDI) |
| 1133 | static float ImGui_ImplWin32_GetLegacyDpiScale() { const HDC dc = ::GetDC(nullptr); UINT xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); ::ReleaseDC(nullptr, dc); return (float)xdpi / 96.0f; } |
| 1134 | static void glfwGetWindowContentScale(GLFWwindow*, float* x_scale, float* y_scale) { *x_scale = *y_scale = ImGui_ImplWin32_GetLegacyDpiScale(); } |
| 1135 | static void glfwGetMonitorContentScale(GLFWmonitor*, float* x_scale, float* y_scale) { *x_scale = *y_scale = ImGui_ImplWin32_GetLegacyDpiScale(); } |
| 1136 | #undef GLFW_HAS_PER_MONITOR_DPI |
| 1137 | #define GLFW_HAS_PER_MONITOR_DPI 1 |
| 1138 | #endif |
| 1139 | |
| 1140 | |
| 1141 | |
| 1142 | |
| 1143 | float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) |
| 1144 | { |
| 1145 | #if GLFW_HAS_WAYLAND |
| 1146 | if (ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window)) |
| 1147 | if (bd->IsWayland) |
| 1148 | return 1.0f; |
| 1149 | #endif |
| 1150 | #if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__)) |
| 1151 | float x_scale, y_scale; |
| 1152 | glfwGetWindowContentScale(window, &x_scale, &y_scale); |
| 1153 | return x_scale; |
| 1154 | #else |
| 1155 | IM_UNUSED(window); |
| 1156 | return 1.0f; |
| 1157 | #endif |
| 1158 | } |
| 1159 | |
| 1160 | float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) |
| 1161 | { |
| 1162 | #if GLFW_HAS_WAYLAND |
| 1163 | if (ImGui_ImplGlfw_IsWayland()) |
| 1164 | return 1.0f; |
| 1165 | #endif |
| 1166 | #if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__)) |
| 1167 | float x_scale, y_scale; |
| 1168 | glfwGetMonitorContentScale(monitor, &x_scale, &y_scale); |
| 1169 | return x_scale; |
| 1170 | #else |
| 1171 | IM_UNUSED(monitor); |
| 1172 | return 1.0f; |
| 1173 | #endif |
| 1174 | } |
| 1175 | |
| 1176 | static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window, ImVec2* out_size, ImVec2* out_framebuffer_scale) |
| 1177 | { |
| 1178 | int w, h; |
| 1179 | int display_w, display_h; |
| 1180 | glfwGetWindowSize(window, &w, &h); |
| 1181 | glfwGetFramebufferSize(window, &display_w, &display_h); |
| 1182 | float fb_scale_x = (w > 0) ? (float)display_w / (float)w : 1.0f; |
| 1183 | float fb_scale_y = (h > 0) ? (float)display_h / (float)h : 1.0f; |
| 1184 | #if GLFW_HAS_WAYLAND |
| 1185 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window); |
| 1186 | if (!bd->IsWayland) |
| 1187 | fb_scale_x = fb_scale_y = 1.0f; |
| 1188 | #endif |
| 1189 | if (out_size != nullptr) |
| 1190 | *out_size = ImVec2((float)w, (float)h); |
| 1191 | if (out_framebuffer_scale != nullptr) |
| 1192 | *out_framebuffer_scale = ImVec2(fb_scale_x, fb_scale_y); |
| 1193 | } |
| 1194 | |
| 1195 | void ImGui_ImplGlfw_NewFrame() |
| 1196 | { |
| 1197 | ImGuiIO& io = ImGui::GetIO(); |
| 1198 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1199 | IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?"); |
| 1200 | |
| 1201 | |
| 1202 | ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale); |
| 1203 | ImGui_ImplGlfw_UpdateMonitors(); |
| 1204 | |
| 1205 | |
| 1206 | |
| 1207 | double current_time = glfwGetTime(); |
| 1208 | if (current_time <= bd->Time) |
| 1209 | current_time = bd->Time + 0.00001; |
| 1210 | io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); |
| 1211 | bd->Time = current_time; |
| 1212 | |
| 1213 | bd->MouseIgnoreButtonUp = false; |
| 1214 | ImGui_ImplGlfw_UpdateMouseData(); |
| 1215 | ImGui_ImplGlfw_UpdateMouseCursor(); |
| 1216 | |
| 1217 | |
| 1218 | ImGui_ImplGlfw_UpdateGamepads(); |
| 1219 | } |
| 1220 | |
| 1221 | |
| 1222 | void ImGui_ImplGlfw_Sleep(int milliseconds) |
| 1223 | { |
| 1224 | #ifdef _WIN32 |
| 1225 | ::Sleep(milliseconds); |
| 1226 | #else |
| 1227 | usleep(milliseconds * 1000); |
| 1228 | #endif |
| 1229 | } |
| 1230 | |
| 1231 | #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 |
| 1232 | static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange(int event_type, const EmscriptenUiEvent* event, void* user_data) |
| 1233 | { |
| 1234 | ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data; |
| 1235 | double canvas_width, canvas_height; |
| 1236 | emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height); |
| 1237 | glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height); |
| 1238 | return true; |
| 1239 | } |
| 1240 | |
| 1241 | static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback(int event_type, const EmscriptenFullscreenChangeEvent* event, void* user_data) |
| 1242 | { |
| 1243 | ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data; |
| 1244 | double canvas_width, canvas_height; |
| 1245 | emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height); |
| 1246 | glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height); |
| 1247 | return true; |
| 1248 | } |
| 1249 | |
| 1250 | |
| 1251 | |
| 1252 | void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow*, const char* canvas_selector) |
| 1253 | { |
| 1254 | IM_ASSERT(canvas_selector != nullptr); |
| 1255 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1256 | IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?"); |
| 1257 | |
| 1258 | bd->CanvasSelector = canvas_selector; |
| 1259 | emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, bd, false, ImGui_ImplGlfw_OnCanvasSizeChange); |
| 1260 | emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, bd, false, ImGui_ImplEmscripten_FullscreenChangeCallback); |
| 1261 | |
| 1262 | |
| 1263 | ImGui_ImplGlfw_OnCanvasSizeChange(EMSCRIPTEN_EVENT_RESIZE, {}, bd); |
| 1264 | |
| 1265 | |
| 1266 | |
| 1267 | |
| 1268 | emscripten_set_wheel_callback(bd->CanvasSelector, bd, false, ImGui_ImplEmscripten_WheelCallback); |
| 1269 | } |
| 1270 | #elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3) |
| 1271 | |
| 1272 | |
| 1273 | |
| 1274 | void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector) |
| 1275 | { |
| 1276 | GLFWwindow* w = (GLFWwindow*)(EM_ASM_INT({ return Module.glfwGetWindow(UTF8ToString($0)); }, canvas_selector)); |
| 1277 | IM_ASSERT(window == w); |
| 1278 | IM_UNUSED(w); |
| 1279 | emscripten_glfw_make_canvas_resizable(window, "window", nullptr); |
| 1280 | } |
| 1281 | #endif |
| 1282 | |
| 1283 | |
| 1284 | |
| 1285 | |
| 1286 | |
| 1287 | |
| 1288 | |
| 1289 | |
| 1290 | |
| 1291 | struct ImGui_ImplGlfw_ViewportData |
| 1292 | { |
| 1293 | GLFWwindow* Window; |
| 1294 | bool WindowOwned; |
| 1295 | int IgnoreWindowPosEventFrame; |
| 1296 | int IgnoreWindowSizeEventFrame; |
| 1297 | #ifdef _WIN32 |
| 1298 | WNDPROC PrevWndProc; |
| 1299 | #endif |
| 1300 | |
| 1301 | ImGui_ImplGlfw_ViewportData() { memset((void*)this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; } |
| 1302 | ~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); } |
| 1303 | }; |
| 1304 | |
| 1305 | static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window) |
| 1306 | { |
| 1307 | if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window)) |
| 1308 | viewport->PlatformRequestClose = true; |
| 1309 | } |
| 1310 | |
| 1311 | |
| 1312 | |
| 1313 | |
| 1314 | |
| 1315 | |
| 1316 | |
| 1317 | static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int) |
| 1318 | { |
| 1319 | if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window)) |
| 1320 | { |
| 1321 | if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) |
| 1322 | { |
| 1323 | bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1); |
| 1324 | |
| 1325 | if (ignore_event) |
| 1326 | return; |
| 1327 | } |
| 1328 | viewport->PlatformRequestMove = true; |
| 1329 | } |
| 1330 | } |
| 1331 | |
| 1332 | static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int) |
| 1333 | { |
| 1334 | if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window)) |
| 1335 | { |
| 1336 | if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) |
| 1337 | { |
| 1338 | bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowSizeEventFrame + 1); |
| 1339 | |
| 1340 | if (ignore_event) |
| 1341 | return; |
| 1342 | } |
| 1343 | viewport->PlatformRequestResize = true; |
| 1344 | } |
| 1345 | } |
| 1346 | |
| 1347 | #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && GLFW_HAS_GETPLATFORM |
| 1348 | #define IMGUI_GLFW_HAS_SETWINDOWFLOATING |
| 1349 | static void ImGui_ImplGlfw_SetWindowFloating(ImGui_ImplGlfw_Data* bd, GLFWwindow* window) |
| 1350 | { |
| 1351 | #ifdef GLFW_EXPOSE_NATIVE_X11 |
| 1352 | if (glfwGetPlatform() == GLFW_PLATFORM_X11) |
| 1353 | { |
| 1354 | Display* display = glfwGetX11Display(); |
| 1355 | Window xwindow = glfwGetX11Window(window); |
| 1356 | Atom wm_type = bd->XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); |
| 1357 | Atom wm_type_dialog = bd->XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); |
| 1358 | bd->XChangeProperty(display, xwindow, wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wm_type_dialog, 1); |
| 1359 | XSetWindowAttributes attrs; |
| 1360 | attrs.override_redirect = False; |
| 1361 | bd->XChangeWindowAttributes(display, xwindow, CWOverrideRedirect, &attrs); |
| 1362 | bd->XFlush(display); |
| 1363 | } |
| 1364 | #endif |
| 1365 | #ifdef GLFW_EXPOSE_NATIVE_WAYLAND |
| 1366 | |
| 1367 | #endif |
| 1368 | } |
| 1369 | #endif |
| 1370 | |
| 1371 | static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport) |
| 1372 | { |
| 1373 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1374 | ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)(); |
| 1375 | viewport->PlatformUserData = vd; |
| 1376 | |
| 1377 | |
| 1378 | #ifdef __linux__ |
| 1379 | bd->MouseIgnoreButtonUpWaitForFocusLoss = true; |
| 1380 | #endif |
| 1381 | |
| 1382 | |
| 1383 | |
| 1384 | glfwWindowHint(GLFW_VISIBLE, false); |
| 1385 | glfwWindowHint(GLFW_FOCUSED, false); |
| 1386 | #if GLFW_HAS_FOCUS_ON_SHOW |
| 1387 | glfwWindowHint(GLFW_FOCUS_ON_SHOW, false); |
| 1388 | #endif |
| 1389 | glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true); |
| 1390 | #if GLFW_HAS_WINDOW_TOPMOST |
| 1391 | glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false); |
| 1392 | #endif |
| 1393 | GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : nullptr; |
| 1394 | vd->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", nullptr, share_window); |
| 1395 | vd->WindowOwned = true; |
| 1396 | ImGui_ImplGlfw_ContextMap_Add(vd->Window, bd->Context); |
| 1397 | viewport->PlatformHandle = (void*)vd->Window; |
| 1398 | #ifdef IMGUI_GLFW_HAS_SETWINDOWFLOATING |
| 1399 | ImGui_ImplGlfw_SetWindowFloating(bd, vd->Window); |
| 1400 | #endif |
| 1401 | #ifdef _WIN32 |
| 1402 | viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window); |
| 1403 | ::SetPropA((HWND)viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", bd); |
| 1404 | #elif defined(__APPLE__) |
| 1405 | viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window); |
| 1406 | #endif |
| 1407 | glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y); |
| 1408 | |
| 1409 | |
| 1410 | glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback); |
| 1411 | glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback); |
| 1412 | glfwSetCursorPosCallback(vd->Window, ImGui_ImplGlfw_CursorPosCallback); |
| 1413 | glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback); |
| 1414 | glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback); |
| 1415 | glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback); |
| 1416 | glfwSetCharCallback(vd->Window, ImGui_ImplGlfw_CharCallback); |
| 1417 | glfwSetWindowCloseCallback(vd->Window, ImGui_ImplGlfw_WindowCloseCallback); |
| 1418 | glfwSetWindowPosCallback(vd->Window, ImGui_ImplGlfw_WindowPosCallback); |
| 1419 | glfwSetWindowSizeCallback(vd->Window, ImGui_ImplGlfw_WindowSizeCallback); |
| 1420 | if (bd->ClientApi == GlfwClientApi_OpenGL) |
| 1421 | { |
| 1422 | glfwMakeContextCurrent(vd->Window); |
| 1423 | glfwSwapInterval(0); |
| 1424 | } |
| 1425 | } |
| 1426 | |
| 1427 | static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport) |
| 1428 | { |
| 1429 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1430 | if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) |
| 1431 | { |
| 1432 | if (vd->WindowOwned) |
| 1433 | { |
| 1434 | #if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32) |
| 1435 | HWND hwnd = (HWND)viewport->PlatformHandleRaw; |
| 1436 | ::RemovePropA(hwnd, "IMGUI_VIEWPORT"); |
| 1437 | #endif |
| 1438 | |
| 1439 | |
| 1440 | |
| 1441 | for (int i = 0; i < IM_COUNTOF(bd->KeyOwnerWindows); i++) |
| 1442 | if (bd->KeyOwnerWindows[i] == vd->Window) |
| 1443 | ImGui_ImplGlfw_KeyCallback(vd->Window, i, 0, GLFW_RELEASE, 0); |
| 1444 | |
| 1445 | ImGui_ImplGlfw_ContextMap_Remove(vd->Window); |
| 1446 | glfwDestroyWindow(vd->Window); |
| 1447 | } |
| 1448 | vd->Window = nullptr; |
| 1449 | IM_DELETE(vd); |
| 1450 | } |
| 1451 | viewport->PlatformUserData = viewport->PlatformHandle = nullptr; |
| 1452 | } |
| 1453 | |
| 1454 | static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport) |
| 1455 | { |
| 1456 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1457 | |
| 1458 | #if defined(_WIN32) |
| 1459 | |
| 1460 | HWND hwnd = (HWND)viewport->PlatformHandleRaw; |
| 1461 | if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) |
| 1462 | { |
| 1463 | LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); |
| 1464 | ex_style &= ~WS_EX_APPWINDOW; |
| 1465 | ex_style |= WS_EX_TOOLWINDOW; |
| 1466 | ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); |
| 1467 | } |
| 1468 | |
| 1469 | |
| 1470 | ::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport); |
| 1471 | vd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC); |
| 1472 | ::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc); |
| 1473 | |
| 1474 | #if !GLFW_HAS_FOCUS_ON_SHOW |
| 1475 | |
| 1476 | |
| 1477 | |
| 1478 | |
| 1479 | if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) |
| 1480 | { |
| 1481 | ::ShowWindow(hwnd, SW_SHOWNA); |
| 1482 | return; |
| 1483 | } |
| 1484 | #endif |
| 1485 | #endif |
| 1486 | |
| 1487 | glfwShowWindow(vd->Window); |
| 1488 | } |
| 1489 | |
| 1490 | static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport) |
| 1491 | { |
| 1492 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1493 | int x = 0, y = 0; |
| 1494 | glfwGetWindowPos(vd->Window, &x, &y); |
| 1495 | return ImVec2((float)x, (float)y); |
| 1496 | } |
| 1497 | |
| 1498 | static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) |
| 1499 | { |
| 1500 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1501 | vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount(); |
| 1502 | glfwSetWindowPos(vd->Window, (int)pos.x, (int)pos.y); |
| 1503 | } |
| 1504 | |
| 1505 | static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport) |
| 1506 | { |
| 1507 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1508 | int w = 0, h = 0; |
| 1509 | glfwGetWindowSize(vd->Window, &w, &h); |
| 1510 | return ImVec2((float)w, (float)h); |
| 1511 | } |
| 1512 | |
| 1513 | static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) |
| 1514 | { |
| 1515 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1516 | #if defined(__APPLE__) && !GLFW_HAS_OSX_WINDOW_POS_FIX |
| 1517 | |
| 1518 | |
| 1519 | |
| 1520 | |
| 1521 | int x, y, width, height; |
| 1522 | glfwGetWindowPos(vd->Window, &x, &y); |
| 1523 | glfwGetWindowSize(vd->Window, &width, &height); |
| 1524 | glfwSetWindowPos(vd->Window, x, y - height + size.y); |
| 1525 | #endif |
| 1526 | vd->IgnoreWindowSizeEventFrame = ImGui::GetFrameCount(); |
| 1527 | glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y); |
| 1528 | } |
| 1529 | |
| 1530 | static ImVec2 ImGui_ImplGlfw_GetWindowFramebufferScale(ImGuiViewport* viewport) |
| 1531 | { |
| 1532 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1533 | ImVec2 framebuffer_scale; |
| 1534 | ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, &framebuffer_scale); |
| 1535 | return framebuffer_scale; |
| 1536 | } |
| 1537 | |
| 1538 | static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title) |
| 1539 | { |
| 1540 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1541 | glfwSetWindowTitle(vd->Window, title); |
| 1542 | } |
| 1543 | |
| 1544 | static void ImGui_ImplGlfw_SetWindowFocus(ImGuiViewport* viewport) |
| 1545 | { |
| 1546 | #if GLFW_HAS_FOCUS_WINDOW |
| 1547 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1548 | glfwFocusWindow(vd->Window); |
| 1549 | #else |
| 1550 | |
| 1551 | (void)viewport; |
| 1552 | #endif |
| 1553 | } |
| 1554 | |
| 1555 | static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport) |
| 1556 | { |
| 1557 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1558 | return glfwGetWindowAttrib(vd->Window, GLFW_FOCUSED) != 0; |
| 1559 | } |
| 1560 | |
| 1561 | static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport) |
| 1562 | { |
| 1563 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1564 | return glfwGetWindowAttrib(vd->Window, GLFW_ICONIFIED) != 0; |
| 1565 | } |
| 1566 | |
| 1567 | #if GLFW_HAS_WINDOW_ALPHA |
| 1568 | static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha) |
| 1569 | { |
| 1570 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1571 | glfwSetWindowOpacity(vd->Window, alpha); |
| 1572 | } |
| 1573 | #endif |
| 1574 | |
| 1575 | static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*) |
| 1576 | { |
| 1577 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1578 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1579 | if (bd->ClientApi == GlfwClientApi_OpenGL) |
| 1580 | glfwMakeContextCurrent(vd->Window); |
| 1581 | } |
| 1582 | |
| 1583 | static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport, void*) |
| 1584 | { |
| 1585 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1586 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1587 | if (bd->ClientApi == GlfwClientApi_OpenGL) |
| 1588 | { |
| 1589 | glfwMakeContextCurrent(vd->Window); |
| 1590 | glfwSwapBuffers(vd->Window); |
| 1591 | } |
| 1592 | } |
| 1593 | |
| 1594 | |
| 1595 | |
| 1596 | |
| 1597 | |
| 1598 | |
| 1599 | #if GLFW_HAS_VULKAN |
| 1600 | #ifndef VULKAN_H_ |
| 1601 | #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; |
| 1602 | #if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) |
| 1603 | #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; |
| 1604 | #else |
| 1605 | #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; |
| 1606 | #endif |
| 1607 | VK_DEFINE_HANDLE(VkInstance) |
| 1608 | VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) |
| 1609 | struct VkAllocationCallbacks; |
| 1610 | enum VkResult { VK_RESULT_MAX_ENUM = 0x7FFFFFFF }; |
| 1611 | #endif |
| 1612 | extern "C" { extern GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); } |
| 1613 | static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) |
| 1614 | { |
| 1615 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1616 | ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData; |
| 1617 | IM_UNUSED(bd); |
| 1618 | IM_ASSERT(bd->ClientApi == GlfwClientApi_Vulkan); |
| 1619 | VkResult err = glfwCreateWindowSurface((VkInstance)vk_instance, vd->Window, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface); |
| 1620 | return (int)err; |
| 1621 | } |
| 1622 | #endif |
| 1623 | |
| 1624 | static void ImGui_ImplGlfw_InitMultiViewportSupport() |
| 1625 | { |
| 1626 | |
| 1627 | ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); |
| 1628 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); |
| 1629 | platform_io.Platform_CreateWindow = ImGui_ImplGlfw_CreateWindow; |
| 1630 | platform_io.Platform_DestroyWindow = ImGui_ImplGlfw_DestroyWindow; |
| 1631 | platform_io.Platform_ShowWindow = ImGui_ImplGlfw_ShowWindow; |
| 1632 | platform_io.Platform_SetWindowPos = ImGui_ImplGlfw_SetWindowPos; |
| 1633 | platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos; |
| 1634 | platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize; |
| 1635 | platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize; |
| 1636 | platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplGlfw_GetWindowFramebufferScale; |
| 1637 | platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus; |
| 1638 | platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus; |
| 1639 | platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized; |
| 1640 | platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle; |
| 1641 | platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow; |
| 1642 | platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers; |
| 1643 | #if GLFW_HAS_WINDOW_ALPHA |
| 1644 | platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha; |
| 1645 | #endif |
| 1646 | #if GLFW_HAS_VULKAN |
| 1647 | platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface; |
| 1648 | #endif |
| 1649 | |
| 1650 | |
| 1651 | |
| 1652 | ImGuiViewport* main_viewport = ImGui::GetMainViewport(); |
| 1653 | ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)(); |
| 1654 | vd->Window = bd->Window; |
| 1655 | vd->WindowOwned = false; |
| 1656 | main_viewport->PlatformUserData = vd; |
| 1657 | main_viewport->PlatformHandle = (void*)bd->Window; |
| 1658 | } |
| 1659 | |
| 1660 | static void ImGui_ImplGlfw_ShutdownMultiViewportSupport() |
| 1661 | { |
| 1662 | ImGui::DestroyPlatformWindows(); |
| 1663 | } |
| 1664 | |
| 1665 | |
| 1666 | |
| 1667 | |
| 1668 | #ifdef _WIN32 |
| 1669 | static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo() |
| 1670 | { |
| 1671 | LPARAM extra_info = ::GetMessageExtraInfo(); |
| 1672 | if ((extra_info & 0xFFFFFF80) == 0xFF515700) |
| 1673 | return ImGuiMouseSource_Pen; |
| 1674 | if ((extra_info & 0xFFFFFF80) == 0xFF515780) |
| 1675 | return ImGuiMouseSource_TouchScreen; |
| 1676 | return ImGuiMouseSource_Mouse; |
| 1677 | } |
| 1678 | static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
| 1679 | { |
| 1680 | ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)::GetPropA(hWnd, "IMGUI_BACKEND_DATA"); |
| 1681 | ImGuiIO& io = ImGui::GetIO(bd->Context); |
| 1682 | |
| 1683 | WNDPROC prev_wndproc = bd->PrevWndProc; |
| 1684 | ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT"); |
| 1685 | if (viewport != NULL) |
| 1686 | if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData) |
| 1687 | prev_wndproc = vd->PrevWndProc; |
| 1688 | |
| 1689 | switch (msg) |
| 1690 | { |
| 1691 | |
| 1692 | |
| 1693 | case WM_MOUSEMOVE: case WM_NCMOUSEMOVE: |
| 1694 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP: |
| 1695 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: |
| 1696 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP: |
| 1697 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP: |
| 1698 | io.AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo()); |
| 1699 | break; |
| 1700 | |
| 1701 | |
| 1702 | |
| 1703 | #if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED |
| 1704 | case WM_NCHITTEST: |
| 1705 | { |
| 1706 | |
| 1707 | |
| 1708 | |
| 1709 | |
| 1710 | if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs)) |
| 1711 | return HTTRANSPARENT; |
| 1712 | break; |
| 1713 | } |
| 1714 | #endif |
| 1715 | default: break; |
| 1716 | } |
| 1717 | return ::CallWindowProcW(prev_wndproc, hWnd, msg, wParam, lParam); |
| 1718 | } |
| 1719 | #endif |
| 1720 | |
| 1721 | |
| 1722 | |
| 1723 | #if defined(__clang__) |
| 1724 | #pragma clang diagnostic pop |
| 1725 | #endif |
| 1726 | |
| 1727 | #endif |