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
0e81484c
Commit
0e81484c
authored
Apr 12, 2006
by
Thomas Kho
Committed by
Alexandre Julliard
Apr 14, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x11drv: Properly handle VK_LMENU input.
parent
513c35a3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
190 additions
and
4 deletions
+190
-4
input.c
dlls/user/tests/input.c
+161
-1
keyboard.c
dlls/x11drv/keyboard.c
+17
-3
queue.c
server/queue.c
+12
-0
No files found.
dlls/user/tests/input.c
View file @
0e81484c
...
@@ -336,7 +336,7 @@ static LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam,
...
@@ -336,7 +336,7 @@ static LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam,
return
0
;
return
0
;
}
}
START_TEST
(
input
)
static
void
test_Input_whitebox
(
void
)
{
{
MSG
msg
;
MSG
msg
;
WNDCLASSA
wclass
;
WNDCLASSA
wclass
;
...
@@ -366,3 +366,163 @@ START_TEST(input)
...
@@ -366,3 +366,163 @@ START_TEST(input)
SendMessageA
(
hWndTest
,
WM_USER
,
0
,
0
);
SendMessageA
(
hWndTest
,
WM_USER
,
0
,
0
);
DestroyWindow
(
hWndTest
);
DestroyWindow
(
hWndTest
);
}
}
static
void
empty_message_queue
(
void
)
{
MSG
msg
;
while
(
PeekMessage
(
&
msg
,
NULL
,
0
,
0
,
PM_REMOVE
))
{
TranslateMessage
(
&
msg
);
DispatchMessage
(
&
msg
);
}
}
struct
transition_s
{
WORD
wVk
;
BYTE
before_state
;
BOOL
_todo_wine
;
};
struct
sendinput_test_s
{
WORD
wVk
;
DWORD
dwFlags
;
struct
transition_s
expected_transitions
[
MAXKEYEVENTS
+
1
];
UINT
expected_messages
[
MAXKEYMESSAGES
+
1
];
}
sendinput_test
[]
=
{
/* test ALT+F */
{
VK_LMENU
,
0
,
{{
VK_MENU
,
0x00
,
0
},
{
VK_LMENU
,
0x00
,
0
},
{
0
}},
{
WM_SYSKEYDOWN
,
0
}},
{
'F'
,
0
,
{{
'F'
,
0x00
,
0
},
{
0
}},
{
WM_SYSKEYDOWN
,
WM_SYSCHAR
,
WM_SYSCOMMAND
,
0
}},
{
'F'
,
KEYEVENTF_KEYUP
,
{{
'F'
,
0x80
,
0
},
{
0
}},
{
WM_SYSKEYUP
,
0
}},
{
VK_LMENU
,
KEYEVENTF_KEYUP
,
{{
VK_MENU
,
0x80
,
0
},
{
VK_LMENU
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
/* test CTRL+O */
{
VK_LCONTROL
,
0
,
{{
VK_CONTROL
,
0x00
,
0
},
{
VK_LCONTROL
,
0x00
,
0
},
{
0
}},
{
WM_KEYDOWN
,
0
}},
{
'O'
,
0
,
{{
'O'
,
0x00
,
0
},
{
0
}},
{
WM_KEYDOWN
,
WM_CHAR
,
0
}},
{
'O'
,
KEYEVENTF_KEYUP
,
{{
'O'
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
{
VK_LCONTROL
,
KEYEVENTF_KEYUP
,
{{
VK_CONTROL
,
0x80
,
0
},
{
VK_LCONTROL
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
/* test ALT+CTRL+X */
{
VK_LMENU
,
0
,
{{
VK_MENU
,
0x00
,
0
},
{
VK_LMENU
,
0x00
,
0
},
{
0
}},
{
WM_SYSKEYDOWN
,
0
}},
{
VK_LCONTROL
,
0
,
{{
VK_CONTROL
,
0x00
,
0
},
{
VK_LCONTROL
,
0x00
,
0
},
{
0
}},
{
WM_KEYDOWN
,
0
}},
{
'X'
,
0
,
{{
'X'
,
0x00
,
0
},
{
0
}},
{
WM_KEYDOWN
,
0
}},
{
'X'
,
KEYEVENTF_KEYUP
,
{{
'X'
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
{
VK_LCONTROL
,
KEYEVENTF_KEYUP
,
{{
VK_CONTROL
,
0x80
,
0
},
{
VK_LCONTROL
,
0x80
,
0
},
{
0
}},
{
WM_SYSKEYUP
,
0
}},
{
VK_LMENU
,
KEYEVENTF_KEYUP
,
{{
VK_MENU
,
0x80
,
0
},
{
VK_LMENU
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
/* test SHIFT+A */
{
VK_LSHIFT
,
0
,
{{
VK_SHIFT
,
0x00
,
0
},
{
VK_LSHIFT
,
0x00
,
0
},
{
0
}},
{
WM_KEYDOWN
,
0
}},
{
'A'
,
0
,
{{
'A'
,
0x00
,
0
},
{
0
}},
{
WM_KEYDOWN
,
WM_CHAR
,
0
}},
{
'A'
,
KEYEVENTF_KEYUP
,
{{
'A'
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
{
VK_LSHIFT
,
KEYEVENTF_KEYUP
,
{{
VK_SHIFT
,
0x80
,
0
},
{
VK_LSHIFT
,
0x80
,
0
},
{
0
}},
{
WM_KEYUP
,
0
}},
{
0
,
0
,
{{
0
}},
{
0
}}
/* end */
};
static
struct
sendinput_test_s
*
pTest
=
sendinput_test
;
static
UINT
*
pMsg
=
sendinput_test
[
0
].
expected_messages
;
/* Verify that only specified key state transitions occur */
static
void
compare_and_check
(
int
id
,
BYTE
*
ks1
,
BYTE
*
ks2
,
struct
transition_s
*
t
)
{
int
i
;
while
(
t
->
wVk
)
{
int
matched
=
((
ks1
[
t
->
wVk
]
&
0x80
)
==
(
t
->
before_state
&
0x80
)
&&
(
ks2
[
t
->
wVk
]
&
0x80
)
==
(
~
t
->
before_state
&
0x80
));
if
(
t
->
_todo_wine
)
{
todo_wine
{
ok
(
matched
,
"%02d: %02x from %02x -> %02x "
"instead of %02x -> %02x
\n
"
,
id
,
t
->
wVk
,
ks1
[
t
->
wVk
]
&
0x80
,
ks2
[
t
->
wVk
]
&
0x80
,
t
->
before_state
,
~
t
->
before_state
&
0x80
);
}
}
else
{
ok
(
matched
,
"%02d: %02x from %02x -> %02x "
"instead of %02x -> %02x
\n
"
,
id
,
t
->
wVk
,
ks1
[
t
->
wVk
]
&
0x80
,
ks2
[
t
->
wVk
]
&
0x80
,
t
->
before_state
,
~
t
->
before_state
&
0x80
);
}
ks2
[
t
->
wVk
]
=
ks1
[
t
->
wVk
];
/* clear the match */
t
++
;
}
for
(
i
=
0
;
i
<
256
;
i
++
)
ok
(
ks2
[
i
]
==
ks1
[
i
],
"%02d: %02x from %02x -> %02x unexpected
\n
"
,
id
,
i
,
ks1
[
i
],
ks2
[
i
]);
}
/* WndProc2 checks that we get at least the messages specified */
static
LRESULT
CALLBACK
WndProc2
(
HWND
hWnd
,
UINT
Msg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
if
(
pTest
->
wVk
!=
0
)
{
/* not end */
while
(
pTest
->
wVk
!=
0
&&
*
pMsg
==
0
)
{
pTest
++
;
pMsg
=
pTest
->
expected_messages
;
}
if
(
Msg
==
*
pMsg
)
pMsg
++
;
}
return
DefWindowProc
(
hWnd
,
Msg
,
wParam
,
lParam
);
}
static
void
test_Input_blackbox
(
void
)
{
INPUT
i
;
int
ii
;
BYTE
ks1
[
256
],
ks2
[
256
];
LONG_PTR
prevWndProc
;
HWND
window
;
window
=
CreateWindow
(
"Static"
,
NULL
,
WS_POPUP
|
WS_HSCROLL
|
WS_VSCROLL
|
WS_VISIBLE
,
0
,
0
,
200
,
60
,
NULL
,
NULL
,
NULL
,
NULL
);
ok
(
window
!=
NULL
,
"error: %d
\n
"
,
(
int
)
GetLastError
());
/* must process all initial messages, otherwise X11DRV_KeymapNotify unsets
* key state set by SendInput(). */
empty_message_queue
();
prevWndProc
=
SetWindowLongPtr
(
window
,
GWLP_WNDPROC
,
(
LONG_PTR
)
WndProc2
);
ok
(
prevWndProc
!=
0
||
(
prevWndProc
==
0
&&
GetLastError
()
==
0
),
"error: %d
\n
"
,
(
int
)
GetLastError
());
i
.
type
=
INPUT_KEYBOARD
;
i
.
ki
.
wScan
=
0
;
i
.
ki
.
time
=
0
;
i
.
ki
.
dwExtraInfo
=
0
;
for
(
ii
=
0
;
ii
<
sizeof
(
sendinput_test
)
/
sizeof
(
struct
sendinput_test_s
)
-
1
;
ii
++
)
{
GetKeyboardState
(
ks1
);
i
.
ki
.
dwFlags
=
sendinput_test
[
ii
].
dwFlags
;
i
.
ki
.
wVk
=
sendinput_test
[
ii
].
wVk
;
SendInput
(
1
,
&
i
,
sizeof
(
INPUT
));
empty_message_queue
();
GetKeyboardState
(
ks2
);
compare_and_check
(
ii
,
ks1
,
ks2
,
sendinput_test
[
ii
].
expected_transitions
);
}
/* *pMsg should be 0 and (++pTest)->wVk should be 0 */
if
(
pTest
->
wVk
&&
*
pMsg
==
0
)
pTest
++
;
while
(
pTest
->
wVk
&&
pTest
->
expected_messages
[
0
]
==
0
)
{
++
pTest
;
}
ok
(
*
pMsg
==
0
&&
pTest
->
wVk
==
0
,
"not enough messages found; looking for %x
\n
"
,
*
pMsg
);
DestroyWindow
(
window
);
}
START_TEST
(
input
)
{
test_Input_whitebox
();
test_Input_blackbox
();
}
dlls/x11drv/keyboard.c
View file @
0e81484c
...
@@ -1113,6 +1113,17 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
...
@@ -1113,6 +1113,17 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
UINT
message
;
UINT
message
;
KEYLP
keylp
;
KEYLP
keylp
;
KBDLLHOOKSTRUCT
hook
;
KBDLLHOOKSTRUCT
hook
;
WORD
wVkStripped
;
/* strip left/right for menu, control, shift */
if
(
wVk
==
VK_LMENU
||
wVk
==
VK_RMENU
)
wVkStripped
=
VK_MENU
;
else
if
(
wVk
==
VK_LCONTROL
||
wVk
==
VK_RCONTROL
)
wVkStripped
=
VK_CONTROL
;
else
if
(
wVk
==
VK_LSHIFT
||
wVk
==
VK_RSHIFT
)
wVkStripped
=
VK_SHIFT
;
else
wVkStripped
=
wVk
;
keylp
.
lp2
=
0
;
keylp
.
lp2
=
0
;
keylp
.
lp1
.
count
=
1
;
keylp
.
lp1
.
count
=
1
;
...
@@ -1128,14 +1139,16 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
...
@@ -1128,14 +1139,16 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
{
{
message
=
WM_KEYUP
;
message
=
WM_KEYUP
;
if
((
key_state_table
[
VK_MENU
]
&
0x80
)
&&
if
((
key_state_table
[
VK_MENU
]
&
0x80
)
&&
((
wVk
==
VK_MENU
)
||
(
wVk
==
VK_CONTROL
)
||
!
(
key_state_table
[
VK_CONTROL
]
&
0x80
)))
((
wVkStripped
==
VK_MENU
)
||
(
wVkStripped
==
VK_CONTROL
)
||
!
(
key_state_table
[
VK_CONTROL
]
&
0x80
)))
{
{
if
(
TrackSysKey
==
VK_MENU
||
/* <ALT>-down/<ALT>-up sequence */
if
(
TrackSysKey
==
VK_MENU
||
/* <ALT>-down/<ALT>-up sequence */
(
wVk
!=
VK_MENU
))
/* <ALT>-down...<something else>-up */
(
wVk
Stripped
!=
VK_MENU
))
/* <ALT>-down...<something else>-up */
message
=
WM_SYSKEYUP
;
message
=
WM_SYSKEYUP
;
TrackSysKey
=
0
;
TrackSysKey
=
0
;
}
}
key_state_table
[
wVk
]
&=
~
0x80
;
key_state_table
[
wVk
]
&=
~
0x80
;
key_state_table
[
wVkStripped
]
&=
~
0x80
;
keylp
.
lp1
.
previous
=
1
;
keylp
.
lp1
.
previous
=
1
;
keylp
.
lp1
.
transition
=
1
;
keylp
.
lp1
.
transition
=
1
;
}
}
...
@@ -1145,12 +1158,13 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
...
@@ -1145,12 +1158,13 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
keylp
.
lp1
.
transition
=
0
;
keylp
.
lp1
.
transition
=
0
;
if
(
!
(
key_state_table
[
wVk
]
&
0x80
))
key_state_table
[
wVk
]
^=
0x01
;
if
(
!
(
key_state_table
[
wVk
]
&
0x80
))
key_state_table
[
wVk
]
^=
0x01
;
key_state_table
[
wVk
]
|=
0xc0
;
key_state_table
[
wVk
]
|=
0xc0
;
key_state_table
[
wVkStripped
]
|=
0xc0
;
message
=
WM_KEYDOWN
;
message
=
WM_KEYDOWN
;
if
((
key_state_table
[
VK_MENU
]
&
0x80
)
&&
!
(
key_state_table
[
VK_CONTROL
]
&
0x80
))
if
((
key_state_table
[
VK_MENU
]
&
0x80
)
&&
!
(
key_state_table
[
VK_CONTROL
]
&
0x80
))
{
{
message
=
WM_SYSKEYDOWN
;
message
=
WM_SYSKEYDOWN
;
TrackSysKey
=
wVk
;
TrackSysKey
=
wVk
Stripped
;
}
}
}
}
...
...
server/queue.c
View file @
0e81484c
...
@@ -1132,6 +1132,18 @@ static void update_input_key_state( struct thread_input *input, const struct mes
...
@@ -1132,6 +1132,18 @@ static void update_input_key_state( struct thread_input *input, const struct mes
case
VK_MENU
:
case
VK_MENU
:
set_input_key_state
(
input
,
extended
?
VK_RMENU
:
VK_LMENU
,
down
);
set_input_key_state
(
input
,
extended
?
VK_RMENU
:
VK_LMENU
,
down
);
break
;
break
;
case
VK_LCONTROL
:
case
VK_RCONTROL
:
set_input_key_state
(
input
,
VK_CONTROL
,
down
);
break
;
case
VK_LMENU
:
case
VK_RMENU
:
set_input_key_state
(
input
,
VK_MENU
,
down
);
break
;
case
VK_LSHIFT
:
case
VK_RSHIFT
:
set_input_key_state
(
input
,
VK_SHIFT
,
down
);
break
;
}
}
break
;
break
;
}
}
...
...
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