Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2022
- 68 participants
- 3274 messages
Re: [PATCH v2 3/5] d2d1: Implement property parsing for RegisterEffectFromStream().
by Nikolay Sivov
On 6/13/22 09:55, Ziqing Hui wrote:
>
> On 6/12/22 4:34 PM, Nikolay Sivov wrote:
>>
>> On 6/12/22 08:31, Ziqing Hui wrote:
>>> + if (!wcscmp(name, L"DisplayName")
>>> + || !wcscmp(name, L"Author")
>>> + || !wcscmp(name, L"Category")
>>> + || !wcscmp(name, L"Description"))
>>> + {
>>> + if (type != D2D1_PROPERTY_TYPE_STRING)
>>> + return E_INVALIDARG;
>>> + ++reg->system_property_count;
>>> + }
>> That's not going to work for nested properties, that likely can have same names as system ones.
>>
> Does "nested properties" means sub properties? If it does, I think it's OK because sub properties is ignored. My plan is to ignore sub properties unless we really need them in effect implementation.
>
> So at least for now add_property() will only be called for top level properties.
I understand that, and it's fine to ignore them. But alternative way to
test for required properties is simply to check if they were added once
you parsed everything, instead of counting them. By checking I mean to
look them up by names in registration structure after xml document was
processed.
>
>
>>> + if (j > entry->property_count)
>>> + {
>>> + hr = D2DERR_INVALID_PROPERTY;
>>> + goto done;
>>> + }
>> Should it be j == entry->property_count ?
>>
June 13, 2022
Re: [PATCH v2 2/5] d2d1: Partially implement RegisterEffectFromStream().
by Nikolay Sivov
On 6/13/22 09:46, Ziqing Hui wrote:
>
> On 6/12/22 4:30 PM, Nikolay Sivov wrote:
>>
>> On 6/12/22 08:31, Ziqing Hui wrote:
>>> + /* Loop inside effect node */
>>> + end_node_found = FALSE;
>>> + while ((hr = next_xml_node(xml_reader, &node_type, &node_name)) == S_OK)
>>> + {
>>> + if (node_type == XmlNodeType_Element)
>>> + {
>>> + if (!wcscmp(node_name, L"Property"))
>>> + hr = parse_property(xml_reader, reg);
>>> + else if (!wcscmp(node_name, L"Inputs"))
>>> + hr = parse_inputs(xml_reader, reg);
>>> + else
>>> + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
>>> +
>>> + if (FAILED(hr))
>>> + goto done;
>>> + }
>>> + else if (node_type == XmlNodeType_EndElement && !wcscmp(node_name, L"Effect"))
>>> + {
>>> + end_node_found = TRUE;
>>> + break;
>>> + }
>>> + }
>>> + hr = (SUCCEEDED(hr) && end_node_found) ? S_OK : E_INVALIDARG;
>> I don't think it's necessary to check EndElement name. The structure is always N elements, followed by EndElement. Each element helper should do the same - skip EndElement on return, and skip elements you're not interested in entirely.
>>
>> Error handling could be better, without SUCCEEDED -> S_OK fixups, or goto's.
>>
> I'm thinking of failure case. The tests in the PATCH 1 show that if we meet element that are not expected, the function will return a error code (mostly HRESULT_FROM_WIN32(ERROR_NOT_FOUND)).
> So I think we should not skip elements we don't interested in, we should return error for them.
>
> Checking EndElement name is for the same reason.
>
> Nikolay, what do you think?
>
What I mean is that xmllite will check that for you, if closing tag does
not match last open tag it will be a parser error. My suggestion was to
make helpers like parse_property() consume entire
<Property>...</Property> element, including end node, so the only
possibility for EndElement at top level would be </Effect> one.
Regarding errors, does that mean the order of elements is important too?
E.g. can you have some property elements before Inputs and some after,
or it's stricter than that? I don't think we should care too much about
that, we can introduce additional checks later, but for now it's fine to
handle that as a general xml document.
June 13, 2022
Re: [PATCH 2/4] user32: Correctly fill the RAWINPUT structure on WoW64.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=116820
Your paranoid android.
=== debian11 (32 bit report) ===
user32:
input.c:2349: Test failed: GetRawInputBuffer succeeded
input.c:2350: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2351: Test failed: GetRawInputBuffer returned deadbeef
input.c:2356: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2384: Test failed: GetRawInputBuffer returned 0
input.c:2385: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2386: Test failed: Unexpected rawinput data: 0
input.c:2397: Test failed: GetRawInputBuffer succeeded
input.c:2398: Test failed: GetRawInputBuffer returned deadbeef
input.c:2399: Test failed: Unexpected rawinput data: 0
input.c:2412: Test failed: Spurious WM_INPUT messages
=== debian11 (32 bit Chinese:China report) ===
user32:
input.c:2349: Test failed: GetRawInputBuffer succeeded
input.c:2350: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2351: Test failed: GetRawInputBuffer returned deadbeef
input.c:2356: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2384: Test failed: GetRawInputBuffer returned 0
input.c:2385: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2386: Test failed: Unexpected rawinput data: 0
input.c:2397: Test failed: GetRawInputBuffer succeeded
input.c:2398: Test failed: GetRawInputBuffer returned deadbeef
input.c:2399: Test failed: Unexpected rawinput data: 0
input.c:2412: Test failed: Spurious WM_INPUT messages
msg.c:6881: Test failed: SetFocus(hwnd) on a button: 4: the msg 0x0007 was expected, but got msg 0x0005 instead
msg.c:6881: Test failed: SetFocus(hwnd) on a button: 5: the msg 0x0135 was expected, but got msg 0x030f instead
msg.c:6881: Test failed: SetFocus(hwnd) on a button: 6: the msg 0x002b was expected, but got msg 0x001c instead
msg.c:6881: Test failed: SetFocus(hwnd) on a button: 7: the msg 0x0111 was expected, but got msg 0x0086 instead
msg.c:6881: Test failed: SetFocus(hwnd) on a button: 8: the msg 0x8000 was expected, but got msg 0x0006 instead
msg.c:6881: Test failed: SetFocus(hwnd) on a button: 9: the msg sequence is not complete: expected 0000 - actual 0009
=== debian11 (32 bit WoW report) ===
user32:
input.c:2349: Test failed: GetRawInputBuffer succeeded
input.c:2350: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2351: Test failed: GetRawInputBuffer returned deadbeef
input.c:2356: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2384: Test failed: GetRawInputBuffer returned 0
input.c:2385: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2386: Test failed: Unexpected rawinput data: 0
input.c:2397: Test failed: GetRawInputBuffer succeeded
input.c:2398: Test failed: GetRawInputBuffer returned deadbeef
input.c:2399: Test failed: Unexpected rawinput data: 0
input.c:2412: Test failed: Spurious WM_INPUT messages
=== debian11 (64 bit WoW report) ===
user32:
input.c:2349: Test failed: GetRawInputBuffer succeeded
input.c:2350: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2351: Test failed: GetRawInputBuffer returned deadbeef
input.c:2356: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2384: Test failed: GetRawInputBuffer returned 0
input.c:2385: Test failed: GetRawInputBuffer returned unexpected size: 0
input.c:2386: Test failed: Unexpected rawinput data: 0
input.c:2397: Test failed: GetRawInputBuffer succeeded
input.c:2398: Test failed: GetRawInputBuffer returned deadbeef
input.c:2399: Test failed: Unexpected rawinput data: 0
input.c:2412: Test failed: Spurious WM_INPUT messages
June 13, 2022
Re: [PATCH v2 0/1] MR134: ntdll: Don't hard-code the battery and AC adapter names on Linux
by Huw Davies (@huw)
On Mon Jun 13 07:35:38 2022 +0000, Alex Henrie wrote:
> It looks like Bluetooth peripherals have a file at
> /sys/class/power_supply/*/scope with the text "Device". The other
> possible values are "System" and "Unknown" (assuming that the file
> exists in the first place). I've pushed a new patch that checks that
> file and skips over batteries that belong to peripheral devices.
I suggest that we talk to the kernel guys (Sebastian Reichel looks to be a good bet) and ask their advice.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/134#note_1927
June 13, 2022
Re: [PATCH 1/4] user32/tests: Add some more tests related to the RAWINPUT structure.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=116819
Your paranoid android.
=== w1064 (32 bit report) ===
user32:
input.c:3484: Test failed: expected WM_LBUTTONDOWN message
input.c:3485: Test failed: expected WM_LBUTTONUP message
input.c:3513: Test failed: expected WM_RBUTTONDOWN message
input.c:3514: Test failed: expected WM_RBUTTONUP message
=== w10pro64_ja (64 bit report) ===
user32:
input.c:4525: Test failed: SendInput triggered unexpected message 0x7fff
input.c:4543: Test failed: SendInput triggered unexpected message 0x7fff
=== w10pro64_zh_CN (64 bit report) ===
user32:
input.c:3118: Test failed: ToAscii for character 'A' didn't return 1 (was 2)
June 13, 2022
Re: [PATCH 0/3] MR230: UiaProviderFromIAccessible: Initial navigation patches. - approved
by Huw Davies (@huw)
This merge request was approved by Huw Davies.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/230
June 13, 2022
[PATCH 4/4] win32u: Move NtUserGetRawInputBuffer from user32.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/user32/rawinput.c | 111 ----------------
dlls/user32/user32.spec | 2 +-
dlls/user32/user_private.h | 4 -
dlls/win32u/gdiobj.c | 1 +
dlls/win32u/ntuser_private.h | 4 +
dlls/win32u/rawinput.c | 244 +++++++++++++++++++++++++++++++++++
dlls/win32u/win32u.spec | 2 +-
dlls/win32u/win32u_private.h | 1 +
dlls/win32u/wrappers.c | 6 +
include/ntuser.h | 1 +
10 files changed, 259 insertions(+), 117 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index b1c79b4e186..f8980f03e9e 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -593,117 +593,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(const RAWINPUTDEVICE *devi
return ret;
}
-#ifdef _WIN64
-typedef RAWINPUTHEADER RAWINPUTHEADER64;
-typedef RAWINPUT RAWINPUT64;
-#else
-typedef struct
-{
- DWORD dwType;
- DWORD dwSize;
- ULONGLONG hDevice;
- ULONGLONG wParam;
-} RAWINPUTHEADER64;
-
-typedef struct
-{
- RAWINPUTHEADER64 header;
- union {
- RAWMOUSE mouse;
- RAWKEYBOARD keyboard;
- RAWHID hid;
- } data;
-} RAWINPUT64;
-#endif
-
-/***********************************************************************
- * GetRawInputBuffer (USER32.@)
- */
-UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size, UINT header_size)
-{
- struct hardware_msg_data *msg_data;
- struct rawinput_thread_data *thread_data;
- RAWINPUT *rawinput;
- UINT count = 0, remaining, rawinput_size, next_size, overhead;
- BOOL is_wow64;
- int i;
-
- if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
- rawinput_size = sizeof(RAWINPUT64);
- else
- rawinput_size = sizeof(RAWINPUT);
- overhead = rawinput_size - sizeof(RAWINPUT);
-
- if (header_size != sizeof(RAWINPUTHEADER))
- {
- WARN("Invalid structure size %u.\n", header_size);
- SetLastError(ERROR_INVALID_PARAMETER);
- return ~0U;
- }
-
- if (!data_size)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return ~0U;
- }
-
- if (!data)
- {
- TRACE("data %p, data_size %p (%u), header_size %u\n", data, data_size, *data_size, header_size);
- SERVER_START_REQ( get_rawinput_buffer )
- {
- req->rawinput_size = rawinput_size;
- req->buffer_size = 0;
- if (wine_server_call( req )) return ~0U;
- *data_size = reply->next_size;
- }
- SERVER_END_REQ;
- return 0;
- }
-
- if (!(thread_data = rawinput_thread_data())) return ~0U;
- rawinput = thread_data->buffer;
-
- /* first RAWINPUT block in the buffer is used for WM_INPUT message data */
- msg_data = (struct hardware_msg_data *)NEXTRAWINPUTBLOCK(rawinput);
- SERVER_START_REQ( get_rawinput_buffer )
- {
- req->rawinput_size = rawinput_size;
- req->buffer_size = *data_size;
- wine_server_set_reply( req, msg_data, RAWINPUT_BUFFER_SIZE - rawinput->header.dwSize );
- if (wine_server_call( req )) return ~0U;
- next_size = reply->next_size;
- count = reply->count;
- }
- SERVER_END_REQ;
-
- remaining = *data_size;
- for (i = 0; i < count; ++i)
- {
- data->header.dwSize = remaining;
- if (!rawinput_from_hardware_message(data, msg_data)) break;
- if (overhead) memmove((char *)&data->data + overhead, &data->data,
- data->header.dwSize - sizeof(RAWINPUTHEADER));
- data->header.dwSize += overhead;
- remaining -= data->header.dwSize;
- data = NEXTRAWINPUTBLOCK(data);
- msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_data->size);
- }
-
- if (count == 0 && next_size == 0) *data_size = 0;
- else if (next_size == 0) next_size = rawinput_size;
-
- if (next_size && *data_size <= next_size)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- *data_size = next_size;
- count = ~0U;
- }
-
- if (count) TRACE("data %p, data_size %p (%u), header_size %u, count %u\n", data, data_size, *data_size, header_size, count);
- return count;
-}
-
/***********************************************************************
* GetRawInputDeviceInfoA (USER32.@)
*/
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 2379c2cced5..15a2a53aa0c 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -366,7 +366,7 @@
@ stdcall GetPropA(long str)
@ stdcall GetPropW(long wstr)
@ stdcall GetQueueStatus(long) NtUserGetQueueStatus
-@ stdcall GetRawInputBuffer(ptr ptr long)
+@ stdcall GetRawInputBuffer(ptr ptr long) NtUserGetRawInputBuffer
@ stdcall GetRawInputData(ptr long ptr ptr long) NtUserGetRawInputData
@ stdcall GetRawInputDeviceInfoA(ptr long ptr ptr)
@ stdcall GetRawInputDeviceInfoW(ptr long ptr ptr)
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 11f8b6389ac..a9ba17a769f 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -47,10 +47,6 @@ struct wm_char_mapping_data
MSG get_msg;
};
-/* on windows the buffer capacity is quite large as well, enough to */
-/* hold up to 10s of 1kHz mouse rawinput events */
-#define RAWINPUT_BUFFER_SIZE (512*1024)
-
extern BOOL (WINAPI *imm_register_window)(HWND) DECLSPEC_HIDDEN;
extern void (WINAPI *imm_unregister_window)(HWND) DECLSPEC_HIDDEN;
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index a988b1a0c4a..ebc7ccaeb5f 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1181,6 +1181,7 @@ static struct unix_funcs unix_funcs =
NtUserGetMessage,
NtUserGetPriorityClipboardFormat,
NtUserGetQueueStatus,
+ NtUserGetRawInputBuffer,
NtUserGetRawInputData,
NtUserGetSystemMenu,
NtUserGetUpdateRect,
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index 717538c1adc..0470b094952 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -67,6 +67,10 @@ struct rawinput_thread_data
RAWINPUT buffer[1]; /* rawinput message data buffer */
};
+/* on windows the buffer capacity is quite large as well, enough to */
+/* hold up to 10s of 1kHz mouse rawinput events */
+#define RAWINPUT_BUFFER_SIZE (512 * 1024)
+
struct user_object
{
HANDLE handle;
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index 0d2c585c36e..1440b1ebe54 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -23,6 +23,7 @@
#pragma makedep unix
#endif
+#include <stdbool.h>
#include "win32u_private.h"
#include "ntuser_private.h"
#include "wine/server.h"
@@ -30,6 +31,249 @@
WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
+#define WINE_MOUSE_HANDLE ((HANDLE)1)
+#define WINE_KEYBOARD_HANDLE ((HANDLE)2)
+
+#ifdef _WIN64
+typedef RAWINPUTHEADER RAWINPUTHEADER64;
+typedef RAWINPUT RAWINPUT64;
+#else
+typedef struct
+{
+ DWORD dwType;
+ DWORD dwSize;
+ ULONGLONG hDevice;
+ ULONGLONG wParam;
+} RAWINPUTHEADER64;
+
+typedef struct
+{
+ RAWINPUTHEADER64 header;
+ union
+ {
+ RAWMOUSE mouse;
+ RAWKEYBOARD keyboard;
+ RAWHID hid;
+ } data;
+} RAWINPUT64;
+#endif
+
+static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct hardware_msg_data *msg_data )
+{
+ SIZE_T size;
+
+ rawinput->header.dwType = msg_data->rawinput.type;
+ if (msg_data->rawinput.type == RIM_TYPEMOUSE)
+ {
+ static const unsigned int button_flags[] =
+ {
+ 0, /* MOUSEEVENTF_MOVE */
+ RI_MOUSE_LEFT_BUTTON_DOWN, /* MOUSEEVENTF_LEFTDOWN */
+ RI_MOUSE_LEFT_BUTTON_UP, /* MOUSEEVENTF_LEFTUP */
+ RI_MOUSE_RIGHT_BUTTON_DOWN, /* MOUSEEVENTF_RIGHTDOWN */
+ RI_MOUSE_RIGHT_BUTTON_UP, /* MOUSEEVENTF_RIGHTUP */
+ RI_MOUSE_MIDDLE_BUTTON_DOWN, /* MOUSEEVENTF_MIDDLEDOWN */
+ RI_MOUSE_MIDDLE_BUTTON_UP, /* MOUSEEVENTF_MIDDLEUP */
+ };
+ unsigned int i;
+
+ rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWMOUSE);
+ rawinput->header.hDevice = WINE_MOUSE_HANDLE;
+ rawinput->header.wParam = 0;
+
+ rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
+ rawinput->data.mouse.usButtonFlags = 0;
+ rawinput->data.mouse.usButtonData = 0;
+ for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
+ {
+ if (msg_data->flags & (1 << i))
+ rawinput->data.mouse.usButtonFlags |= button_flags[i];
+ }
+ if (msg_data->flags & MOUSEEVENTF_WHEEL)
+ {
+ rawinput->data.mouse.usButtonFlags |= RI_MOUSE_WHEEL;
+ rawinput->data.mouse.usButtonData = msg_data->rawinput.mouse.data;
+ }
+ if (msg_data->flags & MOUSEEVENTF_HWHEEL)
+ {
+ rawinput->data.mouse.usButtonFlags |= RI_MOUSE_HORIZONTAL_WHEEL;
+ rawinput->data.mouse.usButtonData = msg_data->rawinput.mouse.data;
+ }
+ if (msg_data->flags & MOUSEEVENTF_XDOWN)
+ {
+ if (msg_data->rawinput.mouse.data == XBUTTON1)
+ rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_4_DOWN;
+ else if (msg_data->rawinput.mouse.data == XBUTTON2)
+ rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_5_DOWN;
+ }
+ if (msg_data->flags & MOUSEEVENTF_XUP)
+ {
+ if (msg_data->rawinput.mouse.data == XBUTTON1)
+ rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_4_UP;
+ else if (msg_data->rawinput.mouse.data == XBUTTON2)
+ rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_5_UP;
+ }
+
+ rawinput->data.mouse.ulRawButtons = 0;
+ rawinput->data.mouse.lLastX = msg_data->rawinput.mouse.x;
+ rawinput->data.mouse.lLastY = msg_data->rawinput.mouse.y;
+ rawinput->data.mouse.ulExtraInformation = msg_data->info;
+ }
+ else if (msg_data->rawinput.type == RIM_TYPEKEYBOARD)
+ {
+ rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWKEYBOARD);
+ rawinput->header.hDevice = WINE_KEYBOARD_HANDLE;
+ rawinput->header.wParam = 0;
+
+ rawinput->data.keyboard.MakeCode = msg_data->rawinput.kbd.scan;
+ rawinput->data.keyboard.Flags = (msg_data->flags & KEYEVENTF_KEYUP) ? RI_KEY_BREAK : RI_KEY_MAKE;
+ if (msg_data->flags & KEYEVENTF_EXTENDEDKEY)
+ rawinput->data.keyboard.Flags |= RI_KEY_E0;
+ rawinput->data.keyboard.Reserved = 0;
+
+ switch (msg_data->rawinput.kbd.vkey)
+ {
+ case VK_LSHIFT:
+ case VK_RSHIFT:
+ rawinput->data.keyboard.VKey = VK_SHIFT;
+ rawinput->data.keyboard.Flags &= ~RI_KEY_E0;
+ break;
+
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ rawinput->data.keyboard.VKey = VK_CONTROL;
+ break;
+
+ case VK_LMENU:
+ case VK_RMENU:
+ rawinput->data.keyboard.VKey = VK_MENU;
+ break;
+
+ default:
+ rawinput->data.keyboard.VKey = msg_data->rawinput.kbd.vkey;
+ break;
+ }
+
+ rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message;
+ rawinput->data.keyboard.ExtraInformation = msg_data->info;
+ }
+ else if (msg_data->rawinput.type == RIM_TYPEHID)
+ {
+ size = msg_data->size - sizeof(*msg_data);
+ if (size > rawinput->header.dwSize - sizeof(*rawinput)) return false;
+
+ rawinput->header.dwSize = FIELD_OFFSET( RAWINPUT, data.hid.bRawData ) + size;
+ rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device );
+ rawinput->header.wParam = 0;
+
+ rawinput->data.hid.dwCount = msg_data->rawinput.hid.count;
+ rawinput->data.hid.dwSizeHid = msg_data->rawinput.hid.length;
+ memcpy( rawinput->data.hid.bRawData, msg_data + 1, size );
+ }
+ else
+ {
+ FIXME( "Unhandled rawinput type %#x.\n", msg_data->rawinput.type );
+ return false;
+ }
+
+ return true;
+}
+
+/**********************************************************************
+ * NtUserGetRawInputBuffer (win32u.@)
+ */
+UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size )
+{
+ unsigned int count = 0, remaining, rawinput_size, next_size, overhead;
+ struct rawinput_thread_data *thread_data;
+ struct hardware_msg_data *msg_data;
+ RAWINPUT *rawinput;
+ int i;
+
+ if (NtCurrentTeb()->WowTebOffset)
+ rawinput_size = sizeof(RAWINPUT64);
+ else
+ rawinput_size = sizeof(RAWINPUT);
+ overhead = rawinput_size - sizeof(RAWINPUT);
+
+ if (header_size != sizeof(RAWINPUTHEADER))
+ {
+ WARN( "Invalid structure size %u.\n", header_size );
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (!data_size)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (!data)
+ {
+ TRACE( "data %p, data_size %p (%u), header_size %u\n", data, data_size, *data_size, header_size );
+ SERVER_START_REQ( get_rawinput_buffer )
+ {
+ req->rawinput_size = rawinput_size;
+ req->buffer_size = 0;
+ if (wine_server_call( req )) return ~0u;
+ *data_size = reply->next_size;
+ }
+ SERVER_END_REQ;
+ return 0;
+ }
+
+ if (!user_callbacks || !(thread_data = user_callbacks->get_rawinput_thread_data())) return ~0u;
+ rawinput = thread_data->buffer;
+
+ /* first RAWINPUT block in the buffer is used for WM_INPUT message data */
+ msg_data = (struct hardware_msg_data *)NEXTRAWINPUTBLOCK(rawinput);
+ SERVER_START_REQ( get_rawinput_buffer )
+ {
+ req->rawinput_size = rawinput_size;
+ req->buffer_size = *data_size;
+ wine_server_set_reply( req, msg_data, RAWINPUT_BUFFER_SIZE - rawinput->header.dwSize );
+ if (wine_server_call( req )) return ~0u;
+ next_size = reply->next_size;
+ count = reply->count;
+ }
+ SERVER_END_REQ;
+
+ remaining = *data_size;
+ for (i = 0; i < count; ++i)
+ {
+ data->header.dwSize = remaining;
+ if (!rawinput_from_hardware_message( data, msg_data )) break;
+ if (overhead)
+ memmove( (char *)&data->data + overhead, &data->data,
+ data->header.dwSize - sizeof(RAWINPUTHEADER) );
+ data->header.dwSize += overhead;
+ remaining -= data->header.dwSize;
+ data = NEXTRAWINPUTBLOCK(data);
+ msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_data->size);
+ }
+
+ if (!next_size)
+ {
+ if (!count)
+ *data_size = 0;
+ else
+ next_size = rawinput_size;
+ }
+
+ if (next_size && *data_size <= next_size)
+ {
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ *data_size = next_size;
+ count = ~0u;
+ }
+
+ if (count)
+ TRACE( "data %p, data_size %p (%u), header_size %u, count %u\n",
+ data, data_size, *data_size, header_size, count );
+ return count;
+}
+
/**********************************************************************
* NtUserGetRawInputData (win32u.@)
*/
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index 8b71504f374..6ad0d80333c 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -983,7 +983,7 @@
@ stdcall -syscall NtUserGetProp(long wstr)
@ stdcall NtUserGetQueueStatus(long)
@ stub NtUserGetQueueStatusReadonly
-@ stub NtUserGetRawInputBuffer
+@ stdcall NtUserGetRawInputBuffer(ptr ptr long)
@ stdcall NtUserGetRawInputData(ptr long ptr ptr long)
@ stub NtUserGetRawInputDeviceInfo
@ stub NtUserGetRawInputDeviceList
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index 87901d1313e..4e386c16436 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -243,6 +243,7 @@ struct unix_funcs
BOOL (WINAPI *pNtUserGetMessage)( MSG *msg, HWND hwnd, UINT first, UINT last );
INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count );
DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags );
+ UINT (WINAPI *pNtUserGetRawInputBuffer)( RAWINPUT *data, UINT *data_size, UINT header_size );
UINT (WINAPI *pNtUserGetRawInputData)( HRAWINPUT rawinput, UINT command,
void *data, UINT *data_size, UINT header_size );
HMENU (WINAPI *pNtUserGetSystemMenu)( HWND hwnd, BOOL revert );
diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c
index 17354abc73e..59b9401751f 100644
--- a/dlls/win32u/wrappers.c
+++ b/dlls/win32u/wrappers.c
@@ -1023,6 +1023,12 @@ DWORD WINAPI NtUserGetQueueStatus( UINT flags )
return unix_funcs->pNtUserGetQueueStatus( flags );
}
+UINT WINAPI DECLSPEC_HOTPATCH NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size )
+{
+ if (!unix_funcs) return ~0u;
+ return unix_funcs->pNtUserGetRawInputBuffer( data, data_size, header_size );
+}
+
UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size )
{
if (!unix_funcs) return ~0u;
diff --git a/include/ntuser.h b/include/ntuser.h
index 85b7a87247f..164ce763155 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -589,6 +589,7 @@ HWINSTA WINAPI NtUserGetProcessWindowStation(void);
HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str );
ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
DWORD WINAPI NtUserGetQueueStatus( UINT flags );
+UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size );
UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size );
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert );
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/233
June 13, 2022
[PATCH 3/4] win32u: Move NtUserGetRawInputData from user32.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/user32/rawinput.c | 54 +--------------------
dlls/user32/user32.spec | 2 +-
dlls/user32/user_main.c | 1 +
dlls/user32/user_private.h | 8 +---
dlls/win32u/Makefile.in | 1 +
dlls/win32u/gdiobj.c | 1 +
dlls/win32u/ntuser_private.h | 7 +++
dlls/win32u/rawinput.c | 91 ++++++++++++++++++++++++++++++++++++
dlls/win32u/win32u.spec | 2 +-
dlls/win32u/win32u_private.h | 2 +
dlls/win32u/wrappers.c | 6 +++
include/ntuser.h | 1 +
12 files changed, 114 insertions(+), 62 deletions(-)
create mode 100644 dlls/win32u/rawinput.c
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 99e2270b77c..b1c79b4e186 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -351,7 +351,7 @@ BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage)
}
-struct rawinput_thread_data *rawinput_thread_data(void)
+struct rawinput_thread_data * WINAPI rawinput_thread_data(void)
{
struct user_thread_info *thread_info = get_user_thread_info();
struct rawinput_thread_data *data = thread_info->rawinput;
@@ -593,58 +593,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(const RAWINPUTDEVICE *devi
return ret;
}
-/***********************************************************************
- * GetRawInputData (USER32.@)
- */
-UINT WINAPI GetRawInputData(HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size)
-{
- struct rawinput_thread_data *thread_data = rawinput_thread_data();
- UINT size;
-
- TRACE("rawinput %p, command %#x, data %p, data_size %p, header_size %u.\n",
- rawinput, command, data, data_size, header_size);
-
- if (!rawinput || thread_data->hw_id != (UINT_PTR)rawinput)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return ~0U;
- }
-
- if (header_size != sizeof(RAWINPUTHEADER))
- {
- WARN("Invalid structure size %u.\n", header_size);
- SetLastError(ERROR_INVALID_PARAMETER);
- return ~0U;
- }
-
- switch (command)
- {
- case RID_INPUT:
- size = thread_data->buffer->header.dwSize;
- break;
- case RID_HEADER:
- size = sizeof(RAWINPUTHEADER);
- break;
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return ~0U;
- }
-
- if (!data)
- {
- *data_size = size;
- return 0;
- }
-
- if (*data_size < size)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return ~0U;
- }
- memcpy(data, thread_data->buffer, size);
- return size;
-}
-
#ifdef _WIN64
typedef RAWINPUTHEADER RAWINPUTHEADER64;
typedef RAWINPUT RAWINPUT64;
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index b41d661ee2a..2379c2cced5 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -367,7 +367,7 @@
@ stdcall GetPropW(long wstr)
@ stdcall GetQueueStatus(long) NtUserGetQueueStatus
@ stdcall GetRawInputBuffer(ptr ptr long)
-@ stdcall GetRawInputData(ptr long ptr ptr long)
+@ stdcall GetRawInputData(ptr long ptr ptr long) NtUserGetRawInputData
@ stdcall GetRawInputDeviceInfoA(ptr long ptr ptr)
@ stdcall GetRawInputDeviceInfoW(ptr long ptr ptr)
@ stdcall GetRawInputDeviceList(ptr ptr long)
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c
index 755fc3d578e..64b9b9f59a9 100644
--- a/dlls/user32/user_main.c
+++ b/dlls/user32/user_main.c
@@ -156,6 +156,7 @@ static const struct user_callbacks user_funcs =
unpack_dde_message,
register_imm,
unregister_imm,
+ rawinput_thread_data,
};
static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params, ULONG size )
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index aa3e1565bfa..11f8b6389ac 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -51,12 +51,6 @@ struct wm_char_mapping_data
/* hold up to 10s of 1kHz mouse rawinput events */
#define RAWINPUT_BUFFER_SIZE (512*1024)
-struct rawinput_thread_data
-{
- UINT hw_id; /* current rawinput message id */
- RAWINPUT buffer[1]; /* rawinput message data buffer */
-};
-
extern BOOL (WINAPI *imm_register_window)(HWND) DECLSPEC_HIDDEN;
extern void (WINAPI *imm_unregister_window)(HWND) DECLSPEC_HIDDEN;
@@ -73,7 +67,7 @@ struct tagWND;
struct hardware_msg_data;
extern BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_msg_data *msg_data);
extern BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage);
-extern struct rawinput_thread_data *rawinput_thread_data(void);
+extern struct rawinput_thread_data * WINAPI rawinput_thread_data(void);
extern void rawinput_update_device_list(void);
extern BOOL post_dde_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD dest_tid,
diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in
index d58ed6bb41c..cc429836de3 100644
--- a/dlls/win32u/Makefile.in
+++ b/dlls/win32u/Makefile.in
@@ -43,6 +43,7 @@ C_SRCS = \
path.c \
pen.c \
printdrv.c \
+ rawinput.c \
region.c \
spy.c \
syscall.c \
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index 72924bb658a..a988b1a0c4a 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1181,6 +1181,7 @@ static struct unix_funcs unix_funcs =
NtUserGetMessage,
NtUserGetPriorityClipboardFormat,
NtUserGetQueueStatus,
+ NtUserGetRawInputData,
NtUserGetSystemMenu,
NtUserGetUpdateRect,
NtUserGetUpdateRgn,
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index e39e3f54169..717538c1adc 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -49,6 +49,7 @@ struct user_callbacks
void **buffer, size_t size );
BOOL (WINAPI *register_imm)( HWND hwnd );
void (WINAPI *unregister_imm)( HWND hwnd );
+ struct rawinput_thread_data *(WINAPI *get_rawinput_thread_data)(void);
};
#define WM_SYSTIMER 0x0118
@@ -60,6 +61,12 @@ enum system_timer_id
SYSTEM_TIMER_CARET = 0xffff,
};
+struct rawinput_thread_data
+{
+ UINT hw_id; /* current rawinput message id */
+ RAWINPUT buffer[1]; /* rawinput message data buffer */
+};
+
struct user_object
{
HANDLE handle;
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
new file mode 100644
index 00000000000..0d2c585c36e
--- /dev/null
+++ b/dlls/win32u/rawinput.c
@@ -0,0 +1,91 @@
+/*
+ * Raw Input
+ *
+ * Copyright 2012 Henri Verbeet
+ * Copyright 2018 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "win32u_private.h"
+#include "ntuser_private.h"
+#include "wine/server.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
+
+/**********************************************************************
+ * NtUserGetRawInputData (win32u.@)
+ */
+UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size )
+{
+ struct rawinput_thread_data *thread_data;
+ UINT size;
+
+ TRACE( "rawinput %p, command %#x, data %p, data_size %p, header_size %u.\n",
+ rawinput, command, data, data_size, header_size );
+
+ if (!user_callbacks || !(thread_data = user_callbacks->get_rawinput_thread_data()))
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return ~0u;
+ }
+
+ if (!rawinput || thread_data->hw_id != (UINT_PTR)rawinput)
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return ~0u;
+ }
+
+ if (header_size != sizeof(RAWINPUTHEADER))
+ {
+ WARN( "Invalid structure size %u.\n", header_size );
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ switch (command)
+ {
+ case RID_INPUT:
+ size = thread_data->buffer->header.dwSize;
+ break;
+
+ case RID_HEADER:
+ size = sizeof(RAWINPUTHEADER);
+ break;
+
+ default:
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return ~0u;
+ }
+
+ if (!data)
+ {
+ *data_size = size;
+ return 0;
+ }
+
+ if (*data_size < size)
+ {
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return ~0u;
+ }
+ memcpy( data, thread_data->buffer, size );
+ return size;
+}
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index de500da143b..8b71504f374 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -984,7 +984,7 @@
@ stdcall NtUserGetQueueStatus(long)
@ stub NtUserGetQueueStatusReadonly
@ stub NtUserGetRawInputBuffer
-@ stub NtUserGetRawInputData
+@ stdcall NtUserGetRawInputData(ptr long ptr ptr long)
@ stub NtUserGetRawInputDeviceInfo
@ stub NtUserGetRawInputDeviceList
@ stub NtUserGetRawPointerDeviceData
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index 957d930d9da..87901d1313e 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -243,6 +243,8 @@ struct unix_funcs
BOOL (WINAPI *pNtUserGetMessage)( MSG *msg, HWND hwnd, UINT first, UINT last );
INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count );
DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags );
+ UINT (WINAPI *pNtUserGetRawInputData)( HRAWINPUT rawinput, UINT command,
+ void *data, UINT *data_size, UINT header_size );
HMENU (WINAPI *pNtUserGetSystemMenu)( HWND hwnd, BOOL revert );
BOOL (WINAPI *pNtUserGetUpdateRect)( HWND hwnd, RECT *rect, BOOL erase );
INT (WINAPI *pNtUserGetUpdateRgn)( HWND hwnd, HRGN hrgn, BOOL erase );
diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c
index 99e0b9f3d88..17354abc73e 100644
--- a/dlls/win32u/wrappers.c
+++ b/dlls/win32u/wrappers.c
@@ -1023,6 +1023,12 @@ DWORD WINAPI NtUserGetQueueStatus( UINT flags )
return unix_funcs->pNtUserGetQueueStatus( flags );
}
+UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size )
+{
+ if (!unix_funcs) return ~0u;
+ return unix_funcs->pNtUserGetRawInputData( rawinput, command, data, data_size, header_size );
+}
+
BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size )
{
if (!unix_funcs) return FALSE;
diff --git a/include/ntuser.h b/include/ntuser.h
index 8320a83800f..85b7a87247f 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -589,6 +589,7 @@ HWINSTA WINAPI NtUserGetProcessWindowStation(void);
HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str );
ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
DWORD WINAPI NtUserGetQueueStatus( UINT flags );
+UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size );
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert );
HDESK WINAPI NtUserGetThreadDesktop( DWORD thread );
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/233
June 13, 2022
[PATCH 2/4] user32: Correctly fill the RAWINPUT structure on WoW64.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
This changes the offset of the wParam field.
---
dlls/user32/rawinput.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index ab542956f11..99e2270b77c 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -646,12 +646,20 @@ UINT WINAPI GetRawInputData(HRAWINPUT rawinput, UINT command, void *data, UINT *
}
#ifdef _WIN64
+typedef RAWINPUTHEADER RAWINPUTHEADER64;
typedef RAWINPUT RAWINPUT64;
#else
typedef struct
{
- RAWINPUTHEADER header;
- char pad[8];
+ DWORD dwType;
+ DWORD dwSize;
+ ULONGLONG hDevice;
+ ULONGLONG wParam;
+} RAWINPUTHEADER64;
+
+typedef struct
+{
+ RAWINPUTHEADER64 header;
union {
RAWMOUSE mouse;
RAWKEYBOARD keyboard;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/233
June 13, 2022
[PATCH 1/4] user32/tests: Add some more tests related to the RAWINPUT structure.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
In order to test the wparam member I removed WS_VISIBLE from the window created
by test_GetRawInputBuffer(). For some reason this caused events injected by that
test not to be received if the test was executed after another test that created
a window. My vague understanding is that we'd need XInput2 support to reliably
receive those events, so as a stopgap solution I moved the tests earlier.
---
dlls/user32/tests/input.c | 104 ++++++++++++++++++++++++++++++++++----
1 file changed, 95 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 6232a7456e8..59039164b6b 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -2101,13 +2101,29 @@ static void test_RegisterRawInputDevices(void)
static int rawinputbuffer_wndproc_count;
+typedef struct
+{
+ DWORD dwType;
+ DWORD dwSize;
+ ULONG hDevice;
+ ULONG wParam;
+} RAWINPUTHEADER32;
+
#ifdef _WIN64
+typedef RAWINPUTHEADER RAWINPUTHEADER64;
typedef RAWINPUT RAWINPUT64;
#else
typedef struct
{
- RAWINPUTHEADER header;
- char pad[8];
+ DWORD dwType;
+ DWORD dwSize;
+ ULONGLONG hDevice;
+ ULONGLONG wParam;
+} RAWINPUTHEADER64;
+
+typedef struct
+{
+ RAWINPUTHEADER64 header;
union {
RAWMOUSE mouse;
RAWKEYBOARD keyboard;
@@ -2124,9 +2140,9 @@ static int rawinput_buffer_mouse_x(void *buffer, size_t index)
static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
+ UINT i, size, count, rawinput_size, iteration = rawinputbuffer_wndproc_count++;
RAWINPUT ri;
char buffer[16 * sizeof(RAWINPUT64)];
- UINT size, count, rawinput_size, iteration = rawinputbuffer_wndproc_count++;
MSG message;
if (is_wow64) rawinput_size = sizeof(RAWINPUT64);
@@ -2134,8 +2150,12 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara
if (msg == WM_INPUT)
{
+ ok(wparam == RIM_INPUTSINK, "Unexpected wparam: %#Ix\n", wparam);
+
+ SetLastError(0xdeadbeef);
count = GetRawInputBuffer(NULL, NULL, sizeof(RAWINPUTHEADER));
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
size = sizeof(buffer);
count = GetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER));
@@ -2147,6 +2167,25 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
ok(count == 3, "GetRawInputBuffer returned %u\n", count);
ok(size == sizeof(buffer), "GetRawInputBuffer returned unexpected size: %u\n", size);
+
+ for (i = 0; i < 3; ++i)
+ {
+ if (is_wow64)
+ {
+ const RAWINPUT64 *data = (RAWINPUT64 *)buffer;
+ ok(data->header.dwType == RIM_TYPEMOUSE, "Unexpected rawinput type: %lu\n", data->header.dwType);
+ ok(data->header.dwSize == sizeof(*data), "Unexpected rawinput size: %lu\n", data->header.dwSize);
+ todo_wine ok(data->header.wParam == wparam, "Unexpected wparam: %#I64x\n", data->header.wParam);
+ }
+ else
+ {
+ const RAWINPUT *data = (RAWINPUT *)buffer;
+ ok(data->header.dwType == RIM_TYPEMOUSE, "Unexpected rawinput type: %lu\n", data->header.dwType);
+ ok(data->header.dwSize == sizeof(*data), "Unexpected rawinput size: %lu\n", data->header.dwSize);
+ todo_wine ok(data->header.wParam == wparam, "Unexpected wparam: %#Ix\n", data->header.wParam);
+ }
+ }
+
ok(rawinput_buffer_mouse_x(buffer, 0) == 2, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 0));
ok(rawinput_buffer_mouse_x(buffer, 1) == 3, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 1));
ok(rawinput_buffer_mouse_x(buffer, 2) == 4, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 2));
@@ -2183,7 +2222,12 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara
{
SetLastError(0xdeadbeef);
count = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &ri, &size, 0);
- ok(count == ~0U, "GetRawInputData succeeded\n");
+ ok(count == ~0u, "GetRawInputData returned %d\n", count);
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputData returned %08lx\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ count = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &ri, &size, sizeof(RAWINPUTHEADER) + 1);
+ ok(count == ~0u, "GetRawInputData returned %d\n", count);
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputData returned %08lx\n", GetLastError());
SetLastError(0xdeadbeef);
@@ -2204,6 +2248,28 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara
ok(count == sizeof(ri), "GetRawInputData failed\n");
ok(ri.data.mouse.lLastX == 6, "Unexpected rawinput data: %ld\n", ri.data.mouse.lLastX);
ok(GetLastError() == 0xdeadbeef, "GetRawInputData returned %08lx\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ size = sizeof(buffer);
+ if (sizeof(void *) == 8)
+ {
+ count = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &ri, &size, sizeof(RAWINPUTHEADER32));
+ ok(count == ~0u, "GetRawInputData returned %d\n", count);
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputData returned %08lx\n", GetLastError());
+ }
+ else if (is_wow64)
+ {
+ count = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &ri, &size, sizeof(RAWINPUTHEADER64));
+ todo_wine ok(count == sizeof(ri), "GetRawInputData returned %d\n", count);
+ ok(ri.data.mouse.lLastX == 6, "Unexpected rawinput data: %ld\n", ri.data.mouse.lLastX);
+ todo_wine ok(GetLastError() == 0xdeadbeef, "GetRawInputData returned %08lx\n", GetLastError());
+ }
+ else
+ {
+ count = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &ri, &size, sizeof(RAWINPUTHEADER64));
+ ok(count == ~0u, "GetRawInputData returned %d\n", count);
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputData returned %08lx\n", GetLastError());
+ }
}
else
{
@@ -2233,7 +2299,7 @@ static void test_GetRawInputBuffer(void)
GetCursorPos(&pt);
ok(pt.x == 300 && pt.y == 300, "Unexpected cursor position pos %ldx%ld\n", pt.x, pt.y);
- hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
+ hwnd = CreateWindowA("static", "static", WS_POPUP,
100, 100, 100, 100, 0, NULL, NULL, NULL);
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)rawinputbuffer_wndproc);
ok(hwnd != 0, "CreateWindow failed\n");
@@ -2295,6 +2361,23 @@ static void test_GetRawInputBuffer(void)
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputBuffer returned %08lx\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ size = sizeof(buffer);
+ count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER) + 1);
+ ok(count == ~0U, "GetRawInputBuffer succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputBuffer returned %08lx\n", GetLastError());
+
+ /* the function returns 64-bit RAWINPUT structures on WoW64, but still
+ * forbids sizeof(RAWINPUTHEADER) from the wrong architecture */
+ SetLastError(0xdeadbeef);
+ size = sizeof(buffer);
+ if (sizeof(void *) == 8)
+ count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER32));
+ else
+ count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER64));
+ ok(count == ~0U, "GetRawInputBuffer succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputBuffer returned %08lx\n", GetLastError());
+
size = sizeof(buffer);
memset(buffer, 0, sizeof(buffer));
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
@@ -2365,6 +2448,9 @@ static LRESULT CALLBACK rawinput_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPA
ret = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &raw, &raw_size, sizeof(RAWINPUTHEADER));
ok(ret > 0 && ret != (UINT)-1, "GetRawInputData failed\n");
ok(raw.header.dwType == RIM_TYPEMOUSE, "Unexpected rawinput type: %lu\n", raw.header.dwType);
+ ok(raw.header.dwSize == raw_size, "Expected size %u, got %lu\n", raw_size, raw.header.dwSize);
+ todo_wine_if (wparam)
+ ok(raw.header.wParam == wparam, "Expected wparam %Iu, got %Iu\n", wparam, raw.header.wParam);
ok(!(raw.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE), "Unexpected absolute rawinput motion\n");
ok(!(raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP), "Unexpected virtual desktop rawinput motion\n");
@@ -4491,6 +4577,10 @@ START_TEST(input)
return;
}
+ test_GetRawInputData();
+ test_GetRawInputBuffer();
+ test_RegisterRawInputDevices();
+ test_rawinput(argv[0]);
test_SendInput();
test_Input_blackbox();
test_Input_whitebox();
@@ -4507,10 +4597,6 @@ START_TEST(input)
test_attach_input();
test_GetKeyState();
test_OemKeyScan();
- test_GetRawInputData();
- test_GetRawInputBuffer();
- test_RegisterRawInputDevices();
- test_rawinput(argv[0]);
if(pGetMouseMovePointsEx)
test_GetMouseMovePointsEx(argv[0]);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/233
June 13, 2022