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
[tools] testbot/Engine: Prevent recursion into ScheduleJobs().
by Francois Gouget
Recursion may happen through the ScheduleJobs() -> VM::Run() ->
VMStatusChange() -> ScheduleJobs() chain.
It can cause multiple revert processes to run on the same VM, or even a
revert process to run at the same time as a task.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This issue is caused by the patch to process notifications originating
from the Engine (9b0894ed386f). What's strange is I'm not seeing this
issue in my test environment.
---
testbot/lib/WineTestBot/Engine/Scheduler.pm | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/testbot/lib/WineTestBot/Engine/Scheduler.pm b/testbot/lib/WineTestBot/Engine/Scheduler.pm
index b9304c1c8f..bba7e6a2cc 100644
--- a/testbot/lib/WineTestBot/Engine/Scheduler.pm
+++ b/testbot/lib/WineTestBot/Engine/Scheduler.pm
@@ -946,6 +946,7 @@ sub _PowerOffDirtyVMs($)
}
}
+my $_InScheduleJobs;
my $_LastTaskCounts = "";
=pod
@@ -1004,6 +1005,11 @@ kept on standby so they are ready when their turn comes.
sub ScheduleJobs()
{
+ # Don't let Engine notifications (specifically VMStatusChange) cause
+ # recursion into ScheduleJobs().
+ return if ($_InScheduleJobs);
+ $_InScheduleJobs = 1;
+
my $Sched = _CheckAndClassifyVMs();
my $NeededVMs = _ScheduleTasks($Sched);
_RevertVMs($Sched, $NeededVMs);
@@ -1053,6 +1059,8 @@ sub ScheduleJobs()
$Timeout = 600;
}
AddEvent("ScheduleJobs", $Timeout, 0, \&ScheduleJobs);
+
+ $_InScheduleJobs = undef;
}
--
2.30.2
June 17, 2022
Re: Gitlab experiment wrapup
by Huw Davies
On Thu, Jun 16, 2022 at 09:08:30PM +0300, Gabriel Ivăncescu wrote:
> On 16/06/2022 20:13, Alexandre Julliard wrote:
> > Alex Henrie <alexhenrie24(a)gmail.com> writes:
> >
> > > On Thu, Jun 16, 2022 at 10:04 AM Gabriel Ivăncescu
> > > <gabrielopcode(a)gmail.com> wrote:
> > > >
> > > > There's one other (pretty big, for me) problem I can't seem to find how
> > > > to replicate with MRs compared to sending patches: how do I add notes
> > > > for each commit that shouldn't actually be committed? For patches I used
> > > > to add below the --- line, and these are super useful when you just want
> > > > to tell the information to the reviewer, which wouldn't make much sense
> > > > to have in the codebase itself.
> > > >
> > > > These seem to get lost when I push. I have to admit `git notes` seems
> > > > pretty convoluted to me and I've no idea how it gets "stored" especially
> > > > for merge requests. Patches were much easier to comprehend.
> > > >
> > > > I mean, I guess I can add it to the MR description but that's not
> > > > pointing out to a specific commit/patch... sigh.
> > >
> > > In a GitLab merge request, I can click on a specific commit to see its
> > > diff, then click on the commit hash again, and GitLab gives me a box
> > > to leave a comment either about a specific line of the commit or about
> > > the commit as a whole. Would that work for you?
> >
> > Unfortunately comments tied to a specific commit are no longer visible
> > when the branch is rebased, for instance when a reviewer pushes fixups.
> > There's a issue filed with Gitlab about that, but until this is fixed
> > it's better to avoid commit-specific comments.
> >
>
> I might go with a normal comment (after a MR is created or after a force
> push for e.g. v2), with something like:
>
>
>
> **Notes for `ntdll: Foobar`**
>
> Notes go here.
> Multiple lines.
> etc.
>
> **Notes for `server: Barfoo`**
>
> v2: blah.
>
>
>
> and so on. Which can also be scripted (and easily taken from own git notes).
> For example with something like:
>
> git log --reverse --pretty='format:**Notes for `%s`**%n%n%N%n%n'
> origin..HEAD
>
> Maybe we can standardize on a common method to encourage and put in the
> wiki? Well, or maybe it's just me.
Feel free to do that, but it sounds over-engineered to me and I don't
think we need to standardise this.
Personally, I've always found these sort of comments somewhat fragile.
When I'm reviewing a series I'm reviewing it in-tree, at which point
the comments have gone. Putting them in one place (in the equivalent
of a cover-letter) means there's more of a chance that I'll read them.
Huw.
June 17, 2022
Re: [PATCH v2 1/4] user32/tests: Add some more tests related to the RAWINPUT structure.
by Marvin
Hi,
It looks like your patch introduced the new failures shown below.
Please investigate and fix them before resubmitting your patch.
If they are not new, fixing them anyway would help a lot. Otherwise
please ask for the known failures list to be updated.
1 TestBot errors prevented a full analysis of your patch.
If the test caused the operating system (e.g. Windows) to crash or
reboot you will probably have to modify it to avoid that.
Other issues should be reported to the TestBot administrators.
The tests also ran into some preexisting test failures. If you know how
to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=117159
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
user32:
input.c:745: Test failed: 0 (a4/0): 00 from 00 -> 80 unexpected
input.c:745: Test failed: 0 (a4/0): 41 from 01 -> 00 unexpected
=== w7u_el (32 bit report) ===
user32:
input.c:4525: Test failed: SendInput triggered unexpected message 0xc042
=== w1064v1809 (64 bit report) ===
user32:
input.c:1421: Test failed: Wrong new pos: (150,150)
=== w1064_tsign (64 bit report) ===
user32:
input.c:1291: Test failed: Wrong set pos: (100,100)
input.c:1311: Test failed: GetCursorPos: (100,100)
=== w10pro64 (testbot log) ===
WineRunTask.pl:error: BotError: The test VM is powered off! Did the test shut it down?
June 17, 2022
Re: [PATCH 0/6] MR261: win32u: nonclient conversion
by Huw Davies (@huw)
Huw Davies (@huw) commented about dlls/win32u/defwnd.c:
> return 0;
> }
>
> +static LRESULT handle_nc_button_dbl_click( HWND hwnd, WPARAM wparam, LPARAM lparam )
> +{
> + /*if this is an icon, send a restore since we are handling a double click */
Missing space after the `/*`.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/261#note_2252
June 17, 2022
Re: [PATCH 0/6] MR261: win32u: nonclient conversion
by Huw Davies (@huw)
Huw Davies (@huw) commented about dlls/win32u/defwnd.c:
> +/***********************************************************************
> + * NtUserDrawCaptionTemp (win32u.@)
> + */
> +BOOL WINAPI NtUserDrawCaptionTemp( HWND hwnd, HDC hdc, const RECT *rect, HFONT font,
> + HICON icon, const WCHAR *str, UINT flags )
> +{
> + RECT rc = *rect;
> +
> + TRACE( "(%p,%p,%p,%p,%p,%s,%08x)\n", hwnd, hdc, rect, font, icon, debugstr_w(str), flags );
> +
> + /* drawing background */
> + if (flags & DC_INBUTTON)
> + {
> + fill_rect( hdc, &rc, get_sys_color_brush( COLOR_3DFACE ));
> +
> + if (flags & DC_ACTIVE) {
Left over K&R brace.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/261#note_2251
June 17, 2022
Re: [PATCH 0/6] MR261: win32u: nonclient conversion
by Huw Davies (@huw)
Huw Davies (@huw) commented about dlls/user32/nonclient.c:
> - {
> - HMODULE hmodule = LoadLibraryA( "shell32.dll" );
> - if (hmodule)
> - {
> - BOOL (WINAPI *aboutproc)(HWND, LPCSTR, LPCSTR, HICON);
> - extern const char * CDECL wine_get_version(void);
> - char app[256];
> -
> - sprintf( app, "Wine %s", wine_get_version() );
> - aboutproc = (void *)GetProcAddress( hmodule, "ShellAboutA" );
> - if (aboutproc) aboutproc( hwnd, app, NULL, 0 );
> - FreeLibrary( hmodule );
> - }
> - }
> - break;
> -
We probably want to remove the item (and the separator above it) from the SYSMENU then ;-)
Also, there are a couple of work-arounds for it in the menu tests that could also go away.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/261#note_2250
June 17, 2022
Re: [PATCH v2 1/1] shell32/tests: Add tests for Program Manager name sanitization.
by Marvin
Hi,
It looks like your patch introduced the new failures shown below.
Please investigate and fix them before resubmitting your patch.
If they are not new, fixing them anyway would help a lot. Otherwise
please ask for the known failures list to be updated.
The full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=117158
Your paranoid android.
=== w10pro64_ja (64 bit report) ===
shell32:
progman_dde.c:573: Test failed: char 39 ''': expected DMLERR_NO_ERROR, got 0x4005
progman_dde.c:575: Test failed: char 39 ''': directory should not exist
progman_dde.c:506: Test failed: char 42 '*': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<':
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<':
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<':
: : : : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<':
: : : : : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: : directory not created
progman_dde.c:506: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: : : expected DMLERR_NO_ERROR, got 0x4006
progman_dde.c:508: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: : : directory not created
progman_dde.c:639: Test failed: char 42 '*': char 43 '+': char 44 ',': char 45 '-': char 46 '.': char 47 '/': char 59 ';': char 60 '<': : : : : : : : : T: °: Ò: D: Š: : : DdeDisconnect() failed: 16390
June 17, 2022
Re: [PATCH v2 3/4] win32u: Move NtUserGetRawInputData from user32.
by Marvin
Hi,
It looks like your patch introduced the new failures shown below.
Please investigate and fix them before resubmitting your patch.
If they are not new, fixing them anyway would help a lot. Otherwise
please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how
to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=117161
Your paranoid android.
=== debian11 (64 bit WoW report) ===
user32:
win.c:10982: Test failed: Expected foreground window 00000000001A0124, got 0000000001430052
win.c:10985: Test failed: Received WM_ACTIVATEAPP(0), did not expect it.
win.c:10992: Test failed: Expected foreground window 00000000001A0124, got 0000000000000000
win.c:10994: Test failed: GetActiveWindow() = 0000000000000000
win.c:10994: Test failed: GetFocus() = 0000000000000000
win.c:10999: Test failed: Expected foreground window 00000000001A0124, got 0000000000000000
June 17, 2022
Re: [PATCH 0/5] MR242: winegstreamer: Use wg_sample to read wg_parser data.
by Zebediah Figura
On 6/16/22 01:58, Rémi Bernon (@rbernon) wrote:
>>> diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c
>>> index ae8a2d4d0c7..eb46982fabf 100644
>>> --- a/dlls/winegstreamer/wg_sample.c
>>> +++ b/dlls/winegstreamer/wg_sample.c
>>> @@ -47,6 +47,11 @@ struct sample
>>>
>>> union
>>> {
>>> + struct
>>> + {
>>> + void *__pad[3];
>>> + BYTE buffer[];
>>> + } raw;
>>> struct
>>> {
>>> IMFSample *sample;
>>
>> Why the padding?
>
> So that buffer is aligned to the end of the structure and so that we can
> safely use a flexible array member. Otherwise offsetof buffer[size] may
> be shorter than the struct, ending up with a undefined behavior when
> accessing a partially allocated structure and an eventual GCC warning.
Okay, that seems like a reasonable workaround; can you please add a
comment so it's clear?
June 17, 2022
[PATCH v2 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 | 245 +++++++++++++++++++++++++++++++++++
dlls/win32u/win32u.spec | 2 +-
dlls/win32u/win32u_private.h | 1 +
dlls/win32u/wrappers.c | 6 +
include/ntuser.h | 1 +
10 files changed, 260 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 de20e692157..70f523da804 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 a31a2bd8a01..9a2b7de4509 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 77c3e16242a..3eb24a7bc32 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1183,6 +1183,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 babbc8208bc..e8051ac39d3 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -68,6 +68,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..d6f38382b4b 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,250 @@
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;
+ }
+
+ 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 c984316e7c9..02c2cddcf5e 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 f431b967c32..d6885e97291 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -245,6 +245,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 56ffef8f478..40c037b3fd7 100644
--- a/dlls/win32u/wrappers.c
+++ b/dlls/win32u/wrappers.c
@@ -1041,6 +1041,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 269ba3ae490..bacba52db76 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -604,6 +604,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 17, 2022