mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-06 03:25:36 +00:00
Win32RawInputSource: Fix handling of absolute positioned devices
Maybe? Works in VMware now, I don't have any actual tablets.
This commit is contained in:
parent
75ae7deadb
commit
a86eabc1f0
@ -1283,9 +1283,9 @@ std::pair<float, float> InputManager::GetPointerAbsolutePosition(u32 index)
|
||||
s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::Y)]);
|
||||
}
|
||||
|
||||
void InputManager::UpdatePointerAbsolutePosition(u32 index, float x, float y)
|
||||
void InputManager::UpdatePointerAbsolutePosition(u32 index, float x, float y, bool raw_input)
|
||||
{
|
||||
if (index >= MAX_POINTER_DEVICES || s_relative_mouse_mode_active) [[unlikely]]
|
||||
if (index >= MAX_POINTER_DEVICES || (s_relative_mouse_mode_active && !raw_input)) [[unlikely]]
|
||||
return;
|
||||
|
||||
const float dx = x - std::exchange(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::X)], x);
|
||||
|
@ -348,7 +348,7 @@ u32 GetPointerCount();
|
||||
std::pair<float, float> GetPointerAbsolutePosition(u32 index);
|
||||
|
||||
/// Updates absolute pointer position. Can call from UI thread, use when the host only reports absolute coordinates.
|
||||
void UpdatePointerAbsolutePosition(u32 index, float x, float y);
|
||||
void UpdatePointerAbsolutePosition(u32 index, float x, float y, bool raw_input = false);
|
||||
|
||||
/// Resets the accumulated pointer movement. Use when pointer tracking was interrupted.
|
||||
void ResetPointerRelativeDelta(u32 index);
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
#include "win32_raw_input_source.h"
|
||||
#include "input_manager.h"
|
||||
#include "platform_misc.h"
|
||||
|
||||
#include "core/gpu_thread.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/error.h"
|
||||
@ -313,16 +316,6 @@ bool Win32RawInputSource::ProcessRawInputEvent(const RAWINPUT* event)
|
||||
|
||||
const RAWMOUSE& rm = event->data.mouse;
|
||||
|
||||
s32 dx = rm.lLastX;
|
||||
s32 dy = rm.lLastY;
|
||||
|
||||
// handle absolute positioned devices
|
||||
if ((rm.usFlags & MOUSE_MOVE_ABSOLUTE) == MOUSE_MOVE_ABSOLUTE)
|
||||
{
|
||||
dx -= std::exchange(dx, state.last_x);
|
||||
dy -= std::exchange(dy, state.last_y);
|
||||
}
|
||||
|
||||
unsigned long button_mask =
|
||||
(rm.usButtonFlags & (rm.usButtonFlags ^ std::exchange(state.button_state, rm.usButtonFlags))) &
|
||||
ALL_BUTTON_MASKS;
|
||||
@ -341,10 +334,56 @@ bool Win32RawInputSource::ProcessRawInputEvent(const RAWINPUT* event)
|
||||
button_mask &= ~(1u << bit_index);
|
||||
}
|
||||
|
||||
if (dx != 0)
|
||||
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::X, static_cast<float>(dx), true);
|
||||
if (dy != 0)
|
||||
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::Y, static_cast<float>(dy), true);
|
||||
// handle absolute positioned devices
|
||||
if ((rm.usFlags & MOUSE_MOVE_ABSOLUTE) == MOUSE_MOVE_ABSOLUTE)
|
||||
{
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawmouse#remarks
|
||||
RECT rect;
|
||||
if (rm.usFlags & MOUSE_VIRTUAL_DESKTOP)
|
||||
{
|
||||
rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||
rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||
rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = GetSystemMetrics(SM_CXSCREEN);
|
||||
rect.bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
int absolute_x = MulDiv(rm.lLastX, rect.right, USHRT_MAX) + rect.left;
|
||||
int absolute_y = MulDiv(rm.lLastY, rect.bottom, USHRT_MAX) + rect.top;
|
||||
|
||||
// This is truely awful. But for something that isn't used much, it's the easiest way to get the render rect...
|
||||
const WindowInfo& render_wi = GPUThread::GetRenderWindowInfo();
|
||||
if (render_wi.type == WindowInfo::Type::Win32 &&
|
||||
GetWindowRect(static_cast<HWND>(render_wi.window_handle), &rect))
|
||||
{
|
||||
absolute_x -= rect.left;
|
||||
absolute_y -= rect.top;
|
||||
}
|
||||
|
||||
InputManager::UpdatePointerAbsolutePosition(pointer_index, static_cast<float>(absolute_x),
|
||||
static_cast<float>(absolute_y), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// relative is easy
|
||||
if (rm.lLastX != 0)
|
||||
{
|
||||
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::X, static_cast<float>(rm.lLastX),
|
||||
true);
|
||||
}
|
||||
|
||||
if (rm.lLastY != 0)
|
||||
{
|
||||
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::Y, static_cast<float>(rm.lLastY),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user