diff options
Diffstat (limited to 'platform/windows')
-rw-r--r-- | platform/windows/SCsub | 2 | ||||
-rw-r--r-- | platform/windows/context_gl_windows.cpp | 186 | ||||
-rw-r--r-- | platform/windows/crash_handler_windows.h | 1 | ||||
-rw-r--r-- | platform/windows/detect.py | 19 | ||||
-rw-r--r-- | platform/windows/display_server_windows.cpp | 525 | ||||
-rw-r--r-- | platform/windows/display_server_windows.h | 20 | ||||
-rw-r--r-- | platform/windows/gl_manager_windows.cpp | 346 | ||||
-rw-r--r-- | platform/windows/gl_manager_windows.h (renamed from platform/windows/context_gl_windows.h) | 93 | ||||
-rw-r--r-- | platform/windows/joypad_windows.cpp | 30 | ||||
-rw-r--r-- | platform/windows/key_mapping_windows.cpp | 564 | ||||
-rw-r--r-- | platform/windows/key_mapping_windows.h | 7 | ||||
-rw-r--r-- | platform/windows/os_windows.cpp | 78 | ||||
-rw-r--r-- | platform/windows/os_windows.h | 10 | ||||
-rw-r--r-- | platform/windows/platform_config.h | 2 | ||||
-rw-r--r-- | platform/windows/vulkan_context_win.h | 2 | ||||
-rw-r--r-- | platform/windows/windows_terminal_logger.cpp | 1 |
16 files changed, 1109 insertions, 777 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 47d8e14680..76234c3065 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -15,7 +15,7 @@ common_win = [ "joypad_windows.cpp", "windows_terminal_logger.cpp", "vulkan_context_win.cpp", - "context_gl_windows.cpp", + "gl_manager_windows.cpp", ] res_file = "godot_res.rc" diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp deleted file mode 100644 index 74b12cbb3b..0000000000 --- a/platform/windows/context_gl_windows.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************/ -/* context_gl_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) - -// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008 - -#include "context_gl_windows.h" - -#include <dwmapi.h> - -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 - -#if defined(__GNUC__) -// Workaround GCC warning from -Wcast-function-type. -#define wglGetProcAddress (void *)wglGetProcAddress -#endif - -typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *); - -void ContextGL_Windows::release_current() { - wglMakeCurrent(hDC, nullptr); -} - -void ContextGL_Windows::make_current() { - wglMakeCurrent(hDC, hRC); -} - -int ContextGL_Windows::get_window_width() { - return OS::get_singleton()->get_video_mode().width; -} - -int ContextGL_Windows::get_window_height() { - return OS::get_singleton()->get_video_mode().height; -} - -void ContextGL_Windows::swap_buffers() { - SwapBuffers(hDC); -} - -void ContextGL_Windows::set_use_vsync(bool p_use) { - if (wglSwapIntervalEXT) { - int swap_interval = p_use ? 1 : 0; - wglSwapIntervalEXT(swap_interval); - } - - use_vsync = p_use; -} - -bool ContextGL_Windows::is_using_vsync() const { - return use_vsync; -} - -#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 - -Error ContextGL_Windows::initialize() { - static PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor - 1, - PFD_DRAW_TO_WINDOW | // Format Must Support Window - PFD_SUPPORT_OPENGL | // Format Must Support OpenGL - PFD_DOUBLEBUFFER, - (BYTE)PFD_TYPE_RGBA, - (BYTE)(OS::get_singleton()->is_layered_allowed() ? 32 : 24), - (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Color Bits Ignored - (BYTE)(OS::get_singleton()->is_layered_allowed() ? 8 : 0), // Alpha Buffer - (BYTE)0, // Shift Bit Ignored - (BYTE)0, // No Accumulation Buffer - (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Accumulation Bits Ignored - (BYTE)24, // 24Bit Z-Buffer (Depth Buffer) - (BYTE)0, // No Stencil Buffer - (BYTE)0, // No Auxiliary Buffer - (BYTE)PFD_MAIN_PLANE, // Main Drawing Layer - (BYTE)0, // Reserved - 0, 0, 0 // Layer Masks Ignored - }; - - hDC = GetDC(hWnd); - if (!hDC) { - return ERR_CANT_CREATE; // Return FALSE - } - - pixel_format = ChoosePixelFormat(hDC, &pfd); - if (!pixel_format) // Did Windows Find A Matching Pixel Format? - { - return ERR_CANT_CREATE; // Return FALSE - } - - BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd); - if (!ret) // Are We Able To Set The Pixel Format? - { - return ERR_CANT_CREATE; // Return FALSE - } - - hRC = wglCreateContext(hDC); - if (!hRC) // Are We Able To Get A Rendering Context? - { - return ERR_CANT_CREATE; // Return FALSE - } - - wglMakeCurrent(hDC, hRC); - - if (opengl_3_context) { - int attribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //we want a 3.3 context - WGL_CONTEXT_MINOR_VERSION_ARB, 3, - //and it shall be forward compatible so that we can only use up to date functionality - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*| _WGL_CONTEXT_DEBUG_BIT_ARB*/, - 0 - }; //zero indicates the end of the array - - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; //pointer to the method - wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); - - if (wglCreateContextAttribsARB == nullptr) //OpenGL 3.0 is not supported - { - wglDeleteContext(hRC); - return ERR_CANT_CREATE; - } - - HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs); - if (!new_hRC) { - wglDeleteContext(hRC); - return ERR_CANT_CREATE; // Return false - } - wglMakeCurrent(hDC, nullptr); - wglDeleteContext(hRC); - hRC = new_hRC; - - if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context - { - return ERR_CANT_CREATE; // Return FALSE - } - } - - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); - //glWrapperInit(wrapper_get_proc_address); - - return OK; -} - -ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) { - opengl_3_context = p_opengl_3_context; - hWnd = hwnd; - use_vsync = false; - pixel_format = 0; -} - -ContextGL_Windows::~ContextGL_Windows() { -} - -#endif diff --git a/platform/windows/crash_handler_windows.h b/platform/windows/crash_handler_windows.h index e1ec8e6787..5cdc6d3e05 100644 --- a/platform/windows/crash_handler_windows.h +++ b/platform/windows/crash_handler_windows.h @@ -31,6 +31,7 @@ #ifndef CRASH_HANDLER_WINDOWS_H #define CRASH_HANDLER_WINDOWS_H +#define WIN32_LEAN_AND_MEAN #include <windows.h> // Crash handler exception only enabled with MSVC diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 3961480d23..aaaa50e729 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -203,11 +203,11 @@ def configure_msvc(env, manual_msvc_config): elif env["optimize"] == "size": # optimize for size env.Append(CCFLAGS=["/O1"]) env.Append(LINKFLAGS=["/OPT:REF"]) - env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"]) elif env["target"] == "debug": env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"]) - env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"]) + # Allow big objects. Only needed for debug, see MinGW branch for rationale. + env.AppendUnique(CCFLAGS=["/bigobj"]) env.Append(LINKFLAGS=["/DEBUG"]) if env["debug_symbols"]: @@ -228,9 +228,9 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CCFLAGS=["/MD"]) env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"]) - # Force to use Unicode encoding - env.AppendUnique(CCFLAGS=["/utf-8"]) + env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding. env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++ + if manual_msvc_config: # should be automatic if SCons found it if os.getenv("WindowsSdkDir") is not None: env.Prepend(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"]) @@ -281,7 +281,7 @@ def configure_msvc(env, manual_msvc_config): if not env["use_volk"]: LIBS += ["vulkan"] - # env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED']) + env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"]) LIBS += ["opengl32"] env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) @@ -351,7 +351,6 @@ def configure_mingw(env): elif env["target"] == "release_debug": env.Append(CCFLAGS=["-O2"]) - env.Append(CPPDEFINES=["DEBUG_ENABLED"]) if env["debug_symbols"]: env.Prepend(CCFLAGS=["-g2"]) if env["optimize"] == "speed": # optimize for speed (default) @@ -361,7 +360,10 @@ def configure_mingw(env): elif env["target"] == "debug": env.Append(CCFLAGS=["-g3"]) - env.Append(CPPDEFINES=["DEBUG_ENABLED"]) + # Allow big objects. It's supposed not to have drawbacks but seems to break + # GCC LTO, so enabling for debug builds only (which are not built with LTO + # and are the only ones with too big objects). + env.Append(CCFLAGS=["-Wa,-mbig-obj"]) if env["windows_subsystem"] == "gui": env.Append(LINKFLAGS=["-Wl,--subsystem,windows"]) @@ -457,8 +459,7 @@ def configure_mingw(env): if not env["use_volk"]: env.Append(LIBS=["vulkan"]) - ## TODO !!! Re-enable when OpenGLES Rendering Device is implemented !!! - # env.Append(CPPDEFINES=['OPENGL_ENABLED']) + env.Append(CPPDEFINES=["GLES3_ENABLED"]) env.Append(LIBS=["opengl32"]) env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)]) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index cf51caa6d5..9fe15366f4 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -38,7 +38,15 @@ #include <avrt.h> -#ifdef DEBUG_ENABLED +#if defined(GLES3_ENABLED) +#include "drivers/gles3/rasterizer_gles3.h" +#endif + +#if defined(__GNUC__) +// Workaround GCC warning from -Wcast-function-type. +#define GetProcAddress (void *)GetProcAddress +#endif + static String format_error_message(DWORD id) { LPWSTR messageBuffer = nullptr; size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -50,7 +58,6 @@ static String format_error_message(DWORD id) { return msg; } -#endif // DEBUG_ENABLED bool DisplayServerWindows::has_feature(Feature p_feature) const { switch (p_feature) { @@ -80,7 +87,7 @@ String DisplayServerWindows::get_name() const { } void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { - if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) { + if (windows.has(MAIN_WINDOW_ID) && (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN)) { // Mouse is grabbed (captured or confined). WindowData &wd = windows[MAIN_WINDOW_ID]; @@ -118,8 +125,10 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) { _THREAD_SAFE_METHOD_ - if (mouse_mode == p_mode) + if (mouse_mode == p_mode) { + // Already in the same mode; do nothing. return; + } mouse_mode = p_mode; @@ -134,7 +143,7 @@ void DisplayServerWindows::mouse_warp_to_position(const Point2i &p_to) { _THREAD_SAFE_METHOD_ if (!windows.has(last_focused_window)) { - return; //no window focused? + return; // No focused window? } if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -154,7 +163,6 @@ Point2i DisplayServerWindows::mouse_get_position() const { POINT p; GetCursorPos(&p); return Point2i(p.x, p.y); - //return Point2(old_x, old_y); } MouseButton DisplayServerWindows::mouse_get_button_state() const { @@ -165,12 +173,12 @@ void DisplayServerWindows::clipboard_set(const String &p_text) { _THREAD_SAFE_METHOD_ if (!windows.has(last_focused_window)) { - return; //no window focused? + return; // No focused window? } - // Convert LF line endings to CRLF in clipboard content - // Otherwise, line endings won't be visible when pasted in other software - String text = p_text.replace("\r\n", "\n").replace("\n", "\r\n"); // avoid \r\r\n + // Convert LF line endings to CRLF in clipboard content. + // Otherwise, line endings won't be visible when pasted in other software. + String text = p_text.replace("\r\n", "\n").replace("\n", "\r\n"); // Avoid \r\r\n. if (!OpenClipboard(windows[last_focused_window].hWnd)) { ERR_FAIL_MSG("Unable to open clipboard."); @@ -187,7 +195,7 @@ void DisplayServerWindows::clipboard_set(const String &p_text) { SetClipboardData(CF_UNICODETEXT, mem); - // set the CF_TEXT version (not needed?) + // Set the CF_TEXT version (not needed?). CharString utf8 = text.utf8(); mem = GlobalAlloc(GMEM_MOVEABLE, utf8.length() + 1); ERR_FAIL_COND_MSG(mem == nullptr, "Unable to allocate memory for clipboard contents."); @@ -206,7 +214,7 @@ String DisplayServerWindows::clipboard_get() const { _THREAD_SAFE_METHOD_ if (!windows.has(last_focused_window)) { - return String(); //no window focused? + return String(); // No focused window? } String ret; @@ -453,8 +461,8 @@ Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const { _THREAD_SAFE_METHOD_ Vector<DisplayServer::WindowID> ret; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<WindowID, WindowData> &E : windows) { + ret.push_back(E.key); } return ret; } @@ -464,9 +472,9 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons p.x = p_position.x; p.y = p_position.y; HWND hwnd = WindowFromPoint(p); - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (E->get().hWnd == hwnd) { - return E->key(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (E.value.hWnd == hwnd) { + return E.key; } } @@ -498,16 +506,18 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod } void DisplayServerWindows::show_window(WindowID p_id) { + ERR_FAIL_COND(!windows.has(p_id)); + WindowData &wd = windows[p_id]; if (p_id != MAIN_WINDOW_ID) { _update_window_style(p_id); } - ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window + ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show the window. if (!wd.no_focus) { - SetForegroundWindow(wd.hWnd); // Slightly Higher Priority - SetFocus(wd.hWnd); // Sets Keyboard Focus To + SetForegroundWindow(wd.hWnd); // Slightly higher priority. + SetFocus(wd.hWnd); // Set keyboard focus. } } @@ -532,6 +542,11 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { context_vulkan->window_destroy(p_window); } #endif +#ifdef GLES3_ENABLED + if (rendering_driver == "opengl3") { + gl_manager->window_destroy(p_window); + } +#endif if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) { wintab_WTClose(windows[p_window].wtctx); @@ -541,6 +556,12 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { windows.erase(p_window); } +void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_window_id) { +#if defined(GLES3_ENABLED) + gl_manager->window_make_current(p_window_id); +#endif +} + void DisplayServerWindows::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { _THREAD_SAFE_METHOD_ @@ -606,6 +627,8 @@ void DisplayServerWindows::window_set_mouse_passthrough(const Vector<Vector2> &p } void DisplayServerWindows::_update_window_mouse_passthrough(WindowID p_window) { + ERR_FAIL_COND(!windows.has(p_window)); + if (windows[p_window].mpath.size() == 0) { SetWindowRgn(windows[p_window].hWnd, nullptr, TRUE); } else { @@ -664,16 +687,11 @@ Point2i DisplayServerWindows::window_get_position(WindowID p_window) const { ClientToScreen(wd.hWnd, &point); return Point2i(point.x, point.y); - -#if 0 - //do not use this method, as it includes windows decorations - RECT r; - GetWindowRect(wd.hWnd, &r); - return Point2(r.left, r.top); -#endif } void DisplayServerWindows::_update_real_mouse_position(WindowID p_window) { + ERR_FAIL_COND(!windows.has(p_window)); + POINT mouse_pos; if (GetCursorPos(&mouse_pos) && ScreenToClient(windows[p_window].hWnd, &mouse_pos)) { if (mouse_pos.x > 0 && mouse_pos.y > 0 && mouse_pos.x <= windows[p_window].width && mouse_pos.y <= windows[p_window].height) { @@ -691,14 +709,9 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; - if (wd.fullscreen) + if (wd.fullscreen) { return; -#if 0 - //wrong needs to account properly for decorations - RECT r; - GetWindowRect(wd.hWnd, &r); - MoveWindow(wd.hWnd, p_position.x, p_position.y, r.right - r.left, r.bottom - r.top, TRUE); -#else + } RECT rc; rc.left = p_position.x; @@ -711,8 +724,8 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window AdjustWindowRectEx(&rc, style, false, exStyle); MoveWindow(wd.hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); -#endif - // Don't let the mouse leave the window when moved + + // Don't let the mouse leave the window when moved. if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { RECT rect; GetClientRect(wd.hWnd, &rect); @@ -729,16 +742,15 @@ void DisplayServerWindows::window_set_transient(WindowID p_window, WindowID p_pa _THREAD_SAFE_METHOD_ ERR_FAIL_COND(p_window == p_parent); - ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd_window = windows[p_window]; ERR_FAIL_COND(wd_window.transient_parent == p_parent); - ERR_FAIL_COND_MSG(wd_window.always_on_top, "Windows with the 'on top' can't become transient."); if (p_parent == INVALID_WINDOW_ID) { - //remove transient + // Remove transient. ERR_FAIL_COND(wd_window.transient_parent == INVALID_WINDOW_ID); ERR_FAIL_COND(!windows.has(wd_window.transient_parent)); @@ -820,6 +832,11 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo context_vulkan->window_resize(p_window, w, h); } #endif +#if defined(GLES3_ENABLED) + if (rendering_driver == "opengl3") { + gl_manager->window_resize(p_window, w, h); + } +#endif if (wd.fullscreen) { return; @@ -838,7 +855,7 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo MoveWindow(wd.hWnd, rect.left, rect.top, w, h, TRUE); - // Don't let the mouse leave the window when resizing to a smaller resolution + // Don't let the mouse leave the window when resizing to a smaller resolution. if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { RECT crect; GetClientRect(wd.hWnd, &crect); @@ -860,7 +877,7 @@ Size2i DisplayServerWindows::window_get_size(WindowID p_window) const { } RECT r; - if (GetClientRect(wd.hWnd, &r)) { // Retrieves area inside of window border. + if (GetClientRect(wd.hWnd, &r)) { // Retrieves area inside of window border, including decoration. return Size2(r.right - r.left, r.bottom - r.top); } return Size2(); @@ -873,13 +890,17 @@ Size2i DisplayServerWindows::window_get_real_size(WindowID p_window) const { const WindowData &wd = windows[p_window]; RECT r; - if (GetWindowRect(wd.hWnd, &r)) { // Includes area of the window border + if (GetWindowRect(wd.hWnd, &r)) { // Retrieves area inside of window border, including decoration. return Size2(r.right - r.left, r.bottom - r.top); } return Size2(); } void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscreen, bool p_borderless, bool p_resizable, bool p_maximized, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex) { + // Windows docs for window styles: + // https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles + // https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles + r_style = 0; r_style_ex = WS_EX_WINDOWEDGE; if (p_main_window) { @@ -887,10 +908,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre } if (p_fullscreen || p_borderless) { - r_style |= WS_POPUP; - //if (p_borderless) { - // r_style_ex |= WS_EX_TOOLWINDOW; - //} + r_style |= WS_POPUP; // p_borderless was WS_EX_TOOLWINDOW in the past. } else { if (p_resizable) { if (p_maximized) { @@ -960,6 +978,11 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) _update_window_style(p_window, false); MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); + + if (restore_mouse_trails > 1) { + SystemParametersInfoA(SPI_SETMOUSETRAILS, restore_mouse_trails, 0, 0); + restore_mouse_trails = 0; + } } else if (p_mode == WINDOW_MODE_WINDOWED) { ShowWindow(wd.hWnd, SW_RESTORE); wd.maximized = false; @@ -999,6 +1022,13 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) _update_window_style(false); MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); + + // If the user has mouse trails enabled in windows, then sometimes the cursor disappears in fullscreen mode. + // Save number of trails so we can restore when exiting, then turn off mouse trails + SystemParametersInfoA(SPI_GETMOUSETRAILS, 0, &restore_mouse_trails, 0); + if (restore_mouse_trails > 1) { + SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, 0, 0); + } } } @@ -1026,7 +1056,7 @@ bool DisplayServerWindows::window_is_maximize_allowed(WindowID p_window) const { // FIXME: Implement this, or confirm that it should always be true. - return true; //no idea + return true; } void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { @@ -1124,8 +1154,8 @@ bool DisplayServerWindows::window_can_draw(WindowID p_window) const { bool DisplayServerWindows::can_any_window_draw() const { _THREAD_SAFE_METHOD_ - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (!E->get().minimized) { + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (!E.value.minimized) { return true; } } @@ -1171,8 +1201,9 @@ void DisplayServerWindows::window_set_ime_position(const Point2i &p_pos, WindowI void DisplayServerWindows::console_set_visible(bool p_enabled) { _THREAD_SAFE_METHOD_ - if (console_visible == p_enabled) + if (console_visible == p_enabled) { return; + } ShowWindow(GetConsoleWindow(), p_enabled ? SW_SHOW : SW_HIDE); console_visible = p_enabled; } @@ -1186,8 +1217,9 @@ void DisplayServerWindows::cursor_set_shape(CursorShape p_shape) { ERR_FAIL_INDEX(p_shape, CURSOR_MAX); - if (cursor_shape == p_shape) + if (cursor_shape == p_shape) { return; + } if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) { cursor_shape = p_shape; @@ -1197,11 +1229,11 @@ void DisplayServerWindows::cursor_set_shape(CursorShape p_shape) { static const LPCTSTR win_cursors[CURSOR_MAX] = { IDC_ARROW, IDC_IBEAM, - IDC_HAND, //finger + IDC_HAND, // Finger. IDC_CROSS, IDC_WAIT, IDC_APPSTARTING, - IDC_ARROW, + IDC_SIZEALL, IDC_ARROW, IDC_NO, IDC_SIZENS, @@ -1228,49 +1260,49 @@ DisplayServer::CursorShape DisplayServerWindows::cursor_get_shape() const { } void DisplayServerWindows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap) { - // Get the system display DC + // Get the system display DC. HDC hDC = GetDC(nullptr); - // Create helper DC + // Create helper DC. HDC hMainDC = CreateCompatibleDC(hDC); HDC hAndMaskDC = CreateCompatibleDC(hDC); HDC hXorMaskDC = CreateCompatibleDC(hDC); - // Get the dimensions of the source bitmap + // Get the dimensions of the source bitmap. BITMAP bm; GetObject(hSourceBitmap, sizeof(BITMAP), &bm); - // Create the mask bitmaps - hAndMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // color - hXorMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // color + // Create the mask bitmaps. + hAndMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // Color. + hXorMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // Color. - // Release the system display DC + // Release the system display DC. ReleaseDC(nullptr, hDC); - // Select the bitmaps to helper DC + // Select the bitmaps to helper DC. HBITMAP hOldMainBitmap = (HBITMAP)SelectObject(hMainDC, hSourceBitmap); HBITMAP hOldAndMaskBitmap = (HBITMAP)SelectObject(hAndMaskDC, hAndMaskBitmap); HBITMAP hOldXorMaskBitmap = (HBITMAP)SelectObject(hXorMaskDC, hXorMaskBitmap); // Assign the monochrome AND mask bitmap pixels so that the pixels of the source bitmap - // with 'clrTransparent' will be white pixels of the monochrome bitmap + // with 'clrTransparent' will be white pixels of the monochrome bitmap. SetBkColor(hMainDC, clrTransparent); BitBlt(hAndMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hMainDC, 0, 0, SRCCOPY); // Assign the color XOR mask bitmap pixels so that the pixels of the source bitmap // with 'clrTransparent' will be black and rest the pixels same as corresponding - // pixels of the source bitmap + // pixels of the source bitmap. SetBkColor(hXorMaskDC, RGB(0, 0, 0)); SetTextColor(hXorMaskDC, RGB(255, 255, 255)); BitBlt(hXorMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hAndMaskDC, 0, 0, SRCCOPY); BitBlt(hXorMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hMainDC, 0, 0, SRCAND); - // Deselect bitmaps from the helper DC + // Deselect bitmaps from the helper DC. SelectObject(hMainDC, hOldMainBitmap); SelectObject(hAndMaskDC, hOldAndMaskBitmap); SelectObject(hXorMaskDC, hOldXorMaskBitmap); - // Delete the helper DC + // Delete the helper DC. DeleteDC(hXorMaskDC); DeleteDC(hAndMaskDC); DeleteDC(hMainDC); @@ -1327,7 +1359,7 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh UINT image_size = texture_size.width * texture_size.height; - // Create the BITMAP with alpha channel + // Create the BITMAP with alpha channel. COLORREF *buffer = (COLORREF *)memalloc(sizeof(COLORREF) * image_size); for (UINT index = 0; index < image_size; index++) { @@ -1342,11 +1374,11 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh *(buffer + index) = image->get_pixel(column_index, row_index).to_argb32(); } - // Using 4 channels, so 4 * 8 bits + // Using 4 channels, so 4 * 8 bits. HBITMAP bitmap = CreateBitmap(texture_size.width, texture_size.height, 1, 4 * 8, buffer); COLORREF clrTransparent = -1; - // Create the AND and XOR masks for the bitmap + // Create the AND and XOR masks for the bitmap. HBITMAP hAndMask = nullptr; HBITMAP hXorMask = nullptr; @@ -1358,7 +1390,7 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh return; } - // Finally, create the icon + // Finally, create the icon. ICONINFO iconinfo; iconinfo.fIcon = FALSE; iconinfo.xHotspot = p_hotspot.x; @@ -1366,8 +1398,9 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh iconinfo.hbmMask = hAndMask; iconinfo.hbmColor = hXorMask; - if (cursors[p_shape]) + if (cursors[p_shape]) { DestroyIcon(cursors[p_shape]); + } cursors[p_shape] = CreateIconIndirect(&iconinfo); @@ -1393,7 +1426,7 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh memfree(buffer); DeleteObject(bitmap); } else { - // Reset to default system cursor + // Reset to default system cursor. if (cursors[p_shape]) { DestroyIcon(cursors[p_shape]); cursors[p_shape] = nullptr; @@ -1466,6 +1499,42 @@ String DisplayServerWindows::keyboard_get_layout_language(int p_index) const { return String::utf16((const char16_t *)buf).substr(0, 2); } +Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) const { + Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK; + Key keycode_no_mod = (Key)(p_keycode & KeyModifierMask::CODE_MASK); + + if (keycode_no_mod == Key::PRINT || + keycode_no_mod == Key::KP_ADD || + keycode_no_mod == Key::KP_5 || + (keycode_no_mod >= Key::KEY_0 && keycode_no_mod <= Key::KEY_9)) { + return p_keycode; + } + + unsigned int scancode = KeyMappingWindows::get_scancode(keycode_no_mod); + if (scancode == 0) { + return p_keycode; + } + + HKL current_layout = GetKeyboardLayout(0); + UINT vk = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK, current_layout); + if (vk == 0) { + return p_keycode; + } + + UINT char_code = MapVirtualKeyEx(vk, MAPVK_VK_TO_CHAR, current_layout) & 0x7FFF; + // Unlike a similar Linux/BSD check which matches full Latin-1 range, + // we limit these to ASCII to fix some layouts, including Arabic ones + if (char_code >= 32 && char_code <= 127) { + // Godot uses 'braces' instead of 'brackets' + if (char_code == (unsigned int)Key::BRACKETLEFT || char_code == (unsigned int)Key::BRACKETRIGHT) { + char_code += 32; + } + return (Key)(char_code | (unsigned int)modifiers); + } + + return (Key)(KeyMappingWindows::get_keysym(vk) | modifiers); +} + String _get_full_layout_name_from_registry(HKL p_layout) { String id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0"); String ret; @@ -1547,6 +1616,9 @@ void DisplayServerWindows::make_rendering_thread() { } void DisplayServerWindows::swap_buffers() { +#if defined(GLES3_ENABLED) + gl_manager->swap_buffers(); +#endif } void DisplayServerWindows::set_native_icon(const String &p_filename) { @@ -1575,9 +1647,9 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY)); f->get_buffer((uint8_t *)&icon_dir->idEntries[0], icon_dir->idCount * sizeof(ICONDIRENTRY)); - int small_icon_index = -1; // Select 16x16 with largest color count + int small_icon_index = -1; // Select 16x16 with largest color count. int small_icon_cc = 0; - int big_icon_index = -1; // Select largest + int big_icon_index = -1; // Select largest. int big_icon_width = 16; int big_icon_cc = 0; @@ -1607,7 +1679,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { small_icon_cc = big_icon_cc; } - // Read the big icon + // Read the big icon. DWORD bytecount_big = icon_dir->idEntries[big_icon_index].dwBytesInRes; Vector<uint8_t> data_big; data_big.resize(bytecount_big); @@ -1617,7 +1689,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { HICON icon_big = CreateIconFromResource((PBYTE)&data_big.write[0], bytecount_big, TRUE, 0x00030000); ERR_FAIL_COND_MSG(!icon_big, "Could not create " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon, error: " + format_error_message(GetLastError()) + "."); - // Read the small icon + // Read the small icon. DWORD bytecount_small = icon_dir->idEntries[small_icon_index].dwBytesInRes; Vector<uint8_t> data_small; data_small.resize(bytecount_small); @@ -1627,7 +1699,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { HICON icon_small = CreateIconFromResource((PBYTE)&data_small.write[0], bytecount_small, TRUE, 0x00030000); ERR_FAIL_COND_MSG(!icon_small, "Could not create 16x16 @" + itos(small_icon_cc) + " icon, error: " + format_error_message(GetLastError()) + "."); - // Online tradition says to be sure last error is cleared and set the small icon first + // Online tradition says to be sure last error is cleared and set the small icon first. int err = 0; SetLastError(err); @@ -1648,12 +1720,13 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) { ERR_FAIL_COND(!p_icon.is_valid()); Ref<Image> icon = p_icon->duplicate(); - if (icon->get_format() != Image::FORMAT_RGBA8) + if (icon->get_format() != Image::FORMAT_RGBA8) { icon->convert(Image::FORMAT_RGBA8); + } int w = icon->get_width(); int h = icon->get_height(); - /* Create temporary bitmap buffer */ + // Create temporary bitmap buffer. int icon_len = 40 + h * w * 4; Vector<BYTE> v; v.resize(icon_len); @@ -1687,27 +1760,28 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) { HICON hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); - /* Set the icon for the window */ + // Set the icon for the window. SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hicon); - /* Set the icon in the task manager (should we do this?) */ + // Set the icon in the task manager (should we do this?). SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_SETICON, ICON_BIG, (LPARAM)hicon); } void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ #if defined(VULKAN_ENABLED) - context_vulkan->set_vsync_mode(p_window, p_vsync_mode); + // TODO disabling for now + //context_vulkan->set_vsync_mode(p_window, p_vsync_mode); #endif } DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ #if defined(VULKAN_ENABLED) - return context_vulkan->get_vsync_mode(p_window); -#else - return DisplayServer::VSYNC_ENABLED; + //TODO disabling for now + //return context_vulkan->get_vsync_mode(p_window); #endif + return DisplayServer::VSYNC_ENABLED; } void DisplayServerWindows::set_context(Context p_context) { @@ -1718,13 +1792,13 @@ void DisplayServerWindows::set_context(Context p_context) { // Keeping the name suggested by Microsoft, but this macro really answers: // Is this mouse event emulated from touch or pen input? #define IsPenEvent(dw) (((dw)&SIGNATURE_MASK) == MI_WP_SIGNATURE) -// This one tells whether the event comes from touchscreen (and not from pen) +// This one tells whether the event comes from touchscreen (and not from pen). #define IsTouchEvent(dw) (IsPenEvent(dw) && ((dw)&0x80)) void DisplayServerWindows::_touch_event(WindowID p_window, bool p_pressed, float p_x, float p_y, int idx) { - // Defensive - if (touch_state.has(idx) == p_pressed) + if (touch_state.has(idx) == p_pressed) { return; + } if (p_pressed) { touch_state.insert(idx, Vector2(p_x, p_y)); @@ -1744,12 +1818,13 @@ void DisplayServerWindows::_touch_event(WindowID p_window, bool p_pressed, float void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y, int idx) { Map<int, Vector2>::Element *curr = touch_state.find(idx); - // Defensive - if (!curr) + if (!curr) { return; + } - if (curr->get() == Vector2(p_x, p_y)) + if (curr->get() == Vector2(p_x, p_y)) { return; + } Ref<InputEventScreenDrag> event; event.instantiate(); @@ -1791,7 +1866,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) Ref<InputEventFromWindow> event_from_window = p_event; if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { - //send to a window + // Send to a single window. if (!windows.has(event_from_window->get_window_id())) { in_dispatch_input_event = false; ERR_FAIL_MSG("DisplayServerWindows: Invalid window id in input event."); @@ -1803,9 +1878,9 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) } callable.call((const Variant **)&evp, 1, ret, ce); } else { - //send to all windows - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - Callable callable = E->get().input_event_callback; + // Send to all windows. + for (const KeyValue<WindowID, WindowData> &E : windows) { + const Callable callable = E.value.input_event_callback; if (callable.is_null()) { continue; } @@ -1816,6 +1891,9 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) in_dispatch_input_event = false; } +// Our default window procedure to handle processing of window-related system messages/events. +// Also known as DefProc or DefWindowProc. +// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/window-procedures LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (drop_events) { if (user_proc) { @@ -1828,27 +1906,28 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA WindowID window_id = INVALID_WINDOW_ID; bool window_created = false; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (E->get().hWnd == hWnd) { - window_id = E->key(); + // Check whether window exists. + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (E.value.hWnd == hWnd) { + window_id = E.key; window_created = true; break; } } + // Window doesn't exist or creation in progress, don't handle messages yet. if (!window_created) { - // Window creation in progress. window_id = window_id_counter; ERR_FAIL_COND_V(!windows.has(window_id), 0); } - switch (uMsg) // Check For Windows Messages - { + // Process window messages. + switch (uMsg) { case WM_SETFOCUS: { windows[window_id].window_has_focus = true; last_focused_window = window_id; - // Restore mouse mode + // Restore mouse mode. _set_mouse_mode_impl(mouse_mode); if (!app_focused) { @@ -1857,18 +1936,17 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } app_focused = true; } - break; - } + } break; case WM_KILLFOCUS: { windows[window_id].window_has_focus = false; last_focused_window = window_id; - // Release capture unconditionally because it can be set due to dragging, in addition to captured mode + // Release capture unconditionally because it can be set due to dragging, in addition to captured mode. ReleaseCapture(); - // Release every touch to avoid sticky points - for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) { - _touch_event(window_id, false, E->get().x, E->get().y, E->key()); + // Release every touch to avoid sticky points. + for (const KeyValue<int, Vector2> &E : touch_state) { + _touch_event(window_id, false, E.value.x, E.value.y, E.key); } touch_state.clear(); @@ -1884,10 +1962,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } app_focused = false; } - - break; - } - case WM_ACTIVATE: { // Watch For Window Activate Message + } break; + case WM_ACTIVATE: { // Watch for window activate message. if (!windows[window_id].window_focused) { _process_activate_event(window_id, wParam, lParam); } else { @@ -1897,8 +1973,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA // Run a timer to prevent event catching warning if the focused window is closing. windows[window_id].focus_timer_id = SetTimer(windows[window_id].hWnd, 2, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); } - return 0; // Return To The Message Loop - } + return 0; // Return to the message loop. + } break; case WM_GETMINMAXINFO: { if (windows[window_id].resizable && !windows[window_id].fullscreen) { // Size of window decorations. @@ -1914,37 +1990,31 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA min_max_info->ptMaxTrackSize.y = windows[window_id].max_size.y + decor.y; } return 0; - } else { - break; } - } - case WM_PAINT: - + } break; + case WM_PAINT: { Main::force_redraw(); - break; - - case WM_SYSCOMMAND: // Intercept System Commands + } break; + case WM_SYSCOMMAND: // Intercept system commands. { - switch (wParam) // Check System Calls + switch (wParam) // Check system calls. { - case SC_SCREENSAVE: // Screensaver Trying To Start? - case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? - return 0; // Prevent From Happening + case SC_SCREENSAVE: // Screensaver trying to start? + case SC_MONITORPOWER: // Monitor trying to enter powersave? + return 0; // Prevent from happening. case SC_KEYMENU: if ((lParam >> 16) <= 0) return 0; } - break; // Exit - } - - case WM_CLOSE: // Did We Receive A Close Message? + } break; + case WM_CLOSE: // Did we receive a close message? { if (windows[window_id].focus_timer_id != 0U) { KillTimer(windows[window_id].hWnd, windows[window_id].focus_timer_id); } _send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST); - return 0; // Jump Back + return 0; // Jump back. } case WM_MOUSELEAVE: { old_invalid = true; @@ -1986,7 +2056,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Point2i c(windows[window_id].width / 2, windows[window_id].height / 2); - // centering just so it works as before + // Centering just so it works as before. POINT pos = { (int)c.x, (int)c.y }; ClientToScreen(windows[window_id].hWnd, &pos); SetCursorPos(pos.x, pos.y); @@ -2009,7 +2079,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA (double(raw->data.mouse.lLastX) - 65536.0 / (nScreenWidth)) * nScreenWidth / 65536.0 + nScreenLeft, (double(raw->data.mouse.lLastY) - 65536.0 / (nScreenHeight)) * nScreenHeight / 65536.0 + nScreenTop); - POINT coords; //client coords + POINT coords; // Client coords. coords.x = abs_pos.x; coords.y = abs_pos.y; @@ -2018,14 +2088,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_relative(Vector2(coords.x - old_x, coords.y - old_y)); old_x = coords.x; old_y = coords.y; - - /*Input.mi.dx = (int)((((double)(pos.x)-nScreenLeft) * 65536) / nScreenWidth + 65536 / (nScreenWidth)); - Input.mi.dy = (int)((((double)(pos.y)-nScreenTop) * 65536) / nScreenHeight + 65536 / (nScreenHeight)); - */ } - if (windows[window_id].window_has_focus && mm->get_relative() != Vector2()) + if (windows[window_id].window_has_focus && mm->get_relative() != Vector2()) { Input::get_singleton()->parse_input_event(mm); + } } delete[] lpb; } break; @@ -2170,7 +2237,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (Input::get_singleton()->is_emulating_mouse_from_touch()) { - // Universal translation enabled; ignore OS translation + // Universal translation enabled; ignore OS translation. LPARAM extra = GetMessageExtraInfo(); if (IsTouchEvent(extra)) { break; @@ -2178,7 +2245,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (outside) { - //mouse enter + // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); @@ -2189,7 +2256,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA cursor_set_shape(c); outside = false; - //Once-Off notification, must call again.... + // Once-off notification, must call again. TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; @@ -2222,7 +2289,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_button_mask(last_button_state); - POINT coords; //client coords + POINT coords; // Client coords. coords.x = GET_X_LPARAM(lParam); coords.y = GET_Y_LPARAM(lParam); @@ -2264,7 +2331,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Input::get_singleton()->parse_input_event(mm); } - return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event + return 0; // Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event. } break; case WM_MOUSEMOVE: { if (windows[window_id].block_mm) { @@ -2276,7 +2343,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (Input::get_singleton()->is_emulating_mouse_from_touch()) { - // Universal translation enabled; ignore OS translation + // Universal translation enabled; ignore OS translation. LPARAM extra = GetMessageExtraInfo(); if (IsTouchEvent(extra)) { break; @@ -2284,7 +2351,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (outside) { - //mouse enter + // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); @@ -2295,7 +2362,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA cursor_set_shape(c); outside = false; - //Once-Off notification, must call again.... + // Once-off notification, must call again. TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; @@ -2373,7 +2440,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_LBUTTONDOWN: case WM_LBUTTONUP: if (Input::get_singleton()->is_emulating_mouse_from_touch()) { - // Universal translation enabled; ignore OS translations for left button + // Universal translation enabled; ignore OS translations for left button. LPARAM extra = GetMessageExtraInfo(); if (IsTouchEvent(extra)) { break; @@ -2399,41 +2466,41 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA switch (uMsg) { case WM_LBUTTONDOWN: { mb->set_pressed(true); - mb->set_button_index(MOUSE_BUTTON_LEFT); + mb->set_button_index(MouseButton::LEFT); } break; case WM_LBUTTONUP: { mb->set_pressed(false); - mb->set_button_index(MOUSE_BUTTON_LEFT); + mb->set_button_index(MouseButton::LEFT); } break; case WM_MBUTTONDOWN: { mb->set_pressed(true); - mb->set_button_index(MOUSE_BUTTON_MIDDLE); + mb->set_button_index(MouseButton::MIDDLE); } break; case WM_MBUTTONUP: { mb->set_pressed(false); - mb->set_button_index(MOUSE_BUTTON_MIDDLE); + mb->set_button_index(MouseButton::MIDDLE); } break; case WM_RBUTTONDOWN: { mb->set_pressed(true); - mb->set_button_index(MOUSE_BUTTON_RIGHT); + mb->set_button_index(MouseButton::RIGHT); } break; case WM_RBUTTONUP: { mb->set_pressed(false); - mb->set_button_index(MOUSE_BUTTON_RIGHT); + mb->set_button_index(MouseButton::RIGHT); } break; case WM_LBUTTONDBLCLK: { mb->set_pressed(true); - mb->set_button_index(MOUSE_BUTTON_LEFT); + mb->set_button_index(MouseButton::LEFT); mb->set_double_click(true); } break; case WM_RBUTTONDBLCLK: { mb->set_pressed(true); - mb->set_button_index(MOUSE_BUTTON_RIGHT); + mb->set_button_index(MouseButton::RIGHT); mb->set_double_click(true); } break; case WM_MBUTTONDBLCLK: { mb->set_pressed(true); - mb->set_button_index(MOUSE_BUTTON_MIDDLE); + mb->set_button_index(MouseButton::MIDDLE); mb->set_double_click(true); } break; case WM_MOUSEWHEEL: { @@ -2444,9 +2511,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (motion > 0) { - mb->set_button_index(MOUSE_BUTTON_WHEEL_UP); + mb->set_button_index(MouseButton::WHEEL_UP); } else { - mb->set_button_index(MOUSE_BUTTON_WHEEL_DOWN); + mb->set_button_index(MouseButton::WHEEL_DOWN); } mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); } break; @@ -2458,34 +2525,34 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (motion < 0) { - mb->set_button_index(MOUSE_BUTTON_WHEEL_LEFT); + mb->set_button_index(MouseButton::WHEEL_LEFT); } else { - mb->set_button_index(MOUSE_BUTTON_WHEEL_RIGHT); + mb->set_button_index(MouseButton::WHEEL_RIGHT); } mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); } break; case WM_XBUTTONDOWN: { mb->set_pressed(true); if (HIWORD(wParam) == XBUTTON1) { - mb->set_button_index(MOUSE_BUTTON_XBUTTON1); + mb->set_button_index(MouseButton::MB_XBUTTON1); } else { - mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + mb->set_button_index(MouseButton::MB_XBUTTON2); } } break; case WM_XBUTTONUP: { mb->set_pressed(false); if (HIWORD(wParam) == XBUTTON1) { - mb->set_button_index(MOUSE_BUTTON_XBUTTON1); + mb->set_button_index(MouseButton::MB_XBUTTON1); } else { - mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + mb->set_button_index(MouseButton::MB_XBUTTON2); } } break; case WM_XBUTTONDBLCLK: { mb->set_pressed(true); if (HIWORD(wParam) == XBUTTON1) { - mb->set_button_index(MOUSE_BUTTON_XBUTTON1); + mb->set_button_index(MouseButton::MB_XBUTTON1); } else { - mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + mb->set_button_index(MouseButton::MB_XBUTTON2); } mb->set_double_click(true); } break; @@ -2497,11 +2564,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_ctrl_pressed((wParam & MK_CONTROL) != 0); mb->set_shift_pressed((wParam & MK_SHIFT) != 0); mb->set_alt_pressed(alt_mem); - //mb->is_alt_pressed()=(wParam&MK_MENU)!=0; + // mb->is_alt_pressed()=(wParam&MK_MENU)!=0; if (mb->is_pressed()) { - last_button_state |= MouseButton(1 << (mb->get_button_index() - 1)); + last_button_state |= mouse_button_to_mask(mb->get_button_index()); } else { - last_button_state &= (MouseButton) ~(1 << (mb->get_button_index() - 1)); + last_button_state &= ~mouse_button_to_mask(mb->get_button_index()); } mb->set_button_mask(last_button_state); @@ -2524,7 +2591,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } } else { - // for reasons unknown to mankind, wheel comes in screen coordinates + // For reasons unknown to mankind, wheel comes in screen coordinates. POINT coords; coords.x = mb->get_position().x; coords.y = mb->get_position().y; @@ -2537,18 +2604,17 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_global_position(mb->get_position()); Input::get_singleton()->parse_input_event(mb); - if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) { - //send release for mouse wheel + if (mb->is_pressed() && mb->get_button_index() >= MouseButton::WHEEL_UP && mb->get_button_index() <= MouseButton::WHEEL_RIGHT) { + // Send release for mouse wheel. Ref<InputEventMouseButton> mbd = mb->duplicate(); mbd->set_window_id(window_id); - last_button_state &= (MouseButton) ~(1 << (mbd->get_button_index() - 1)); + last_button_state &= ~mouse_button_to_mask(mbd->get_button_index()); mbd->set_button_mask(last_button_state); mbd->set_pressed(false); Input::get_singleton()->parse_input_event(mbd); } } break; - case WM_MOVE: { if (!IsIconic(windows[window_id].hWnd)) { int x = int16_t(LOWORD(lParam)); @@ -2564,7 +2630,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } } break; - case WM_SIZE: { // Ignore window size change when a SIZE_MINIMIZED event is triggered. if (wParam != SIZE_MINIMIZED) { @@ -2642,7 +2707,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } #endif } break; - case WM_ENTERSIZEMOVE: { Input::get_singleton()->release_pressed_events(); windows[window_id].move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); @@ -2662,7 +2726,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA windows[window_id].focus_timer_id = 0U; } } break; - case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYUP: @@ -2714,7 +2777,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_INPUTLANGCHANGEREQUEST: { // FIXME: Do something? } break; - case WM_TOUCH: { BOOL bHandled = FALSE; UINT cInputs = LOWORD(wParam); @@ -2728,7 +2790,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA TOUCH_COORD_TO_PIXEL(ti.y), }; ScreenToClient(hWnd, &touch_pos); - //do something with each touch input entry + // Do something with each touch input entry. if (ti.dwFlags & TOUCHEVENTF_MOVE) { _drag_event(window_id, touch_pos.x, touch_pos.y, ti.dwID); } else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) { @@ -2737,11 +2799,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } bHandled = TRUE; } else { - /* handle the error here */ + // TODO: Handle the error here. } memdelete_arr(pInputs); } else { - /* handle the error here, probably out of memory */ + // TODO: Handle the error here, probably out of memory. } if (bHandled) { CloseTouchInputHandle((HTOUCHINPUT)lParam); @@ -2749,14 +2811,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA }; } break; - case WM_DEVICECHANGE: { joypad->probe_joypads(); } break; case WM_SETCURSOR: { if (LOWORD(lParam) == HTCLIENT) { if (windows[window_id].window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN)) { - //Hide the cursor + // Hide the cursor. if (hCursor == nullptr) { hCursor = SetCursor(nullptr); } else { @@ -2771,7 +2832,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } } - } break; case WM_DROPFILES: { HDROP hDropInfo = (HDROP)wParam; @@ -2795,9 +2855,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Callable::CallError ce; windows[window_id].drop_files_callback.call((const Variant **)&vp, 1, ret, ce); } - } break; - default: { if (user_proc) { return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam); @@ -2823,7 +2881,7 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM alt_mem = false; control_mem = false; shift_mem = false; - } else { // WM_INACTIVE + } else { // WM_INACTIVE. Input::get_singleton()->release_pressed_events(); _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT); windows[p_window_id].window_focused = false; @@ -2840,7 +2898,7 @@ void DisplayServerWindows::_process_key_events() { KeyEvent &ke = key_event_buffer[i]; switch (ke.uMsg) { case WM_CHAR: { - // extended keys should only be processed as WM_KEYDOWN message. + // Extended keys should only be processed as WM_KEYDOWN message. if (!KeyMappingWindows::is_extended_key(ke.wParam) && ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR))) { static char32_t prev_wc = 0; char32_t unicode = ke.wParam; @@ -2881,9 +2939,9 @@ void DisplayServerWindows::_process_key_events() { k->set_unicode(0); Input::get_singleton()->parse_input_event(k); + } else { + // Do nothing. } - - //do nothing } break; case WM_KEYUP: case WM_KEYDOWN: { @@ -2899,8 +2957,8 @@ void DisplayServerWindows::_process_key_events() { k->set_pressed(ke.uMsg == WM_KEYDOWN); if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) { - // Special case for Numpad Enter key - k->set_keycode(KEY_KP_ENTER); + // Special case for Numpad Enter key. + k->set_keycode(Key::KP_ENTER); } else { k->set_keycode((Key)KeyMappingWindows::get_keysym(ke.wParam)); } @@ -2948,8 +3006,8 @@ void DisplayServerWindows::_process_key_events() { } void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const String &p_new_driver) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - WindowData &wd = E->get(); + for (KeyValue<WindowID, WindowData> &E : windows) { + WindowData &wd = E.value; wd.block_mm = false; if ((p_old_driver == "wintab") && wintab_available && wd.wtctx) { wintab_WTEnable(wd.wtctx, false); @@ -3045,8 +3103,8 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, if (p_mode != WINDOW_MODE_FULLSCREEN) { wd.pre_fs_valid = true; } -#ifdef VULKAN_ENABLED +#ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) { memdelete(context_vulkan); @@ -3057,6 +3115,13 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, } #endif +#ifdef GLES3_ENABLED + if (rendering_driver == "opengl3") { + Error err = gl_manager->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Failed to create an OpenGL window."); + } +#endif + RegisterTouchWindow(wd.hWnd, 0); TRACKMOUSEEVENT tme; @@ -3101,7 +3166,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, wd.last_pressure_update = 0; wd.last_tilt = Vector2(); - // IME + // IME. wd.im_himc = ImmGetContext(wd.hWnd); ImmReleaseContext(wd.hWnd, wd.im_himc); @@ -3116,7 +3181,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, return id; } -// WinTab API +// WinTab API. bool DisplayServerWindows::wintab_available = false; WTOpenPtr DisplayServerWindows::wintab_WTOpen = nullptr; WTClosePtr DisplayServerWindows::wintab_WTClose = nullptr; @@ -3124,7 +3189,7 @@ WTInfoPtr DisplayServerWindows::wintab_WTInfo = nullptr; WTPacketPtr DisplayServerWindows::wintab_WTPacket = nullptr; WTEnablePtr DisplayServerWindows::wintab_WTEnable = nullptr; -// Windows Ink API +// Windows Ink API. bool DisplayServerWindows::winink_available = false; GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr; GetPointerPenInfoPtr DisplayServerWindows::win8p_GetPointerPenInfo = nullptr; @@ -3187,7 +3252,9 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win outside = true; - //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink. + rendering_driver = p_rendering_driver; + + // Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink. HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll"); if (wintab_lib) { wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW"); @@ -3203,7 +3270,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win tablet_drivers.push_back("wintab"); } - //Note: Windows Ink API for pen input, available on Windows 8+ only. + // Note: Windows Ink API for pen input, available on Windows 8+ only. HMODULE user32_lib = LoadLibraryW(L"user32.dll"); if (user32_lib) { win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType"); @@ -3236,7 +3303,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win wc.lpfnWndProc = (WNDPROC)::WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - //wc.hInstance = hInstance; wc.hInstance = hInstance ? hInstance : GetModuleHandle(nullptr); wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO); wc.hCursor = nullptr; //LoadCursor(nullptr, IDC_ARROW); @@ -3260,12 +3326,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win Rid[0].hwndTarget = 0; if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) { - //registration failed. + // Registration failed. use_raw_input = false; } - rendering_driver = "vulkan"; - #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { context_vulkan = memnew(VulkanContextWindows); @@ -3277,28 +3341,26 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } #endif -#if defined(OPENGL_ENABLED) - if (rendering_driver_index == VIDEO_DRIVER_GLES2) { - context_gles2 = memnew(ContextGL_Windows(hWnd, false)); - - if (context_gles2->initialize() != OK) { - memdelete(context_gles2); - context_gles2 = nullptr; - ERR_FAIL_V(ERR_UNAVAILABLE); - } + // Init context and rendering device +#if defined(GLES3_ENABLED) - context_gles2->set_use_vsync(video_mode.use_vsync); + if (rendering_driver == "opengl3") { + GLManager_Windows::ContextType opengl_api_type = GLManager_Windows::GLES_3_0_COMPATIBLE; - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - } else { - memdelete(context_gles2); - context_gles2 = nullptr; - ERR_FAIL_V(ERR_UNAVAILABLE); + gl_manager = memnew(GLManager_Windows(opengl_api_type)); + + if (gl_manager->initialize() != OK) { + memdelete(gl_manager); + gl_manager = nullptr; + r_error = ERR_UNAVAILABLE; + return; } + + // gl_manager->set_use_vsync(current_videomode.use_vsync); + RasterizerGLES3::make_current(); } #endif + Point2i window_position( (screen_get_size(0).width - p_resolution.width) / 2, (screen_get_size(0).height - p_resolution.height) / 2); @@ -3327,7 +3389,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win //set_ime_active(false); if (!OS::get_singleton()->is_in_low_processor_usage_mode()) { - //SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); DWORD index = 0; HANDLE handle = AvSetMmThreadCharacteristics("Games", &index); @@ -3335,7 +3396,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win AvSetMmThreadPriority(handle, AVRT_PRIORITY_CRITICAL); // This is needed to make sure that background work does not starve the main thread. - // This is only setting priority of this thread, not the whole process. + // This is only setting the priority of this thread, not the whole process. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); } @@ -3357,8 +3418,8 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() { #ifdef VULKAN_ENABLED drivers.push_back("vulkan"); #endif -#ifdef OPENGL_ENABLED - drivers.push_back("opengl"); +#ifdef GLES3_ENABLED + drivers.push_back("opengl3"); #endif return drivers; @@ -3367,7 +3428,7 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() { DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n" + OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.\n" "Please update your drivers or if you have a very old or integrated GPU upgrade it.", "Unable to initialize Video driver"); } @@ -3388,6 +3449,10 @@ DisplayServerWindows::~DisplayServerWindows() { SetWindowLongPtr(windows[MAIN_WINDOW_ID].hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc); }; +#ifdef GLES3_ENABLED + // destroy windows .. NYI? +#endif + if (windows.has(MAIN_WINDOW_ID)) { #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { @@ -3412,4 +3477,14 @@ DisplayServerWindows::~DisplayServerWindows() { memdelete(context_vulkan); } #endif + + if (restore_mouse_trails > 1) { + SystemParametersInfoA(SPI_SETMOUSETRAILS, restore_mouse_trails, 0, 0); + } +#ifdef GLES3_ENABLED + if (gl_manager) { + memdelete(gl_manager); + gl_manager = nullptr; + } +#endif } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 06014fbabe..a59f8ebb44 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -51,18 +51,19 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #endif -#if defined(OPENGL_ENABLED) -#include "context_gl_windows.h" -#endif - #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/windows/vulkan_context_win.h" #endif +#if defined(GLES3_ENABLED) +#include "gl_manager_windows.h" +#endif + #include <fcntl.h> #include <io.h> #include <stdio.h> +#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <windowsx.h> @@ -303,8 +304,8 @@ class DisplayServerWindows : public DisplayServer { int old_x, old_y; Point2i center; -#if defined(OPENGL_ENABLED) - ContextGL_Windows *context_gles2; +#if defined(GLES3_ENABLED) + GLManager_Windows *gl_manager; #endif #if defined(VULKAN_ENABLED) @@ -403,12 +404,13 @@ class DisplayServerWindows : public DisplayServer { void _get_window_style(bool p_main_window, bool p_fullscreen, bool p_borderless, bool p_resizable, bool p_maximized, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex); MouseMode mouse_mode; + int restore_mouse_trails = 0; bool alt_mem = false; bool gr_mem = false; bool shift_mem = false; bool control_mem = false; bool meta_mem = false; - MouseButton last_button_state = MOUSE_BUTTON_NONE; + MouseButton last_button_state = MouseButton::NONE; bool use_raw_input = false; bool drop_events = false; bool in_dispatch_input_event = false; @@ -460,7 +462,7 @@ public: virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override; - ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver virtual bool screen_is_kept_on() const override; @@ -475,6 +477,7 @@ public: virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override; virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override; + virtual void gl_window_make_current(DisplayServer::WindowID p_window_id); virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; @@ -542,6 +545,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual int tablet_get_driver_count() const override; virtual String tablet_get_driver_name(int p_driver) const override; diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp new file mode 100644 index 0000000000..fe98f8b0ba --- /dev/null +++ b/platform/windows/gl_manager_windows.cpp @@ -0,0 +1,346 @@ +/*************************************************************************/ +/* gl_manager_windows.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "gl_manager_windows.h" + +#ifdef WINDOWS_ENABLED +#ifdef GLES3_ENABLED + +#include <stdio.h> +#include <stdlib.h> + +#include <dwmapi.h> + +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 + +#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 + +#if defined(__GNUC__) +// Workaround GCC warning from -Wcast-function-type. +#define wglGetProcAddress (void *)wglGetProcAddress +#endif + +typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *); + +int GLManager_Windows::_find_or_create_display(GLWindow &win) { + // find display NYI, only 1 supported so far + if (_displays.size()) + return 0; + + // for (unsigned int n = 0; n < _displays.size(); n++) { + // const GLDisplay &d = _displays[n]; + // if (d.x11_display == p_x11_display) + // return n; + // } + + // create + GLDisplay d_temp = {}; + _displays.push_back(d_temp); + int new_display_id = _displays.size() - 1; + + // create context + GLDisplay &d = _displays[new_display_id]; + Error err = _create_context(win, d); + + if (err != OK) { + // not good + // delete the _display? + _displays.remove_at(new_display_id); + return -1; + } + + return new_display_id; +} + +Error GLManager_Windows::_create_context(GLWindow &win, GLDisplay &gl_display) { + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, + (BYTE)PFD_TYPE_RGBA, + (BYTE)(OS::get_singleton()->is_layered_allowed() ? 32 : 24), + (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Color Bits Ignored + (BYTE)(OS::get_singleton()->is_layered_allowed() ? 8 : 0), // Alpha Buffer + (BYTE)0, // Shift Bit Ignored + (BYTE)0, // No Accumulation Buffer + (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Accumulation Bits Ignored + (BYTE)24, // 24Bit Z-Buffer (Depth Buffer) + (BYTE)0, // No Stencil Buffer + (BYTE)0, // No Auxiliary Buffer + (BYTE)PFD_MAIN_PLANE, // Main Drawing Layer + (BYTE)0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + // alias + HDC hDC = win.hDC; + + int pixel_format = ChoosePixelFormat(hDC, &pfd); + if (!pixel_format) // Did Windows Find A Matching Pixel Format? + { + return ERR_CANT_CREATE; // Return FALSE + } + + BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd); + if (!ret) // Are We Able To Set The Pixel Format? + { + return ERR_CANT_CREATE; // Return FALSE + } + + gl_display.hRC = wglCreateContext(hDC); + if (!gl_display.hRC) // Are We Able To Get A Rendering Context? + { + return ERR_CANT_CREATE; // Return FALSE + } + + wglMakeCurrent(hDC, gl_display.hRC); + + int attribs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //we want a 3.3 context + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + //and it shall be forward compatible so that we can only use up to date functionality + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*| _WGL_CONTEXT_DEBUG_BIT_ARB*/, + 0 + }; //zero indicates the end of the array + + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; //pointer to the method + wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + + if (wglCreateContextAttribsARB == nullptr) //OpenGL 3.0 is not supported + { + wglDeleteContext(gl_display.hRC); + gl_display.hRC = 0; + return ERR_CANT_CREATE; + } + + HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs); + if (!new_hRC) { + wglDeleteContext(gl_display.hRC); + gl_display.hRC = 0; + return ERR_CANT_CREATE; // Return false + } + wglMakeCurrent(hDC, nullptr); + wglDeleteContext(gl_display.hRC); + gl_display.hRC = new_hRC; + + if (!wglMakeCurrent(hDC, gl_display.hRC)) // Try To Activate The Rendering Context + { + wglDeleteContext(gl_display.hRC); + gl_display.hRC = 0; + return ERR_CANT_CREATE; // Return FALSE + } + + return OK; +} + +Error GLManager_Windows::window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, int p_width, int p_height) { + HDC hdc = GetDC(p_hwnd); + if (!hdc) { + return ERR_CANT_CREATE; // Return FALSE + } + + // make sure vector is big enough... + // we can mirror the external vector, it is simpler + // to keep the IDs identical for fast lookup + if (p_window_id >= (int)_windows.size()) { + _windows.resize(p_window_id + 1); + } + + GLWindow &win = _windows[p_window_id]; + win.in_use = true; + win.window_id = p_window_id; + win.width = p_width; + win.height = p_height; + win.hwnd = p_hwnd; + win.hDC = hdc; + + win.gldisplay_id = _find_or_create_display(win); + + if (win.gldisplay_id == -1) { + // release DC? + _windows.remove_at(_windows.size() - 1); + return FAILED; + } + + // make current + window_make_current(_windows.size() - 1); + + return OK; +} + +void GLManager_Windows::_internal_set_current_window(GLWindow *p_win) { + _current_window = p_win; +} + +void GLManager_Windows::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) { + get_window(p_window_id).width = p_width; + get_window(p_window_id).height = p_height; +} + +int GLManager_Windows::window_get_width(DisplayServer::WindowID p_window_id) { + return get_window(p_window_id).width; +} + +int GLManager_Windows::window_get_height(DisplayServer::WindowID p_window_id) { + return get_window(p_window_id).height; +} + +void GLManager_Windows::window_destroy(DisplayServer::WindowID p_window_id) { + GLWindow &win = get_window(p_window_id); + win.in_use = false; + + if (_current_window == &win) { + _current_window = nullptr; + } +} + +void GLManager_Windows::release_current() { + if (!_current_window) + return; + + wglMakeCurrent(_current_window->hDC, nullptr); +} + +void GLManager_Windows::window_make_current(DisplayServer::WindowID p_window_id) { + if (p_window_id == -1) + return; + + GLWindow &win = _windows[p_window_id]; + if (!win.in_use) + return; + + // noop + if (&win == _current_window) + return; + + const GLDisplay &disp = get_display(win.gldisplay_id); + wglMakeCurrent(win.hDC, disp.hRC); + + _internal_set_current_window(&win); +} + +void GLManager_Windows::make_current() { + if (!_current_window) + return; + if (!_current_window->in_use) { + WARN_PRINT("current window not in use!"); + return; + } + const GLDisplay &disp = get_current_display(); + wglMakeCurrent(_current_window->hDC, disp.hRC); +} + +void GLManager_Windows::swap_buffers() { + // NO NEED TO CALL SWAP BUFFERS for each window... + // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml + + if (!_current_window) + return; + if (!_current_window->in_use) { + WARN_PRINT("current window not in use!"); + return; + } + + // print_line("\tswap_buffers"); + + // only for debugging without drawing anything + // glClearColor(Math::randf(), 0, 1, 1); + //glClear(GL_COLOR_BUFFER_BIT); + + // const GLDisplay &disp = get_current_display(); + SwapBuffers(_current_window->hDC); +} + +Error GLManager_Windows::initialize() { + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); + //glWrapperInit(wrapper_get_proc_address); + + return OK; +} + +void GLManager_Windows::set_use_vsync(bool p_use) { + /* + static bool setup = false; + static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; + static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA = nullptr; + static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; + + if (!setup) { + setup = true; + String extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); + if (extensions.find("GLX_EXT_swap_control") != -1) + glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT"); + if (extensions.find("GLX_MESA_swap_control") != -1) + glXSwapIntervalMESA = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA"); + if (extensions.find("GLX_SGI_swap_control") != -1) + glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI"); + } + int val = p_use ? 1 : 0; + if (glXSwapIntervalMESA) { + glXSwapIntervalMESA(val); + } else if (glXSwapIntervalSGI) { + glXSwapIntervalSGI(val); + } else if (glXSwapIntervalEXT) { + GLXDrawable drawable = glXGetCurrentDrawable(); + glXSwapIntervalEXT(x11_display, drawable, val); + } else + return; + use_vsync = p_use; + */ +} + +bool GLManager_Windows::is_using_vsync() const { + return use_vsync; +} + +GLManager_Windows::GLManager_Windows(ContextType p_context_type) { + context_type = p_context_type; + + direct_render = false; + glx_minor = glx_major = 0; + use_vsync = false; + _current_window = nullptr; +} + +GLManager_Windows::~GLManager_Windows() { + release_current(); +} + +#endif // GLES3_ENABLED +#endif // WINDOWS diff --git a/platform/windows/context_gl_windows.h b/platform/windows/gl_manager_windows.h index c8e8a0891d..9733a57420 100644 --- a/platform/windows/context_gl_windows.h +++ b/platform/windows/gl_manager_windows.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* context_gl_windows.h */ +/* gl_manager_windows.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,49 +28,100 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) +#ifndef GL_MANAGER_WINDOWS_H +#define GL_MANAGER_WINDOWS_H -// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008 - -#ifndef CONTEXT_GL_WIN_H -#define CONTEXT_GL_WIN_H +#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED) #include "core/error/error_list.h" #include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "servers/display_server.h" #include <windows.h> typedef bool(APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval); typedef int(APIENTRY *PFNWGLGETSWAPINTERVALEXTPROC)(void); -class ContextGL_Windows { - HDC hDC; - HGLRC hRC; - unsigned int pixel_format; - HWND hWnd; - bool opengl_3_context; - bool use_vsync; +class GLManager_Windows { +public: + enum ContextType { + GLES_3_0_COMPATIBLE, + }; + +private: + // any data specific to the window + struct GLWindow { + GLWindow() { in_use = false; } + bool in_use; + + // the external ID .. should match the GL window number .. unused I think + DisplayServer::WindowID window_id; + int width; + int height; + + // windows specific + HDC hDC; + HWND hwnd; + + int gldisplay_id; + }; + + struct GLDisplay { + // windows specific + HGLRC hRC; + }; + + LocalVector<GLWindow> _windows; + LocalVector<GLDisplay> _displays; + + GLWindow *_current_window; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; + // funcs + void _internal_set_current_window(GLWindow *p_win); + + GLWindow &get_window(unsigned int id) { return _windows[id]; } + const GLWindow &get_window(unsigned int id) const { return _windows[id]; } + + const GLDisplay &get_current_display() const { return _displays[_current_window->gldisplay_id]; } + const GLDisplay &get_display(unsigned int id) { return _displays[id]; } + + bool direct_render; + int glx_minor, glx_major; + bool use_vsync; + ContextType context_type; + +private: + int _find_or_create_display(GLWindow &win); + Error _create_context(GLWindow &win, GLDisplay &gl_display); + public: - void release_current(); + Error window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, int p_width, int p_height); + void window_destroy(DisplayServer::WindowID p_window_id); + void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height); - void make_current(); + // get directly from the cached GLWindow + int window_get_width(DisplayServer::WindowID p_window_id = 0); + int window_get_height(DisplayServer::WindowID p_window_id = 0); - int get_window_width(); - int get_window_height(); + void release_current(); + void make_current(); void swap_buffers(); + void window_make_current(DisplayServer::WindowID p_window_id); + Error initialize(); void set_use_vsync(bool p_use); bool is_using_vsync() const; - ContextGL_Windows(HWND hwnd, bool p_opengl_3_context); - ~ContextGL_Windows(); + GLManager_Windows(ContextType p_context_type); + ~GLManager_Windows(); }; -#endif -#endif +#endif // defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED) + +#endif // GL_MANAGER_WINDOWS_H diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 94da63e49d..1d3761ee83 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -334,12 +334,12 @@ void JoypadWindows::process_joypads() { button_mask = button_mask * 2; } - input->joy_axis(joy.id, JOY_AXIS_LEFT_X, axis_correct(joy.state.Gamepad.sThumbLX, true)); - input->joy_axis(joy.id, JOY_AXIS_LEFT_Y, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); - input->joy_axis(joy.id, JOY_AXIS_RIGHT_X, axis_correct(joy.state.Gamepad.sThumbRX, true)); - input->joy_axis(joy.id, JOY_AXIS_RIGHT_Y, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); - input->joy_axis(joy.id, JOY_AXIS_TRIGGER_LEFT, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); - input->joy_axis(joy.id, JOY_AXIS_TRIGGER_RIGHT, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); + input->joy_axis(joy.id, JoyAxis::LEFT_X, axis_correct(joy.state.Gamepad.sThumbLX, true)); + input->joy_axis(joy.id, JoyAxis::LEFT_Y, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); + input->joy_axis(joy.id, JoyAxis::RIGHT_X, axis_correct(joy.state.Gamepad.sThumbRX, true)); + input->joy_axis(joy.id, JoyAxis::RIGHT_Y, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); + input->joy_axis(joy.id, JoyAxis::TRIGGER_LEFT, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); + input->joy_axis(joy.id, JoyAxis::TRIGGER_RIGHT, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); joy.last_packet = joy.state.dwPacketNumber; } uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id); @@ -417,31 +417,31 @@ void JoypadWindows::post_hat(int p_device, DWORD p_dpad) { // BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);" // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks if (LOWORD(p_dpad) == 0xFFFF) { - dpad_val = (HatMask)HatMask::HAT_MASK_CENTER; + dpad_val = (HatMask)HatMask::CENTER; } if (p_dpad == 0) { - dpad_val = (HatMask)HatMask::HAT_MASK_UP; + dpad_val = (HatMask)HatMask::UP; } else if (p_dpad == 4500) { - dpad_val = (HatMask)(HatMask::HAT_MASK_UP | HatMask::HAT_MASK_RIGHT); + dpad_val = (HatMask)(HatMask::UP | HatMask::RIGHT); } else if (p_dpad == 9000) { - dpad_val = (HatMask)HatMask::HAT_MASK_RIGHT; + dpad_val = (HatMask)HatMask::RIGHT; } else if (p_dpad == 13500) { - dpad_val = (HatMask)(HatMask::HAT_MASK_RIGHT | HatMask::HAT_MASK_DOWN); + dpad_val = (HatMask)(HatMask::RIGHT | HatMask::DOWN); } else if (p_dpad == 18000) { - dpad_val = (HatMask)HatMask::HAT_MASK_DOWN; + dpad_val = (HatMask)HatMask::DOWN; } else if (p_dpad == 22500) { - dpad_val = (HatMask)(HatMask::HAT_MASK_DOWN | HatMask::HAT_MASK_LEFT); + dpad_val = (HatMask)(HatMask::DOWN | HatMask::LEFT); } else if (p_dpad == 27000) { - dpad_val = (HatMask)HatMask::HAT_MASK_LEFT; + dpad_val = (HatMask)HatMask::LEFT; } else if (p_dpad == 31500) { - dpad_val = (HatMask)(HatMask::HAT_MASK_LEFT | HatMask::HAT_MASK_UP); + dpad_val = (HatMask)(HatMask::LEFT | HatMask::UP); } input->joy_hat(p_device, dpad_val); }; diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index db99d6c122..65ee5dd46b 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -33,200 +33,200 @@ #include <stdio.h> struct _WinTranslatePair { - unsigned int keysym; + Key keysym; unsigned int keycode; }; static _WinTranslatePair _vk_to_keycode[] = { - { KEY_BACKSPACE, VK_BACK }, // (0x08) // backspace - { KEY_TAB, VK_TAB }, //(0x09) + { Key::BACKSPACE, VK_BACK }, // (0x08) // backspace + { Key::TAB, VK_TAB }, //(0x09) //VK_CLEAR (0x0C) - { KEY_ENTER, VK_RETURN }, //(0x0D) + { Key::ENTER, VK_RETURN }, //(0x0D) - { KEY_SHIFT, VK_SHIFT }, //(0x10) + { Key::SHIFT, VK_SHIFT }, //(0x10) - { KEY_CTRL, VK_CONTROL }, //(0x11) + { Key::CTRL, VK_CONTROL }, //(0x11) - { KEY_ALT, VK_MENU }, //(0x12) + { Key::ALT, VK_MENU }, //(0x12) - { KEY_PAUSE, VK_PAUSE }, //(0x13) + { Key::PAUSE, VK_PAUSE }, //(0x13) - { KEY_CAPSLOCK, VK_CAPITAL }, //(0x14) + { Key::CAPSLOCK, VK_CAPITAL }, //(0x14) - { KEY_ESCAPE, VK_ESCAPE }, //(0x1B) + { Key::ESCAPE, VK_ESCAPE }, //(0x1B) - { KEY_SPACE, VK_SPACE }, //(0x20) + { Key::SPACE, VK_SPACE }, //(0x20) - { KEY_PAGEUP, VK_PRIOR }, //(0x21) + { Key::PAGEUP, VK_PRIOR }, //(0x21) - { KEY_PAGEDOWN, VK_NEXT }, //(0x22) + { Key::PAGEDOWN, VK_NEXT }, //(0x22) - { KEY_END, VK_END }, //(0x23) + { Key::END, VK_END }, //(0x23) - { KEY_HOME, VK_HOME }, //(0x24) + { Key::HOME, VK_HOME }, //(0x24) - { KEY_LEFT, VK_LEFT }, //(0x25) + { Key::LEFT, VK_LEFT }, //(0x25) - { KEY_UP, VK_UP }, //(0x26) + { Key::UP, VK_UP }, //(0x26) - { KEY_RIGHT, VK_RIGHT }, //(0x27) + { Key::RIGHT, VK_RIGHT }, //(0x27) - { KEY_DOWN, VK_DOWN }, // (0x28) + { Key::DOWN, VK_DOWN }, // (0x28) //VK_SELECT (0x29) - { KEY_PRINT, VK_PRINT }, // (0x2A) + { Key::PRINT, VK_PRINT }, // (0x2A) //VK_EXECUTE (0x2B) - { KEY_PRINT, VK_SNAPSHOT }, // (0x2C) - - { KEY_INSERT, VK_INSERT }, // (0x2D) - - { KEY_DELETE, VK_DELETE }, // (0x2E) - - { KEY_HELP, VK_HELP }, // (0x2F) - - { KEY_0, (0x30) }, ////0 key - { KEY_1, (0x31) }, ////1 key - { KEY_2, (0x32) }, ////2 key - { KEY_3, (0x33) }, ////3 key - { KEY_4, (0x34) }, ////4 key - { KEY_5, (0x35) }, ////5 key - { KEY_6, (0x36) }, ////6 key - { KEY_7, (0x37) }, ////7 key - { KEY_8, (0x38) }, ////8 key - { KEY_9, (0x39) }, ////9 key - { KEY_A, (0x41) }, ////A key - { KEY_B, (0x42) }, ////B key - { KEY_C, (0x43) }, ////C key - { KEY_D, (0x44) }, ////D key - { KEY_E, (0x45) }, ////E key - { KEY_F, (0x46) }, ////F key - { KEY_G, (0x47) }, ////G key - { KEY_H, (0x48) }, ////H key - { KEY_I, (0x49) }, ////I key - { KEY_J, (0x4A) }, ////J key - { KEY_K, (0x4B) }, ////K key - { KEY_L, (0x4C) }, ////L key - { KEY_M, (0x4D) }, ////M key - { KEY_N, (0x4E) }, ////N key - { KEY_O, (0x4F) }, ////O key - { KEY_P, (0x50) }, ////P key - { KEY_Q, (0x51) }, ////Q key - { KEY_R, (0x52) }, ////R key - { KEY_S, (0x53) }, ////S key - { KEY_T, (0x54) }, ////T key - { KEY_U, (0x55) }, ////U key - { KEY_V, (0x56) }, ////V key - { KEY_W, (0x57) }, ////W key - { KEY_X, (0x58) }, ////X key - { KEY_Y, (0x59) }, ////Y key - { KEY_Z, (0x5A) }, ////Z key - - { KEY_MASK_META, VK_LWIN }, //(0x5B) - { KEY_MASK_META, VK_RWIN }, //(0x5C) - { KEY_MENU, VK_APPS }, //(0x5D) - { KEY_STANDBY, VK_SLEEP }, //(0x5F) - { KEY_KP_0, VK_NUMPAD0 }, //(0x60) - { KEY_KP_1, VK_NUMPAD1 }, //(0x61) - { KEY_KP_2, VK_NUMPAD2 }, //(0x62) - { KEY_KP_3, VK_NUMPAD3 }, //(0x63) - { KEY_KP_4, VK_NUMPAD4 }, //(0x64) - { KEY_KP_5, VK_NUMPAD5 }, //(0x65) - { KEY_KP_6, VK_NUMPAD6 }, //(0x66) - { KEY_KP_7, VK_NUMPAD7 }, //(0x67) - { KEY_KP_8, VK_NUMPAD8 }, //(0x68) - { KEY_KP_9, VK_NUMPAD9 }, //(0x69) - { KEY_KP_MULTIPLY, VK_MULTIPLY }, // (0x6A) - { KEY_KP_ADD, VK_ADD }, // (0x6B) + { Key::PRINT, VK_SNAPSHOT }, // (0x2C) + + { Key::INSERT, VK_INSERT }, // (0x2D) + + { Key::KEY_DELETE, VK_DELETE }, // (0x2E) + + { Key::HELP, VK_HELP }, // (0x2F) + + { Key::KEY_0, (0x30) }, ////0 key + { Key::KEY_1, (0x31) }, ////1 key + { Key::KEY_2, (0x32) }, ////2 key + { Key::KEY_3, (0x33) }, ////3 key + { Key::KEY_4, (0x34) }, ////4 key + { Key::KEY_5, (0x35) }, ////5 key + { Key::KEY_6, (0x36) }, ////6 key + { Key::KEY_7, (0x37) }, ////7 key + { Key::KEY_8, (0x38) }, ////8 key + { Key::KEY_9, (0x39) }, ////9 key + { Key::A, (0x41) }, ////A key + { Key::B, (0x42) }, ////B key + { Key::C, (0x43) }, ////C key + { Key::D, (0x44) }, ////D key + { Key::E, (0x45) }, ////E key + { Key::F, (0x46) }, ////F key + { Key::G, (0x47) }, ////G key + { Key::H, (0x48) }, ////H key + { Key::I, (0x49) }, ////I key + { Key::J, (0x4A) }, ////J key + { Key::K, (0x4B) }, ////K key + { Key::L, (0x4C) }, ////L key + { Key::M, (0x4D) }, ////M key + { Key::N, (0x4E) }, ////N key + { Key::O, (0x4F) }, ////O key + { Key::P, (0x50) }, ////P key + { Key::Q, (0x51) }, ////Q key + { Key::R, (0x52) }, ////R key + { Key::S, (0x53) }, ////S key + { Key::T, (0x54) }, ////T key + { Key::U, (0x55) }, ////U key + { Key::V, (0x56) }, ////V key + { Key::W, (0x57) }, ////W key + { Key::X, (0x58) }, ////X key + { Key::Y, (0x59) }, ////Y key + { Key::Z, (0x5A) }, ////Z key + + { (Key)KeyModifierMask::META, VK_LWIN }, //(0x5B) + { (Key)KeyModifierMask::META, VK_RWIN }, //(0x5C) + { Key::MENU, VK_APPS }, //(0x5D) + { Key::STANDBY, VK_SLEEP }, //(0x5F) + { Key::KP_0, VK_NUMPAD0 }, //(0x60) + { Key::KP_1, VK_NUMPAD1 }, //(0x61) + { Key::KP_2, VK_NUMPAD2 }, //(0x62) + { Key::KP_3, VK_NUMPAD3 }, //(0x63) + { Key::KP_4, VK_NUMPAD4 }, //(0x64) + { Key::KP_5, VK_NUMPAD5 }, //(0x65) + { Key::KP_6, VK_NUMPAD6 }, //(0x66) + { Key::KP_7, VK_NUMPAD7 }, //(0x67) + { Key::KP_8, VK_NUMPAD8 }, //(0x68) + { Key::KP_9, VK_NUMPAD9 }, //(0x69) + { Key::KP_MULTIPLY, VK_MULTIPLY }, // (0x6A) + { Key::KP_ADD, VK_ADD }, // (0x6B) //VK_SEPARATOR (0x6C) - { KEY_KP_SUBTRACT, VK_SUBTRACT }, // (0x6D) - { KEY_KP_PERIOD, VK_DECIMAL }, // (0x6E) - { KEY_KP_DIVIDE, VK_DIVIDE }, // (0x6F) - { KEY_F1, VK_F1 }, // (0x70) - { KEY_F2, VK_F2 }, // (0x71) - { KEY_F3, VK_F3 }, // (0x72) - { KEY_F4, VK_F4 }, // (0x73) - { KEY_F5, VK_F5 }, // (0x74) - { KEY_F6, VK_F6 }, // (0x75) - { KEY_F7, VK_F7 }, // (0x76) - { KEY_F8, VK_F8 }, // (0x77) - { KEY_F9, VK_F9 }, // (0x78) - { KEY_F10, VK_F10 }, // (0x79) - { KEY_F11, VK_F11 }, // (0x7A) - { KEY_F12, VK_F12 }, // (0x7B) - { KEY_F13, VK_F13 }, // (0x7C) - { KEY_F14, VK_F14 }, // (0x7D) - { KEY_F15, VK_F15 }, // (0x7E) - { KEY_F16, VK_F16 }, // (0x7F) - { KEY_NUMLOCK, VK_NUMLOCK }, // (0x90) - { KEY_SCROLLLOCK, VK_SCROLL }, // (0x91) - { KEY_SHIFT, VK_LSHIFT }, // (0xA0) - { KEY_SHIFT, VK_RSHIFT }, // (0xA1) - { KEY_CTRL, VK_LCONTROL }, // (0xA2) - { KEY_CTRL, VK_RCONTROL }, // (0xA3) - { KEY_MENU, VK_LMENU }, // (0xA4) - { KEY_MENU, VK_RMENU }, // (0xA5) + { Key::KP_SUBTRACT, VK_SUBTRACT }, // (0x6D) + { Key::KP_PERIOD, VK_DECIMAL }, // (0x6E) + { Key::KP_DIVIDE, VK_DIVIDE }, // (0x6F) + { Key::F1, VK_F1 }, // (0x70) + { Key::F2, VK_F2 }, // (0x71) + { Key::F3, VK_F3 }, // (0x72) + { Key::F4, VK_F4 }, // (0x73) + { Key::F5, VK_F5 }, // (0x74) + { Key::F6, VK_F6 }, // (0x75) + { Key::F7, VK_F7 }, // (0x76) + { Key::F8, VK_F8 }, // (0x77) + { Key::F9, VK_F9 }, // (0x78) + { Key::F10, VK_F10 }, // (0x79) + { Key::F11, VK_F11 }, // (0x7A) + { Key::F12, VK_F12 }, // (0x7B) + { Key::F13, VK_F13 }, // (0x7C) + { Key::F14, VK_F14 }, // (0x7D) + { Key::F15, VK_F15 }, // (0x7E) + { Key::F16, VK_F16 }, // (0x7F) + { Key::NUMLOCK, VK_NUMLOCK }, // (0x90) + { Key::SCROLLLOCK, VK_SCROLL }, // (0x91) + { Key::SHIFT, VK_LSHIFT }, // (0xA0) + { Key::SHIFT, VK_RSHIFT }, // (0xA1) + { Key::CTRL, VK_LCONTROL }, // (0xA2) + { Key::CTRL, VK_RCONTROL }, // (0xA3) + { Key::MENU, VK_LMENU }, // (0xA4) + { Key::MENU, VK_RMENU }, // (0xA5) - { KEY_BACK, VK_BROWSER_BACK }, // (0xA6) + { Key::BACK, VK_BROWSER_BACK }, // (0xA6) - { KEY_FORWARD, VK_BROWSER_FORWARD }, // (0xA7) + { Key::FORWARD, VK_BROWSER_FORWARD }, // (0xA7) - { KEY_REFRESH, VK_BROWSER_REFRESH }, // (0xA8) + { Key::REFRESH, VK_BROWSER_REFRESH }, // (0xA8) - { KEY_STOP, VK_BROWSER_STOP }, // (0xA9) + { Key::STOP, VK_BROWSER_STOP }, // (0xA9) - { KEY_SEARCH, VK_BROWSER_SEARCH }, // (0xAA) + { Key::SEARCH, VK_BROWSER_SEARCH }, // (0xAA) - { KEY_FAVORITES, VK_BROWSER_FAVORITES }, // (0xAB) + { Key::FAVORITES, VK_BROWSER_FAVORITES }, // (0xAB) - { KEY_HOMEPAGE, VK_BROWSER_HOME }, // (0xAC) + { Key::HOMEPAGE, VK_BROWSER_HOME }, // (0xAC) - { KEY_VOLUMEMUTE, VK_VOLUME_MUTE }, // (0xAD) + { Key::VOLUMEMUTE, VK_VOLUME_MUTE }, // (0xAD) - { KEY_VOLUMEDOWN, VK_VOLUME_DOWN }, // (0xAE) + { Key::VOLUMEDOWN, VK_VOLUME_DOWN }, // (0xAE) - { KEY_VOLUMEUP, VK_VOLUME_UP }, // (0xAF) + { Key::VOLUMEUP, VK_VOLUME_UP }, // (0xAF) - { KEY_MEDIANEXT, VK_MEDIA_NEXT_TRACK }, // (0xB0) + { Key::MEDIANEXT, VK_MEDIA_NEXT_TRACK }, // (0xB0) - { KEY_MEDIAPREVIOUS, VK_MEDIA_PREV_TRACK }, // (0xB1) + { Key::MEDIAPREVIOUS, VK_MEDIA_PREV_TRACK }, // (0xB1) - { KEY_MEDIASTOP, VK_MEDIA_STOP }, // (0xB2) + { Key::MEDIASTOP, VK_MEDIA_STOP }, // (0xB2) //VK_MEDIA_PLAY_PAUSE (0xB3) - { KEY_LAUNCHMAIL, VK_LAUNCH_MAIL }, // (0xB4) + { Key::LAUNCHMAIL, VK_LAUNCH_MAIL }, // (0xB4) - { KEY_LAUNCHMEDIA, VK_LAUNCH_MEDIA_SELECT }, // (0xB5) + { Key::LAUNCHMEDIA, VK_LAUNCH_MEDIA_SELECT }, // (0xB5) - { KEY_LAUNCH0, VK_LAUNCH_APP1 }, // (0xB6) + { Key::LAUNCH0, VK_LAUNCH_APP1 }, // (0xB6) - { KEY_LAUNCH1, VK_LAUNCH_APP2 }, // (0xB7) + { Key::LAUNCH1, VK_LAUNCH_APP2 }, // (0xB7) - { KEY_SEMICOLON, VK_OEM_1 }, // (0xBA) + { Key::SEMICOLON, VK_OEM_1 }, // (0xBA) - { KEY_EQUAL, VK_OEM_PLUS }, // (0xBB) // Windows 2000/XP: For any country/region, the '+' key - { KEY_COMMA, VK_OEM_COMMA }, // (0xBC) // Windows 2000/XP: For any country/region, the ',' key - { KEY_MINUS, VK_OEM_MINUS }, // (0xBD) // Windows 2000/XP: For any country/region, the '-' key - { KEY_PERIOD, VK_OEM_PERIOD }, // (0xBE) // Windows 2000/XP: For any country/region, the '.' key - { KEY_SLASH, VK_OEM_2 }, // (0xBF) //Windows 2000/XP: For the US standard keyboard, the '/?' key + { Key::EQUAL, VK_OEM_PLUS }, // (0xBB) // Windows 2000/XP: For any country/region, the '+' key + { Key::COMMA, VK_OEM_COMMA }, // (0xBC) // Windows 2000/XP: For any country/region, the ',' key + { Key::MINUS, VK_OEM_MINUS }, // (0xBD) // Windows 2000/XP: For any country/region, the '-' key + { Key::PERIOD, VK_OEM_PERIOD }, // (0xBE) // Windows 2000/XP: For any country/region, the '.' key + { Key::SLASH, VK_OEM_2 }, // (0xBF) //Windows 2000/XP: For the US standard keyboard, the '/?' key - { KEY_QUOTELEFT, VK_OEM_3 }, // (0xC0) - { KEY_BRACELEFT, VK_OEM_4 }, // (0xDB) - { KEY_BACKSLASH, VK_OEM_5 }, // (0xDC) - { KEY_BRACERIGHT, VK_OEM_6 }, // (0xDD) - { KEY_APOSTROPHE, VK_OEM_7 }, // (0xDE) + { Key::QUOTELEFT, VK_OEM_3 }, // (0xC0) + { Key::BRACELEFT, VK_OEM_4 }, // (0xDB) + { Key::BACKSLASH, VK_OEM_5 }, // (0xDC) + { Key::BRACERIGHT, VK_OEM_6 }, // (0xDD) + { Key::APOSTROPHE, VK_OEM_7 }, // (0xDE) /* {VK_OEM_8 (0xDF) {VK_OEM_102 (0xE2) // Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard */ - //{ KEY_PLAY, VK_PLAY},// (0xFA) + //{ Key::PLAY, VK_PLAY},// (0xFA) - { KEY_UNKNOWN, 0 } + { Key::UNKNOWN, 0 } }; /* @@ -237,104 +237,104 @@ VK_OEM_CLEAR (0xFE) */ static _WinTranslatePair _scancode_to_keycode[] = { - { KEY_ESCAPE, 0x01 }, - { KEY_1, 0x02 }, - { KEY_2, 0x03 }, - { KEY_3, 0x04 }, - { KEY_4, 0x05 }, - { KEY_5, 0x06 }, - { KEY_6, 0x07 }, - { KEY_7, 0x08 }, - { KEY_8, 0x09 }, - { KEY_9, 0x0A }, - { KEY_0, 0x0B }, - { KEY_MINUS, 0x0C }, - { KEY_EQUAL, 0x0D }, - { KEY_BACKSPACE, 0x0E }, - { KEY_TAB, 0x0F }, - { KEY_Q, 0x10 }, - { KEY_W, 0x11 }, - { KEY_E, 0x12 }, - { KEY_R, 0x13 }, - { KEY_T, 0x14 }, - { KEY_Y, 0x15 }, - { KEY_U, 0x16 }, - { KEY_I, 0x17 }, - { KEY_O, 0x18 }, - { KEY_P, 0x19 }, - { KEY_BRACELEFT, 0x1A }, - { KEY_BRACERIGHT, 0x1B }, - { KEY_ENTER, 0x1C }, - { KEY_CTRL, 0x1D }, - { KEY_A, 0x1E }, - { KEY_S, 0x1F }, - { KEY_D, 0x20 }, - { KEY_F, 0x21 }, - { KEY_G, 0x22 }, - { KEY_H, 0x23 }, - { KEY_J, 0x24 }, - { KEY_K, 0x25 }, - { KEY_L, 0x26 }, - { KEY_SEMICOLON, 0x27 }, - { KEY_APOSTROPHE, 0x28 }, - { KEY_QUOTELEFT, 0x29 }, - { KEY_SHIFT, 0x2A }, - { KEY_BACKSLASH, 0x2B }, - { KEY_Z, 0x2C }, - { KEY_X, 0x2D }, - { KEY_C, 0x2E }, - { KEY_V, 0x2F }, - { KEY_B, 0x30 }, - { KEY_N, 0x31 }, - { KEY_M, 0x32 }, - { KEY_COMMA, 0x33 }, - { KEY_PERIOD, 0x34 }, - { KEY_SLASH, 0x35 }, - { KEY_SHIFT, 0x36 }, - { KEY_PRINT, 0x37 }, - { KEY_ALT, 0x38 }, - { KEY_SPACE, 0x39 }, - { KEY_CAPSLOCK, 0x3A }, - { KEY_F1, 0x3B }, - { KEY_F2, 0x3C }, - { KEY_F3, 0x3D }, - { KEY_F4, 0x3E }, - { KEY_F5, 0x3F }, - { KEY_F6, 0x40 }, - { KEY_F7, 0x41 }, - { KEY_F8, 0x42 }, - { KEY_F9, 0x43 }, - { KEY_F10, 0x44 }, - { KEY_NUMLOCK, 0x45 }, - { KEY_SCROLLLOCK, 0x46 }, - { KEY_HOME, 0x47 }, - { KEY_UP, 0x48 }, - { KEY_PAGEUP, 0x49 }, - { KEY_KP_SUBTRACT, 0x4A }, - { KEY_LEFT, 0x4B }, - { KEY_KP_5, 0x4C }, - { KEY_RIGHT, 0x4D }, - { KEY_KP_ADD, 0x4E }, - { KEY_END, 0x4F }, - { KEY_DOWN, 0x50 }, - { KEY_PAGEDOWN, 0x51 }, - { KEY_INSERT, 0x52 }, - { KEY_DELETE, 0x53 }, - //{ KEY_???, 0x56 }, //NON US BACKSLASH - { KEY_F11, 0x57 }, - { KEY_F12, 0x58 }, - { KEY_META, 0x5B }, - { KEY_META, 0x5C }, - { KEY_MENU, 0x5D }, - { KEY_F13, 0x64 }, - { KEY_F14, 0x65 }, - { KEY_F15, 0x66 }, - { KEY_F16, 0x67 }, - { KEY_UNKNOWN, 0 } + { Key::ESCAPE, 0x01 }, + { Key::KEY_1, 0x02 }, + { Key::KEY_2, 0x03 }, + { Key::KEY_3, 0x04 }, + { Key::KEY_4, 0x05 }, + { Key::KEY_5, 0x06 }, + { Key::KEY_6, 0x07 }, + { Key::KEY_7, 0x08 }, + { Key::KEY_8, 0x09 }, + { Key::KEY_9, 0x0A }, + { Key::KEY_0, 0x0B }, + { Key::MINUS, 0x0C }, + { Key::EQUAL, 0x0D }, + { Key::BACKSPACE, 0x0E }, + { Key::TAB, 0x0F }, + { Key::Q, 0x10 }, + { Key::W, 0x11 }, + { Key::E, 0x12 }, + { Key::R, 0x13 }, + { Key::T, 0x14 }, + { Key::Y, 0x15 }, + { Key::U, 0x16 }, + { Key::I, 0x17 }, + { Key::O, 0x18 }, + { Key::P, 0x19 }, + { Key::BRACELEFT, 0x1A }, + { Key::BRACERIGHT, 0x1B }, + { Key::ENTER, 0x1C }, + { Key::CTRL, 0x1D }, + { Key::A, 0x1E }, + { Key::S, 0x1F }, + { Key::D, 0x20 }, + { Key::F, 0x21 }, + { Key::G, 0x22 }, + { Key::H, 0x23 }, + { Key::J, 0x24 }, + { Key::K, 0x25 }, + { Key::L, 0x26 }, + { Key::SEMICOLON, 0x27 }, + { Key::APOSTROPHE, 0x28 }, + { Key::QUOTELEFT, 0x29 }, + { Key::SHIFT, 0x2A }, + { Key::BACKSLASH, 0x2B }, + { Key::Z, 0x2C }, + { Key::X, 0x2D }, + { Key::C, 0x2E }, + { Key::V, 0x2F }, + { Key::B, 0x30 }, + { Key::N, 0x31 }, + { Key::M, 0x32 }, + { Key::COMMA, 0x33 }, + { Key::PERIOD, 0x34 }, + { Key::SLASH, 0x35 }, + { Key::SHIFT, 0x36 }, + { Key::PRINT, 0x37 }, + { Key::ALT, 0x38 }, + { Key::SPACE, 0x39 }, + { Key::CAPSLOCK, 0x3A }, + { Key::F1, 0x3B }, + { Key::F2, 0x3C }, + { Key::F3, 0x3D }, + { Key::F4, 0x3E }, + { Key::F5, 0x3F }, + { Key::F6, 0x40 }, + { Key::F7, 0x41 }, + { Key::F8, 0x42 }, + { Key::F9, 0x43 }, + { Key::F10, 0x44 }, + { Key::NUMLOCK, 0x45 }, + { Key::SCROLLLOCK, 0x46 }, + { Key::HOME, 0x47 }, + { Key::UP, 0x48 }, + { Key::PAGEUP, 0x49 }, + { Key::KP_SUBTRACT, 0x4A }, + { Key::LEFT, 0x4B }, + { Key::KP_5, 0x4C }, + { Key::RIGHT, 0x4D }, + { Key::KP_ADD, 0x4E }, + { Key::END, 0x4F }, + { Key::DOWN, 0x50 }, + { Key::PAGEDOWN, 0x51 }, + { Key::INSERT, 0x52 }, + { Key::KEY_DELETE, 0x53 }, + //{ Key::???, 0x56 }, //NON US BACKSLASH + { Key::F11, 0x57 }, + { Key::F12, 0x58 }, + { Key::META, 0x5B }, + { Key::META, 0x5C }, + { Key::MENU, 0x5D }, + { Key::F13, 0x64 }, + { Key::F14, 0x65 }, + { Key::F15, 0x66 }, + { Key::F16, 0x67 }, + { Key::UNKNOWN, 0 } }; -unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { - for (int i = 0; _vk_to_keycode[i].keysym != KEY_UNKNOWN; i++) { +Key KeyMappingWindows::get_keysym(unsigned int p_code) { + for (int i = 0; _vk_to_keycode[i].keysym != Key::UNKNOWN; i++) { if (_vk_to_keycode[i].keycode == p_code) { //printf("outcode: %x\n",_vk_to_keycode[i].keysym); @@ -342,12 +342,22 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { } } - return KEY_UNKNOWN; + return Key::UNKNOWN; } -unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) { - unsigned int keycode = KEY_UNKNOWN; - for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { +unsigned int KeyMappingWindows::get_scancode(Key p_keycode) { + for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { + if (_scancode_to_keycode[i].keysym == p_keycode) { + return _scancode_to_keycode[i].keycode; + } + } + + return 0; +} + +Key KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) { + Key keycode = Key::UNKNOWN; + for (int i = 0; _scancode_to_keycode[i].keysym != Key::UNKNOWN; i++) { if (_scancode_to_keycode[i].keycode == p_code) { keycode = _scancode_to_keycode[i].keysym; break; @@ -356,55 +366,55 @@ unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended if (p_extended) { switch (keycode) { - case KEY_ENTER: { - keycode = KEY_KP_ENTER; + case Key::ENTER: { + keycode = Key::KP_ENTER; } break; - case KEY_SLASH: { - keycode = KEY_KP_DIVIDE; + case Key::SLASH: { + keycode = Key::KP_DIVIDE; } break; - case KEY_CAPSLOCK: { - keycode = KEY_KP_ADD; + case Key::CAPSLOCK: { + keycode = Key::KP_ADD; } break; default: break; } } else { switch (keycode) { - case KEY_NUMLOCK: { - keycode = KEY_PAUSE; + case Key::NUMLOCK: { + keycode = Key::PAUSE; } break; - case KEY_HOME: { - keycode = KEY_KP_7; + case Key::HOME: { + keycode = Key::KP_7; } break; - case KEY_UP: { - keycode = KEY_KP_8; + case Key::UP: { + keycode = Key::KP_8; } break; - case KEY_PAGEUP: { - keycode = KEY_KP_9; + case Key::PAGEUP: { + keycode = Key::KP_9; } break; - case KEY_LEFT: { - keycode = KEY_KP_4; + case Key::LEFT: { + keycode = Key::KP_4; } break; - case KEY_RIGHT: { - keycode = KEY_KP_6; + case Key::RIGHT: { + keycode = Key::KP_6; } break; - case KEY_END: { - keycode = KEY_KP_1; + case Key::END: { + keycode = Key::KP_1; } break; - case KEY_DOWN: { - keycode = KEY_KP_2; + case Key::DOWN: { + keycode = Key::KP_2; } break; - case KEY_PAGEDOWN: { - keycode = KEY_KP_3; + case Key::PAGEDOWN: { + keycode = Key::KP_3; } break; - case KEY_INSERT: { - keycode = KEY_KP_0; + case Key::INSERT: { + keycode = Key::KP_0; } break; - case KEY_DELETE: { - keycode = KEY_KP_PERIOD; + case Key::KEY_DELETE: { + keycode = Key::KP_PERIOD; } break; - case KEY_PRINT: { - keycode = KEY_KP_MULTIPLY; + case Key::PRINT: { + keycode = Key::KP_MULTIPLY; } break; default: break; @@ -416,13 +426,13 @@ unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended bool KeyMappingWindows::is_extended_key(unsigned int p_code) { return p_code == VK_INSERT || - p_code == VK_DELETE || - p_code == VK_HOME || - p_code == VK_END || - p_code == VK_PRIOR || - p_code == VK_NEXT || - p_code == VK_LEFT || - p_code == VK_UP || - p_code == VK_RIGHT || - p_code == VK_DOWN; + p_code == VK_DELETE || + p_code == VK_HOME || + p_code == VK_END || + p_code == VK_PRIOR || + p_code == VK_NEXT || + p_code == VK_LEFT || + p_code == VK_UP || + p_code == VK_RIGHT || + p_code == VK_DOWN; } diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h index fb07227014..0454be7310 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -33,16 +33,17 @@ #include "core/os/keyboard.h" +#define WIN32_LEAN_AND_MEAN #include <windows.h> - #include <winuser.h> class KeyMappingWindows { KeyMappingWindows() {} public: - static unsigned int get_keysym(unsigned int p_code); - static unsigned int get_scansym(unsigned int p_code, bool p_extended); + static Key get_keysym(unsigned int p_code); + static unsigned int get_scancode(Key p_keycode); + static Key get_scansym(unsigned int p_code, bool p_extended); static bool is_extended_key(unsigned int p_code); }; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 2a0a509d43..d8d4e92d9d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -28,15 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Must include Winsock before windows.h (included by os_windows.h) -#include "drivers/unix/net_socket_posix.h" - #include "os_windows.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" #include "core/io/marshalls.h" #include "core/version_generated.gen.h" +#include "drivers/unix/net_socket_posix.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "joypad_windows.h" @@ -75,7 +73,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; #define GetProcAddress (void *)GetProcAddress #endif -#ifdef DEBUG_ENABLED static String format_error_message(DWORD id) { LPWSTR messageBuffer = nullptr; size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -87,7 +84,6 @@ static String format_error_message(DWORD id) { return msg; } -#endif // DEBUG_ENABLED void RedirectIOToConsole() { int hConHandle; @@ -294,12 +290,13 @@ String OS_Windows::get_name() const { return "Windows"; } -OS::Date OS_Windows::get_date(bool utc) const { +OS::Date OS_Windows::get_date(bool p_utc) const { SYSTEMTIME systemtime; - if (utc) + if (p_utc) { GetSystemTime(&systemtime); - else + } else { GetLocalTime(&systemtime); + } Date date; date.day = systemtime.wDay; @@ -310,12 +307,13 @@ OS::Date OS_Windows::get_date(bool utc) const { return date; } -OS::Time OS_Windows::get_time(bool utc) const { +OS::Time OS_Windows::get_time(bool p_utc) const { SYSTEMTIME systemtime; - if (utc) + if (p_utc) { GetSystemTime(&systemtime); - else + } else { GetLocalTime(&systemtime); + } Time time; time.hour = systemtime.wHour; @@ -449,7 +447,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, ZeroMemory(&pi.pi, sizeof(pi.pi)); LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; - int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); + int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); WaitForSingleObject(pi.pi.hProcess, INFINITE); @@ -477,7 +475,7 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg ZeroMemory(&pi.pi, sizeof(pi.pi)); LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; - int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); + int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); ProcessID pid = pi.pi.dwProcessId; @@ -557,8 +555,27 @@ String OS_Windows::get_stdin_string(bool p_block) { } Error OS_Windows::shell_open(String p_uri) { - ShellExecuteW(nullptr, nullptr, (LPCWSTR)(p_uri.utf16().get_data()), nullptr, nullptr, SW_SHOWNORMAL); - return OK; + INT_PTR ret = (INT_PTR)ShellExecuteW(nullptr, nullptr, (LPCWSTR)(p_uri.utf16().get_data()), nullptr, nullptr, SW_SHOWNORMAL); + if (ret > 32) { + return OK; + } else { + switch (ret) { + case ERROR_FILE_NOT_FOUND: + case SE_ERR_DLLNOTFOUND: + return ERR_FILE_NOT_FOUND; + case ERROR_PATH_NOT_FOUND: + return ERR_FILE_BAD_PATH; + case ERROR_BAD_FORMAT: + return ERR_FILE_CORRUPT; + case SE_ERR_ACCESSDENIED: + return ERR_UNAUTHORIZED; + case 0: + case SE_ERR_OOM: + return ERR_OUT_OF_MEMORY; + default: + return FAILED; + } + } } String OS_Windows::get_locale() const { @@ -662,18 +679,27 @@ String OS_Windows::get_data_path() const { } String OS_Windows::get_cache_path() const { - // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. - if (has_environment("XDG_CACHE_HOME")) { - if (get_environment("XDG_CACHE_HOME").is_absolute_path()) { - return get_environment("XDG_CACHE_HOME").replace("\\", "/"); - } else { - WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%TEMP%` or `get_config_path()` per the XDG Base Directory specification."); + static String cache_path_cache; + if (cache_path_cache.is_empty()) { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. + if (has_environment("XDG_CACHE_HOME")) { + if (get_environment("XDG_CACHE_HOME").is_absolute_path()) { + cache_path_cache = get_environment("XDG_CACHE_HOME").replace("\\", "/"); + } else { + WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%LOCALAPPDATA%\\cache`, `%TEMP%` or `get_config_path()` per the XDG Base Directory specification."); + } + } + if (cache_path_cache.is_empty() && has_environment("LOCALAPPDATA")) { + cache_path_cache = get_environment("LOCALAPPDATA").replace("\\", "/"); + } + if (cache_path_cache.is_empty() && has_environment("TEMP")) { + cache_path_cache = get_environment("TEMP").replace("\\", "/"); + } + if (cache_path_cache.is_empty()) { + cache_path_cache = get_config_path(); } } - if (has_environment("TEMP")) { - return get_environment("TEMP").replace("\\", "/"); - } - return get_config_path(); + return cache_path_cache; } // Get properly capitalized engine name for system paths @@ -734,7 +760,7 @@ String OS_Windows::get_user_data_dir() const { } } - return ProjectSettings::get_singleton()->get_resource_path(); + return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file("[unnamed project]"); } String OS_Windows::get_unique_id() const { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index c4a2eda8f4..1342d95575 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -46,10 +46,6 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #endif -#if defined(OPENGL_ENABLED) -#include "context_gl_windows.h" -#endif - #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/windows/vulkan_context_win.h" @@ -57,7 +53,9 @@ #include <fcntl.h> #include <io.h> +#include <shellapi.h> #include <stdio.h> +#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <windowsx.h> @@ -120,8 +118,8 @@ public: virtual void initialize_joypads() override {} - virtual Date get_date(bool utc) const override; - virtual Time get_time(bool utc) const override; + virtual Date get_date(bool p_utc) const override; + virtual Time get_time(bool p_utc) const override; virtual TimeZoneInfo get_time_zone_info() const override; virtual double get_unix_time() const override; diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 481f583f6f..dace0f86af 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -29,3 +29,5 @@ /*************************************************************************/ #include <malloc.h> + +#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h" diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h index 39dd2641fd..61e66b8ae0 100644 --- a/platform/windows/vulkan_context_win.h +++ b/platform/windows/vulkan_context_win.h @@ -32,6 +32,8 @@ #define VULKAN_DEVICE_WIN_H #include "drivers/vulkan/vulkan_context.h" + +#define WIN32_LEAN_AND_MEAN #include <windows.h> class VulkanContextWindows : public VulkanContext { diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index 8cab7ca521..e54a61fdfd 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -33,6 +33,7 @@ #ifdef WINDOWS_ENABLED #include <stdio.h> +#define WIN32_LEAN_AND_MEAN #include <windows.h> void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_err) { |