Commit d6ae45b5 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move NtUserGetAsyncKeyState implementation from user32.

parent bd604c80
......@@ -455,7 +455,7 @@ static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARA
}
if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL)
InterlockedIncrement( &global_key_state_counter ); /* force refreshing the key state cache */
NtUserCallOneParam( 1, NtUserIncrementKeyStateCounter ); /* force refreshing the key state cache */
return ret;
}
......
......@@ -49,8 +49,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(win);
WINE_DECLARE_DEBUG_CHANNEL(keyboard);
LONG global_key_state_counter = 0;
/***********************************************************************
* get_key_state
*/
......@@ -60,19 +58,19 @@ static WORD get_key_state(void)
if (GetSystemMetrics( SM_SWAPBUTTON ))
{
if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON;
if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON;
if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON;
if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON;
}
else
{
if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON;
if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON;
if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON;
if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON;
}
if (GetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON;
if (GetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT;
if (GetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL;
if (GetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1;
if (GetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2;
if (NtUserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON;
if (NtUserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT;
if (NtUserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL;
if (NtUserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1;
if (NtUserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2;
return ret;
}
......@@ -376,75 +374,6 @@ HWND WINAPI GetCapture(void)
}
static void check_for_events( UINT flags )
{
if (USER_Driver->pMsgWaitForMultipleObjectsEx( 0, NULL, 0, flags, 0 ) == WAIT_TIMEOUT)
flush_window_surfaces( TRUE );
}
/**********************************************************************
* GetAsyncKeyState (USER32.@)
*
* Determine if a key is or was pressed. retval has high-order
* bit set to 1 if currently pressed, low-order bit set to 1 if key has
* been pressed.
*/
SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
INT counter = global_key_state_counter;
BYTE prev_key_state;
SHORT ret;
if (key < 0 || key >= 256) return 0;
check_for_events( QS_INPUT );
if (key_state_info && !(key_state_info->state[key] & 0xc0) &&
key_state_info->counter == counter && GetTickCount() - key_state_info->time < 50)
{
/* use cached value */
return 0;
}
else if (!key_state_info)
{
key_state_info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*key_state_info) );
get_user_thread_info()->key_state = key_state_info;
}
ret = 0;
SERVER_START_REQ( get_key_state )
{
req->async = 1;
req->key = key;
if (key_state_info)
{
prev_key_state = key_state_info->state[key];
wine_server_set_reply( req, key_state_info->state, sizeof(key_state_info->state) );
}
if (!wine_server_call( req ))
{
if (reply->state & 0x40) ret |= 0x0001;
if (reply->state & 0x80) ret |= 0x8000;
if (key_state_info)
{
/* force refreshing the key state cache - some multithreaded programs
* (like Adobe Photoshop CS5) expect that changes to the async key state
* are also immediately available in other threads. */
if (prev_key_state != key_state_info->state[key])
counter = InterlockedIncrement( &global_key_state_counter );
key_state_info->time = GetTickCount();
key_state_info->counter = counter;
}
}
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* GetInputState (USER32.@)
*/
......
......@@ -3239,7 +3239,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
struct send_message_info info;
int prev_x, prev_y, new_x, new_y;
INT counter = global_key_state_counter;
INT counter = NtUserCallOneParam( 0, NtUserIncrementKeyStateCounter );
USAGE hid_usage_page, hid_usage;
NTSTATUS ret;
BOOL wait;
......
......@@ -255,7 +255,7 @@
@ stdcall GetAncestor(long long)
@ stdcall GetAppCompatFlags(long)
@ stdcall GetAppCompatFlags2(long)
@ stdcall GetAsyncKeyState(long)
@ stdcall -import GetAsyncKeyState(long) NtUserGetAsyncKeyState
@ stdcall GetAutoRotationState(ptr)
@ stdcall GetAwarenessFromDpiAwarenessContext(long)
@ stdcall GetCapture()
......
......@@ -256,10 +256,10 @@ static void thread_detach(void)
WDML_NotifyThreadDetach();
USER_Driver->pThreadDetach();
NtUserCallNoParam( NtUserThreadDetach );
destroy_thread_windows();
CloseHandle( thread_info->server_queue );
HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );
HeapFree( GetProcessHeap(), 0, thread_info->key_state );
HeapFree( GetProcessHeap(), 0, thread_info->rawinput );
exiting_thread_id = 0;
......
......@@ -102,7 +102,6 @@ struct rawinput_thread_data
RAWINPUT buffer[1]; /* rawinput message data buffer */
};
extern LONG global_key_state_counter DECLSPEC_HIDDEN;
extern BOOL (WINAPI *imm_register_window)(HWND) DECLSPEC_HIDDEN;
extern void (WINAPI *imm_unregister_window)(HWND) DECLSPEC_HIDDEN;
#define WM_IME_INTERNAL 0x287
......
......@@ -1159,6 +1159,7 @@ static struct unix_funcs unix_funcs =
NtUserEnumDisplayDevices,
NtUserEnumDisplayMonitors,
NtUserEnumDisplaySettings,
NtUserGetAsyncKeyState,
NtUserGetDisplayConfigBufferSizes,
NtUserGetKeyNameText,
NtUserGetKeyboardLayoutList,
......
......@@ -45,6 +45,8 @@ static const WCHAR keyboard_layouts_keyW[] =
};
LONG global_key_state_counter = 0;
/**********************************************************************
* NtUserAttachThreadInput (win32u.@)
*/
......@@ -135,6 +137,64 @@ static void check_for_events( UINT flags )
flush_window_surfaces( TRUE );
}
/**********************************************************************
* GetAsyncKeyState (win32u.@)
*/
SHORT WINAPI NtUserGetAsyncKeyState( INT key )
{
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
INT counter = global_key_state_counter;
BYTE prev_key_state;
SHORT ret;
if (key < 0 || key >= 256) return 0;
check_for_events( QS_INPUT );
if (key_state_info && !(key_state_info->state[key] & 0xc0) &&
key_state_info->counter == counter && NtGetTickCount() - key_state_info->time < 50)
{
/* use cached value */
return 0;
}
else if (!key_state_info)
{
key_state_info = calloc( 1, sizeof(*key_state_info) );
get_user_thread_info()->key_state = key_state_info;
}
ret = 0;
SERVER_START_REQ( get_key_state )
{
req->async = 1;
req->key = key;
if (key_state_info)
{
prev_key_state = key_state_info->state[key];
wine_server_set_reply( req, key_state_info->state, sizeof(key_state_info->state) );
}
if (!wine_server_call( req ))
{
if (reply->state & 0x40) ret |= 0x0001;
if (reply->state & 0x80) ret |= 0x8000;
if (key_state_info)
{
/* force refreshing the key state cache - some multithreaded programs
* (like Adobe Photoshop CS5) expect that changes to the async key state
* are also immediately available in other threads. */
if (prev_key_state != key_state_info->state[key])
counter = InterlockedIncrement( &global_key_state_counter );
key_state_info->time = NtGetTickCount();
key_state_info->counter = counter;
}
}
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* NtUserGetQueueStatus (win32u.@)
*/
......
......@@ -4484,6 +4484,14 @@ static BOOL message_beep( UINT i )
return TRUE;
}
static void thread_detach(void)
{
struct user_thread_info *thread_info = get_user_thread_info();
free( thread_info->key_state );
thread_info->key_state = 0;
}
/***********************************************************************
* NtUserCallOneParam (win32u.@)
*/
......@@ -4493,6 +4501,10 @@ ULONG_PTR WINAPI NtUserCallNoParam( ULONG code )
{
case NtUserGetInputState:
return get_input_state();
/* temporary exports */
case NtUserThreadDetach:
thread_detach();
return 0;
default:
FIXME( "invalid code %u\n", code );
return 0;
......@@ -4528,6 +4540,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
return 0;
case NtUserGetDeskPattern:
return get_entry( &entry_DESKPATTERN, 256, (WCHAR *)arg );
case NtUserIncrementKeyStateCounter:
return InterlockedAdd( &global_key_state_counter, arg );
default:
FIXME( "invalid code %u\n", code );
return 0;
......
......@@ -891,7 +891,7 @@
@ stub NtUserGetAltTabInfo
@ stub NtUserGetAncestor
@ stub NtUserGetAppImeLevel
@ stub NtUserGetAsyncKeyState
@ stdcall NtUserGetAsyncKeyState(long)
@ stub NtUserGetAtomName
@ stub NtUserGetAutoRotationState
@ stub NtUserGetCIMSSM
......
......@@ -204,6 +204,7 @@ struct unix_funcs
BOOL (WINAPI *pNtUserEnumDisplayMonitors)( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp );
BOOL (WINAPI *pNtUserEnumDisplaySettings)( UNICODE_STRING *device, DWORD mode,
DEVMODEW *dev_mode, DWORD flags );
SHORT (WINAPI *pNtUserGetAsyncKeyState)( INT key );
LONG (WINAPI *pNtUserGetDisplayConfigBufferSizes)( UINT32 flags, UINT32 *num_path_info,
UINT32 *num_mode_info );
INT (WINAPI *pNtUserGetKeyNameText)( LONG lparam, WCHAR *buffer, INT size );
......@@ -248,6 +249,7 @@ struct unix_funcs
extern BOOL get_clip_cursor( RECT *rect ) DECLSPEC_HIDDEN;
/* input.c */
extern LONG global_key_state_counter DECLSPEC_HIDDEN;
extern BOOL get_cursor_pos( POINT *pt ) DECLSPEC_HIDDEN;
extern DWORD get_input_state(void) DECLSPEC_HIDDEN;
......
......@@ -758,6 +758,12 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
return unix_funcs->pNtUserEnumDisplaySettings( device, mode, dev_mode, flags );
}
SHORT WINAPI NtUserGetAsyncKeyState( INT key )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserGetAsyncKeyState( key );
}
LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_info,
UINT32 *num_mode_info )
{
......
......@@ -53,6 +53,8 @@ struct enum_display_monitor_params
enum
{
NtUserGetInputState,
/* temporary exports */
NtUserThreadDetach,
};
/* NtUserCallOneParam codes, not compatible with Windows */
......@@ -69,6 +71,7 @@ enum
/* temporary exports */
NtUserFlushWindowSurfaces,
NtUserGetDeskPattern,
NtUserIncrementKeyStateCounter,
};
/* NtUserCallTwoParam codes, not compatible with Windows */
......@@ -128,6 +131,7 @@ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
BOOL WINAPI NtUserEnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp );
BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
DEVMODEW *dev_mode, DWORD flags );
SHORT WINAPI NtUserGetAsyncKeyState( INT key );
INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
HWND WINAPI NtUserGetClipboardOwner(void);
DWORD WINAPI NtUserGetClipboardSequenceNumber(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment