Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
07d52242
Commit
07d52242
authored
Jan 20, 2024
by
Rémi Bernon
Committed by
Alexandre Julliard
Jan 25, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32/tests: Cleanup the mouse input WM_NCHITTEST / SetCapture tests.
And run them in the dedicated desktop.
parent
2b3b9004
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
409 additions
and
286 deletions
+409
-286
input.c
dlls/user32/tests/input.c
+409
-286
No files found.
dlls/user32/tests/input.c
View file @
07d52242
...
...
@@ -109,6 +109,7 @@ enum user_function
{
MSG_TEST_WIN
=
1
,
LL_HOOK_KEYBD
,
LL_HOOK_MOUSE
,
};
struct
user_call
...
...
@@ -132,6 +133,15 @@ struct user_call
UINT
flags
;
UINT_PTR
extra
;
}
ll_hook_kbd
;
struct
{
UINT
msg
;
POINT
point
;
UINT
data
;
UINT
flags
;
UINT
time
;
UINT_PTR
extra
;
}
ll_hook_ms
;
};
BOOL
todo
;
...
...
@@ -154,6 +164,11 @@ static const char *debugstr_wm( UINT msg )
case
WM_SYSCOMMAND
:
return
"WM_SYSCOMMAND"
;
case
WM_SYSKEYDOWN
:
return
"WM_SYSKEYDOWN"
;
case
WM_SYSKEYUP
:
return
"WM_SYSKEYUP"
;
case
WM_MOUSEMOVE
:
return
"WM_MOUSEMOVE"
;
case
WM_LBUTTONDOWN
:
return
"WM_LBUTTONDOWN"
;
case
WM_LBUTTONUP
:
return
"WM_LBUTTONUP"
;
case
WM_LBUTTONDBLCLK
:
return
"WM_LBUTTONDBLCLK"
;
case
WM_NCHITTEST
:
return
"WM_NCHITTEST"
;
}
return
wine_dbg_sprintf
(
"%#x"
,
msg
);
}
...
...
@@ -200,6 +215,15 @@ static int ok_call_( const char *file, int line, const struct user_call *expecte
if
((
ret
=
(
expected
->
ll_hook_kbd
.
flags
-
received
->
ll_hook_kbd
.
flags
)))
goto
done
;
if
((
ret
=
(
expected
->
ll_hook_kbd
.
extra
-
received
->
ll_hook_kbd
.
extra
)))
goto
done
;
break
;
case
LL_HOOK_MOUSE
:
if
((
ret
=
expected
->
ll_hook_ms
.
msg
-
received
->
ll_hook_ms
.
msg
))
goto
done
;
if
((
ret
=
expected
->
ll_hook_ms
.
point
.
x
-
received
->
ll_hook_ms
.
point
.
x
))
goto
done
;
if
((
ret
=
expected
->
ll_hook_ms
.
point
.
y
-
received
->
ll_hook_ms
.
point
.
y
))
goto
done
;
if
((
ret
=
(
expected
->
ll_hook_ms
.
data
-
received
->
ll_hook_ms
.
data
)))
goto
done
;
if
((
ret
=
(
expected
->
ll_hook_ms
.
flags
-
received
->
ll_hook_ms
.
flags
)))
goto
done
;
if
(
0
&&
(
ret
=
expected
->
ll_hook_ms
.
time
-
received
->
ll_hook_ms
.
time
))
goto
done
;
if
((
ret
=
(
expected
->
ll_hook_ms
.
extra
-
received
->
ll_hook_ms
.
extra
)))
goto
done
;
break
;
}
done:
...
...
@@ -218,6 +242,12 @@ done:
received
->
ll_hook_kbd
.
scan
,
debugstr_vk
(
received
->
ll_hook_kbd
.
vkey
),
received
->
ll_hook_kbd
.
flags
,
received
->
ll_hook_kbd
.
extra
);
return
ret
;
case
LL_HOOK_MOUSE
:
todo_wine_if
(
expected
->
todo
||
expected
->
todo_value
)
ok_
(
file
,
line
)(
!
ret
,
"got LL_HOOK_MOUSE msg %s, point %s, data %#x, flags %#x, time %u, extra %#Ix
\n
"
,
debugstr_wm
(
received
->
ll_hook_ms
.
msg
),
wine_dbgstr_point
(
&
received
->
ll_hook_ms
.
point
),
received
->
ll_hook_ms
.
data
,
received
->
ll_hook_ms
.
flags
,
received
->
ll_hook_ms
.
time
,
received
->
ll_hook_ms
.
extra
);
return
ret
;
}
switch
(
expected
->
func
)
...
...
@@ -233,6 +263,12 @@ done:
expected
->
ll_hook_kbd
.
scan
,
debugstr_vk
(
expected
->
ll_hook_kbd
.
vkey
),
expected
->
ll_hook_kbd
.
flags
,
expected
->
ll_hook_kbd
.
extra
);
break
;
case
LL_HOOK_MOUSE
:
todo_wine_if
(
expected
->
todo
||
expected
->
todo_value
)
ok_
(
file
,
line
)(
!
ret
,
"LL_HOOK_MOUSE msg %s, point %s, data %#x, flags %#x, time %u, extra %#Ix
\n
"
,
debugstr_wm
(
received
->
ll_hook_ms
.
msg
),
wine_dbgstr_point
(
&
received
->
ll_hook_ms
.
point
),
received
->
ll_hook_ms
.
data
,
received
->
ll_hook_ms
.
flags
,
received
->
ll_hook_ms
.
time
,
received
->
ll_hook_ms
.
extra
);
return
ret
;
}
return
0
;
...
...
@@ -281,6 +317,21 @@ static void append_ll_hook_kbd( UINT msg, const KBDLLHOOKSTRUCT *info )
current_sequence
[
index
]
=
call
;
}
static
void
append_ll_hook_ms
(
UINT
msg
,
const
MSLLHOOKSTRUCT
*
info
)
{
struct
user_call
call
=
{
.
func
=
LL_HOOK_MOUSE
,
.
ll_hook_ms
=
{
.
msg
=
msg
,
.
point
=
info
->
pt
,
.
data
=
info
->
mouseData
,
.
flags
=
info
->
flags
,
.
time
=
info
->
time
,
.
extra
=
info
->
dwExtraInfo
}
};
ULONG
index
=
InterlockedIncrement
(
&
current_sequence_len
)
-
1
;
ok
(
index
<
ARRAY_SIZE
(
current_sequence
),
"got %lu calls
\n
"
,
index
);
current_sequence
[
index
]
=
call
;
}
static
BOOL
append_message_hwnd
;
static
BOOL
(
*
p_accept_message
)(
UINT
msg
);
static
void
append_message
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
...
...
@@ -3535,24 +3586,6 @@ static void simulate_click(BOOL left, int x, int y)
ok
(
events_no
==
2
,
"SendInput returned %d
\n
"
,
events_no
);
}
static
BOOL
wait_for_message
(
MSG
*
msg
)
{
BOOL
ret
;
for
(;;)
{
ret
=
PeekMessageA
(
msg
,
0
,
0
,
0
,
PM_REMOVE
);
if
(
ret
)
{
if
(
msg
->
message
==
WM_PAINT
)
DispatchMessageA
(
msg
);
else
break
;
}
else
if
(
MsgWaitForMultipleObjects
(
0
,
NULL
,
FALSE
,
100
,
QS_ALLINPUT
)
==
WAIT_TIMEOUT
)
break
;
}
if
(
!
ret
)
msg
->
message
=
0
;
return
ret
;
}
static
BOOL
wait_for_event
(
HANDLE
event
,
int
timeout
)
{
DWORD
end_time
=
GetTickCount
()
+
timeout
;
...
...
@@ -3569,49 +3602,42 @@ static BOOL wait_for_event(HANDLE event, int timeout)
return
FALSE
;
}
static
WNDPROC
def_static_proc
;
static
DWORD
hittest_no
;
static
LRESULT
WINAPI
static_hook_proc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wp
,
LPARAM
lp
)
static
LRESULT
CALLBACK
httransparent_wndproc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
if
(
msg
==
WM_NCHITTEST
)
{
/* break infinite hittest loop */
if
(
hittest_no
>
50
)
return
HTCLIENT
;
hittest_no
++
;
}
return
def_static_proc
(
hwnd
,
msg
,
wp
,
lp
);
append_message
(
hwnd
,
msg
,
wparam
,
lparam
);
if
(
msg
==
WM_NCHITTEST
)
return
HTTRANSPARENT
;
return
DefWindowProcW
(
hwnd
,
msg
,
wparam
,
lparam
);
}
struct
thread_data
struct
create_transparent_window_params
{
HANDLE
start_event
;
HANDLE
end_event
;
HWND
win
;
HWND
hwnd
;
};
static
DWORD
WINAPI
create_
static_win
(
void
*
arg
)
static
DWORD
WINAPI
create_
transparent_window_thread
(
void
*
arg
)
{
struct
thread_data
*
thread_data
=
arg
;
HWND
win
;
MSG
msg
;
struct
create_transparent_window_params
*
params
=
arg
;
ULONG_PTR
old_proc
;
params
->
hwnd
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_POPUP
,
0
,
0
,
100
,
100
,
NULL
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
params
->
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
old_proc
=
SetWindowLongPtrW
(
params
->
hwnd
,
GWLP_WNDPROC
,
(
LONG_PTR
)
httransparent_wndproc
);
ok_ne
(
0
,
old_proc
,
LONG_PTR
,
"%#Ix"
);
win
=
CreateWindowA
(
"static"
,
"static"
,
WS_VISIBLE
|
WS_POPUP
,
100
,
100
,
100
,
100
,
0
,
NULL
,
NULL
,
NULL
);
ok
(
win
!=
0
,
"CreateWindow failed
\n
"
);
def_static_proc
=
(
void
*
)
SetWindowLongPtrA
(
win
,
GWLP_WNDPROC
,
(
LONG_PTR
)
static_hook_proc
);
thread_data
->
win
=
win
;
ok_ret
(
1
,
SetEvent
(
params
->
start_event
)
);
wait_for_event
(
params
->
end_event
,
5000
);
while
(
wait_for_message
(
&
msg
))
DispatchMessageA
(
&
msg
);
SetEvent
(
thread_data
->
start_event
);
wait_for_event
(
thread_data
->
end_event
,
5000
);
ok_ret
(
1
,
DestroyWindow
(
params
->
hwnd
)
);
wait_messages
(
100
,
FALSE
);
return
0
;
}
static
LRESULT
CALLBACK
mouse_move_wndproc
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
static
DWORD
last_x
=
200
,
expect_x
=
21
0
;
static
DWORD
last_x
=
50
,
expect_x
=
6
0
;
if
(
msg
==
WM_MOUSEMOVE
)
{
...
...
@@ -3621,281 +3647,378 @@ static LRESULT CALLBACK mouse_move_wndproc(HWND hwnd, UINT msg, WPARAM wparam, L
flaky
if
(
pt
.
x
!=
last_x
)
ok
(
pt
.
x
==
expect_x
,
"got unexpected WM_MOUSEMOVE x %ld, expected %ld
\n
"
,
pt
.
x
,
expect_x
);
expect_x
=
pt
.
x
==
200
?
210
:
20
0
;
expect_x
=
pt
.
x
==
50
?
60
:
5
0
;
last_x
=
pt
.
x
;
}
return
DefWindowProcW
(
hwnd
,
msg
,
wparam
,
lparam
);
}
st
atic
void
test_Input_mouse
(
void
)
st
ruct
send_input_mouse_test
{
BOOL
got_button_down
,
got_button_up
;
HWND
hwnd
,
button_win
,
static_win
;
struct
thread_data
thread_data
;
HANDLE
thread
;
DWORD
thread_id
;
POINT
pt
,
pt_org
;
MSG
msg
;
BOOL
ret
;
BOOL
set_cursor_pos
;
POINT
cursor_pos
;
UINT
data
;
UINT
flags
;
ULONG_PTR
extra
;
struct
user_call
expect
[
8
];
BYTE
expect_state
[
256
];
BOOL
todo_state
[
256
];
};
SetLastError
(
0xdeadbeef
);
ret
=
GetCursorPos
(
NULL
);
ok
(
!
ret
,
"GetCursorPos succeed
\n
"
);
ok
(
GetLastError
()
==
0xdeadbeef
||
GetLastError
()
==
ERROR_NOACCESS
,
"error %lu
\n
"
,
GetLastError
());
static
LRESULT
CALLBACK
ll_hook_ms_proc
(
int
code
,
WPARAM
wparam
,
LPARAM
lparam
)
{
MSLLHOOKSTRUCT
*
hook_info
=
(
MSLLHOOKSTRUCT
*
)
lparam
;
if
(
code
==
HC_ACTION
)
append_ll_hook_ms
(
wparam
,
hook_info
);
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
}
SetLastError
(
0xdeadbeef
);
ret
=
GetCursorPos
(
&
pt_org
);
ok
(
ret
,
"GetCursorPos failed
\n
"
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"error %lu
\n
"
,
GetLastError
());
button_win
=
CreateWindowA
(
"button"
,
"button"
,
WS_VISIBLE
|
WS_POPUP
,
100
,
100
,
100
,
100
,
0
,
NULL
,
NULL
,
NULL
);
ok
(
button_win
!=
0
,
"CreateWindow failed
\n
"
);
pt
.
x
=
pt
.
y
=
50
;
ClientToScreen
(
button_win
,
&
pt
);
hwnd
=
WindowFromPoint
(
pt
);
if
(
hwnd
!=
button_win
)
{
skip
(
"there's another window covering test window
\n
"
);
DestroyWindow
(
button_win
);
return
;
}
static
BOOL
accept_mouse_messages_nomove
(
UINT
msg
)
{
return
is_mouse_message
(
msg
)
&&
msg
!=
WM_MOUSEMOVE
;
}
/* simple button click test */
simulate_click
(
TRUE
,
pt
.
x
,
pt
.
y
);
got_button_down
=
got_button_up
=
FALSE
;
while
(
wait_for_message
(
&
msg
))
static
void
test_SendInput_mouse_messages
(
void
)
{
#define WIN_MSG(m, h, w, l, ...) {.func = MSG_TEST_WIN, .message = {.msg = m, .hwnd = h, .wparam = w, .lparam = l}, ## __VA_ARGS__}
#define MS_HOOK(m, x, y, ...) {.func = LL_HOOK_MOUSE, .ll_hook_ms = {.msg = m, .point = {x, y}, .flags = 1}, ## __VA_ARGS__}
struct
user_call
button_down_hwnd
[]
=
{
DispatchMessageA
(
&
msg
);
MS_HOOK
(
WM_LBUTTONDOWN
,
50
,
50
),
WIN_MSG
(
WM_LBUTTONDOWN
,
(
HWND
)
-
1
/*hwnd*/
,
0x1
,
MAKELONG
(
50
,
50
)),
{
0
},
};
struct
user_call
button_down_hwnd_todo
[]
=
{
MS_HOOK
(
WM_LBUTTONDOWN
,
50
,
50
),
WIN_MSG
(
WM_LBUTTONDOWN
,
(
HWND
)
-
1
/*hwnd*/
,
0x1
,
MAKELONG
(
50
,
50
),
.
todo
=
TRUE
),
{
0
},
};
struct
user_call
button_down_hwnd_todo_attached
[]
=
{
MS_HOOK
(
WM_LBUTTONDOWN
,
50
,
50
),
WIN_MSG
(
WM_LBUTTONDOWN
,
(
HWND
)
-
1
/*hwnd*/
,
0x1
,
MAKELONG
(
50
,
50
),
.
todo
=
TRUE
),
{.
todo
=
TRUE
/* spurious message on Wine */
},
{
0
},
};
struct
user_call
button_up_hwnd
[]
=
{
MS_HOOK
(
WM_LBUTTONUP
,
50
,
50
),
WIN_MSG
(
WM_LBUTTONUP
,
(
HWND
)
-
1
/*hwnd*/
,
0
,
MAKELONG
(
50
,
50
)),
{
0
},
};
struct
user_call
button_up_hwnd_todo
[]
=
{
MS_HOOK
(
WM_LBUTTONUP
,
50
,
50
),
WIN_MSG
(
WM_LBUTTONUP
,
(
HWND
)
-
1
/*hwnd*/
,
0
,
MAKELONG
(
50
,
50
),
.
todo
=
TRUE
),
{
0
},
};
struct
user_call
button_down_no_message
[]
=
{
MS_HOOK
(
WM_LBUTTONDOWN
,
50
,
50
),
{.
todo
=
TRUE
/* spurious message on Wine */
},
{
0
},
};
struct
user_call
button_up_no_message
[]
=
{
MS_HOOK
(
WM_LBUTTONUP
,
50
,
50
),
{.
todo
=
TRUE
/* spurious message on Wine */
},
{
0
},
};
#undef WIN_MSG
#undef MS_HOOK
static
const
POINT
expect_60x50
=
{
60
,
50
},
expect_50x50
=
{
50
,
50
};
if
(
msg
.
message
==
WM_LBUTTONDOWN
)
{
got_button_down
=
TRUE
;
}
else
if
(
msg
.
message
==
WM_LBUTTONUP
)
{
got_button_up
=
TRUE
;
break
;
}
}
ok
(
got_button_down
,
"expected WM_LBUTTONDOWN message
\n
"
);
ok
(
got_button_up
,
"expected WM_LBUTTONUP message
\n
"
);
struct
create_transparent_window_params
params
=
{
0
};
ULONG_PTR
old_proc
,
old_other_proc
;
UINT
dblclk_time
;
HWND
hwnd
,
other
;
DWORD
thread_id
;
HANDLE
thread
;
HHOOK
hook
;
POINT
pt
;
/* click through HTTRANSPARENT child window */
static_win
=
CreateWindowA
(
"static"
,
"static"
,
WS_VISIBLE
|
WS_CHILD
,
0
,
0
,
100
,
100
,
button_win
,
NULL
,
NULL
,
NULL
);
ok
(
static_win
!=
0
,
"CreateWindow failed
\n
"
);
def_static_proc
=
(
void
*
)
SetWindowLongPtrA
(
static_win
,
GWLP_WNDPROC
,
(
LONG_PTR
)
static_hook_proc
);
simulate_click
(
FALSE
,
pt
.
x
,
pt
.
y
);
hittest_no
=
0
;
got_button_down
=
got_button_up
=
FALSE
;
while
(
wait_for_message
(
&
msg
))
{
DispatchMessageA
(
&
msg
);
params
.
start_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ok
(
!!
params
.
start_event
,
"CreateEvent failed
\n
"
);
params
.
end_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ok
(
!!
params
.
end_event
,
"CreateEvent failed
\n
"
);
dblclk_time
=
GetDoubleClickTime
();
ok_eq
(
500
,
dblclk_time
,
UINT
,
"%u"
);
ok_ret
(
1
,
SetCursorPos
(
50
,
50
)
);
ok_ret
(
1
,
SetDoubleClickTime
(
1
)
);
hwnd
=
CreateWindowW
(
L"static"
,
NULL
,
WS_POPUP
|
WS_VISIBLE
,
0
,
0
,
100
,
100
,
NULL
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
trace
(
"hwnd %p
\n
"
,
hwnd
);
hook
=
SetWindowsHookExW
(
WH_MOUSE_LL
,
ll_hook_ms_proc
,
GetModuleHandleW
(
NULL
),
0
);
ok_ne
(
NULL
,
hook
,
HHOOK
,
"%p"
);
append_message_hwnd
=
TRUE
;
p_accept_message
=
accept_mouse_messages_nomove
;
ok_seq
(
empty_sequence
);
/* basic button messages */
old_proc
=
SetWindowLongPtrW
(
hwnd
,
GWLP_WNDPROC
,
(
LONG_PTR
)
append_message_wndproc
);
ok_ne
(
0
,
old_proc
,
LONG_PTR
,
"%#Ix"
);
ok_ret
(
1
,
SetCursorPos
(
50
,
50
)
);
wait_messages
(
100
,
FALSE
);
ok_seq
(
empty_sequence
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_down_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd
);
/* click through top-level window */
other
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_POPUP
,
0
,
0
,
100
,
100
,
NULL
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
current_sequence_len
=
0
;
old_other_proc
=
SetWindowLongPtrW
(
other
,
GWLP_WNDPROC
,
(
LONG_PTR
)
append_message_wndproc
);
ok_ne
(
0
,
old_other_proc
,
LONG_PTR
,
"%#Ix"
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd
[
1
].
message
.
hwnd
=
other
;
ok_seq
(
button_down_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
other
;
ok_seq
(
button_up_hwnd
);
ok_ret
(
1
,
DestroyWindow
(
other
)
);
wait_messages
(
0
,
FALSE
);
/* click through child window */
other
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_CHILD
,
0
,
0
,
100
,
100
,
hwnd
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
current_sequence_len
=
0
;
old_other_proc
=
SetWindowLongPtrW
(
other
,
GWLP_WNDPROC
,
(
LONG_PTR
)
append_message_wndproc
);
ok_ne
(
0
,
old_other_proc
,
LONG_PTR
,
"%#Ix"
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd
[
1
].
message
.
hwnd
=
other
;
ok_seq
(
button_down_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
other
;
ok_seq
(
button_up_hwnd
);
ok_ret
(
1
,
DestroyWindow
(
other
)
);
wait_messages
(
0
,
FALSE
);
if
(
msg
.
message
==
WM_RBUTTONDOWN
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_down
=
TRUE
;
}
else
if
(
msg
.
message
==
WM_RBUTTONUP
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_up
=
TRUE
;
break
;
}
}
ok
(
hittest_no
&&
hittest_no
<
50
,
"expected WM_NCHITTEST message
\n
"
);
ok
(
got_button_down
,
"expected WM_RBUTTONDOWN message
\n
"
);
ok
(
got_button_up
,
"expected WM_RBUTTONUP message
\n
"
);
DestroyWindow
(
static_win
);
/* click through HTTRANSPARENT top-level window */
static_win
=
CreateWindowA
(
"static"
,
"static"
,
WS_VISIBLE
|
WS_POPUP
,
100
,
100
,
100
,
100
,
0
,
NULL
,
NULL
,
NULL
);
ok
(
static_win
!=
0
,
"CreateWindow failed
\n
"
);
def_static_proc
=
(
void
*
)
SetWindowLongPtrA
(
static_win
,
GWLP_WNDPROC
,
(
LONG_PTR
)
static_hook_proc
);
pt
.
x
=
pt
.
y
=
50
;
ClientToScreen
(
static_win
,
&
pt
);
simulate_click
(
TRUE
,
pt
.
x
,
pt
.
y
);
hittest_no
=
0
;
got_button_down
=
got_button_up
=
FALSE
;
while
(
wait_for_message
(
&
msg
))
{
DispatchMessageA
(
&
msg
);
if
(
msg
.
message
==
WM_LBUTTONDOWN
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_down
=
TRUE
;
}
else
if
(
msg
.
message
==
WM_LBUTTONUP
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_up
=
TRUE
;
break
;
}
}
ok
(
hittest_no
&&
hittest_no
<
50
,
"expected WM_NCHITTEST message
\n
"
);
todo_wine
ok
(
got_button_down
,
"expected WM_LBUTTONDOWN message
\n
"
);
todo_wine
ok
(
got_button_up
,
"expected WM_LBUTTONUP message
\n
"
);
DestroyWindow
(
static_win
);
other
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_POPUP
,
0
,
0
,
100
,
100
,
NULL
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
current_sequence_len
=
0
;
old_other_proc
=
SetWindowLongPtrW
(
other
,
GWLP_WNDPROC
,
(
LONG_PTR
)
httransparent_wndproc
);
ok_ne
(
0
,
old_other_proc
,
LONG_PTR
,
"%#Ix"
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd_todo
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_down_hwnd_todo
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd_todo
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd_todo
);
ok_ret
(
1
,
DestroyWindow
(
other
)
);
wait_messages
(
0
,
FALSE
);
/* click through HTTRANSPARENT child window */
other
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_CHILD
,
0
,
0
,
100
,
100
,
hwnd
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
current_sequence_len
=
0
;
old_other_proc
=
SetWindowLongPtrW
(
other
,
GWLP_WNDPROC
,
(
LONG_PTR
)
httransparent_wndproc
);
ok_ne
(
0
,
old_other_proc
,
LONG_PTR
,
"%#Ix"
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_down_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd
);
ok_ret
(
1
,
DestroyWindow
(
other
)
);
wait_messages
(
0
,
FALSE
);
/* click on HTTRANSPARENT top-level window that belongs to other thread */
thread_data
.
start_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ok
(
thread_data
.
start_event
!=
NULL
,
"CreateEvent failed
\n
"
);
thread_data
.
end_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ok
(
thread_data
.
end_event
!=
NULL
,
"CreateEvent failed
\n
"
);
thread
=
CreateThread
(
NULL
,
0
,
create_static_win
,
&
thread_data
,
0
,
NULL
);
ok
(
thread
!=
NULL
,
"CreateThread failed
\n
"
);
hittest_no
=
0
;
got_button_down
=
got_button_up
=
FALSE
;
WaitForSingleObject
(
thread_data
.
start_event
,
INFINITE
);
pt
.
x
=
pt
.
y
=
50
;
ClientToScreen
(
thread_data
.
win
,
&
pt
);
simulate_click
(
FALSE
,
pt
.
x
,
pt
.
y
);
while
(
wait_for_message
(
&
msg
))
{
DispatchMessageA
(
&
msg
);
if
(
msg
.
message
==
WM_RBUTTONDOWN
)
got_button_down
=
TRUE
;
else
if
(
msg
.
message
==
WM_RBUTTONUP
)
got_button_up
=
TRUE
;
}
SetEvent
(
thread_data
.
end_event
);
WaitForSingleObject
(
thread
,
INFINITE
);
CloseHandle
(
thread
);
flaky_wine
ok
(
hittest_no
&&
hittest_no
<
50
,
"expected WM_NCHITTEST message
\n
"
);
ok
(
!
got_button_down
,
"unexpected WM_RBUTTONDOWN message
\n
"
);
ok
(
!
got_button_up
,
"unexpected WM_RBUTTONUP message
\n
"
);
thread
=
CreateThread
(
NULL
,
0
,
create_transparent_window_thread
,
&
params
,
0
,
NULL
);
ok_ne
(
NULL
,
thread
,
HANDLE
,
"%p"
);
ok_ret
(
0
,
WaitForSingleObject
(
params
.
start_event
,
5000
)
);
ok_ret
(
0
,
SendMessageW
(
params
.
hwnd
,
WM_USER
,
0
,
0
)
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
ok_seq
(
button_down_no_message
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
ok_seq
(
button_up_no_message
);
ok_ret
(
1
,
SetEvent
(
params
.
end_event
)
);
ok_ret
(
0
,
WaitForSingleObject
(
thread
,
5000
)
);
ok_ret
(
1
,
CloseHandle
(
thread
)
);
ResetEvent
(
params
.
start_event
);
ResetEvent
(
params
.
end_event
);
/* click on HTTRANSPARENT top-level window that belongs to other thread,
* thread input queues are attached */
thread
=
CreateThread
(
NULL
,
0
,
create_static_win
,
&
thread_data
,
0
,
&
thread_id
);
ok
(
thread
!=
NULL
,
"CreateThread failed
\n
"
);
hittest_no
=
0
;
got_button_down
=
got_button_up
=
FALSE
;
WaitForSingleObject
(
thread_data
.
start_event
,
INFINITE
);
ok
(
AttachThreadInput
(
thread_id
,
GetCurrentThreadId
(),
TRUE
),
"AttachThreadInput failed
\n
"
);
while
(
wait_for_message
(
&
msg
))
DispatchMessageA
(
&
msg
);
SetWindowPos
(
thread_data
.
win
,
button_win
,
0
,
0
,
0
,
0
,
SWP_NOSIZE
|
SWP_NOMOVE
);
pt
.
x
=
pt
.
y
=
50
;
ClientToScreen
(
thread_data
.
win
,
&
pt
);
simulate_click
(
TRUE
,
pt
.
x
,
pt
.
y
);
while
(
wait_for_message
(
&
msg
))
{
DispatchMessageA
(
&
msg
);
if
(
msg
.
message
==
WM_LBUTTONDOWN
)
got_button_down
=
TRUE
;
else
if
(
msg
.
message
==
WM_LBUTTONUP
)
got_button_up
=
TRUE
;
}
SetEvent
(
thread_data
.
end_event
);
WaitForSingleObject
(
thread
,
INFINITE
);
todo_wine
ok
(
hittest_no
>
50
,
"expected loop with WM_NCHITTEST messages
\n
"
);
ok
(
!
got_button_down
,
"unexpected WM_LBUTTONDOWN message
\n
"
);
ok
(
!
got_button_up
,
"unexpected WM_LBUTTONUP message
\n
"
);
thread
=
CreateThread
(
NULL
,
0
,
create_transparent_window_thread
,
&
params
,
0
,
&
thread_id
);
ok_ne
(
NULL
,
thread
,
HANDLE
,
"%p"
);
/* click after SetCapture call */
hwnd
=
CreateWindowA
(
"button"
,
"button"
,
WS_VISIBLE
|
WS_POPUP
,
0
,
0
,
100
,
100
,
0
,
NULL
,
NULL
,
NULL
);
ok
(
hwnd
!=
0
,
"CreateWindow failed
\n
"
);
SetCapture
(
button_win
);
got_button_down
=
got_button_up
=
FALSE
;
pt
.
x
=
pt
.
y
=
50
;
ClientToScreen
(
hwnd
,
&
pt
);
simulate_click
(
FALSE
,
pt
.
x
,
pt
.
y
);
while
(
wait_for_message
(
&
msg
))
{
DispatchMessageA
(
&
msg
);
ok_ret
(
0
,
WaitForSingleObject
(
params
.
start_event
,
5000
)
);
todo_wine
ok_ret
(
1
,
AttachThreadInput
(
thread_id
,
GetCurrentThreadId
(),
TRUE
)
);
ok_ret
(
0
,
SendMessageW
(
params
.
hwnd
,
WM_USER
,
0
,
0
)
);
if
(
msg
.
message
==
WM_RBUTTONDOWN
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_down
=
TRUE
;
}
else
if
(
msg
.
message
==
WM_RBUTTONUP
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_up
=
TRUE
;
break
;
}
}
ok
(
got_button_down
,
"expected WM_RBUTTONDOWN message
\n
"
);
ok
(
got_button_up
,
"expected WM_RBUTTONUP message
\n
"
);
DestroyWindow
(
hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd_todo_attached
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_down_hwnd_todo_attached
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd
);
/* click on child window after SetCapture call */
hwnd
=
CreateWindowA
(
"button"
,
"button2"
,
WS_VISIBLE
|
WS_CHILD
,
0
,
0
,
100
,
100
,
button_win
,
NULL
,
NULL
,
NULL
);
ok
(
hwnd
!=
0
,
"CreateWindow failed
\n
"
);
got_button_down
=
got_button_up
=
FALSE
;
pt
.
x
=
pt
.
y
=
50
;
ClientToScreen
(
hwnd
,
&
pt
);
simulate_click
(
TRUE
,
pt
.
x
,
pt
.
y
);
while
(
wait_for_message
(
&
msg
))
{
DispatchMessageA
(
&
msg
);
todo_wine
ok_ret
(
1
,
AttachThreadInput
(
thread_id
,
GetCurrentThreadId
(),
FALSE
)
);
ok_ret
(
1
,
SetEvent
(
params
.
end_event
)
);
ok_ret
(
0
,
WaitForSingleObject
(
thread
,
5000
)
);
ok_ret
(
1
,
CloseHandle
(
thread
)
);
ResetEvent
(
params
.
start_event
);
ResetEvent
(
params
.
end_event
);
if
(
msg
.
message
==
WM_LBUTTONDOWN
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_down
=
TRUE
;
}
else
if
(
msg
.
message
==
WM_LBUTTONUP
)
{
ok
(
msg
.
hwnd
==
button_win
,
"msg.hwnd = %p
\n
"
,
msg
.
hwnd
);
got_button_up
=
TRUE
;
break
;
}
}
ok
(
got_button_down
,
"expected WM_LBUTTONDOWN message
\n
"
);
ok
(
got_button_up
,
"expected WM_LBUTTONUP message
\n
"
);
DestroyWindow
(
hwnd
);
ok
(
ReleaseCapture
(),
"ReleaseCapture failed
\n
"
);
SetCursorPos
(
pt_org
.
x
,
pt_org
.
y
);
CloseHandle
(
thread_data
.
start_event
);
CloseHandle
(
thread_data
.
end_event
);
DestroyWindow
(
button_win
);
/* click on top-level window with SetCapture called for the underlying window */
other
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_POPUP
,
0
,
0
,
100
,
100
,
NULL
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
current_sequence_len
=
0
;
old_other_proc
=
SetWindowLongPtrW
(
other
,
GWLP_WNDPROC
,
(
LONG_PTR
)
append_message_wndproc
);
ok_ne
(
0
,
old_other_proc
,
LONG_PTR
,
"%#Ix"
);
SetCapture
(
hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_down_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd
);
ok_ret
(
1
,
DestroyWindow
(
other
)
);
wait_messages
(
0
,
FALSE
);
SetCapture
(
0
);
/* click through child window with SetCapture called for the underlying window */
other
=
CreateWindowW
(
L"static"
,
NULL
,
WS_VISIBLE
|
WS_CHILD
,
0
,
0
,
100
,
100
,
hwnd
,
NULL
,
NULL
,
NULL
);
ok_ne
(
NULL
,
hwnd
,
HWND
,
"%p"
);
wait_messages
(
100
,
FALSE
);
current_sequence_len
=
0
;
old_other_proc
=
SetWindowLongPtrW
(
other
,
GWLP_WNDPROC
,
(
LONG_PTR
)
append_message_wndproc
);
ok_ne
(
0
,
old_other_proc
,
LONG_PTR
,
"%#Ix"
);
SetCapture
(
hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTDOWN
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_down_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_down_hwnd
);
mouse_event
(
MOUSEEVENTF_LEFTUP
,
0
,
0
,
0
,
0
);
wait_messages
(
5
,
FALSE
);
button_up_hwnd
[
1
].
message
.
hwnd
=
hwnd
;
ok_seq
(
button_up_hwnd
);
ok_ret
(
1
,
DestroyWindow
(
other
)
);
wait_messages
(
0
,
FALSE
);
SetCapture
(
0
);
SetCursorPos
(
200
,
200
);
hwnd
=
CreateWindowA
(
"static"
,
"Title"
,
WS_OVERLAPPEDWINDOW
|
WS_VISIBLE
,
100
,
100
,
200
,
200
,
NULL
,
NULL
,
NULL
,
NULL
);
ok
(
hwnd
!=
NULL
,
"CreateWindowA failed %lu
\n
"
,
GetLastError
());
/* warm up test case by moving cursor and window a bit first */
SetCursorPos
(
210
,
200
);
SetWindowPos
(
hwnd
,
NULL
,
110
,
100
,
0
,
0
,
SWP_NOSIZE
);
empty_message_queue
();
SetCursorPos
(
200
,
200
);
SetWindowPos
(
hwnd
,
NULL
,
100
,
100
,
0
,
0
,
SWP_NOSIZE
);
empty_message_queue
();
SetWindowLongPtrA
(
hwnd
,
GWLP_WNDPROC
,
(
LONG_PTR
)
mouse_move_wndproc
);
ok_ret
(
1
,
SetCursorPos
(
60
,
50
)
);
ok_ret
(
1
,
SetWindowPos
(
hwnd
,
NULL
,
10
,
0
,
0
,
0
,
SWP_NOSIZE
)
);
wait_messages
(
5
,
FALSE
);
ok_ret
(
1
,
SetCursorPos
(
50
,
50
)
);
ok_ret
(
1
,
SetWindowPos
(
hwnd
,
NULL
,
0
,
0
,
0
,
0
,
SWP_NOSIZE
)
);
wait_messages
(
5
,
FALSE
);
SetWindowLongPtrW
(
hwnd
,
GWLP_WNDPROC
,
(
LONG_PTR
)
mouse_move_wndproc
);
ok_ret
(
1
,
SetCursorPos
(
60
,
50
)
);
ok_ret
(
1
,
SetWindowPos
(
hwnd
,
NULL
,
10
,
0
,
0
,
0
,
SWP_NOSIZE
)
);
wait_messages
(
5
,
FALSE
);
ok_ret
(
1
,
GetCursorPos
(
&
pt
)
);
ok_point
(
expect_60x50
,
pt
);
ok_ret
(
1
,
SetCursorPos
(
50
,
50
)
);
ok_ret
(
1
,
SetWindowPos
(
hwnd
,
NULL
,
0
,
0
,
0
,
0
,
SWP_NOSIZE
)
);
wait_messages
(
5
,
FALSE
);
ok_ret
(
1
,
GetCursorPos
(
&
pt
)
);
ok_point
(
expect_50x50
,
pt
);
SetCursorPos
(
210
,
200
);
SetWindowPos
(
hwnd
,
NULL
,
110
,
100
,
0
,
0
,
SWP_NOSIZE
);
empty_message_queue
();
GetCursorPos
(
&
pt
);
ok
(
pt
.
x
==
210
&&
pt
.
y
==
200
,
"GetCursorPos returned %ldx%ld, expected 210x200
\n
"
,
pt
.
x
,
pt
.
y
);
SetCursorPos
(
200
,
200
);
SetWindowPos
(
hwnd
,
NULL
,
100
,
100
,
0
,
0
,
SWP_NOSIZE
);
empty_message_queue
();
GetCursorPos
(
&
pt
);
ok
(
pt
.
x
==
200
&&
pt
.
y
==
200
,
"GetCursorPos returned %ldx%ld, expected 200x200
\n
"
,
pt
.
x
,
pt
.
y
);
ok_ret
(
1
,
UnhookWindowsHookEx
(
hook
)
);
SetCursorPos
(
pt_org
.
x
,
pt_org
.
y
);
empty_message_queue
();
DestroyWindow
(
hwnd
);
wait_messages
(
100
,
FALSE
);
todo_wine
ok_seq
(
empty_sequence
);
p_accept_message
=
NULL
;
append_message_hwnd
=
FALSE
;
ok_ret
(
1
,
DestroyWindow
(
hwnd
)
);
CloseHandle
(
params
.
start_event
);
CloseHandle
(
params
.
end_event
);
ok_ret
(
1
,
SetDoubleClickTime
(
dblclk_time
)
);
}
...
...
@@ -5234,6 +5357,7 @@ static void test_input_desktop( char **argv )
get_test_scan
(
'F'
,
&
scan
,
&
wch
,
&
wch_shift
);
test_SendInput
(
'F'
,
wch
);
test_SendInput_keyboard_messages
(
'F'
,
scan
,
wch
,
wch_shift
,
'\x06'
);
test_SendInput_mouse_messages
();
test_keyboard_ll_hook_blocking
();
...
...
@@ -5291,7 +5415,6 @@ START_TEST(input)
return
test_input_desktop
(
argv
);
run_in_desktop
(
argv
,
"test_input_desktop"
,
1
);
test_Input_mouse
();
test_keynames
();
test_mouse_ll_hook
();
test_key_map
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment