diff options
Diffstat (limited to 'platform/windows/os_windows.cpp')
-rw-r--r-- | platform/windows/os_windows.cpp | 424 |
1 files changed, 288 insertions, 136 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index bd76db8796..55d2bb2153 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -28,27 +28,27 @@ /* 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/io/marshalls.h" +#include "core/version_generated.gen.h" #include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" #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 "servers/audio_server.h" #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" -#include "version_generated.gen.h" #include "windows_terminal_logger.h" #include <process.h> @@ -58,11 +58,8 @@ static const WORD MAX_CONSOLE_LINES = 1500; extern "C" { -#ifdef _MSC_VER -_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; -#else -__attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001; -#endif +__declspec(dllexport) DWORD NvOptimusEnablement = 1; +__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } // Workaround mingw-w64 < 4.0 bug @@ -219,9 +216,7 @@ void OS_Windows::initialize_core() { DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); - TCPServerWinsock::make_default(); - StreamPeerTCPWinsock::make_default(); - PacketPeerUDPWinsock::make_default(); + NetSocketPosix::make_default(); // We need to know how often the clock is updated if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second)) @@ -249,7 +244,11 @@ bool OS_Windows::can_draw() const { #define MI_WP_SIGNATURE 0xFF515700 #define SIGNATURE_MASK 0xFFFFFF00 +// 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) +#define IsTouchEvent(dw) (IsPenEvent(dw) && ((dw)&0x80)) void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) { @@ -301,19 +300,17 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { case WM_SETFOCUS: { window_has_focus = true; - // Re-capture cursor if we're in one of the capture modes - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { - SetCapture(hWnd); - } + + // Restore mouse mode + _set_mouse_mode_impl(mouse_mode); + break; } case WM_KILLFOCUS: { window_has_focus = false; - // Release capture if we're in one of the capture modes - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { - ReleaseCapture(); - } + // 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()) { @@ -335,15 +332,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) alt_mem = false; control_mem = false; shift_mem = false; - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { - RECT clipRect; - GetClientRect(hWnd, &clipRect); - ClientToScreen(hWnd, (POINT *)&clipRect.left); - ClientToScreen(hWnd, (POINT *)&clipRect.right); - ClipCursor(&clipRect); - SetCapture(hWnd); - } - } else { + } else { // WM_INACTIVE main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); alt_mem = false; }; @@ -387,12 +376,89 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) input->set_mouse_in_window(false); } break; + case WM_INPUT: { + if (mouse_mode != MOUSE_MODE_CAPTURED || !use_raw_input) { + break; + } + + UINT dwSize; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); + LPBYTE lpb = new BYTE[dwSize]; + if (lpb == NULL) { + return 0; + } + + if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) + OutputDebugString(TEXT("GetRawInputData does not return correct size !\n")); + + RAWINPUT *raw = (RAWINPUT *)lpb; + + if (raw->header.dwType == RIM_TYPEMOUSE) { + Ref<InputEventMouseMotion> mm; + mm.instance(); + + mm->set_control(control_mem); + mm->set_shift(shift_mem); + mm->set_alt(alt_mem); + + mm->set_button_mask(last_button_state); + + Point2i c(video_mode.width / 2, video_mode.height / 2); + + // centering just so it works as before + POINT pos = { (int)c.x, (int)c.y }; + ClientToScreen(hWnd, &pos); + SetCursorPos(pos.x, pos.y); + + mm->set_position(c); + mm->set_global_position(c); + input->set_mouse_position(c); + mm->set_speed(Vector2(0, 0)); + + if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) { + mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY)); + + } else if (raw->data.mouse.usFlags == MOUSE_MOVE_ABSOLUTE) { + + int nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + int nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); + int nScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN); + int nScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN); + + Vector2 abs_pos( + (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 + coords.x = abs_pos.x; + coords.y = abs_pos.y; + + ScreenToClient(hWnd, &coords); + + 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 (window_has_focus && main_loop && mm->get_relative() != Vector2()) + input->parse_input_event(mm); + } + delete[] lpb; + } break; case WM_MOUSEMOVE: { + if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) { + break; + } if (input->is_emulating_mouse_from_touch()) { // Universal translation enabled; ignore OS translation LPARAM extra = GetMessageExtraInfo(); - if (IsPenEvent(extra)) { + if (IsTouchEvent(extra)) { break; } } @@ -483,7 +549,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (input->is_emulating_mouse_from_touch()) { // Universal translation enabled; ignore OS translations for left button LPARAM extra = GetMessageExtraInfo(); - if (IsPenEvent(extra)) { + if (IsTouchEvent(extra)) { break; } } @@ -618,7 +684,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) last_button_state = mb->get_button_mask(); mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); - if (mouse_mode == MOUSE_MODE_CAPTURED) { + if (mouse_mode == MOUSE_MODE_CAPTURED && !use_raw_input) { mb->set_position(Vector2(old_x, old_y)); } @@ -626,12 +692,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) { if (mb->is_pressed()) { - if (++pressrc > 0) + if (++pressrc > 0 && mouse_mode != MOUSE_MODE_CAPTURED) SetCapture(hWnd); } else { if (--pressrc <= 0) { - ReleaseCapture(); + if (mouse_mode != MOUSE_MODE_CAPTURED) { + ReleaseCapture(); + } pressrc = 0; } } @@ -659,16 +727,28 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } break; + case WM_MOVE: { + if (!IsIconic(hWnd)) { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + last_pos = Point2(x, y); + } + } break; + case WM_SIZE: { - int window_w = LOWORD(lParam); - int window_h = HIWORD(lParam); - if (window_w > 0 && window_h > 0 && !preserve_window_size) { - video_mode.width = window_w; - video_mode.height = window_h; - } else { - preserve_window_size = false; - set_window_size(Size2(video_mode.width, video_mode.height)); + // Ignore size when a SIZE_MINIMIZED event is triggered + if (wParam != SIZE_MINIMIZED) { + int window_w = LOWORD(lParam); + int window_h = HIWORD(lParam); + if (window_w > 0 && window_h > 0 && !preserve_window_size) { + video_mode.width = window_w; + video_mode.height = window_h; + } else { + preserve_window_size = false; + set_window_size(Size2(video_mode.width, video_mode.height)); + } } + if (wParam == SIZE_MAXIMIZED) { maximized = true; minimized = false; @@ -684,7 +764,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) RECT r; GetWindowRect(hWnd, &r); - dib_size = Size2(r.right - r.left, r.bottom - r.top); + dib_size = Size2i(r.right - r.left, r.bottom - r.top); BITMAPINFO bmi; ZeroMemory(&bmi, sizeof(BITMAPINFO)); @@ -694,7 +774,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = dib_size.x, dib_size.y * 4; + bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4; hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, NULL, 0x0); SelectObject(hDC_dib, hBitmap); @@ -754,14 +834,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (ke.uMsg == WM_SYSKEYUP) ke.uMsg = WM_KEYUP; - /*if (ke.uMsg==WM_KEYDOWN && alt_mem && uMsg!=WM_SYSKEYDOWN) { - //altgr hack for intl keyboards, not sure how good it is - //windows is weeeeird - ke.mod_state.alt=false; - ke.mod_state.control=false; - print_line("") - }*/ - ke.wParam = wParam; ke.lParam = lParam; key_event_buffer[key_event_pos++] = ke; @@ -769,7 +841,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; case WM_INPUTLANGCHANGEREQUEST: { - print_line("input lang change"); + // FIXME: Do something? } break; case WM_TOUCH: { @@ -979,7 +1051,6 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau UINT x = 0, y = 0; HRESULT hr = E_FAIL; - bool bSet = false; if (hmon && (Shcore != (HMODULE)INVALID_HANDLE_VALUE)) { hr = getDPIForMonitor(hmon, dpiType /*MDT_Effective_DPI*/, &x, &y); if (SUCCEEDED(hr) && (x > 0) && (y > 0)) { @@ -1024,7 +1095,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int WNDCLASSEXW wc; if (is_hidpi_allowed()) { - print_line("hidpi aware?"); HMODULE Shcore = LoadLibraryW(L"Shcore.dll"); if (Shcore != NULL) { @@ -1066,6 +1136,20 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int return ERR_UNAVAILABLE; } + use_raw_input = true; + + RAWINPUTDEVICE Rid[1]; + + Rid[0].usUsagePage = 0x01; + Rid[0].usUsage = 0x02; + Rid[0].dwFlags = 0; + Rid[0].hwndTarget = 0; + + if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) { + //registration failed. + use_raw_input = false; + } + pre_fs_valid = true; if (video_mode.fullscreen) { @@ -1085,8 +1169,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int WindowRect.right = data.size.width; WindowRect.bottom = data.size.height; - print_line("wr right " + itos(WindowRect.right) + ", " + itos(WindowRect.bottom)); - /* DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); @@ -1122,7 +1204,14 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); - char *windowid = getenv("GODOT_WINDOWID"); + char *windowid; +#ifdef MINGW_ENABLED + windowid = getenv("GODOT_WINDOWID"); +#else + size_t len; + _dupenv_s(&windowid, &len, "GODOT_WINDOWID"); +#endif + if (windowid) { // strtoull on mingw @@ -1131,6 +1220,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int #else hWnd = (HWND)_strtoui64(windowid, NULL, 0); #endif + free(windowid); SetLastError(0); user_proc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC); SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)(WNDPROC)::WndProc); @@ -1139,7 +1229,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int printf("Error setting WNDPROC: %li\n", le); }; - LONG_PTR proc = GetWindowLongPtr(hWnd, GWLP_WNDPROC); + GetWindowLongPtr(hWnd, GWLP_WNDPROC); RECT rect; if (!GetClientRect(hWnd, &rect)) { @@ -1171,45 +1261,83 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int } #if defined(OPENGL_ENABLED) + + bool gles3_context = true; if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_context = memnew(ContextGL_Win(hWnd, false)); - gl_context->initialize(); + gles3_context = false; + } - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - } else { - gl_context = memnew(ContextGL_Win(hWnd, true)); - gl_context->initialize(); + bool editor = Engine::get_singleton()->is_editor_hint(); + bool gl_initialization_error = false; + + gl_context = NULL; + while (!gl_context) { + gl_context = memnew(ContextGL_Win(hWnd, gles3_context)); + + if (gl_context->initialize() != OK) { + memdelete(gl_context); + gl_context = NULL; + + if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) { + if (p_video_driver == VIDEO_DRIVER_GLES2) { + gl_initialization_error = true; + break; + } - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); + p_video_driver = VIDEO_DRIVER_GLES2; + gles3_context = false; + } else { + gl_initialization_error = true; + break; + } + } + } + + while (true) { + if (gles3_context) { + if (RasterizerGLES3::is_viable() == OK) { + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + break; + } else { + if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) { + p_video_driver = VIDEO_DRIVER_GLES2; + gles3_context = false; + continue; + } else { + gl_initialization_error = true; + break; + } + } + } else { + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + break; + } else { + gl_initialization_error = true; + break; + } + } } - video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED + if (gl_initialization_error) { + OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" + "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + "Unable to initialize Video driver"); + return ERR_UNAVAILABLE; + } + + video_driver_index = p_video_driver; gl_context->set_use_vsync(video_mode.use_vsync); #endif visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { - visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } - /* - DEVMODE dmScreenSettings; // Device Mode - memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared - dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure - dmScreenSettings.dmPelsWidth = width; // Selected Screen Width - dmScreenSettings.dmPelsHeight = height; // Selected Screen Height - dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel - dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; - if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) - - - - - */ visual_server->init(); input = memnew(InputDefault); @@ -1219,10 +1347,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int AudioDriverManager::initialize(p_audio_driver); -#ifdef WINMIDI_ENABLED - driver_midi.open(); -#endif - TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; @@ -1374,12 +1498,6 @@ void OS_Windows::finalize() { if (user_proc) { SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc); }; - - /* - if (debugger_connection_console) { - memdelete(debugger_connection_console); - } - */ } void OS_Windows::finalize_core() { @@ -1387,9 +1505,7 @@ void OS_Windows::finalize_core() { timeEndPeriod(1); memdelete(process_map); - - TCPServerWinsock::cleanup(); - StreamPeerTCPWinsock::cleanup(); + NetSocketPosix::cleanup(); } void OS_Windows::alert(const String &p_alert, const String &p_title) { @@ -1404,18 +1520,27 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) { if (mouse_mode == p_mode) return; + + _set_mouse_mode_impl(p_mode); + mouse_mode = p_mode; - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { +} + +void OS_Windows::_set_mouse_mode_impl(MouseMode p_mode) { + + if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED) { RECT clipRect; GetClientRect(hWnd, &clipRect); ClientToScreen(hWnd, (POINT *)&clipRect.left); ClientToScreen(hWnd, (POINT *)&clipRect.right); ClipCursor(&clipRect); - center = Point2i(video_mode.width / 2, video_mode.height / 2); - POINT pos = { (int)center.x, (int)center.y }; - ClientToScreen(hWnd, &pos); - if (mouse_mode == MOUSE_MODE_CAPTURED) + if (p_mode == MOUSE_MODE_CAPTURED) { + center = Point2i(video_mode.width / 2, video_mode.height / 2); + POINT pos = { (int)center.x, (int)center.y }; + ClientToScreen(hWnd, &pos); SetCursorPos(pos.x, pos.y); + SetCapture(hWnd); + } } else { ReleaseCapture(); ClipCursor(NULL); @@ -1429,7 +1554,6 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) { set_cursor_shape(c); } } - OS_Windows::MouseMode OS_Windows::get_mouse_mode() const { return mouse_mode; @@ -1573,6 +1697,10 @@ int OS_Windows::get_screen_dpi(int p_screen) const { Point2 OS_Windows::get_window_position() const { + if (minimized) { + return last_pos; + } + RECT r; GetWindowRect(hWnd, &r); return Point2(r.left, r.top); @@ -1584,18 +1712,37 @@ void OS_Windows::set_window_position(const Point2 &p_position) { RECT r; GetWindowRect(hWnd, &r); MoveWindow(hWnd, p_position.x, p_position.y, r.right - r.left, r.bottom - r.top, TRUE); + + // Don't let the mouse leave the window when moved + if (mouse_mode == MOUSE_MODE_CONFINED) { + RECT rect; + GetClientRect(hWnd, &rect); + ClientToScreen(hWnd, (POINT *)&rect.left); + ClientToScreen(hWnd, (POINT *)&rect.right); + ClipCursor(&rect); + } + + last_pos = p_position; } Size2 OS_Windows::get_window_size() const { + if (minimized) { + return Size2(video_mode.width, video_mode.height); + } + RECT r; - GetClientRect(hWnd, &r); - return Vector2(r.right - r.left, r.bottom - r.top); + if (GetClientRect(hWnd, &r)) { // Only area inside of window border + return Size2(r.right - r.left, r.bottom - r.top); + } + return Size2(); } Size2 OS_Windows::get_real_window_size() const { RECT r; - GetWindowRect(hWnd, &r); - return Vector2(r.right - r.left, r.bottom - r.top); + if (GetWindowRect(hWnd, &r)) { // Includes area of the window border + return Size2(r.right - r.left, r.bottom - r.top); + } + return Size2(); } void OS_Windows::set_window_size(const Size2 p_size) { @@ -1612,7 +1759,7 @@ void OS_Windows::set_window_size(const Size2 p_size) { RECT rect; GetWindowRect(hWnd, &rect); - if (video_mode.borderless_window == false) { + if (!video_mode.borderless_window) { RECT crect; GetClientRect(hWnd, &crect); @@ -1643,9 +1790,6 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) { if (pre_fs_valid) { GetWindowRect(hWnd, &pre_fs_rect); - //print_line("A: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top)); - //MapWindowPoints(hWnd, GetParent(hWnd), (LPPOINT) &pre_fs_rect, 2); - //print_line("B: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top)); } int cs = get_current_screen(); @@ -2128,14 +2272,15 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap } ERR_FAIL_COND(!texture.is_valid()); + ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); + ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); image = texture->get_data(); ERR_FAIL_COND(!image.is_valid()); UINT image_size = texture_size.width * texture_size.height; - UINT size = sizeof(UINT) * image_size; // Create the BITMAP with alpha channel COLORREF *buffer = (COLORREF *)memalloc(sizeof(COLORREF) * image_size); @@ -2180,8 +2325,10 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap cursors[p_shape] = CreateIconIndirect(&iconinfo); - if (p_shape == CURSOR_ARROW) { - SetCursor(cursors[p_shape]); + if (p_shape == cursor_shape) { + if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + SetCursor(cursors[p_shape]); + } } if (hAndMask != NULL) { @@ -2197,8 +2344,10 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap } else { // Reset to default system cursor cursors[p_shape] = NULL; + + CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; - set_cursor_shape(p_shape); + set_cursor_shape(c); } } @@ -2309,6 +2458,8 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, if (r_exitcode) *r_exitcode = ret; + CloseHandle(pi.pi.hProcess); + CloseHandle(pi.pi.hThread); } else { ProcessID pid = pi.pi.dwProcessId; @@ -2322,17 +2473,15 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, Error OS_Windows::kill(const ProcessID &p_pid) { - HANDLE h; + ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); - if (process_map->has(p_pid)) { - h = (*process_map)[p_pid].pi.hProcess; - process_map->erase(p_pid); - } else { + const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi; + process_map->erase(p_pid); - ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); - }; + const int ret = TerminateProcess(pi.hProcess, 0); - int ret = TerminateProcess(h, 0); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); return ret != 0 ? OK : FAILED; }; @@ -2411,7 +2560,16 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) { bool OS_Windows::has_environment(const String &p_var) const { +#ifdef MINGW_ENABLED return _wgetenv(p_var.c_str()) != NULL; +#else + wchar_t *env; + size_t len; + _wdupenv_s(&env, &len, p_var.c_str()); + const bool has_env = env != NULL; + free(env); + return has_env; +#endif }; String OS_Windows::get_environment(const String &p_var) const { @@ -2594,15 +2752,10 @@ void OS_Windows::run() { main_loop->init(); - uint64_t last_ticks = get_ticks_usec(); - - int frames = 0; - uint64_t frame = 0; - while (!force_quit) { process_events(); // get rid of pending events - if (Main::iteration() == true) + if (Main::iteration()) break; }; @@ -2777,7 +2930,7 @@ int OS_Windows::get_power_percent_left() { bool OS_Windows::_check_internal_feature_support(const String &p_feature) { - return p_feature == "pc" || p_feature == "s3tc"; + return p_feature == "pc" || p_feature == "s3tc" || p_feature == "bptc"; } void OS_Windows::disable_crash_handler() { @@ -2789,10 +2942,9 @@ bool OS_Windows::is_disable_crash_handler() const { } Error OS_Windows::move_to_trash(const String &p_path) { - SHFILEOPSTRUCTA sf; - TCHAR *from = new TCHAR[p_path.length() + 2]; - strcpy(from, p_path.utf8().get_data()); - from[p_path.length()] = 0; + SHFILEOPSTRUCTW sf; + WCHAR *from = new WCHAR[p_path.length() + 2]; + wcscpy_s(from, p_path.length() + 1, p_path.c_str()); from[p_path.length() + 1] = 0; sf.hwnd = hWnd; @@ -2804,7 +2956,7 @@ Error OS_Windows::move_to_trash(const String &p_path) { sf.hNameMappings = NULL; sf.lpszProgressTitle = NULL; - int ret = SHFileOperation(&sf); + int ret = SHFileOperationW(&sf); delete[] from; if (ret) { |