Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
c7efa293
Commit
c7efa293
authored
Mar 02, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Invoke low-level hardware hooks directly from the server side.
parent
ae895a1f
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
211 additions
and
143 deletions
+211
-143
message.c
dlls/user32/message.c
+48
-0
keyboard.c
dlls/winex11.drv/keyboard.c
+0
-9
mouse.c
dlls/winex11.drv/mouse.c
+21
-84
server_protocol.h
include/wine/server_protocol.h
+7
-4
hook.c
server/hook.c
+11
-0
protocol.def
server/protocol.def
+5
-3
queue.c
server/queue.c
+110
-40
request.h
server/request.h
+2
-1
trace.c
server/trace.c
+6
-2
user.h
server/user.h
+1
-0
No files found.
dlls/user32/message.c
View file @
c7efa293
...
...
@@ -2709,6 +2709,38 @@ static BOOL peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags
info
.
msg
.
lParam
,
msg_data
->
winevent
.
tid
,
info
.
msg
.
time
);
}
continue
;
case
MSG_HOOK_LL
:
info
.
flags
=
ISMEX_SEND
;
result
=
0
;
if
(
info
.
msg
.
message
==
WH_KEYBOARD_LL
&&
size
>=
sizeof
(
msg_data
->
hardware
))
{
KBDLLHOOKSTRUCT
hook
;
hook
.
vkCode
=
LOWORD
(
info
.
msg
.
lParam
);
hook
.
scanCode
=
HIWORD
(
info
.
msg
.
lParam
);
hook
.
flags
=
msg_data
->
hardware
.
flags
;
hook
.
time
=
info
.
msg
.
time
;
hook
.
dwExtraInfo
=
msg_data
->
hardware
.
info
;
TRACE
(
"calling keyboard LL hook vk %x scan %x flags %x time %u info %lx
\n
"
,
hook
.
vkCode
,
hook
.
scanCode
,
hook
.
flags
,
hook
.
time
,
hook
.
dwExtraInfo
);
result
=
HOOK_CallHooks
(
WH_KEYBOARD_LL
,
HC_ACTION
,
info
.
msg
.
wParam
,
(
LPARAM
)
&
hook
,
TRUE
);
}
else
if
(
info
.
msg
.
message
==
WH_MOUSE_LL
&&
size
>=
sizeof
(
msg_data
->
hardware
))
{
MSLLHOOKSTRUCT
hook
;
hook
.
pt
.
x
=
msg_data
->
hardware
.
x
;
hook
.
pt
.
y
=
msg_data
->
hardware
.
y
;
hook
.
mouseData
=
info
.
msg
.
lParam
;
hook
.
flags
=
msg_data
->
hardware
.
flags
;
hook
.
time
=
info
.
msg
.
time
;
hook
.
dwExtraInfo
=
msg_data
->
hardware
.
info
;
TRACE
(
"calling mouse LL hook pos %d,%d data %x flags %x time %u info %lx
\n
"
,
hook
.
pt
.
x
,
hook
.
pt
.
y
,
hook
.
mouseData
,
hook
.
flags
,
hook
.
time
,
hook
.
dwExtraInfo
);
result
=
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
info
.
msg
.
wParam
,
(
LPARAM
)
&
hook
,
TRUE
);
}
reply_message
(
&
info
,
result
,
TRUE
);
continue
;
case
MSG_OTHER_PROCESS
:
info
.
flags
=
ISMEX_SEND
;
if
(
!
unpack_message
(
info
.
msg
.
hwnd
,
info
.
msg
.
message
,
&
info
.
msg
.
wParam
,
...
...
@@ -3072,7 +3104,15 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
*/
NTSTATUS
send_hardware_message
(
HWND
hwnd
,
const
INPUT
*
input
,
UINT
flags
)
{
struct
send_message_info
info
;
NTSTATUS
ret
;
BOOL
wait
;
info
.
type
=
MSG_HARDWARE
;
info
.
dest_tid
=
0
;
info
.
hwnd
=
hwnd
;
info
.
flags
=
0
;
info
.
timeout
=
0
;
SERVER_START_REQ
(
send_hardware_message
)
{
...
...
@@ -3102,8 +3142,16 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
break
;
}
ret
=
wine_server_call
(
req
);
wait
=
reply
->
wait
;
}
SERVER_END_REQ
;
if
(
wait
)
{
LRESULT
ignored
;
wait_message_reply
(
0
);
retrieve_reply
(
&
info
,
0
,
&
ignored
);
}
return
ret
;
}
...
...
dlls/winex11.drv/keyboard.c
View file @
c7efa293
...
...
@@ -1155,7 +1155,6 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
{
UINT
message
;
INPUT
input
;
KBDLLHOOKSTRUCT
hook
;
WORD
flags
,
wVkStripped
,
wVkL
,
wVkR
,
vk_hook
=
wVk
;
if
(
!
time
)
time
=
GetTickCount
();
...
...
@@ -1227,14 +1226,6 @@ void X11DRV_send_keyboard_input( HWND hwnd, WORD wVk, WORD wScan, DWORD event_fl
if
(
event_flags
&
KEYEVENTF_UNICODE
)
vk_hook
=
wVk
=
VK_PACKET
;
/* Hook gets whatever key was sent. */
hook
.
vkCode
=
vk_hook
;
hook
.
scanCode
=
wScan
;
hook
.
flags
=
(
flags
>>
8
)
|
injected_flags
;
hook
.
time
=
time
;
hook
.
dwExtraInfo
=
dwExtraInfo
;
if
(
HOOK_CallHooks
(
WH_KEYBOARD_LL
,
HC_ACTION
,
message
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
input
.
type
=
INPUT_KEYBOARD
;
input
.
u
.
ki
.
wVk
=
vk_hook
;
input
.
u
.
ki
.
wScan
=
wScan
;
...
...
dlls/winex11.drv/mouse.c
View file @
c7efa293
...
...
@@ -293,7 +293,6 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
{
POINT
pt
;
INPUT
input
;
MSLLHOOKSTRUCT
hook
;
if
(
!
time
)
time
=
GetTickCount
();
...
...
@@ -308,34 +307,29 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
{
pt
.
x
=
x
;
pt
.
y
=
y
;
wine_tsx11_lock
();
if
(
cursor_pos
.
x
==
x
&&
cursor_pos
.
y
==
y
&&
(
flags
&
~
(
MOUSEEVENTF_MOVE
|
MOUSEEVENTF_ABSOLUTE
)))
flags
&=
~
MOUSEEVENTF_MOVE
;
wine_tsx11_unlock
();
}
}
else
if
(
flags
&
MOUSEEVENTF_MOVE
)
{
int
accel
[
3
]
,
xMult
=
1
,
yMult
=
1
;
int
accel
[
3
];
/* dx and dy can be negative numbers for relative movements */
SystemParametersInfoW
(
SPI_GETMOUSE
,
0
,
accel
,
0
);
if
(
abs
(
x
)
>
accel
[
0
]
&&
accel
[
2
]
!=
0
)
{
x
Mult
=
2
;
if
((
abs
(
x
)
>
accel
[
1
])
&&
(
accel
[
2
]
==
2
))
x
Mult
=
4
;
x
=
(
int
)
x
*
2
;
if
((
abs
(
x
)
>
accel
[
1
])
&&
(
accel
[
2
]
==
2
))
x
=
(
int
)
x
*
2
;
}
if
(
abs
(
y
)
>
accel
[
0
]
&&
accel
[
2
]
!=
0
)
{
y
Mult
=
2
;
if
((
abs
(
y
)
>
accel
[
1
])
&&
(
accel
[
2
]
==
2
))
y
Mult
=
4
;
y
=
(
int
)
y
*
2
;
if
((
abs
(
y
)
>
accel
[
1
])
&&
(
accel
[
2
]
==
2
))
y
=
(
int
)
y
*
2
;
}
wine_tsx11_lock
();
pt
.
x
=
cursor_pos
.
x
+
(
long
)
x
*
xMult
;
pt
.
y
=
cursor_pos
.
y
+
(
long
)
y
*
yMult
;
pt
.
x
=
cursor_pos
.
x
+
x
;
pt
.
y
=
cursor_pos
.
y
+
y
;
wine_tsx11_unlock
();
}
else
...
...
@@ -345,85 +339,28 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
wine_tsx11_unlock
();
}
hook
.
pt
.
x
=
pt
.
x
;
hook
.
pt
.
y
=
pt
.
y
;
hook
.
mouseData
=
MAKELONG
(
0
,
data
);
hook
.
flags
=
injected_flags
;
hook
.
time
=
time
;
hook
.
dwExtraInfo
=
extra_info
;
last_time_modified
=
GetTickCount
();
if
(
flags
&
MOUSEEVENTF_MOVE
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
WM_MOUSEMOVE
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
if
((
injected_flags
&
LLMHF_INJECTED
)
&&
((
flags
&
MOUSEEVENTF_ABSOLUTE
)
||
x
||
y
))
/* we have to actually move the cursor */
{
clip_point_to_rect
(
&
cursor_clip
,
&
pt
);
X11DRV_SetCursorPos
(
pt
.
x
,
pt
.
y
);
}
else
{
wine_tsx11_lock
();
clip_point_to_rect
(
&
cursor_clip
,
&
pt
);
cursor_pos
=
pt
;
wine_tsx11_unlock
();
}
}
if
(
flags
&
MOUSEEVENTF_LEFTDOWN
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
GetSystemMetrics
(
SM_SWAPBUTTON
)
?
WM_RBUTTONDOWN
:
WM_LBUTTONDOWN
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_LEFTUP
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
GetSystemMetrics
(
SM_SWAPBUTTON
)
?
WM_RBUTTONUP
:
WM_LBUTTONUP
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_RIGHTDOWN
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
GetSystemMetrics
(
SM_SWAPBUTTON
)
?
WM_LBUTTONDOWN
:
WM_RBUTTONDOWN
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_RIGHTUP
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
GetSystemMetrics
(
SM_SWAPBUTTON
)
?
WM_LBUTTONUP
:
WM_RBUTTONUP
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_MIDDLEDOWN
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
WM_MBUTTONDOWN
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_MIDDLEUP
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
WM_MBUTTONUP
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_WHEEL
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
WM_MOUSEWHEEL
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_XDOWN
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
WM_XBUTTONDOWN
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
if
(
flags
&
MOUSEEVENTF_XUP
)
{
if
(
HOOK_CallHooks
(
WH_MOUSE_LL
,
HC_ACTION
,
WM_XBUTTONUP
,
(
LPARAM
)
&
hook
,
TRUE
))
return
;
}
input
.
type
=
INPUT_MOUSE
;
input
.
u
.
mi
.
dx
=
pt
.
x
;
input
.
u
.
mi
.
dy
=
pt
.
y
;
input
.
u
.
mi
.
dx
=
x
;
input
.
u
.
mi
.
dy
=
y
;
input
.
u
.
mi
.
mouseData
=
data
;
input
.
u
.
mi
.
dwFlags
=
flags
|
MOUSEEVENTF_ABSOLUTE
;
input
.
u
.
mi
.
dwFlags
=
flags
;
input
.
u
.
mi
.
time
=
time
;
input
.
u
.
mi
.
dwExtraInfo
=
extra_info
;
__wine_send_input
(
hwnd
,
&
input
,
(
injected_flags
&
LLMHF_INJECTED
)
!=
0
);
if
(
injected_flags
&
LLMHF_INJECTED
)
{
if
((
flags
&
MOUSEEVENTF_MOVE
)
&&
((
flags
&
MOUSEEVENTF_ABSOLUTE
)
||
x
||
y
))
/* we have to actually move the cursor */
{
GetCursorPos
(
&
pt
);
if
(
!
(
flags
&
MOUSEEVENTF_ABSOLUTE
)
||
pt
.
x
!=
x
||
pt
.
y
!=
y
)
X11DRV_SetCursorPos
(
pt
.
x
,
pt
.
y
);
}
}
}
#ifdef SONAME_LIBXCURSOR
...
...
include/wine/server_protocol.h
View file @
c7efa293
...
...
@@ -283,7 +283,7 @@ struct hardware_msg_data
int
x
;
int
y
;
unsigned
int
hw_id
;
int
__pad
;
unsigned
int
flags
;
};
struct
callback_msg_data
...
...
@@ -2782,7 +2782,8 @@ enum message_type
MSG_OTHER_PROCESS
,
MSG_POSTED
,
MSG_HARDWARE
,
MSG_WINEVENT
MSG_WINEVENT
,
MSG_HOOK_LL
};
#define SEND_MSG_ABORT_IF_HUNG 0x01
...
...
@@ -2794,11 +2795,13 @@ struct send_hardware_message_request
user_handle_t
win
;
hw_input_t
input
;
unsigned
int
flags
;
unsigned
int
msg
;
char
__pad_52
[
4
]
;
};
struct
send_hardware_message_reply
{
struct
reply_header
__header
;
int
wait
;
char
__pad_12
[
4
];
};
#define SEND_HWMSG_INJECTED 0x01
...
...
@@ -5556,6 +5559,6 @@ union generic_reply
struct
set_cursor_reply
set_cursor_reply
;
};
#define SERVER_PROTOCOL_VERSION 41
6
#define SERVER_PROTOCOL_VERSION 41
7
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/hook.c
View file @
c7efa293
...
...
@@ -369,6 +369,17 @@ unsigned int get_active_hooks(void)
return
ret
;
}
/* return the thread that owns the first global hook */
struct
thread
*
get_first_global_hook
(
int
id
)
{
struct
hook
*
hook
;
struct
hook_table
*
global_hooks
=
get_global_hooks
(
current
);
if
(
!
global_hooks
)
return
NULL
;
if
(
!
(
hook
=
get_first_valid_hook
(
global_hooks
,
id
-
WH_MINHOOK
,
EVENT_MIN
,
0
,
0
,
0
)))
return
NULL
;
return
hook
->
owner
;
}
/* set a window hook */
DECL_HANDLER
(
set_hook
)
{
...
...
server/protocol.def
View file @
c7efa293
...
...
@@ -299,7 +299,7 @@ struct hardware_msg_data
int x; /* x position */
int y; /* y position */
unsigned int hw_id; /* unique id */
int __pad;
unsigned int flags; /* hook flags */
};
struct callback_msg_data
...
...
@@ -2024,7 +2024,8 @@ enum message_type
MSG_OTHER_PROCESS, /* sent from other process, may include vararg data, always Unicode */
MSG_POSTED, /* posted message (from PostMessageW), always Unicode */
MSG_HARDWARE, /* hardware message */
MSG_WINEVENT /* winevent message */
MSG_WINEVENT, /* winevent message */
MSG_HOOK_LL /* low-level hardware hook */
};
#define SEND_MSG_ABORT_IF_HUNG 0x01
...
...
@@ -2034,7 +2035,8 @@ enum message_type
user_handle_t win; /* window handle */
hw_input_t input; /* input data */
unsigned int flags; /* flags (see below) */
unsigned int msg; /* message code */
@REPLY
int wait; /* do we need to wait for a reply? */
@END
#define SEND_HWMSG_INJECTED 0x01
...
...
server/queue.c
View file @
c7efa293
...
...
@@ -58,6 +58,8 @@ struct message_result
int
replied
;
/* has it been replied to? */
unsigned
int
error
;
/* error code to pass back to sender */
lparam_t
result
;
/* reply result */
struct
message
*
hardware_msg
;
/* hardware message if low-level hook result */
struct
desktop
*
desktop
;
/* desktop for hardware message */
struct
message
*
callback_msg
;
/* message to queue for callback */
void
*
data
;
/* message reply data */
unsigned
int
data_size
;
/* size of message reply data */
...
...
@@ -201,6 +203,7 @@ static const struct object_ops thread_input_ops =
/* pointer to input structure of foreground thread */
static
unsigned
int
last_input_time
;
static
void
queue_hardware_message
(
struct
desktop
*
desktop
,
struct
message
*
msg
);
static
void
free_message
(
struct
message
*
msg
);
/* set the caret window in a given thread input */
...
...
@@ -436,6 +439,8 @@ static void free_result( struct message_result *result )
if
(
result
->
timeout
)
remove_timeout_user
(
result
->
timeout
);
free
(
result
->
data
);
if
(
result
->
callback_msg
)
free_message
(
result
->
callback_msg
);
if
(
result
->
hardware_msg
)
free_message
(
result
->
hardware_msg
);
if
(
result
->
desktop
)
release_object
(
result
->
desktop
);
free
(
result
);
}
...
...
@@ -460,6 +465,17 @@ static void store_message_result( struct message_result *res, lparam_t result, u
remove_timeout_user
(
res
->
timeout
);
res
->
timeout
=
NULL
;
}
if
(
res
->
hardware_msg
)
{
if
(
!
error
&&
result
)
/* rejected by the hook */
free_message
(
res
->
hardware_msg
);
else
queue_hardware_message
(
res
->
desktop
,
res
->
hardware_msg
);
res
->
hardware_msg
=
NULL
;
}
if
(
res
->
sender
)
{
if
(
res
->
callback_msg
)
...
...
@@ -479,7 +495,7 @@ static void store_message_result( struct message_result *res, lparam_t result, u
set_queue_bits
(
res
->
sender
,
QS_SMRESULT
);
}
}
else
if
(
!
res
->
receiver
)
free_result
(
res
);
}
/* free a message when deleting a queue or window */
...
...
@@ -489,12 +505,8 @@ static void free_message( struct message *msg )
if
(
result
)
{
result
->
msg
=
NULL
;
if
(
result
->
sender
)
{
result
->
receiver
=
NULL
;
store_message_result
(
result
,
0
,
STATUS_ACCESS_DENIED
/*FIXME*/
);
}
else
free_result
(
result
);
result
->
receiver
=
NULL
;
store_message_result
(
result
,
0
,
STATUS_ACCESS_DENIED
/*FIXME*/
);
}
free
(
msg
->
data
);
free
(
msg
);
...
...
@@ -535,13 +547,7 @@ static void result_timeout( void *private )
msg
->
result
=
NULL
;
remove_queue_message
(
result
->
receiver
,
msg
,
SEND_MESSAGE
);
result
->
receiver
=
NULL
;
if
(
!
result
->
sender
)
{
free_result
(
result
);
return
;
}
}
store_message_result
(
result
,
0
,
STATUS_TIMEOUT
);
}
...
...
@@ -553,13 +559,16 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue
struct
message_result
*
result
=
mem_alloc
(
sizeof
(
*
result
)
);
if
(
result
)
{
result
->
msg
=
msg
;
result
->
sender
=
send_queue
;
result
->
receiver
=
recv_queue
;
result
->
replied
=
0
;
result
->
data
=
NULL
;
result
->
data_size
=
0
;
result
->
timeout
=
NULL
;
result
->
msg
=
msg
;
result
->
sender
=
send_queue
;
result
->
receiver
=
recv_queue
;
result
->
replied
=
0
;
result
->
data
=
NULL
;
result
->
data_size
=
0
;
result
->
timeout
=
NULL
;
result
->
hardware_msg
=
NULL
;
result
->
desktop
=
NULL
;
result
->
callback_msg
=
NULL
;
if
(
msg
->
type
==
MSG_CALLBACK
)
{
...
...
@@ -586,11 +595,7 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue
result
->
callback_msg
=
callback_msg
;
list_add_head
(
&
send_queue
->
callback_result
,
&
result
->
sender_entry
);
}
else
{
result
->
callback_msg
=
NULL
;
list_add_head
(
&
send_queue
->
send_result
,
&
result
->
sender_entry
);
}
else
if
(
send_queue
)
list_add_head
(
&
send_queue
->
send_result
,
&
result
->
sender_entry
);
if
(
timeout
!=
TIMEOUT_INFINITE
)
result
->
timeout
=
add_timeout_user
(
timeout
,
result_timeout
,
result
);
...
...
@@ -641,7 +646,7 @@ static void reply_message( struct msg_queue *queue, lparam_t result,
{
queue
->
recv_result
=
res
->
recv_next
;
res
->
receiver
=
NULL
;
if
(
!
res
->
sender
)
/* no one waiting for it */
if
(
!
res
->
sender
&&
!
res
->
hardware_msg
)
/* no one waiting for it */
{
free_result
(
res
);
return
;
...
...
@@ -1328,13 +1333,58 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
release_object
(
thread
);
}
/* send the low-level hook message for a given hardware message */
static
int
send_hook_ll_message
(
struct
desktop
*
desktop
,
struct
message
*
hardware_msg
,
const
hw_input_t
*
input
,
struct
msg_queue
*
sender
)
{
struct
thread
*
hook_thread
;
struct
msg_queue
*
queue
;
struct
message
*
msg
;
timeout_t
timeout
=
2000
*
-
10000
;
/* FIXME: load from registry */
int
id
=
(
input
->
type
==
INPUT_MOUSE
)
?
WH_MOUSE_LL
:
WH_KEYBOARD_LL
;
if
(
!
(
hook_thread
=
get_first_global_hook
(
id
)))
return
0
;
if
(
!
(
queue
=
hook_thread
->
queue
))
return
0
;
if
(
!
(
msg
=
mem_alloc
(
sizeof
(
*
msg
)
)))
return
0
;
msg
->
type
=
MSG_HOOK_LL
;
msg
->
win
=
0
;
msg
->
msg
=
id
;
msg
->
wparam
=
hardware_msg
->
msg
;
msg
->
time
=
hardware_msg
->
time
;
msg
->
data_size
=
hardware_msg
->
data_size
;
msg
->
result
=
NULL
;
if
(
input
->
type
==
INPUT_KEYBOARD
)
{
unsigned
short
vkey
=
input
->
kbd
.
vkey
;
if
(
input
->
kbd
.
flags
&
KEYEVENTF_UNICODE
)
vkey
=
VK_PACKET
;
msg
->
lparam
=
(
input
->
kbd
.
scan
<<
16
)
|
vkey
;
}
else
msg
->
lparam
=
input
->
mouse
.
data
;
if
(
!
(
msg
->
data
=
memdup
(
hardware_msg
->
data
,
hardware_msg
->
data_size
))
||
!
(
msg
->
result
=
alloc_message_result
(
sender
,
queue
,
msg
,
timeout
)))
{
free_message
(
msg
);
return
0
;
}
msg
->
result
->
hardware_msg
=
hardware_msg
;
msg
->
result
->
desktop
=
(
struct
desktop
*
)
grab_object
(
desktop
);
list_add_tail
(
&
queue
->
msg_list
[
SEND_MESSAGE
],
&
msg
->
entry
);
set_queue_bits
(
queue
,
QS_SENDMESSAGE
);
return
1
;
}
/* queue a hardware message for a mouse event */
static
void
queue_mouse_message
(
struct
desktop
*
desktop
,
user_handle_t
win
,
const
hw_input_t
*
input
)
static
int
queue_mouse_message
(
struct
desktop
*
desktop
,
user_handle_t
win
,
const
hw_input_t
*
input
,
unsigned
int
hook_flags
,
struct
msg_queue
*
sender
)
{
struct
hardware_msg_data
*
msg_data
;
struct
message
*
msg
;
unsigned
int
i
,
time
,
flags
;
int
x
,
y
;
int
wait
=
0
,
x
,
y
;
static
const
unsigned
int
messages
[]
=
{
...
...
@@ -1383,12 +1433,13 @@ static void queue_mouse_message( struct desktop *desktop, user_handle_t win, con
{
if
(
!
messages
[
i
])
continue
;
if
(
!
(
flags
&
(
1
<<
i
)))
continue
;
flags
&=
~
(
1
<<
i
);
if
(
!
(
msg
=
mem_alloc
(
sizeof
(
*
msg
)
)))
return
;
if
(
!
(
msg
=
mem_alloc
(
sizeof
(
*
msg
)
)))
return
0
;
if
(
!
(
msg_data
=
mem_alloc
(
sizeof
(
*
msg_data
)
)))
{
free
(
msg
);
return
;
return
0
;
}
memset
(
msg_data
,
0
,
sizeof
(
*
msg_data
)
);
...
...
@@ -1404,23 +1455,34 @@ static void queue_mouse_message( struct desktop *desktop, user_handle_t win, con
msg_data
->
x
=
x
;
msg_data
->
y
=
y
;
msg_data
->
info
=
input
->
mouse
.
info
;
if
(
hook_flags
&
SEND_HWMSG_INJECTED
)
msg_data
->
flags
=
LLMHF_INJECTED
;
queue_hardware_message
(
desktop
,
msg
);
/* specify a sender only when sending the last message */
if
(
!
(
flags
&
((
1
<<
sizeof
(
messages
)
/
sizeof
(
messages
[
0
]))
-
1
)))
{
if
(
!
(
wait
=
send_hook_ll_message
(
desktop
,
msg
,
input
,
sender
)))
queue_hardware_message
(
desktop
,
msg
);
}
else
if
(
!
send_hook_ll_message
(
desktop
,
msg
,
input
,
NULL
))
queue_hardware_message
(
desktop
,
msg
);
}
return
wait
;
}
/* queue a hardware message for a keyboard event */
static
void
queue_keyboard_message
(
struct
desktop
*
desktop
,
user_handle_t
win
,
const
hw_input_t
*
input
)
static
int
queue_keyboard_message
(
struct
desktop
*
desktop
,
user_handle_t
win
,
const
hw_input_t
*
input
,
unsigned
int
hook_flags
,
struct
msg_queue
*
sender
)
{
struct
hardware_msg_data
*
msg_data
;
struct
message
*
msg
;
unsigned
char
vkey
=
input
->
kbd
.
vkey
;
int
wait
;
if
(
!
(
msg
=
mem_alloc
(
sizeof
(
*
msg
)
)))
return
;
if
(
!
(
msg
=
mem_alloc
(
sizeof
(
*
msg
)
)))
return
0
;
if
(
!
(
msg_data
=
mem_alloc
(
sizeof
(
*
msg_data
)
)))
{
free
(
msg
);
return
;
return
0
;
}
memset
(
msg_data
,
0
,
sizeof
(
*
msg_data
)
);
...
...
@@ -1433,6 +1495,7 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
msg
->
data_size
=
sizeof
(
*
msg_data
);
msg_data
->
info
=
input
->
kbd
.
info
;
if
(
!
msg
->
time
)
msg
->
time
=
get_tick_count
();
if
(
hook_flags
&
SEND_HWMSG_INJECTED
)
msg_data
->
flags
=
LLKHF_INJECTED
;
if
(
input
->
kbd
.
flags
&
KEYEVENTF_UNICODE
)
{
...
...
@@ -1440,6 +1503,7 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
}
else
{
unsigned
int
flags
=
0
;
switch
(
vkey
)
{
case
VK_MENU
:
...
...
@@ -1458,12 +1522,14 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
vkey
=
(
input
->
kbd
.
flags
&
KEYEVENTF_EXTENDEDKEY
)
?
VK_RSHIFT
:
VK_LSHIFT
;
break
;
}
if
(
input
->
kbd
.
flags
&
KEYEVENTF_EXTENDEDKEY
)
msg
->
lparam
|=
KF_EXTENDED
<<
16
;
if
(
input
->
kbd
.
flags
&
KEYEVENTF_EXTENDEDKEY
)
flags
|=
KF_EXTENDED
;
/* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
if
(
input
->
kbd
.
flags
&
KEYEVENTF_KEYUP
)
msg
->
lparam
|=
(
KF_REPEAT
|
KF_UP
)
<<
16
;
else
if
(
desktop
->
keystate
[
vkey
]
&
0x80
)
msg
->
lparam
|=
KF_REPEAT
<<
16
;
if
(
input
->
kbd
.
flags
&
KEYEVENTF_KEYUP
)
flags
|=
KF_REPEAT
|
KF_UP
;
else
if
(
desktop
->
keystate
[
vkey
]
&
0x80
)
flags
|=
KF_REPEAT
;
msg
->
wparam
=
vkey
;
msg
->
lparam
|=
flags
<<
16
;
msg_data
->
flags
|=
(
flags
&
(
KF_EXTENDED
|
KF_ALTDOWN
|
KF_UP
))
>>
8
;
}
msg
->
msg
=
(
input
->
kbd
.
flags
&
KEYEVENTF_KEYUP
)
?
WM_KEYUP
:
WM_KEYDOWN
;
...
...
@@ -1508,8 +1574,10 @@ static void queue_keyboard_message( struct desktop *desktop, user_handle_t win,
desktop
->
keystate
[
VK_MENU
]
&=
~
0x02
;
break
;
}
if
(
!
(
wait
=
send_hook_ll_message
(
desktop
,
msg
,
input
,
sender
)))
queue_hardware_message
(
desktop
,
msg
);
queue_hardware_message
(
desktop
,
msg
)
;
return
wait
;
}
/* queue a hardware message for a custom type of event */
...
...
@@ -1941,6 +2009,7 @@ DECL_HANDLER(send_message)
break
;
case
MSG_HARDWARE
:
/* should use send_hardware_message instead */
case
MSG_CALLBACK_RESULT
:
/* cannot send this one */
case
MSG_HOOK_LL
:
/* generated internally */
default
:
set_error
(
STATUS_INVALID_PARAMETER
);
free
(
msg
);
...
...
@@ -1955,6 +2024,7 @@ DECL_HANDLER(send_hardware_message)
{
struct
thread
*
thread
=
NULL
;
struct
desktop
*
desktop
;
struct
msg_queue
*
sender
=
get_current_queue
();
if
(
req
->
win
)
{
...
...
@@ -1966,10 +2036,10 @@ DECL_HANDLER(send_hardware_message)
switch
(
req
->
input
.
type
)
{
case
INPUT_MOUSE
:
queue_mouse_message
(
desktop
,
req
->
win
,
&
req
->
input
);
reply
->
wait
=
queue_mouse_message
(
desktop
,
req
->
win
,
&
req
->
input
,
req
->
flags
,
sender
);
break
;
case
INPUT_KEYBOARD
:
queue_keyboard_message
(
desktop
,
req
->
win
,
&
req
->
input
);
reply
->
wait
=
queue_keyboard_message
(
desktop
,
req
->
win
,
&
req
->
input
,
req
->
flags
,
sender
);
break
;
case
INPUT_HARDWARE
:
queue_custom_hardware_message
(
desktop
,
req
->
win
,
&
req
->
input
);
...
...
server/request.h
View file @
c7efa293
...
...
@@ -1381,8 +1381,9 @@ C_ASSERT( sizeof(struct post_quit_message_request) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
send_hardware_message_request
,
win
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
send_hardware_message_request
,
input
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
send_hardware_message_request
,
flags
)
==
48
);
C_ASSERT
(
FIELD_OFFSET
(
struct
send_hardware_message_request
,
msg
)
==
52
);
C_ASSERT
(
sizeof
(
struct
send_hardware_message_request
)
==
56
);
C_ASSERT
(
FIELD_OFFSET
(
struct
send_hardware_message_reply
,
wait
)
==
8
);
C_ASSERT
(
sizeof
(
struct
send_hardware_message_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_message_request
,
flags
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_message_request
,
get_win
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_message_request
,
get_first
)
==
20
);
...
...
server/trace.c
View file @
c7efa293
...
...
@@ -2496,7 +2496,11 @@ static void dump_send_hardware_message_request( const struct send_hardware_messa
fprintf
(
stderr
,
" win=%08x"
,
req
->
win
);
dump_hw_input
(
", input="
,
&
req
->
input
);
fprintf
(
stderr
,
", flags=%08x"
,
req
->
flags
);
fprintf
(
stderr
,
", msg=%08x"
,
req
->
msg
);
}
static
void
dump_send_hardware_message_reply
(
const
struct
send_hardware_message_reply
*
req
)
{
fprintf
(
stderr
,
" wait=%d"
,
req
->
wait
);
}
static
void
dump_get_message_request
(
const
struct
get_message_request
*
req
)
...
...
@@ -4275,7 +4279,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_get_process_idle_event_reply
,
NULL
,
NULL
,
NULL
,
(
dump_func
)
dump_send_hardware_message_reply
,
(
dump_func
)
dump_get_message_reply
,
NULL
,
NULL
,
...
...
server/user.h
View file @
c7efa293
...
...
@@ -87,6 +87,7 @@ extern void cleanup_clipboard_thread( struct thread *thread );
extern
void
remove_thread_hooks
(
struct
thread
*
thread
);
extern
unsigned
int
get_active_hooks
(
void
);
extern
struct
thread
*
get_first_global_hook
(
int
id
);
/* queue functions */
...
...
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