diff options
Diffstat (limited to 'platform/windows/os_windows.cpp')
-rw-r--r-- | platform/windows/os_windows.cpp | 189 |
1 files changed, 143 insertions, 46 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 0f62dbb9e8..6cab683e83 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -34,19 +34,20 @@ #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/mutex_windows.h" +#include "drivers/windows/packet_peer_udp_winsock.h" #include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" +#include "drivers/windows/stream_peer_tcp_winsock.h" +#include "drivers/windows/tcp_server_winsock.h" #include "drivers/windows/thread_windows.h" #include "io/marshalls.h" #include "joypad.h" #include "lang_table.h" #include "main/main.h" -#include "packet_peer_udp_winsock.h" #include "servers/audio_server.h" #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" -#include "stream_peer_winsock.h" -#include "tcp_server_winsock.h" +#include "version_generated.gen.h" #include "windows_terminal_logger.h" #include <process.h> @@ -68,6 +69,19 @@ __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001; #define WM_TOUCH 576 #endif +static String format_error_message(DWORD id) { + + LPWSTR messageBuffer = NULL; + size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL); + + String msg = "Error " + itos(id) + ": " + String(messageBuffer, size); + + LocalFree(messageBuffer); + + return msg; +} + extern HINSTANCE godot_hinstance; void RedirectIOToConsole() { @@ -143,7 +157,7 @@ int OS_Windows::get_video_driver_count() const { } const char *OS_Windows::get_video_driver_name(int p_driver) const { - return "GLES2"; + return "GLES3"; } int OS_Windows::get_audio_driver_count() const { @@ -182,7 +196,7 @@ void OS_Windows::initialize_core() { DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); TCPServerWinsock::make_default(); - StreamPeerWinsock::make_default(); + StreamPeerTCPWinsock::make_default(); PacketPeerUDPWinsock::make_default(); // We need to know how often the clock is updated @@ -200,15 +214,6 @@ void OS_Windows::initialize_core() { cursor_shape = CURSOR_ARROW; } -void OS_Windows::initialize_logger() { - Vector<Logger *> loggers; - loggers.push_back(memnew(WindowsTerminalLogger)); - // FIXME: Reenable once we figure out how to get this properly in user:// - // instead of littering the user's working dirs (res:// + pwd) with log files (GH-12277) - //loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt"))); - _set_logger(memnew(CompositeLogger(loggers))); -} - bool OS_Windows::can_draw() const { return !minimized; @@ -218,7 +223,17 @@ bool OS_Windows::can_draw() const { #define SIGNATURE_MASK 0xFFFFFF00 #define IsPenEvent(dw) (((dw)&SIGNATURE_MASK) == MI_WP_SIGNATURE) -void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) { +void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) { + + // Defensive + if (touch_state.has(idx) == p_pressed) + return; + + if (p_pressed) { + touch_state.insert(idx, Vector2(p_x, p_y)); + } else { + touch_state.erase(idx); + } Ref<InputEventScreenTouch> event; event.instance(); @@ -231,7 +246,17 @@ void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) { } }; -void OS_Windows::_drag_event(int p_x, int p_y, int idx) { +void OS_Windows::_drag_event(float p_x, float p_y, int idx) { + + Map<int, Vector2>::Element *curr = touch_state.find(idx); + // Defensive + if (!curr) + return; + + if (curr->get() == Vector2(p_x, p_y)) + return; + + curr->get() = Vector2(p_x, p_y); Ref<InputEventScreenDrag> event; event.instance(); @@ -261,6 +286,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { ReleaseCapture(); } + + // Release every touch to avoid sticky points + for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) { + _touch_event(false, E->get().x, E->get().y, E->key()); + } + touch_state.clear(); + break; } case WM_ACTIVATE: // Watch For Window Activate Message @@ -664,7 +696,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) print_line("input lang change"); } break; -#if WINVER >= 0x0601 // for windows 7 case WM_TOUCH: { BOOL bHandled = FALSE; @@ -677,10 +708,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) //do something with each touch input entry if (ti.dwFlags & TOUCHEVENTF_MOVE) { - _drag_event(ti.x / 100, ti.y / 100, ti.dwID); + _drag_event(ti.x / 100.0f, ti.y / 100.0f, ti.dwID); } else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) { - _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN != 0, ti.x / 100, ti.y / 100, ti.dwID); + _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, ti.x / 100.0f, ti.y / 100.0f, ti.dwID); }; } bHandled = TRUE; @@ -698,7 +729,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; -#endif case WM_DEVICECHANGE: { joypad->probe_joypads(); @@ -1044,6 +1074,8 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int RasterizerGLES3::register_config(); RasterizerGLES3::make_current(); + + gl_context->set_use_vsync(video_mode.use_vsync); #endif visual_server = memnew(VisualServerRaster); @@ -1052,12 +1084,6 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } - if (!is_no_window_mode_enabled()) { - ShowWindow(hWnd, SW_SHOW); // Show The Window - SetForegroundWindow(hWnd); // Slightly Higher Priority - SetFocus(hWnd); // Sets Keyboard Focus To - } - /* DEVMODE dmScreenSettings; // Device Mode memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared @@ -1088,13 +1114,19 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int tme.dwHoverTime = HOVER_DEFAULT; TrackMouseEvent(&tme); - //RegisterTouchWindow(hWnd, 0); // Windows 7 + RegisterTouchWindow(hWnd, 0); - _ensure_data_dir(); + _ensure_user_data_dir(); DragAcceptFiles(hWnd, true); move_timer_id = 1; + + if (!is_no_window_mode_enabled()) { + ShowWindow(hWnd, SW_SHOW); // Show The Window + SetForegroundWindow(hWnd); // Slightly Higher Priority + SetFocus(hWnd); // Sets Keyboard Focus To + } } void OS_Windows::set_clipboard(const String &p_text) { @@ -1196,6 +1228,7 @@ void OS_Windows::finalize() { memdelete(joypad); memdelete(input); + touch_state.clear(); visual_server->finish(); memdelete(visual_server); @@ -1220,7 +1253,7 @@ void OS_Windows::finalize_core() { memdelete(process_map); TCPServerWinsock::cleanup(); - StreamPeerWinsock::cleanup(); + StreamPeerTCPWinsock::cleanup(); } void OS_Windows::alert(const String &p_alert, const String &p_title) { @@ -1565,7 +1598,7 @@ bool OS_Windows::is_window_maximized() const { return maximized; } -void OS_Windows::set_borderless_window(int p_borderless) { +void OS_Windows::set_borderless_window(bool p_borderless) { if (video_mode.borderless_window == p_borderless) return; @@ -1596,10 +1629,29 @@ void OS_Windows::_update_window_style(bool repaint) { } } -Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle) { - p_library_handle = (void *)LoadLibrary(p_path.utf8().get_data()); +Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { + + typedef DLL_DIRECTORY_COOKIE(WINAPI * PAddDllDirectory)(PCWSTR); + typedef BOOL(WINAPI * PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE); + + PAddDllDirectory add_dll_directory = (PAddDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "AddDllDirectory"); + PRemoveDllDirectory remove_dll_directory = (PRemoveDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "RemoveDllDirectory"); + + bool has_dll_directory_api = ((add_dll_directory != NULL) && (remove_dll_directory != NULL)); + DLL_DIRECTORY_COOKIE cookie; + + if (p_also_set_library_path && has_dll_directory_api) { + cookie = add_dll_directory(p_path.get_base_dir().c_str()); + } + + p_library_handle = (void *)LoadLibraryExW(p_path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0); + + if (p_also_set_library_path && has_dll_directory_api) { + remove_dll_directory(cookie); + } + if (!p_library_handle) { - ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError())); + ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + format_error_message(GetLastError())); ERR_FAIL_V(ERR_CANT_OPEN); } return OK; @@ -1851,7 +1903,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, modstr.resize(cmdline.size()); for (int i = 0; i < cmdline.size(); i++) modstr[i] = cmdline[i]; - int ret = CreateProcessW(NULL, modstr.ptr(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi); + int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi); ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); if (p_blocking) { @@ -1962,7 +2014,7 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) { bool OS_Windows::has_environment(const String &p_var) const { - return getenv(p_var.utf8().get_data()) != NULL; + return _wgetenv(p_var.c_str()) != NULL; }; String OS_Windows::get_environment(const String &p_var) const { @@ -2104,6 +2156,10 @@ void OS_Windows::swap_buffers() { gl_context->swap_buffers(); } +void OS_Windows::force_process_input() { + process_events(); // get rid of pending events +} + void OS_Windows::run() { if (!main_loop) @@ -2131,6 +2187,43 @@ MainLoop *OS_Windows::get_main_loop() const { return main_loop; } +String OS_Windows::get_config_path() const { + + if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not? + return get_environment("XDG_CONFIG_HOME"); + } else if (has_environment("APPDATA")) { + return get_environment("APPDATA"); + } else { + return "."; + } +} + +String OS_Windows::get_data_path() const { + + if (has_environment("XDG_DATA_HOME")) { + return get_environment("XDG_DATA_HOME"); + } else { + return get_config_path(); + } +} + +String OS_Windows::get_cache_path() const { + + if (has_environment("XDG_CACHE_HOME")) { + return get_environment("XDG_CACHE_HOME"); + } else if (has_environment("TEMP")) { + return get_environment("TEMP"); + } else { + return get_config_path(); + } +} + +// Get properly capitalized engine name for system paths +String OS_Windows::get_godot_dir_name() const { + + return String(VERSION_SHORT_NAME).capitalize(); +} + String OS_Windows::get_system_dir(SystemDir p_dir) const { int id; @@ -2167,18 +2260,20 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const { ERR_FAIL_COND_V(res != S_OK, String()); return String(szPath); } -String OS_Windows::get_data_dir() const { - String an = get_safe_application_name(); - if (an != "") { +String OS_Windows::get_user_data_dir() const { - if (has_environment("APPDATA")) { - - bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir"); - if (!use_godot) - return (OS::get_singleton()->get_environment("APPDATA") + "/" + an).replace("\\", "/"); - else - return (OS::get_singleton()->get_environment("APPDATA") + "/Godot/app_userdata/" + an).replace("\\", "/"); + String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name")); + if (appname != "") { + bool use_custom_dir = ProjectSettings::get_singleton()->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); + if (custom_dir == "") { + custom_dir = appname; + } + return get_data_path().plus_file(custom_dir).replace("\\", "/"); + } else { + return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname).replace("\\", "/"); } } @@ -2289,7 +2384,9 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) { AudioDriverManager::add_driver(&driver_xaudio2); #endif - _set_logger(memnew(WindowsTerminalLogger)); + Vector<Logger *> loggers; + loggers.push_back(memnew(WindowsTerminalLogger)); + _set_logger(memnew(CompositeLogger(loggers))); } OS_Windows::~OS_Windows() { |