summaryrefslogtreecommitdiffstats
path: root/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/windows/display_server_windows.cpp149
-rw-r--r--platform/windows/display_server_windows.h3
-rw-r--r--platform/windows/joypad_windows.cpp4
-rw-r--r--platform/windows/platform_windows_builders.py16
-rw-r--r--platform/windows/wgl_detect_version.cpp24
-rw-r--r--platform/windows/wgl_detect_version.h4
7 files changed, 145 insertions, 57 deletions
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 7caa0153d7..bdacdbb9ba 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -419,6 +419,7 @@ def configure_msvc(env, vcvars_msvc_config):
"dwmapi",
"dwrite",
"wbemuuid",
+ "ntdll",
]
if env.debug_features:
@@ -610,6 +611,7 @@ def configure_mingw(env):
"dwmapi",
"dwrite",
"wbemuuid",
+ "ntdll",
]
)
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 1a1bba833d..cc5ae9ad45 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -222,24 +222,45 @@ void DisplayServerWindows::tts_stop() {
Error DisplayServerWindows::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_INDEX_V(int(p_mode), FILE_DIALOG_MODE_SAVE_MAX, FAILED);
+
Vector<Char16String> filter_names;
Vector<Char16String> filter_exts;
for (const String &E : p_filters) {
Vector<String> tokens = E.split(";");
- if (tokens.size() == 2) {
- filter_exts.push_back(tokens[0].strip_edges().utf16());
- filter_names.push_back(tokens[1].strip_edges().utf16());
- } else if (tokens.size() == 1) {
- filter_exts.push_back(tokens[0].strip_edges().utf16());
- filter_names.push_back(tokens[0].strip_edges().utf16());
+ if (tokens.size() >= 1) {
+ String flt = tokens[0].strip_edges();
+ int filter_slice_count = flt.get_slice_count(",");
+ Vector<String> exts;
+ for (int j = 0; j < filter_slice_count; j++) {
+ String str = (flt.get_slice(",", j).strip_edges());
+ if (!str.is_empty()) {
+ exts.push_back(str);
+ }
+ }
+ if (!exts.is_empty()) {
+ String str = String(";").join(exts);
+ filter_exts.push_back(str.utf16());
+ if (tokens.size() == 2) {
+ filter_names.push_back(tokens[1].strip_edges().utf16());
+ } else {
+ filter_names.push_back(str.utf16());
+ }
+ }
}
}
+ if (filter_names.is_empty()) {
+ filter_exts.push_back(String("*.*").utf16());
+ filter_names.push_back(RTR("All Files").utf16());
+ }
Vector<COMDLG_FILTERSPEC> filters;
for (int i = 0; i < filter_names.size(); i++) {
filters.push_back({ (LPCWSTR)filter_names[i].ptr(), (LPCWSTR)filter_exts[i].ptr() });
}
+ WindowID prev_focus = last_focused_window;
+
HRESULT hr = S_OK;
IFileDialog *pfd = nullptr;
if (p_mode == FILE_DIALOG_MODE_SAVE_FILE) {
@@ -285,6 +306,9 @@ Error DisplayServerWindows::file_dialog_show(const String &p_title, const String
}
hr = pfd->Show(windows[window_id].hWnd);
+ UINT index = 0;
+ pfd->GetFileTypeIndex(&index);
+
if (SUCCEEDED(hr)) {
Vector<String> file_names;
@@ -322,24 +346,17 @@ Error DisplayServerWindows::file_dialog_show(const String &p_title, const String
}
}
if (!p_callback.is_null()) {
- Variant v_status = true;
- Variant v_files = file_names;
- Variant *v_args[2] = { &v_status, &v_files };
- Variant ret;
- Callable::CallError ce;
- p_callback.callp((const Variant **)&v_args, 2, ret, ce);
+ p_callback.call(true, file_names, index);
}
} else {
if (!p_callback.is_null()) {
- Variant v_status = false;
- Variant v_files = Vector<String>();
- Variant *v_args[2] = { &v_status, &v_files };
- Variant ret;
- Callable::CallError ce;
- p_callback.callp((const Variant **)&v_args, 2, ret, ce);
+ p_callback.call(false, Vector<String>(), index);
}
}
pfd->Release();
+ if (prev_focus != INVALID_WINDOW_ID) {
+ callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(prev_focus);
+ }
return OK;
} else {
@@ -1191,6 +1208,51 @@ void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_wi
SetWindowTextW(windows[p_window].hWnd, (LPCWSTR)(p_title.utf16().get_data()));
}
+Size2i DisplayServerWindows::window_get_title_size(const String &p_title, WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+
+ Size2i size;
+ ERR_FAIL_COND_V(!windows.has(p_window), size);
+
+ const WindowData &wd = windows[p_window];
+ if (wd.fullscreen || wd.minimized || wd.borderless) {
+ return size;
+ }
+
+ HDC hdc = GetDCEx(wd.hWnd, NULL, DCX_WINDOW);
+ if (hdc) {
+ Char16String s = p_title.utf16();
+ SIZE text_size;
+ if (GetTextExtentPoint32W(hdc, (LPCWSTR)(s.get_data()), s.length(), &text_size)) {
+ size.x = text_size.cx;
+ size.y = text_size.cy;
+ }
+
+ ReleaseDC(wd.hWnd, hdc);
+ }
+ RECT rect;
+ if (DwmGetWindowAttribute(wd.hWnd, DWMWA_CAPTION_BUTTON_BOUNDS, &rect, sizeof(RECT)) == S_OK) {
+ if (rect.right - rect.left > 0) {
+ ClientToScreen(wd.hWnd, (POINT *)&rect.left);
+ ClientToScreen(wd.hWnd, (POINT *)&rect.right);
+
+ if (win81p_PhysicalToLogicalPointForPerMonitorDPI) {
+ win81p_PhysicalToLogicalPointForPerMonitorDPI(0, (POINT *)&rect.left);
+ win81p_PhysicalToLogicalPointForPerMonitorDPI(0, (POINT *)&rect.right);
+ }
+
+ size.x += (rect.right - rect.left);
+ size.y = MAX(size.y, rect.bottom - rect.top);
+ }
+ }
+ if (icon.is_valid()) {
+ size.x += 32;
+ } else {
+ size.x += 16;
+ }
+ return size;
+}
+
void DisplayServerWindows::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -2591,12 +2653,9 @@ void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y,
}
void DisplayServerWindows::_send_window_event(const WindowData &wd, WindowEvent p_event) {
- if (!wd.event_callback.is_null()) {
+ if (wd.event_callback.is_valid()) {
Variant event = int(p_event);
- Variant *eventp = &event;
- Variant ret;
- Callable::CallError ce;
- wd.event_callback.callp((const Variant **)&eventp, 1, ret, ce);
+ wd.event_callback.call(event);
}
}
@@ -2609,12 +2668,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
if (in_dispatch_input_event) {
return;
}
-
in_dispatch_input_event = true;
- Variant ev = p_event;
- Variant *evp = &ev;
- Variant ret;
- Callable::CallError ce;
{
List<WindowID>::Element *E = popup_list.back();
@@ -2623,7 +2677,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
if (windows.has(E->get())) {
Callable callable = windows[E->get()].input_event_callback;
if (callable.is_valid()) {
- callable.callp((const Variant **)&evp, 1, ret, ce);
+ callable.call(p_event);
}
}
in_dispatch_input_event = false;
@@ -2637,7 +2691,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
if (windows.has(event_from_window->get_window_id())) {
Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
if (callable.is_valid()) {
- callable.callp((const Variant **)&evp, 1, ret, ce);
+ callable.call(p_event);
}
}
} else {
@@ -2645,7 +2699,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
for (const KeyValue<WindowID, WindowData> &E : windows) {
const Callable callable = E.value.input_event_callback;
if (callable.is_valid()) {
- callable.callp((const Variant **)&evp, 1, ret, ce);
+ callable.call(p_event);
}
}
}
@@ -3708,11 +3762,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
if (rect_changed) {
if (!window.rect_changed_callback.is_null()) {
- Variant size = Rect2i(window.last_pos.x, window.last_pos.y, window.width, window.height);
- const Variant *args[] = { &size };
- Variant ret;
- Callable::CallError ce;
- window.rect_changed_callback.callp(args, 1, ret, ce);
+ window.rect_changed_callback.call(Rect2i(window.last_pos.x, window.last_pos.y, window.width, window.height));
}
// Update cursor clip region after window rect has changed.
@@ -3929,11 +3979,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
if (files.size() && !windows[window_id].drop_files_callback.is_null()) {
- Variant v = files;
- Variant *vp = &v;
- Variant ret;
- Callable::CallError ce;
- windows[window_id].drop_files_callback.callp((const Variant **)&vp, 1, ret, ce);
+ windows[window_id].drop_files_callback.call(files);
}
} break;
default: {
@@ -4385,6 +4431,7 @@ bool DisplayServerWindows::winink_available = false;
GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr;
GetPointerPenInfoPtr DisplayServerWindows::win8p_GetPointerPenInfo = nullptr;
LogicalToPhysicalPointForPerMonitorDPIPtr DisplayServerWindows::win81p_LogicalToPhysicalPointForPerMonitorDPI = nullptr;
+PhysicalToLogicalPointForPerMonitorDPIPtr DisplayServerWindows::win81p_PhysicalToLogicalPointForPerMonitorDPI = nullptr;
typedef enum _SHC_PROCESS_DPI_AWARENESS {
SHC_PROCESS_DPI_UNAWARE = 0,
@@ -4522,6 +4569,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
win81p_LogicalToPhysicalPointForPerMonitorDPI = (LogicalToPhysicalPointForPerMonitorDPIPtr)GetProcAddress(user32_lib, "LogicalToPhysicalPointForPerMonitorDPI");
+ win81p_PhysicalToLogicalPointForPerMonitorDPI = (PhysicalToLogicalPointForPerMonitorDPIPtr)GetProcAddress(user32_lib, "PhysicalToLogicalPointForPerMonitorDPI");
winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo;
}
@@ -4579,9 +4627,22 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
// Init context and rendering device
#if defined(GLES3_ENABLED)
- if (rendering_driver == "opengl3") {
- int gl_version = detect_wgl_version();
- if (gl_version < 30003) {
+ bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_angle");
+ if (fallback && (rendering_driver == "opengl3")) {
+ Dictionary gl_info = detect_wgl();
+
+ bool force_angle = false;
+
+ Array device_list = GLOBAL_GET("rendering/gl_compatibility/force_angle_on_devices");
+ for (int i = 0; i < device_list.size(); i++) {
+ const Dictionary &device = device_list[i];
+ if (device.has("vendor") && device.has("name") && device["vendor"].operator String().to_upper() == gl_info["vendor"].operator String().to_upper() && (device["name"] == "*" || device["name"].operator String().to_upper() == gl_info["name"].operator String().to_upper())) {
+ force_angle = true;
+ break;
+ }
+ }
+
+ if (force_angle || (gl_info["version"].operator int() < 30003)) {
WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE.");
rendering_driver = "opengl3_angle";
}
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 28f2f7e6ff..48c8c20280 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -262,6 +262,7 @@ typedef struct tagPOINTER_PEN_INFO {
typedef BOOL(WINAPI *GetPointerTypePtr)(uint32_t p_id, POINTER_INPUT_TYPE *p_type);
typedef BOOL(WINAPI *GetPointerPenInfoPtr)(uint32_t p_id, POINTER_PEN_INFO *p_pen_info);
typedef BOOL(WINAPI *LogicalToPhysicalPointForPerMonitorDPIPtr)(HWND hwnd, LPPOINT lpPoint);
+typedef BOOL(WINAPI *PhysicalToLogicalPointForPerMonitorDPIPtr)(HWND hwnd, LPPOINT lpPoint);
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
@@ -309,6 +310,7 @@ class DisplayServerWindows : public DisplayServer {
// DPI conversion API
static LogicalToPhysicalPointForPerMonitorDPIPtr win81p_LogicalToPhysicalPointForPerMonitorDPI;
+ static PhysicalToLogicalPointForPerMonitorDPIPtr win81p_PhysicalToLogicalPointForPerMonitorDPI;
void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver);
String tablet_driver;
@@ -569,6 +571,7 @@ public:
virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual Size2i window_get_title_size(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID) override;
virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index 0ac6c2c8b0..60edb00dd2 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -109,6 +109,7 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) {
static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+ static GUID IID_XOneElite2WirelessGamepad = { MAKELONG(0x045E, 0x0B22), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
if (memcmp(p_guid, &IID_ValveStreamingGamepad, sizeof(*p_guid)) == 0 ||
memcmp(p_guid, &IID_X360WiredGamepad, sizeof(*p_guid)) == 0 ||
@@ -120,7 +121,8 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) {
memcmp(p_guid, &IID_XOneNewWirelessGamepad, sizeof(*p_guid)) == 0 ||
memcmp(p_guid, &IID_XOneSWirelessGamepad, sizeof(*p_guid)) == 0 ||
memcmp(p_guid, &IID_XOneSBluetoothGamepad, sizeof(*p_guid)) == 0 ||
- memcmp(p_guid, &IID_XOneEliteWirelessGamepad, sizeof(*p_guid)) == 0)
+ memcmp(p_guid, &IID_XOneEliteWirelessGamepad, sizeof(*p_guid)) == 0 ||
+ memcmp(p_guid, &IID_XOneElite2WirelessGamepad, sizeof(*p_guid)) == 0)
return true;
PRAWINPUTDEVICELIST dev_list = nullptr;
diff --git a/platform/windows/platform_windows_builders.py b/platform/windows/platform_windows_builders.py
index b522a75a9c..51652fa814 100644
--- a/platform/windows/platform_windows_builders.py
+++ b/platform/windows/platform_windows_builders.py
@@ -5,14 +5,24 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
"""
import os
from detect import get_mingw_bin_prefix
+from detect import try_cmd
from platform_methods import subprocess_main
def make_debug_mingw(target, source, env):
mingw_bin_prefix = get_mingw_bin_prefix(env["mingw_prefix"], env["arch"])
- os.system(mingw_bin_prefix + "objcopy --only-keep-debug {0} {0}.debugsymbols".format(target[0]))
- os.system(mingw_bin_prefix + "strip --strip-debug --strip-unneeded {0}".format(target[0]))
- os.system(mingw_bin_prefix + "objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(target[0]))
+ if try_cmd("objcopy --version", env["mingw_prefix"], env["arch"]):
+ os.system(mingw_bin_prefix + "objcopy --only-keep-debug {0} {0}.debugsymbols".format(target[0]))
+ else:
+ os.system("objcopy --only-keep-debug {0} {0}.debugsymbols".format(target[0]))
+ if try_cmd("strip --version", env["mingw_prefix"], env["arch"]):
+ os.system(mingw_bin_prefix + "strip --strip-debug --strip-unneeded {0}".format(target[0]))
+ else:
+ os.system("strip --strip-debug --strip-unneeded {0}".format(target[0]))
+ if try_cmd("objcopy --version", env["mingw_prefix"], env["arch"]):
+ os.system(mingw_bin_prefix + "objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(target[0]))
+ else:
+ os.system("objcopy --add-gnu-debuglink={0}.debugsymbols {0}".format(target[0]))
if __name__ == "__main__":
diff --git a/platform/windows/wgl_detect_version.cpp b/platform/windows/wgl_detect_version.cpp
index 264cd525c5..49da4b58c7 100644
--- a/platform/windows/wgl_detect_version.cpp
+++ b/platform/windows/wgl_detect_version.cpp
@@ -35,6 +35,7 @@
#include "core/string/print_string.h"
#include "core/string/ustring.h"
+#include "core/variant/dictionary.h"
#include <windows.h>
@@ -64,9 +65,11 @@ typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int
typedef void *(APIENTRY *PFNWGLGETPROCADDRESS)(LPCSTR);
typedef const char *(APIENTRY *PFNWGLGETSTRINGPROC)(unsigned int);
-int detect_wgl_version() {
- int major = 0;
- int minor = 0;
+Dictionary detect_wgl() {
+ Dictionary gl_info;
+ gl_info["version"] = 0;
+ gl_info["vendor"] = String();
+ gl_info["name"] = String();
PFNWGLCREATECONTEXT gd_wglCreateContext;
PFNWGLMAKECURRENT gd_wglMakeCurrent;
@@ -75,14 +78,14 @@ int detect_wgl_version() {
HMODULE module = LoadLibraryW(L"opengl32.dll");
if (!module) {
- return 0;
+ return gl_info;
}
gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
- return 0;
+ return gl_info;
}
LPCWSTR class_name = L"EngineWGLDetect";
@@ -151,8 +154,8 @@ int detect_wgl_version() {
};
const char *version = (const char *)gd_wglGetString(WGL_VERSION);
if (version) {
- const String device_vendor = String::utf8((const char *)gd_wglGetString(WGL_VENDOR)).strip_edges();
- const String device_name = String::utf8((const char *)gd_wglGetString(WGL_RENDERER)).strip_edges();
+ const String device_vendor = String::utf8((const char *)gd_wglGetString(WGL_VENDOR)).strip_edges().trim_suffix(" Corporation");
+ const String device_name = String::utf8((const char *)gd_wglGetString(WGL_RENDERER)).strip_edges().trim_suffix("/PCIe/SSE2");
for (int i = 0; prefixes[i]; i++) {
size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0) {
@@ -160,12 +163,17 @@ int detect_wgl_version() {
break;
}
}
+ int major = 0;
+ int minor = 0;
#ifdef _MSC_VER
sscanf_s(version, "%d.%d", &major, &minor);
#else
sscanf(version, "%d.%d", &major, &minor);
#endif
print_verbose(vformat("Native OpenGL API detected: %d.%d: %s - %s", major, minor, device_vendor, device_name));
+ gl_info["vendor"] = device_vendor;
+ gl_info["name"] = device_name;
+ gl_info["version"] = major * 10000 + minor;
}
}
}
@@ -183,7 +191,7 @@ int detect_wgl_version() {
}
UnregisterClassW(class_name, hInstance);
- return major * 10000 + minor;
+ return gl_info;
}
#endif // WINDOWS_ENABLED && GLES3_ENABLED
diff --git a/platform/windows/wgl_detect_version.h b/platform/windows/wgl_detect_version.h
index 0be2923ba3..c110b1219e 100644
--- a/platform/windows/wgl_detect_version.h
+++ b/platform/windows/wgl_detect_version.h
@@ -33,7 +33,9 @@
#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
-int detect_wgl_version();
+class Dictionary;
+
+Dictionary detect_wgl();
#endif // WINDOWS_ENABLED && GLES3_ENABLED