diff options
Diffstat (limited to 'platform/windows/os_windows.cpp')
-rw-r--r-- | platform/windows/os_windows.cpp | 160 |
1 files changed, 132 insertions, 28 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index d6cfd039d9..b7b207dde1 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -190,6 +190,28 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) { } } +BOOL CALLBACK _CloseWindowsEnum(HWND hWnd, LPARAM lParam) { + DWORD dwID; + + GetWindowThreadProcessId(hWnd, &dwID); + + if (dwID == (DWORD)lParam) { + PostMessage(hWnd, WM_CLOSE, 0, 0); + } + + return TRUE; +} + +bool _close_gracefully(const PROCESS_INFORMATION &pi, const DWORD dwStopWaitMsec) { + if (!EnumWindows(_CloseWindowsEnum, pi.dwProcessId)) + return false; + + if (WaitForSingleObject(pi.hProcess, dwStopWaitMsec) != WAIT_OBJECT_0) + return false; + + return true; +} + void OS_Windows::initialize_debugging() { SetConsoleCtrlHandler(HandlerRoutine, TRUE); @@ -387,7 +409,84 @@ 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) + 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 @@ -754,14 +853,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 +860,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: { @@ -1024,7 +1115,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 +1156,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 +1189,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); @@ -1374,12 +1476,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() { @@ -1643,9 +1739,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(); @@ -2322,20 +2415,26 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, return OK; }; -Error OS_Windows::kill(const ProcessID &p_pid) { - +Error OS_Windows::kill(const ProcessID &p_pid, const int p_max_wait_msec) { ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi; process_map->erase(p_pid); - const int ret = TerminateProcess(pi.hProcess, 0); + Error result; + + if (p_max_wait_msec != -1 && _close_gracefully(pi, p_max_wait_msec)) { + result = OK; + } else { + const int ret = TerminateProcess(pi.hProcess, 0); + result = ret != 0 ? OK : FAILED; + } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); - return ret != 0 ? OK : FAILED; -}; + return result; +} int OS_Windows::get_process_id() const { return _getpid(); @@ -2777,7 +2876,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() { @@ -2790,9 +2889,13 @@ bool OS_Windows::is_disable_crash_handler() const { Error OS_Windows::move_to_trash(const String &p_path) { SHFILEOPSTRUCTW sf; + WCHAR *from = new WCHAR[p_path.length() + 2]; + wcscpy(from, p_path.c_str()); + from[p_path.length() + 1] = 0; + sf.hwnd = hWnd; sf.wFunc = FO_DELETE; - sf.pFrom = p_path.c_str(); + sf.pFrom = from; sf.pTo = NULL; sf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION; sf.fAnyOperationsAborted = FALSE; @@ -2800,6 +2903,7 @@ Error OS_Windows::move_to_trash(const String &p_path) { sf.lpszProgressTitle = NULL; int ret = SHFileOperationW(&sf); + delete[] from; if (ret) { ERR_PRINTS("SHFileOperation error: " + itos(ret)); |