Simplify hardware message processing by merging the "raw" and "cooked"
processing into a single function.
This commit is contained in:
parent
ac147fefc7
commit
564915eadc
|
@ -306,12 +306,11 @@ inline static BOOL is_mouse_message( UINT message )
|
||||||
(message >= WM_MOUSEFIRST && message <= WM_MOUSELAST));
|
(message >= WM_MOUSEFIRST && message <= WM_MOUSELAST));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether message matches the specified filter */
|
/* check whether message matches the specified hwnd filter */
|
||||||
inline static BOOL check_message_filter( const MSG *msg, HWND hwnd, UINT first, UINT last )
|
inline static BOOL check_hwnd_filter( const MSG *msg, HWND hwnd_filter )
|
||||||
{
|
{
|
||||||
if (hwnd && msg->hwnd != hwnd && !IsChild( hwnd, msg->hwnd )) return FALSE;
|
if (!hwnd_filter) return TRUE;
|
||||||
if (first || last) return (msg->message >= first && msg->message <= last);
|
return (msg->hwnd == hwnd_filter || IsChild( hwnd_filter, msg->hwnd ));
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1562,14 +1561,35 @@ static void send_parent_notify( HWND hwnd, WORD event, WORD idChild, POINT pt )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* process_raw_keyboard_message
|
* accept_hardware_message
|
||||||
|
*
|
||||||
|
* Tell the server we have passed the message to the app
|
||||||
|
* (even though we may end up dropping it later on)
|
||||||
|
*/
|
||||||
|
static void accept_hardware_message( BOOL remove )
|
||||||
|
{
|
||||||
|
SERVER_START_REQ( reply_message )
|
||||||
|
{
|
||||||
|
req->type = MSG_HARDWARE;
|
||||||
|
req->result = 0;
|
||||||
|
req->remove = remove;
|
||||||
|
if (wine_server_call( req ))
|
||||||
|
FIXME("Failed to reply to MSG_HARDWARE message. Message may not be removed from queue.\n");
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* process_keyboard_message
|
||||||
*
|
*
|
||||||
* returns TRUE if the contents of 'msg' should be passed to the application
|
* returns TRUE if the contents of 'msg' should be passed to the application
|
||||||
*/
|
*/
|
||||||
static BOOL process_raw_keyboard_message( MSG *msg, HWND hwnd_filter, UINT first, UINT last )
|
static BOOL process_keyboard_message( MSG *msg, HWND hwnd_filter, UINT first, UINT last, BOOL remove )
|
||||||
{
|
{
|
||||||
EVENTMSG event;
|
EVENTMSG event;
|
||||||
|
|
||||||
|
/* FIXME: is this really the right place for this hook? */
|
||||||
event.message = msg->message;
|
event.message = msg->message;
|
||||||
event.hwnd = msg->hwnd;
|
event.hwnd = msg->hwnd;
|
||||||
event.time = msg->time;
|
event.time = msg->time;
|
||||||
|
@ -1577,17 +1597,11 @@ static BOOL process_raw_keyboard_message( MSG *msg, HWND hwnd_filter, UINT first
|
||||||
event.paramH = msg->lParam & 0x7FFF;
|
event.paramH = msg->lParam & 0x7FFF;
|
||||||
if (HIWORD(msg->lParam) & 0x0100) event.paramH |= 0x8000; /* special_key - bit */
|
if (HIWORD(msg->lParam) & 0x0100) event.paramH |= 0x8000; /* special_key - bit */
|
||||||
HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
|
HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
|
||||||
return check_message_filter( msg, hwnd_filter, first, last );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* check message filters */
|
||||||
|
if (msg->message < first || msg->message > last) return FALSE;
|
||||||
|
if (!check_hwnd_filter( msg, hwnd_filter )) return FALSE;
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* process_cooked_keyboard_message
|
|
||||||
*
|
|
||||||
* returns TRUE if the contents of 'msg' should be passed to the application
|
|
||||||
*/
|
|
||||||
static BOOL process_cooked_keyboard_message( MSG *msg, BOOL remove )
|
|
||||||
{
|
|
||||||
if (remove)
|
if (remove)
|
||||||
{
|
{
|
||||||
/* Handle F1 key by sending out WM_HELP message */
|
/* Handle F1 key by sending out WM_HELP message */
|
||||||
|
@ -1612,17 +1626,21 @@ static BOOL process_cooked_keyboard_message( MSG *msg, BOOL remove )
|
||||||
{
|
{
|
||||||
/* skip this message */
|
/* skip this message */
|
||||||
HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, TRUE );
|
HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED, LOWORD(msg->wParam), msg->lParam, TRUE );
|
||||||
|
accept_hardware_message( TRUE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
accept_hardware_message( remove );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* process_raw_mouse_message
|
* process_mouse_message
|
||||||
|
*
|
||||||
|
* returns TRUE if the contents of 'msg' should be passed to the application
|
||||||
*/
|
*/
|
||||||
static BOOL process_raw_mouse_message( MSG *msg, HWND hwnd_filter, UINT first,
|
static BOOL process_mouse_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_filter,
|
||||||
UINT last, BOOL remove )
|
UINT first, UINT last, BOOL remove )
|
||||||
{
|
{
|
||||||
static MSG clk_msg;
|
static MSG clk_msg;
|
||||||
|
|
||||||
|
@ -1631,6 +1649,8 @@ static BOOL process_raw_mouse_message( MSG *msg, HWND hwnd_filter, UINT first,
|
||||||
INT hittest;
|
INT hittest;
|
||||||
EVENTMSG event;
|
EVENTMSG event;
|
||||||
GUITHREADINFO info;
|
GUITHREADINFO info;
|
||||||
|
MOUSEHOOKSTRUCT hook;
|
||||||
|
BOOL eatMsg;
|
||||||
HWND hWndScope = msg->hwnd;
|
HWND hWndScope = msg->hwnd;
|
||||||
|
|
||||||
/* find the window to dispatch this mouse message to */
|
/* find the window to dispatch this mouse message to */
|
||||||
|
@ -1646,6 +1666,7 @@ static BOOL process_raw_mouse_message( MSG *msg, HWND hwnd_filter, UINT first,
|
||||||
msg->hwnd = GetDesktopWindow();
|
msg->hwnd = GetDesktopWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: is this really the right place for this hook? */
|
||||||
event.message = msg->message;
|
event.message = msg->message;
|
||||||
event.time = msg->time;
|
event.time = msg->time;
|
||||||
event.hwnd = msg->hwnd;
|
event.hwnd = msg->hwnd;
|
||||||
|
@ -1653,10 +1674,7 @@ static BOOL process_raw_mouse_message( MSG *msg, HWND hwnd_filter, UINT first,
|
||||||
event.paramH = msg->pt.y;
|
event.paramH = msg->pt.y;
|
||||||
HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
|
HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&event, TRUE );
|
||||||
|
|
||||||
if (hwnd_filter)
|
if (!check_hwnd_filter( msg, hwnd_filter )) return FALSE;
|
||||||
{
|
|
||||||
if (msg->hwnd != hwnd_filter && !IsChild( hwnd_filter, msg->hwnd )) return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt = msg->pt;
|
pt = msg->pt;
|
||||||
message = msg->message;
|
message = msg->message;
|
||||||
|
@ -1684,6 +1702,8 @@ static BOOL process_raw_mouse_message( MSG *msg, HWND hwnd_filter, UINT first,
|
||||||
(msg->message == WM_RBUTTONDOWN) ||
|
(msg->message == WM_RBUTTONDOWN) ||
|
||||||
(msg->message == WM_MBUTTONDOWN))
|
(msg->message == WM_MBUTTONDOWN))
|
||||||
{
|
{
|
||||||
|
BOOL update = remove;
|
||||||
|
|
||||||
/* translate double clicks -
|
/* translate double clicks -
|
||||||
* note that ...MOUSEMOVEs can slip in between
|
* note that ...MOUSEMOVEs can slip in between
|
||||||
* ...BUTTONDOWN and ...BUTTONDBLCLK messages */
|
* ...BUTTONDOWN and ...BUTTONDBLCLK messages */
|
||||||
|
@ -1699,86 +1719,68 @@ static BOOL process_raw_mouse_message( MSG *msg, HWND hwnd_filter, UINT first,
|
||||||
(abs(msg->pt.y - clk_msg.pt.y) < GetSystemMetrics(SM_CYDOUBLECLK)/2))
|
(abs(msg->pt.y - clk_msg.pt.y) < GetSystemMetrics(SM_CYDOUBLECLK)/2))
|
||||||
{
|
{
|
||||||
message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
|
message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
|
||||||
msg->message = 0; /* to clear the double click conditions */
|
clk_msg.message = 0; /* clear the double click conditions */
|
||||||
|
update = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (first || last)
|
if (message < first || message > last) return FALSE;
|
||||||
{
|
|
||||||
if (message < first || message > last) remove = FALSE;
|
|
||||||
}
|
|
||||||
/* update static double click conditions */
|
/* update static double click conditions */
|
||||||
if (remove) clk_msg = *msg;
|
if (update) clk_msg = *msg;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
msg->message = message;
|
|
||||||
if (first || last) return (message >= first && message <= last);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* process_cooked_mouse_message
|
|
||||||
*
|
|
||||||
* returns TRUE if the contents of 'msg' should be passed to the application
|
|
||||||
*/
|
|
||||||
static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL remove )
|
|
||||||
{
|
|
||||||
MOUSEHOOKSTRUCT hook;
|
|
||||||
INT hittest = HTCLIENT;
|
|
||||||
UINT raw_message = msg->message;
|
|
||||||
BOOL eatMsg;
|
|
||||||
|
|
||||||
if (msg->message >= WM_NCMOUSEFIRST && msg->message <= WM_NCMOUSELAST)
|
|
||||||
{
|
{
|
||||||
raw_message += WM_MOUSEFIRST - WM_NCMOUSEFIRST;
|
if (message < first || message > last) return FALSE;
|
||||||
hittest = msg->wParam;
|
|
||||||
}
|
|
||||||
if (raw_message == WM_LBUTTONDBLCLK ||
|
|
||||||
raw_message == WM_RBUTTONDBLCLK ||
|
|
||||||
raw_message == WM_MBUTTONDBLCLK)
|
|
||||||
{
|
|
||||||
raw_message += WM_LBUTTONDOWN - WM_LBUTTONDBLCLK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* message is accepted now (but may still get dropped) */
|
||||||
|
|
||||||
hook.pt = msg->pt;
|
hook.pt = msg->pt;
|
||||||
hook.hwnd = msg->hwnd;
|
hook.hwnd = msg->hwnd;
|
||||||
hook.wHitTestCode = hittest;
|
hook.wHitTestCode = hittest;
|
||||||
hook.dwExtraInfo = extra_info;
|
hook.dwExtraInfo = extra_info;
|
||||||
if (HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
|
if (HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
|
||||||
msg->message, (LPARAM)&hook, TRUE ))
|
message, (LPARAM)&hook, TRUE ))
|
||||||
{
|
{
|
||||||
hook.pt = msg->pt;
|
hook.pt = msg->pt;
|
||||||
hook.hwnd = msg->hwnd;
|
hook.hwnd = msg->hwnd;
|
||||||
hook.wHitTestCode = hittest;
|
hook.wHitTestCode = hittest;
|
||||||
hook.dwExtraInfo = extra_info;
|
hook.dwExtraInfo = extra_info;
|
||||||
HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, msg->message, (LPARAM)&hook, TRUE );
|
HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, TRUE );
|
||||||
|
accept_hardware_message( TRUE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hittest == HTERROR) || (hittest == HTNOWHERE))
|
if ((hittest == HTERROR) || (hittest == HTNOWHERE))
|
||||||
{
|
{
|
||||||
SendMessageW( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
|
SendMessageW( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
|
||||||
MAKELONG( hittest, raw_message ));
|
MAKELONG( hittest, msg->message ));
|
||||||
|
accept_hardware_message( TRUE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remove || GetCapture()) return TRUE;
|
accept_hardware_message( remove );
|
||||||
|
|
||||||
|
if (!remove || info.hwndCapture)
|
||||||
|
{
|
||||||
|
msg->message = message;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
eatMsg = FALSE;
|
eatMsg = FALSE;
|
||||||
|
|
||||||
if ((raw_message == WM_LBUTTONDOWN) ||
|
if ((msg->message == WM_LBUTTONDOWN) ||
|
||||||
(raw_message == WM_RBUTTONDOWN) ||
|
(msg->message == WM_RBUTTONDOWN) ||
|
||||||
(raw_message == WM_MBUTTONDOWN))
|
(msg->message == WM_MBUTTONDOWN))
|
||||||
{
|
{
|
||||||
/* Send the WM_PARENTNOTIFY,
|
/* Send the WM_PARENTNOTIFY,
|
||||||
* note that even for double/nonclient clicks
|
* note that even for double/nonclient clicks
|
||||||
* notification message is still WM_L/M/RBUTTONDOWN.
|
* notification message is still WM_L/M/RBUTTONDOWN.
|
||||||
*/
|
*/
|
||||||
send_parent_notify( msg->hwnd, raw_message, 0, msg->pt );
|
send_parent_notify( msg->hwnd, msg->message, 0, msg->pt );
|
||||||
|
|
||||||
/* Activate the window if needed */
|
/* Activate the window if needed */
|
||||||
|
|
||||||
if (msg->hwnd != GetActiveWindow())
|
if (msg->hwnd != info.hwndActive)
|
||||||
{
|
{
|
||||||
HWND hwndTop = msg->hwnd;
|
HWND hwndTop = msg->hwnd;
|
||||||
while (hwndTop)
|
while (hwndTop)
|
||||||
|
@ -1790,7 +1792,7 @@ static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL r
|
||||||
if (hwndTop && hwndTop != GetDesktopWindow())
|
if (hwndTop && hwndTop != GetDesktopWindow())
|
||||||
{
|
{
|
||||||
LONG ret = SendMessageW( msg->hwnd, WM_MOUSEACTIVATE, (WPARAM)hwndTop,
|
LONG ret = SendMessageW( msg->hwnd, WM_MOUSEACTIVATE, (WPARAM)hwndTop,
|
||||||
MAKELONG( hittest, raw_message ) );
|
MAKELONG( hittest, msg->message ) );
|
||||||
switch(ret)
|
switch(ret)
|
||||||
{
|
{
|
||||||
case MA_NOACTIVATEANDEAT:
|
case MA_NOACTIVATEANDEAT:
|
||||||
|
@ -1817,9 +1819,9 @@ static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL r
|
||||||
|
|
||||||
/* Windows sends the normal mouse message as the message parameter
|
/* Windows sends the normal mouse message as the message parameter
|
||||||
in the WM_SETCURSOR message even if it's non-client mouse message */
|
in the WM_SETCURSOR message even if it's non-client mouse message */
|
||||||
SendMessageW( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
|
SendMessageW( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd, MAKELONG( hittest, msg->message ));
|
||||||
MAKELONG( hittest, raw_message ));
|
|
||||||
|
|
||||||
|
msg->message = message;
|
||||||
return !eatMsg;
|
return !eatMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,40 +1831,17 @@ static BOOL process_cooked_mouse_message( MSG *msg, ULONG_PTR extra_info, BOOL r
|
||||||
*
|
*
|
||||||
* Process a hardware message; return TRUE if message should be passed on to the app
|
* Process a hardware message; return TRUE if message should be passed on to the app
|
||||||
*/
|
*/
|
||||||
static BOOL process_hardware_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd,
|
static BOOL process_hardware_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_filter,
|
||||||
UINT first, UINT last, BOOL remove )
|
UINT first, UINT last, BOOL remove )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
if (is_keyboard_message( msg->message ))
|
if (is_keyboard_message( msg->message ))
|
||||||
{
|
return process_keyboard_message( msg, hwnd_filter, first, last, remove );
|
||||||
if (!process_raw_keyboard_message( msg, hwnd, first, last )) return FALSE;
|
|
||||||
ret = process_cooked_keyboard_message( msg, remove );
|
if (is_mouse_message( msg->message ))
|
||||||
}
|
return process_mouse_message( msg, extra_info, hwnd_filter, first, last, remove );
|
||||||
else if (is_mouse_message( msg->message ))
|
|
||||||
{
|
|
||||||
if (!process_raw_mouse_message( msg, hwnd, first, last, remove )) return FALSE;
|
|
||||||
ret = process_cooked_mouse_message( msg, extra_info, remove );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR( "unknown message type %x\n", msg->message );
|
ERR( "unknown message type %x\n", msg->message );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/* tell the server we have passed it to the app
|
|
||||||
* (even though we may end up dropping it later on)
|
|
||||||
*/
|
|
||||||
SERVER_START_REQ( reply_message )
|
|
||||||
{
|
|
||||||
req->type = MSG_HARDWARE;
|
|
||||||
req->result = 0;
|
|
||||||
req->remove = remove || !ret;
|
|
||||||
if (wine_server_call( req ))
|
|
||||||
FIXME("Failed to reply to MSG_HARDWARE message. Message may not be removed from queue.\n");
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue