mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-06 19:45:33 +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)]);
|
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;
|
return;
|
||||||
|
|
||||||
const float dx = x - std::exchange(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::X)], x);
|
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);
|
std::pair<float, float> GetPointerAbsolutePosition(u32 index);
|
||||||
|
|
||||||
/// Updates absolute pointer position. Can call from UI thread, use when the host only reports absolute coordinates.
|
/// 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.
|
/// Resets the accumulated pointer movement. Use when pointer tracking was interrupted.
|
||||||
void ResetPointerRelativeDelta(u32 index);
|
void ResetPointerRelativeDelta(u32 index);
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "win32_raw_input_source.h"
|
#include "win32_raw_input_source.h"
|
||||||
#include "input_manager.h"
|
#include "input_manager.h"
|
||||||
|
#include "platform_misc.h"
|
||||||
|
|
||||||
|
#include "core/gpu_thread.h"
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
@ -313,16 +316,6 @@ bool Win32RawInputSource::ProcessRawInputEvent(const RAWINPUT* event)
|
|||||||
|
|
||||||
const RAWMOUSE& rm = event->data.mouse;
|
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 =
|
unsigned long button_mask =
|
||||||
(rm.usButtonFlags & (rm.usButtonFlags ^ std::exchange(state.button_state, rm.usButtonFlags))) &
|
(rm.usButtonFlags & (rm.usButtonFlags ^ std::exchange(state.button_state, rm.usButtonFlags))) &
|
||||||
ALL_BUTTON_MASKS;
|
ALL_BUTTON_MASKS;
|
||||||
@ -341,10 +334,56 @@ bool Win32RawInputSource::ProcessRawInputEvent(const RAWINPUT* event)
|
|||||||
button_mask &= ~(1u << bit_index);
|
button_mask &= ~(1u << bit_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dx != 0)
|
// handle absolute positioned devices
|
||||||
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::X, static_cast<float>(dx), true);
|
if ((rm.usFlags & MOUSE_MOVE_ABSOLUTE) == MOUSE_MOVE_ABSOLUTE)
|
||||||
if (dy != 0)
|
{
|
||||||
InputManager::UpdatePointerRelativeDelta(pointer_index, InputPointerAxis::Y, static_cast<float>(dy), true);
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user