summaryrefslogtreecommitdiff
path: root/platform/windows/os_windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows/os_windows.cpp')
-rw-r--r--platform/windows/os_windows.cpp141
1 files changed, 135 insertions, 6 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 81b8d08b3d..c4cd8e068c 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -70,6 +70,10 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#define WM_TOUCH 576
#endif
+#ifndef WM_POINTERUPDATE
+#define WM_POINTERUPDATE 0x0245
+#endif
+
typedef struct {
int count;
int screen;
@@ -192,6 +196,9 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
}
}
+GetPointerTypePtr OS_Windows::win8p_GetPointerType = NULL;
+GetPointerPenInfoPtr OS_Windows::win8p_GetPointerPenInfo = NULL;
+
void OS_Windows::initialize_debugging() {
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
@@ -288,15 +295,16 @@ void OS_Windows::_drag_event(float p_x, float p_y, int idx) {
if (curr->get() == Vector2(p_x, p_y))
return;
- curr->get() = Vector2(p_x, p_y);
-
Ref<InputEventScreenDrag> event;
event.instance();
event->set_index(idx);
event->set_position(Vector2(p_x, p_y));
+ event->set_relative(Vector2(p_x, p_y) - curr->get());
if (main_loop)
input->accumulate_input_event(event);
+
+ curr->get() = Vector2(p_x, p_y);
};
LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
@@ -480,6 +488,113 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
delete[] lpb;
} break;
+ case WM_POINTERUPDATE: {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
+ break;
+ }
+
+ if (!win8p_GetPointerType || !win8p_GetPointerPenInfo) {
+ break;
+ }
+
+ uint32_t pointer_id = LOWORD(wParam);
+ POINTER_INPUT_TYPE pointer_type = PT_POINTER;
+ if (!win8p_GetPointerType(pointer_id, &pointer_type)) {
+ break;
+ }
+
+ if (pointer_type != PT_PEN) {
+ break;
+ }
+
+ POINTER_PEN_INFO pen_info;
+ if (!win8p_GetPointerPenInfo(pointer_id, &pen_info)) {
+ break;
+ }
+
+ if (input->is_emulating_mouse_from_touch()) {
+ // Universal translation enabled; ignore OS translation
+ LPARAM extra = GetMessageExtraInfo();
+ if (IsTouchEvent(extra)) {
+ break;
+ }
+ }
+
+ if (outside) {
+ //mouse enter
+
+ if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
+ main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
+
+ CursorShape c = cursor_shape;
+ cursor_shape = CURSOR_MAX;
+ set_cursor_shape(c);
+ outside = false;
+
+ //Once-Off notification, must call again....
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hWnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+ }
+
+ // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
+ if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
+ break;
+
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_pressure(pen_info.pressure ? (float)pen_info.pressure / 1024 : 0);
+ mm->set_tilt(Vector2(pen_info.tiltX ? (float)pen_info.tiltX / 90 : 0, pen_info.tiltY ? (float)pen_info.tiltY / 90 : 0));
+
+ mm->set_control((wParam & MK_CONTROL) != 0);
+ mm->set_shift((wParam & MK_SHIFT) != 0);
+ mm->set_alt(alt_mem);
+
+ mm->set_button_mask(last_button_state);
+
+ mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ mm->set_global_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
+
+ Point2i c(video_mode.width / 2, video_mode.height / 2);
+ old_x = c.x;
+ old_y = c.y;
+
+ if (mm->get_position() == c) {
+ center = c;
+ return 0;
+ }
+
+ Point2i ncenter = mm->get_position();
+ center = ncenter;
+ POINT pos = { (int)c.x, (int)c.y };
+ ClientToScreen(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+ }
+
+ input->set_mouse_position(mm->get_position());
+ mm->set_speed(input->get_last_mouse_speed());
+
+ if (old_invalid) {
+
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
+ old_invalid = false;
+ }
+
+ 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 (window_has_focus && main_loop)
+ input->parse_input_event(mm);
+
+ return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event
+ } break;
case WM_MOUSEMOVE: {
if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
break;
@@ -1875,6 +1990,8 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
if (p_enabled) {
+ was_maximized = maximized;
+
if (pre_fs_valid) {
GetWindowRect(hWnd, &pre_fs_rect);
}
@@ -1904,7 +2021,7 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
rect.bottom = video_mode.height;
}
- _update_window_style(false);
+ _update_window_style(false, was_maximized);
MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
@@ -2086,12 +2203,16 @@ bool OS_Windows::get_borderless_window() {
return video_mode.borderless_window;
}
-void OS_Windows::_update_window_style(bool repaint) {
+void OS_Windows::_update_window_style(bool p_repaint, bool p_maximized) {
if (video_mode.fullscreen || video_mode.borderless_window) {
SetWindowLongPtr(hWnd, GWL_STYLE, WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE);
} else {
if (video_mode.resizable) {
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
+ if (p_maximized) {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE);
+ } else {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
+ }
} else {
SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_VISIBLE);
}
@@ -2099,7 +2220,7 @@ void OS_Windows::_update_window_style(bool repaint) {
SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
- if (repaint) {
+ if (p_repaint) {
RECT rect;
GetWindowRect(hWnd, &rect);
MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
@@ -3246,8 +3367,16 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
control_mem = false;
meta_mem = false;
minimized = false;
+ was_maximized = false;
console_visible = IsWindowVisible(GetConsoleWindow());
+ //Note: Functions for pen input, available on Windows 8+
+ HMODULE user32_lib = LoadLibraryW(L"user32.dll");
+ if (user32_lib) {
+ win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
+ win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
+ }
+
hInstance = _hInstance;
pressrc = 0;
old_invalid = true;