diff --git a/src/pl.c b/src/pl.c index 5210f775..6d0a83d3 100644 --- a/src/pl.c +++ b/src/pl.c @@ -1667,6 +1667,7 @@ pl__load_core_apis(void) tWindowApi.set_cursor_mode = pl_set_cursor_mode; tWindowApi.get_cursor_mode = pl_get_cursor_mode; tWindowApi.set_raw_mouse_input = pl_set_raw_mouse_input; + tWindowApi.set_mouse_pos = pl_set_mouse_pos; tWindowApi.set_fullscreen = pl_set_fullscreen; tWindowApi.get_capabilities = pl_get_window_capabilities; diff --git a/src/pl.h b/src/pl.h index e84d91cc..84d30321 100644 --- a/src/pl.h +++ b/src/pl.h @@ -197,6 +197,7 @@ PL_API bool pl_window_get_attribute (plWindow*, plWindowAttribute, plWindowAttri PL_API bool pl_window_set_cursor_mode (plWindow*, plCursorMode); PL_API plCursorMode pl_window_get_cursor_mode (plWindow*); PL_API bool pl_window_set_raw_mouse_input (plWindow*, bool); +PL_API bool pl_window_set_mouse_pos (plWindow*, plVec2); // full screen modes PL_API bool pl_window_set_fullscreen(plWindow*, const plFullScreenDesc*); @@ -328,6 +329,7 @@ typedef struct _plWindowI bool (*set_cursor_mode) (plWindow*, plCursorMode); plCursorMode (*get_cursor_mode) (plWindow*); bool (*set_raw_mouse_input) (plWindow*, bool); + bool (*set_mouse_pos) (plWindow*, plVec2); // full screen modes bool (*set_fullscreen)(plWindow*, const plFullScreenDesc*); diff --git a/src/pl_internal.h b/src/pl_internal.h index 9653dbe8..6c6b1a2c 100644 --- a/src/pl_internal.h +++ b/src/pl_internal.h @@ -71,6 +71,7 @@ bool pl_get_window_attribute(plWindow*, plWindowAttribute bool pl_set_cursor_mode(plWindow*, plCursorMode); plCursorMode pl_get_cursor_mode(plWindow*); bool pl_set_raw_mouse_input(plWindow*, bool); +bool pl_set_mouse_pos(plWindow*, plVec2); bool pl_set_fullscreen(plWindow*, const plFullScreenDesc*); const plWindowCapabilities* pl_get_window_capabilities(void); diff --git a/src/pl_main_glfw.cpp b/src/pl_main_glfw.cpp index b2c1b76b..e479bd3a 100644 --- a/src/pl_main_glfw.cpp +++ b/src/pl_main_glfw.cpp @@ -1706,6 +1706,12 @@ pl_glfw_cursor_enter_callback(GLFWwindow* window, int entered) } } +bool +pl_set_mouse_pos(plWindow* ptWindow, plVec2 tPos) +{ + return false; // not implemented on this platform +} + void pl_glfw_window_focus_callback(GLFWwindow* window, int focused) { diff --git a/src/pl_main_macos.m b/src/pl_main_macos.m index 9b0fefe9..0dcd2678 100644 --- a/src/pl_main_macos.m +++ b/src/pl_main_macos.m @@ -1159,6 +1159,12 @@ - (void)unmarkText return PL_CURSOR_MODE_NORMAL; } +bool +pl_set_mouse_pos(plWindow* ptWindow, plVec2 tPos) +{ + return false; // not implemented on this platform +} + bool pl_set_raw_mouse_input(plWindow* ptWindow, bool bValue) { diff --git a/src/pl_main_null.c b/src/pl_main_null.c index cad36b85..29159ae3 100644 --- a/src/pl_main_null.c +++ b/src/pl_main_null.c @@ -314,6 +314,12 @@ pl_get_cursor_mode(plWindow* ptWindow) return PL_CURSOR_MODE_NORMAL; } +bool +pl_set_mouse_pos(plWindow* ptWindow, plVec2 tPos) +{ + return false; // not implemented on this platform +} + bool pl_set_raw_mouse_input(plWindow* ptWindow, bool bValue) { diff --git a/src/pl_main_win32.c b/src/pl_main_win32.c index 202cd00f..f41285db 100644 --- a/src/pl_main_win32.c +++ b/src/pl_main_win32.c @@ -428,6 +428,29 @@ pl__windows_procedure(HWND tHwnd, UINT tMsg, WPARAM tWParam, LPARAM tLParam) break; } + case WM_INPUT: + { + UINT uSize = 0; + GetRawInputData((HRAWINPUT)tLParam, RID_INPUT, NULL, &uSize, sizeof(RAWINPUTHEADER)); + if(uSize > 0) + { + RAWINPUT* ptRaw = (RAWINPUT*)malloc(uSize); + if(GetRawInputData((HRAWINPUT)tLParam, RID_INPUT, ptRaw, &uSize, sizeof(RAWINPUTHEADER)) == uSize) + { + if(ptRaw->header.dwType == RIM_TYPEMOUSE) + { + // get current cursor pos in client space and feed as mouse event + POINT tCurrent; + GetCursorPos(&tCurrent); + ScreenToClient(tHwnd, &tCurrent); + gptIOI->add_mouse_pos_event((float)tCurrent.x, (float)tCurrent.y); + } + } + free(ptRaw); + } + break; + } + case WM_MOUSEMOVE: { tMouseHandle = tHwnd; @@ -844,7 +867,31 @@ pl_get_window_attribute(plWindow* ptWindow, plWindowAttribute tAttribute, plWind bool pl_set_cursor_mode(plWindow* ptWindow, plCursorMode tMode) { - return tMode == PL_CURSOR_MODE_NORMAL; + HWND tHwnd = (HWND)ptWindow->_pBackendData; + + if(tMode == PL_CURSOR_MODE_NORMAL) + { + ShowCursor(true); + ClipCursor(NULL); + return true; + } + else if(tMode == PL_CURSOR_MODE_HIDDEN) + { + ShowCursor(false); + ClipCursor(NULL); + return true; + } + else if(tMode == PL_CURSOR_MODE_DISABLED) + { + ShowCursor(false); + RECT tRect; + GetClientRect(tHwnd, &tRect); + MapWindowPoints(tHwnd, NULL, (POINT*)&tRect, 2); + ClipCursor(&tRect); + return true; + } + + return false; } plCursorMode @@ -856,7 +903,23 @@ pl_get_cursor_mode(plWindow* ptWindow) bool pl_set_raw_mouse_input(plWindow* ptWindow, bool bValue) { - return !bValue; + HWND tHwnd = (HWND)ptWindow->_pBackendData; + RAWINPUTDEVICE tRid = { + .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = bValue ? 0 : RIDEV_REMOVE, + .hwndTarget = bValue ? tHwnd : NULL + }; + return RegisterRawInputDevices(&tRid, 1, sizeof(tRid)); +} + +bool +pl_set_mouse_pos(plWindow* ptWindow, plVec2 tPos) +{ + HWND tHwnd = (HWND)ptWindow->_pBackendData; + POINT tPoint = {(LONG)tPos.x, (LONG)tPos.y}; + ClientToScreen(tHwnd, &tPoint); + return SetCursorPos(tPoint.x, tPoint.y); } bool @@ -868,10 +931,10 @@ pl_set_fullscreen(plWindow* ptWindow, const plFullScreenDesc* tDesc) const plWindowCapabilities* pl_get_window_capabilities(void) { - static plWindowCapabilities tCapabilities = {}; + static plWindowCapabilities tCapabilities = {0}; - tCapabilities.uCursorModeCount = 1; - tCapabilities.uAttributeCount = 1; + tCapabilities.uCursorModeCount = 3; + tCapabilities.uAttributeCount = 1; tCapabilities.uFullScreenModeCount = 2; static const plWindowAttribute atSupportedAttributes[] = { @@ -879,7 +942,9 @@ pl_get_window_capabilities(void) }; static const plCursorMode atSupportedCursorModes[] = { - PL_CURSOR_MODE_NORMAL + PL_CURSOR_MODE_NORMAL, + PL_CURSOR_MODE_HIDDEN, + PL_CURSOR_MODE_DISABLED }; static const plFullScreenMode atSupportedScreenModes[] = { @@ -887,10 +952,10 @@ pl_get_window_capabilities(void) PL_FULLSCREEN_MODE_EXCLUSIVE }; - tCapabilities.atCursorModes = atSupportedCursorModes; - tCapabilities.atFullScreenModes = atSupportedScreenModes; - tCapabilities.atWindowAttributes = atSupportedAttributes; - tCapabilities.tFlags = PL_WINDOW_CAPABILITY_FLAGS_NONE; + tCapabilities.atCursorModes = atSupportedCursorModes; + tCapabilities.atFullScreenModes = atSupportedScreenModes; + tCapabilities.atWindowAttributes = atSupportedAttributes; + tCapabilities.tFlags = PL_WINDOW_CAPABILITY_FLAGS_RAW_MOUSE_INPUT; return &tCapabilities; } diff --git a/src/pl_main_x11.c b/src/pl_main_x11.c index 90e30eb3..717fc33d 100644 --- a/src/pl_main_x11.c +++ b/src/pl_main_x11.c @@ -1013,6 +1013,12 @@ pl_get_cursor_mode(plWindow* ptWindow) return PL_CURSOR_MODE_NORMAL; } +bool +pl_set_mouse_pos(plWindow* ptWindow, plVec2 tPos) +{ + return false; // not implemented on this platform +} + bool pl_set_raw_mouse_input(plWindow* ptWindow, bool bValue) {