summaryrefslogtreecommitdiff
path: root/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/SCsub25
-rw-r--r--platform/windows/console_wrapper_windows.cpp181
-rw-r--r--platform/windows/detect.py12
-rw-r--r--platform/windows/display_server_windows.cpp99
-rw-r--r--platform/windows/display_server_windows.h8
-rw-r--r--platform/windows/export/export_plugin.cpp58
-rw-r--r--platform/windows/export/export_plugin.h3
-rw-r--r--platform/windows/gl_manager_windows.cpp10
-rw-r--r--platform/windows/gl_manager_windows.h3
-rw-r--r--platform/windows/godot_res_wrap.rc31
-rw-r--r--platform/windows/joypad_windows.cpp2
-rw-r--r--platform/windows/os_windows.cpp21
-rw-r--r--platform/windows/os_windows.h4
-rw-r--r--platform/windows/platform_config.h2
-rw-r--r--platform/windows/vulkan_context_win.h4
15 files changed, 383 insertions, 80 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index 7e412b140f..efbb47d965 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -19,19 +19,44 @@ common_win = [
"gl_manager_windows.cpp",
]
+common_win_wrap = [
+ "console_wrapper_windows.cpp",
+]
+
res_file = "godot_res.rc"
res_target = "godot_res" + env["OBJSUFFIX"]
res_obj = env.RES(res_target, res_file)
prog = env.add_program("#bin/godot", common_win + res_obj, PROGSUFFIX=env["PROGSUFFIX"])
+# Build console wrapper app.
+if env["windows_subsystem"] == "gui":
+ env_wrap = env.Clone()
+ res_wrap_file = "godot_res_wrap.rc"
+ res_wrap_target = "godot_res_wrap" + env["OBJSUFFIX"]
+ res_wrap_obj = env_wrap.RES(res_wrap_target, res_wrap_file)
+
+ if env.msvc:
+ env_wrap.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
+ env_wrap.Append(LINKFLAGS=["version.lib"])
+ else:
+ env_wrap.Append(LINKFLAGS=["-Wl,--subsystem,console"])
+ env_wrap.Append(LIBS=["version"])
+
+ prog_wrap = env_wrap.add_program("#bin/godot", common_win_wrap + res_wrap_obj, PROGSUFFIX=env["PROGSUFFIX_WRAP"])
+
# Microsoft Visual Studio Project Generation
if env["vsproj"]:
env.vs_srcs += ["platform/windows/" + res_file]
env.vs_srcs += ["platform/windows/godot.natvis"]
for x in common_win:
env.vs_srcs += ["platform/windows/" + str(x)]
+ if env["windows_subsystem"] == "gui":
+ for x in common_win_wrap:
+ env.vs_srcs += ["platform/windows/" + str(x)]
if not os.getenv("VCINSTALLDIR"):
if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw))
+ if env["windows_subsystem"] == "gui":
+ env.AddPostAction(prog_wrap, run_in_subprocess(platform_windows_builders.make_debug_mingw))
diff --git a/platform/windows/console_wrapper_windows.cpp b/platform/windows/console_wrapper_windows.cpp
new file mode 100644
index 0000000000..258176426b
--- /dev/null
+++ b/platform/windows/console_wrapper_windows.cpp
@@ -0,0 +1,181 @@
+/*************************************************************************/
+/* console_wrapper_windows.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 <windows.h>
+
+#include <shlwapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
+#endif
+
+int main(int argc, char *argv[]) {
+ // Get executable name.
+ WCHAR exe_name[MAX_PATH] = {};
+ if (!GetModuleFileNameW(nullptr, exe_name, MAX_PATH)) {
+ wprintf(L"GetModuleFileName failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ // Get product name from the resources and set console title.
+ DWORD ver_info_handle = 0;
+ DWORD ver_info_size = GetFileVersionInfoSizeW(exe_name, &ver_info_handle);
+ if (ver_info_size > 0) {
+ LPBYTE ver_info = (LPBYTE)malloc(ver_info_size);
+ if (ver_info) {
+ if (GetFileVersionInfoW(exe_name, ver_info_handle, ver_info_size, ver_info)) {
+ LPCWSTR text_ptr = nullptr;
+ UINT text_size = 0;
+ if (VerQueryValueW(ver_info, L"\\StringFileInfo\\040904b0\\ProductName", (void **)&text_ptr, &text_size) && (text_size > 0)) {
+ SetConsoleTitleW(text_ptr);
+ }
+ }
+ free(ver_info);
+ }
+ }
+
+ // Enable virtual terminal sequences processing.
+ HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ DWORD out_mode = ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ SetConsoleMode(stdout_handle, out_mode);
+
+ // Find main executable name and check if it exist.
+ static PCWSTR exe_renames[] = {
+ L".console.exe",
+ L"_console.exe",
+ L" console.exe",
+ L"console.exe",
+ nullptr,
+ };
+
+ bool rename_found = false;
+ for (int i = 0; exe_renames[i]; i++) {
+ PWSTR c = StrRStrIW(exe_name, nullptr, exe_renames[i]);
+ if (c) {
+ CopyMemory(c, L".exe", sizeof(WCHAR) * 5);
+ rename_found = true;
+ break;
+ }
+ }
+ if (!rename_found) {
+ wprintf(L"Invalid wrapper executable name.\n");
+ return -1;
+ }
+
+ DWORD file_attrib = GetFileAttributesW(exe_name);
+ if (file_attrib == INVALID_FILE_ATTRIBUTES || (file_attrib & FILE_ATTRIBUTE_DIRECTORY)) {
+ wprintf(L"Main executable %ls not found.\n", exe_name);
+ return -1;
+ }
+
+ // Create job to monitor process tree.
+ HANDLE job_handle = CreateJobObjectW(nullptr, nullptr);
+ if (!job_handle) {
+ wprintf(L"CreateJobObject failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ HANDLE io_port_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
+ if (!io_port_handle) {
+ wprintf(L"CreateIoCompletionPort failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ JOBOBJECT_ASSOCIATE_COMPLETION_PORT compl_port;
+ ZeroMemory(&compl_port, sizeof(compl_port));
+ compl_port.CompletionKey = job_handle;
+ compl_port.CompletionPort = io_port_handle;
+
+ if (!SetInformationJobObject(job_handle, JobObjectAssociateCompletionPortInformation, &compl_port, sizeof(compl_port))) {
+ wprintf(L"SetInformationJobObject(AssociateCompletionPortInformation) failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
+ ZeroMemory(&jeli, sizeof(jeli));
+ jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+
+ if (!SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) {
+ wprintf(L"SetInformationJobObject(ExtendedLimitInformation) failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ // Start the main process.
+ PROCESS_INFORMATION pi;
+ ZeroMemory(&pi, sizeof(pi));
+
+ STARTUPINFOW si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ WCHAR new_command_line[32767];
+ _snwprintf_s(new_command_line, 32767, _TRUNCATE, L"%ls %ls", exe_name, PathGetArgsW(GetCommandLineW()));
+
+ if (!CreateProcessW(nullptr, new_command_line, nullptr, nullptr, true, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) {
+ wprintf(L"CreateProcess failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ if (!AssignProcessToJobObject(job_handle, pi.hProcess)) {
+ wprintf(L"AssignProcessToJobObject failed, error %d\n", GetLastError());
+ return -1;
+ }
+
+ ResumeThread(pi.hThread);
+ CloseHandle(pi.hThread);
+
+ // Wait until main process and all of its children are finished.
+ DWORD completion_code = 0;
+ ULONG_PTR completion_key = 0;
+ LPOVERLAPPED overlapped = nullptr;
+
+ while (GetQueuedCompletionStatus(io_port_handle, &completion_code, &completion_key, &overlapped, INFINITE)) {
+ if ((HANDLE)completion_key == job_handle && completion_code == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) {
+ break;
+ }
+ }
+
+ CloseHandle(job_handle);
+ CloseHandle(io_port_handle);
+
+ // Get exit code of the main process.
+ DWORD exit_code = 0;
+ GetExitCodeProcess(pi.hProcess, &exit_code);
+
+ CloseHandle(pi.hProcess);
+
+ return exit_code;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
+ return main(0, nullptr);
+}
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 74868fc6a2..705e83dace 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -582,12 +582,14 @@ def configure_mingw(env):
]
)
- env.Append(CPPDEFINES=["VULKAN_ENABLED"])
- if not env["use_volk"]:
- env.Append(LIBS=["vulkan"])
+ if env["vulkan"]:
+ env.Append(CPPDEFINES=["VULKAN_ENABLED"])
+ if not env["use_volk"]:
+ env.Append(LIBS=["vulkan"])
- env.Append(CPPDEFINES=["GLES3_ENABLED"])
- env.Append(LIBS=["opengl32"])
+ if env["opengl3"]:
+ 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 3b773685c3..af80a07da9 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -741,9 +741,20 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
case WINDOW_HANDLE: {
return (int64_t)windows[p_window].hWnd;
}
+#if defined(GLES3_ENABLED)
case WINDOW_VIEW: {
- return 0; // Not supported.
+ if (gl_manager) {
+ return (int64_t)gl_manager->get_hdc(p_window);
+ }
+ return 0;
+ }
+ case OPENGL_CONTEXT: {
+ if (gl_manager) {
+ return (int64_t)gl_manager->get_hglrc(p_window);
+ }
+ return 0;
}
+#endif
default: {
return 0;
}
@@ -1881,7 +1892,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) {
pos += sizeof(WORD);
f->seek(pos);
- icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY));
+ icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) - sizeof(ICONDIRENTRY) + 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.
@@ -2444,10 +2455,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
return 0; // Jump back.
}
case WM_MOUSELEAVE: {
- old_invalid = true;
- windows[window_id].mouse_outside = true;
+ if (window_mouseover_id == window_id) {
+ old_invalid = true;
+ window_mouseover_id = INVALID_WINDOW_ID;
- _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
+ _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
+ } else if (window_mouseover_id != INVALID_WINDOW_ID) {
+ // This is reached during drag and drop, after dropping in a different window.
+ // Once-off notification, must call again.
+ track_mouse_leave_event(windows[window_mouseover_id].hWnd);
+ }
} break;
case WM_INPUT: {
@@ -2678,17 +2695,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
- if (windows[window_id].mouse_outside) {
+ if (window_mouseover_id != window_id) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ // Leave previous window.
+ _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
- windows[window_id].mouse_outside = false;
+ window_mouseover_id = window_id;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@@ -2779,17 +2800,29 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
- if (windows[window_id].mouse_outside) {
+ DisplayServer::WindowID over_id = get_window_at_screen_position(mouse_get_position());
+ if (!Rect2(window_get_position(over_id), Point2(windows[over_id].width, windows[over_id].height)).has_point(mouse_get_position())) {
+ // Don't consider the windowborder as part of the window.
+ over_id = INVALID_WINDOW_ID;
+ }
+ if (window_mouseover_id != over_id) {
// Mouse enter.
if (mouse_mode != MOUSE_MODE_CAPTURED) {
- _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ // Leave previous window.
+ _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+
+ if (over_id != INVALID_WINDOW_ID) {
+ _send_window_event(windows[over_id], WINDOW_EVENT_MOUSE_ENTER);
+ }
}
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
cursor_set_shape(c);
- windows[window_id].mouse_outside = false;
+ window_mouseover_id = over_id;
// Once-off notification, must call again.
track_mouse_leave_event(hWnd);
@@ -2800,9 +2833,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
+ DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup();
+ if (receiving_window_id == INVALID_WINDOW_ID) {
+ receiving_window_id = window_id;
+ }
Ref<InputEventMouseMotion> mm;
mm.instantiate();
- mm->set_window_id(window_id);
+ mm->set_window_id(receiving_window_id);
mm->set_ctrl_pressed((wParam & MK_CONTROL) != 0);
mm->set_shift_pressed((wParam & MK_SHIFT) != 0);
mm->set_alt_pressed(alt_mem);
@@ -2859,9 +2896,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
old_x = mm->get_position().x;
old_y = mm->get_position().y;
- if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
- Input::get_singleton()->parse_input_event(mm);
+
+ if (!windows[receiving_window_id].window_has_focus) {
+ // In case of unfocused Popups, adjust event position.
+ Point2i pos = mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id);
+ mm->set_position(pos);
+ mm->set_global_position(pos);
}
+ Input::get_singleton()->parse_input_event(mm);
} break;
case WM_LBUTTONDOWN:
@@ -3087,7 +3129,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
rect_changed = true;
}
#if defined(VULKAN_ENABLED)
- if (context_vulkan && window_created) {
+ if (context_vulkan && window.context_created) {
// Note: Trigger resize event to update swapchains when window is minimized/restored, even if size is not changed.
context_vulkan->window_resize(window_id, window.width, window.height);
}
@@ -3547,6 +3589,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
windows.erase(id);
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create Vulkan Window.");
}
+ wd.context_created = true;
}
#endif
@@ -3703,7 +3746,7 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) {
}
}
-DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
drop_events = false;
key_event_pos = 0;
@@ -3855,6 +3898,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
+ if (p_position != nullptr) {
+ window_position = *p_position;
+ }
+
WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution));
ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
@@ -3918,12 +3965,24 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
return drivers;
}
-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));
+DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
if (r_error != OK) {
- 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");
+ if (p_rendering_driver == "vulkan") {
+ String executable_name = OS::get_singleton()->get_executable_path().get_file();
+ OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n"
+ "Please try updating your GPU driver or try using the OpenGL 3 driver.\n"
+ "You can enable the OpenGL 3 driver by starting the engine from the\n"
+ "command line with the command:\n'./" +
+ executable_name + " --rendering-driver opengl3'.\n "
+ "If you have updated your graphics drivers recently, try rebooting.",
+ "Unable to initialize Video driver");
+ } else {
+ OS::get_singleton()->alert("Your video card driver does not support the selected OpenGL version.\n"
+ "Please try updating your GPU driver.\n"
+ "If you have updated your graphics drivers recently, try rebooting.",
+ "Unable to initialize Video driver");
+ }
}
return ds;
}
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 6403b57d8d..8ac0086d69 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -323,6 +323,8 @@ class DisplayServerWindows : public DisplayServer {
LPARAM lParam;
};
+ WindowID window_mouseover_id = INVALID_WINDOW_ID;
+
KeyEvent key_event_buffer[KEY_EVENT_BUFFER_SIZE];
int key_event_pos;
@@ -369,6 +371,7 @@ class DisplayServerWindows : public DisplayServer {
bool no_focus = false;
bool window_has_focus = false;
bool exclusive = false;
+ bool context_created = false;
// Used to transfer data between events using timer.
WPARAM saved_wparam;
@@ -397,7 +400,6 @@ class DisplayServerWindows : public DisplayServer {
Size2 window_rect;
Point2 last_pos;
- bool mouse_outside = true;
ObjectID instance_id;
@@ -622,11 +624,11 @@ public:
virtual void set_context(Context p_context) override;
- static DisplayServer *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);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_windows_driver();
- DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
~DisplayServerWindows();
};
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 016d201f2c..d15380ac7a 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -41,24 +41,13 @@ Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPres
}
}
-Error EditorExportPlatformWindows::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
- Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
- if (f.is_null()) {
- add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path));
- return ERR_CANT_CREATE;
- }
-
- f->store_line("@echo off");
- f->store_line("title \"" + p_app_name + "\"");
- f->store_line("\"%~dp0" + p_pkg_name + "\" \"%*\"");
- f->store_line("pause > nul");
-
- return OK;
-}
-
Error EditorExportPlatformWindows::modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
if (p_preset->get("application/modify_resources")) {
- _rcedit_add_data(p_preset, p_path);
+ _rcedit_add_data(p_preset, p_path, true);
+ String wrapper_path = p_path.get_basename() + ".console.exe";
+ if (FileAccess::exists(wrapper_path)) {
+ _rcedit_add_data(p_preset, wrapper_path, false);
+ }
}
return OK;
}
@@ -71,6 +60,10 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, pck_path, p_flags);
if (p_preset->get("codesign/enable") && err == OK) {
_code_sign(p_preset, pck_path);
+ String wrapper_path = p_path.get_basename() + ".console.exe";
+ if (FileAccess::exists(wrapper_path)) {
+ _code_sign(p_preset, wrapper_path);
+ }
}
if (p_preset->get("binary_format/embed_pck") && err == OK) {
@@ -81,25 +74,6 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
}
}
- String app_name;
- if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") {
- app_name = String(ProjectSettings::get_singleton()->get("application/config/name"));
- } else {
- app_name = "Unnamed";
- }
- app_name = OS::get_singleton()->get_safe_dir_name(app_name);
-
- // Save console script.
- if (err == OK) {
- int con_scr = p_preset->get("debug/export_console_script");
- if ((con_scr == 1 && p_debug) || (con_scr == 2)) {
- String scr_path = p_path.get_basename() + ".cmd";
- if (_export_debug_script(p_preset, app_name, p_path.get_file(), scr_path) != OK) {
- add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), TTR("Could not create console script."));
- }
- }
- }
-
return err;
}
@@ -146,8 +120,8 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
}
-Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
- String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
+Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path, bool p_set_icon) {
+ String rcedit_path = EDITOR_GET("export/windows/rcedit");
if (rcedit_path != String() && !FileAccess::exists(rcedit_path)) {
add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Could not find rcedit executable at \"%s\"."), rcedit_path));
@@ -160,7 +134,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
#ifndef WINDOWS_ENABLED
// On non-Windows we need WINE to run rcedit
- String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
+ String wine_path = EDITOR_GET("export/windows/wine");
if (!wine_path.is_empty() && !FileAccess::exists(wine_path)) {
add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Could not find wine executable at \"%s\"."), wine_path));
@@ -184,7 +158,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
List<String> args;
args.push_back(p_path);
- if (!icon_path.is_empty()) {
+ if (!icon_path.is_empty() && p_set_icon) {
args.push_back("--set-icon");
args.push_back(icon_path);
}
@@ -248,7 +222,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
List<String> args;
#ifdef WINDOWS_ENABLED
- String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool");
+ String signtool_path = EDITOR_GET("export/windows/signtool");
if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) {
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Could not find signtool executable at \"%s\"."), signtool_path));
return ERR_FILE_NOT_FOUND;
@@ -257,7 +231,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
signtool_path = "signtool"; // try to run signtool from PATH
}
#else
- String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode");
+ String signtool_path = EDITOR_GET("export/windows/osslsigncode");
if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) {
add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Could not find osslsigncode executable at \"%s\"."), signtool_path));
return ERR_FILE_NOT_FOUND;
@@ -420,7 +394,7 @@ bool EditorExportPlatformWindows::has_valid_export_configuration(const Ref<Edito
String err = "";
bool valid = EditorExportPlatformPC::has_valid_export_configuration(p_preset, err, r_missing_templates);
- String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
+ String rcedit_path = EDITOR_GET("export/windows/rcedit");
if (p_preset->get("application/modify_resources") && rcedit_path.is_empty()) {
err += TTR("The rcedit tool must be configured in the Editor Settings (Export > Windows > rcedit) to change the icon or app information data.") + "\n";
}
diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h
index f85331c898..ec3b60aa76 100644
--- a/platform/windows/export/export_plugin.h
+++ b/platform/windows/export/export_plugin.h
@@ -38,9 +38,8 @@
#include "platform/windows/logo.gen.h"
class EditorExportPlatformWindows : public EditorExportPlatformPC {
- Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+ Error _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path, bool p_set_icon);
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
- Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path);
public:
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp
index 7689751f1b..900bca8258 100644
--- a/platform/windows/gl_manager_windows.cpp
+++ b/platform/windows/gl_manager_windows.cpp
@@ -339,6 +339,16 @@ bool GLManager_Windows::is_using_vsync() const {
return use_vsync;
}
+HDC GLManager_Windows::get_hdc(DisplayServer::WindowID p_window_id) {
+ return get_window(p_window_id).hDC;
+}
+
+HGLRC GLManager_Windows::get_hglrc(DisplayServer::WindowID p_window_id) {
+ const GLWindow &win = get_window(p_window_id);
+ const GLDisplay &disp = get_display(win.gldisplay_id);
+ return disp.hRC;
+}
+
GLManager_Windows::GLManager_Windows(ContextType p_context_type) {
context_type = p_context_type;
diff --git a/platform/windows/gl_manager_windows.h b/platform/windows/gl_manager_windows.h
index 5e43a3de2a..c6d5f9f855 100644
--- a/platform/windows/gl_manager_windows.h
+++ b/platform/windows/gl_manager_windows.h
@@ -113,6 +113,9 @@ public:
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
+ HDC get_hdc(DisplayServer::WindowID p_window_id);
+ HGLRC get_hglrc(DisplayServer::WindowID p_window_id);
+
GLManager_Windows(ContextType p_context_type);
~GLManager_Windows();
};
diff --git a/platform/windows/godot_res_wrap.rc b/platform/windows/godot_res_wrap.rc
new file mode 100644
index 0000000000..ed93bb1ec3
--- /dev/null
+++ b/platform/windows/godot_res_wrap.rc
@@ -0,0 +1,31 @@
+#include "core/version.h"
+#ifndef _STR
+#define _STR(m_x) #m_x
+#define _MKSTR(m_x) _STR(m_x)
+#endif
+
+1 VERSIONINFO
+FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0
+PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0
+FILEOS 4
+FILETYPE 1
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Godot Engine"
+ VALUE "FileDescription", VERSION_NAME " (Console)"
+ VALUE "FileVersion", VERSION_NUMBER
+ VALUE "ProductName", VERSION_NAME " (Console)"
+ VALUE "Licence", "MIT"
+ VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur and contributors"
+ VALUE "Info", "https://godotengine.org"
+ VALUE "ProductVersion", VERSION_FULL_BUILD
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index d039fd13a7..2b5c8cad48 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -167,7 +167,7 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) {
const GUID &guid = instance->guidProduct;
char uid[128];
- ERR_FAIL_COND_V_MSG(memcmp(&guid.Data4[2], "PIDVID", 6), false, "DirectInput device not recognised.");
+ ERR_FAIL_COND_V_MSG(memcmp(&guid.Data4[2], "PIDVID", 6), false, "DirectInput device not recognized.");
WORD type = BSWAP16(0x03);
WORD vendor = BSWAP16(LOWORD(guid.Data1));
WORD product = BSWAP16(HIWORD(guid.Data1));
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 5ca064e523..08897bb190 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -103,8 +103,6 @@ void RedirectIOToConsole() {
RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE);
RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE);
RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE);
-
- printf("\n"); // Make sure our output is starting from the new line.
}
}
@@ -311,6 +309,10 @@ String OS_Windows::get_version() const {
}
Vector<String> OS_Windows::get_video_adapter_driver_info() const {
+ if (RenderingServer::get_singleton()->get_rendering_device() == nullptr) {
+ return Vector<String>();
+ }
+
REFCLSID clsid = CLSID_WbemLocator; // Unmarshaler CLSID
REFIID uuid = IID_IWbemLocator; // Interface UUID
IWbemLocator *wbemLocator = NULL; // to get the services
@@ -1153,11 +1155,11 @@ String OS_Windows::get_system_dir(SystemDir p_dir, bool p_shared_storage) const
}
String OS_Windows::get_user_data_dir() const {
- String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
+ String appname = get_safe_dir_name(GLOBAL_GET("application/config/name"));
if (!appname.is_empty()) {
- bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
+ bool use_custom_dir = GLOBAL_GET("application/config/use_custom_user_dir");
if (use_custom_dir) {
- String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true);
+ String custom_dir = get_safe_dir_name(GLOBAL_GET("application/config/custom_user_dir_name"), true);
if (custom_dir.is_empty()) {
custom_dir = appname;
}
@@ -1177,7 +1179,14 @@ String OS_Windows::get_unique_id() const {
}
bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
- return p_feature == "pc";
+ if (p_feature == "system_fonts") {
+ return true;
+ }
+ if (p_feature == "pc") {
+ return true;
+ }
+
+ return false;
}
void OS_Windows::disable_crash_handler() {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index bf934bce64..6f89be699a 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -63,6 +63,10 @@
#define WINDOWS_DEBUG_OUTPUT_ENABLED
#endif
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
+#endif
+
template <class T>
class ComAutoreleaseRef {
public:
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
index 8e80f8cacb..7f0042d76f 100644
--- a/platform/windows/platform_config.h
+++ b/platform/windows/platform_config.h
@@ -30,4 +30,4 @@
#include <malloc.h>
-#define OPENGL_INCLUDE_H "thirdparty/glad/glad/glad.h"
+#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h"
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index 2ecdfc8f3f..9dedcabb2b 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -31,6 +31,8 @@
#ifndef VULKAN_CONTEXT_WIN_H
#define VULKAN_CONTEXT_WIN_H
+#ifdef VULKAN_ENABLED
+
#include "drivers/vulkan/vulkan_context.h"
#define WIN32_LEAN_AND_MEAN
@@ -46,4 +48,6 @@ public:
~VulkanContextWindows();
};
+#endif // VULKAN_ENABLED
+
#endif // VULKAN_CONTEXT_WIN_H