From: Grigory Vasilyev h0tc0d3@gmail.com
Adds the registry key HKEY_CURRENT_USER\Software\Wine\Wayland Driver\rawinput witch allows mouse raw input. This makes it easier to calculate the same sensitivity in different games, use sensitivity calculators, and easily change values when changing DPI and do not depend on the compositor or OS.
For example, you want to set the sensitivity to half as much, and sensitivity curves in libinput are more difficult to calculate than in the games themselves. --- dlls/winewayland.drv/Makefile.in | 1 + dlls/winewayland.drv/dllmain.c | 42 ++++++++++++++++++++++++++ dlls/winewayland.drv/unixlib.h | 1 + dlls/winewayland.drv/wayland_pointer.c | 33 +++++++++++++++----- dlls/winewayland.drv/waylanddrv_main.c | 10 ++++++ 5 files changed, 79 insertions(+), 8 deletions(-)
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index 9ad1ad6889d..bee478257ae 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -2,6 +2,7 @@ MODULE = winewayland.drv UNIXLIB = winewayland.so UNIX_CFLAGS = $(EGL_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_EGL_CFLAGS) $(XKBCOMMON_CFLAGS) $(XKBREGISTRY_CFLAGS) UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(WAYLAND_EGL_LIBS) $(XKBCOMMON_LIBS) $(XKBREGISTRY_LIBS) $(PTHREAD_LIBS) -lm +IMPORTS = advapi32
SOURCES = \ display.c \ diff --git a/dlls/winewayland.drv/dllmain.c b/dlls/winewayland.drv/dllmain.c index d040620957b..a958533fc27 100644 --- a/dlls/winewayland.drv/dllmain.c +++ b/dlls/winewayland.drv/dllmain.c @@ -20,7 +20,9 @@
#include "waylanddrv_dll.h"
+#include "winreg.h" #include "wine/debug.h" +#include "wine/server_protocol.h"
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
@@ -38,12 +40,52 @@ static DWORD WINAPI wayland_read_events_thread(void *arg) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { DWORD tid; + DWORD regRes; + DWORD regValueSize; + LPWSTR regValue = NULL; + HKEY hSubKey = NULL; + UINT rawinput_flag = 0;
if (reason != DLL_PROCESS_ATTACH) return TRUE;
DisableThreadLibraryCalls(instance); if (__wine_init_unix_call()) return FALSE;
+ regRes = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\Wine\Wayland Driver", 0, KEY_READ, &hSubKey); + if (regRes != ERROR_SUCCESS) + { + WINE_TRACE("Registry key HKCU\Software\Wine\Wayland Driver not exist.\n"); + goto close_registry; + } + + regRes = RegQueryValueExW(hSubKey, L"rawinput", NULL, NULL, NULL, ®ValueSize); + if (regRes != ERROR_SUCCESS) + { + WINE_ERR("Can't get value size for HKCU\Software\Wine\Wayland Driver\rawinput. Error: %ld\n", regRes); + goto close_registry; + } + + regValue = calloc(regValueSize + 1, sizeof(*regValue)); + + regRes = RegQueryValueExW(hSubKey, L"rawinput", NULL, NULL, (LPBYTE)regValue, ®ValueSize); + if (regRes != ERROR_SUCCESS) + { + WINE_ERR("Can't get value for HKCU\Software\Wine\Wayland Driver\rawinput. Error: %ld\n", regRes); + free(regValue); + goto close_registry; + } + + WINE_TRACE("Registry HKCU\Software\Wine\Wayland Driver\rawinput value=%hs.\n", regValue); + if(*regValue) + rawinput_flag = SEND_HWMSG_RAWINPUT; + + free(regValue); + +close_registry: + RegCloseKey(hSubKey); + + WAYLANDDRV_UNIX_CALL(set_rawinput_flag, &rawinput_flag); + if (WAYLANDDRV_UNIX_CALL(init, NULL)) return FALSE;
diff --git a/dlls/winewayland.drv/unixlib.h b/dlls/winewayland.drv/unixlib.h index dc3bfdf8893..cf81b88498d 100644 --- a/dlls/winewayland.drv/unixlib.h +++ b/dlls/winewayland.drv/unixlib.h @@ -27,6 +27,7 @@ enum waylanddrv_unix_func { waylanddrv_unix_func_init, waylanddrv_unix_func_read_events, + waylanddrv_unix_func_set_rawinput_flag, waylanddrv_unix_func_count, };
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 1d8acaeabd2..51f3c202f5a 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -31,9 +31,12 @@
#include "waylanddrv.h" #include "wine/debug.h" +#include "wine/server_protocol.h"
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
+extern UINT waylanddrv_rawinput_flag; + static HWND wayland_pointer_get_focused_hwnd(void) { struct wayland_pointer *pointer = &process_wayland.pointer; @@ -86,7 +89,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) hwnd, wl_fixed_to_double(sx), wl_fixed_to_double(sy), (int)screen.x, (int)screen.y);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, waylanddrv_rawinput_flag, &input, 0); }
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, @@ -185,7 +188,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
TRACE("hwnd=%p button=%#x state=%u\n", hwnd, button, state);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, waylanddrv_rawinput_flag, &input, 0); }
static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, @@ -232,7 +235,7 @@ static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_point
TRACE("hwnd=%p axis=%u discrete=%d\n", hwnd, axis, discrete);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, waylanddrv_rawinput_flag, &input, 0); }
static const struct wl_pointer_listener pointer_listener = @@ -259,15 +262,28 @@ static void relative_pointer_v1_relative_motion(void *data, POINT screen, origin; struct wayland_surface *surface; RECT window_rect; + double delta_x; + double delta_y;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; if (!(surface = wayland_surface_lock_hwnd(hwnd))) return;
window_rect = surface->window.rect;
+ if(waylanddrv_rawinput_flag & SEND_HWMSG_RAWINPUT) + { + delta_x = wl_fixed_to_double(dx_unaccel); + delta_y = wl_fixed_to_double(dy_unaccel); + } + else + { + delta_x = wl_fixed_to_double(dx); + delta_y = wl_fixed_to_double(dy); + } + wayland_surface_coords_to_window(surface, - wl_fixed_to_double(dx), - wl_fixed_to_double(dy), + delta_x, + delta_y, (int *)&screen.x, (int *)&screen.y);
pthread_mutex_unlock(&surface->mutex); @@ -313,11 +329,12 @@ static void relative_pointer_v1_relative_motion(void *data, input.mi.dy = screen.y; input.mi.dwFlags = MOUSEEVENTF_MOVE;
- TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f screen_dxdy=%d,%d\n", - hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), + TRACE("hwnd=%p rawinput=%d wayland_dxdy=%.2f,%.2f screen_dxdy=%d,%d\n", + hwnd, waylanddrv_rawinput_flag, delta_x, delta_y, (int)screen.x, (int)screen.y);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, waylanddrv_rawinput_flag, &input, 0); + }
static const struct zwp_relative_pointer_v1_listener relative_pointer_v1_listener = diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 47c1299dd01..5b3e56a286b 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -80,6 +80,14 @@ static void wayland_init_process_name(void) } }
+UINT waylanddrv_rawinput_flag; + +static NTSTATUS waylanddrv_unix_set_rawinput_flag(void *arg) +{ + waylanddrv_rawinput_flag = arg ? *((UINT *)arg) : 0; + return 0; +} + static NTSTATUS waylanddrv_unix_init(void *arg) { /* Set the user driver functions now so that they are available during @@ -111,6 +119,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { waylanddrv_unix_init, waylanddrv_unix_read_events, + waylanddrv_unix_set_rawinput_flag, };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == waylanddrv_unix_func_count); @@ -121,6 +130,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { waylanddrv_unix_init, waylanddrv_unix_read_events, + waylanddrv_unix_set_rawinput_flag, };
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == waylanddrv_unix_func_count);