From: Hecheng Yu <kde-yyds(a)qq.com> This commit adds pointer info cache structure and helper functions. It's useful when implementing pointer APIs later. --- dlls/win32u/Makefile.in | 3 +- dlls/win32u/message.c | 1 + dlls/win32u/pointer.c | 125 +++++++++++++++++++++++++++++++++++ dlls/win32u/win32u_private.h | 3 + 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 dlls/win32u/pointer.c diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in index 454fb2555bc..1ed93b37187 100644 --- a/dlls/win32u/Makefile.in +++ b/dlls/win32u/Makefile.in @@ -55,4 +55,5 @@ SOURCES = \ vertical.c \ vulkan.c \ window.c \ - winstation.c + winstation.c \ + pointer.c diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index b28ce272099..41f1544d251 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3863,6 +3863,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA case INPUT_HARDWARE: req->input.hw.msg = input->hi.uMsg; req->input.hw.wparam = MAKELONG( input->hi.wParamL, input->hi.wParamH ); + store_pointer_info( hwnd, input, lparam ); switch (input->hi.uMsg) { case WM_INPUT: diff --git a/dlls/win32u/pointer.c b/dlls/win32u/pointer.c new file mode 100644 index 00000000000..6fa9f329f2c --- /dev/null +++ b/dlls/win32u/pointer.c @@ -0,0 +1,125 @@ +#if 0 +#pragma makedep unix +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "win32u_private.h" +#include <pthread.h> + +WINE_DEFAULT_DEBUG_CHANNEL(pointer); + +#define MAX_ACTIVE_POINTERS 10 + +struct pointer_info_entry +{ + BOOL active; + UINT32 pointerId; + POINTER_INPUT_TYPE pointerType; + HWND hwndTarget; + POINT ptPixelLocation; + DWORD pointerFlags; + DWORD dwTime; + DWORD releaseTime; + UINT message; +}; + +static struct pointer_info_entry pointer_cache[MAX_ACTIVE_POINTERS]; +static pthread_mutex_t pointer_cache_mutex = PTHREAD_MUTEX_INITIALIZER; + + +/* Find a cache entry by pointer ID */ +static struct pointer_info_entry *find_pointer_entry( UINT32 id ) +{ + int i; + for (i = 0; i < MAX_ACTIVE_POINTERS; i++) + { + if (pointer_cache[i].active && pointer_cache[i].pointerId == id) + return &pointer_cache[i]; + } + return NULL; +} + +/* Find an empty cache slot */ +static struct pointer_info_entry *get_free_pointer_entry( void ) +{ + int i; + for (i = 0; i < MAX_ACTIVE_POINTERS; i++) + { + if (!pointer_cache[i].active) + return &pointer_cache[i]; + } + WARN( "Pointer cache full!\n" ); + return NULL; +} + +/* Store pointer information from hardware input */ +void store_pointer_info( HWND hwnd, const INPUT *input, LPARAM lparam ) +{ + struct pointer_info_entry *entry; + UINT32 id; + DWORD flags; + DWORD msg; + POINT pos; + + if (input->type != INPUT_HARDWARE) return; + + msg = input->hi.uMsg; + + /* Only handle WM_POINTER* messages */ + if (msg != WM_POINTERDOWN && + msg != WM_POINTERUPDATE && + msg != WM_POINTERUP) + return; + + id = input->hi.wParamL; + + /* Reconstruct full 32-bit flags: add high bits based on message type */ + flags = input->hi.wParamH; + if (msg == WM_POINTERDOWN) + flags |= POINTER_FLAG_DOWN; + else if (msg == WM_POINTERUPDATE) + flags |= POINTER_FLAG_UPDATE; + else if (msg == WM_POINTERUP) + flags |= POINTER_FLAG_UP; + + /* lparam contains normalized position (0-65535) */ + pos.x = LOWORD(lparam); + pos.y = HIWORD(lparam); + + TRACE("Storing pointer %u, msg=%u, flags=%u, pos=(%d,%d)\n", + id, msg, flags, pos.x, pos.y); + + pthread_mutex_lock( &pointer_cache_mutex ); + + entry = find_pointer_entry( id ); + + if (msg == WM_POINTERDOWN) + { + /* New touch - allocate entry */ + if (!entry) entry = get_free_pointer_entry(); + if (entry) + { + entry->active = TRUE; + entry->pointerId = id; + entry->pointerType = PT_TOUCH; // Since currently only XI_TOUCH* triggers WM_POINTER*, it's okay to use hardcoded PT_TOUCH here. + entry->hwndTarget = hwnd; + } + } + + if (entry) + { + entry->message = msg; + entry->pointerFlags = flags; + entry->ptPixelLocation.x = pos.x; + entry->ptPixelLocation.y = pos.y; + entry->dwTime = NtGetTickCount(); + + if (msg == WM_POINTERUP) + { + entry->releaseTime = NtGetTickCount(); + } + } + + pthread_mutex_unlock( &pointer_cache_mutex ); +} diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 0b69ccd481d..180c2f85145 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -135,6 +135,9 @@ extern size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM extern void pack_user_message( void *buffer, size_t size, UINT message, WPARAM wparam, LPARAM lparam, BOOL ansi, void **extra_buffer ); +/* pointer.c */ +extern void store_pointer_info( HWND hwnd, const INPUT *input, LPARAM lparam ); + /* rawinput.c */ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9628