mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-21 21:17:19 +00:00
[host] windows: do not callback from the mouse hook context
The windows hook WH_MOUSE_LL is called in such a way that any delay in processing causes a system wide stall. This change spawns an extra thread which waits on an event set by the hook which is then used to call the callback with an artifical limit of 1000Hz.
This commit is contained in:
parent
ed717351cf
commit
d615514799
@ -31,8 +31,8 @@ struct mouseHook
|
||||
HHOOK hook;
|
||||
MouseHookFn callback;
|
||||
int x, y;
|
||||
HANDLE event;
|
||||
HANDLE thread;
|
||||
HANDLE event , updateEvent;
|
||||
HANDLE thread, updateThread;
|
||||
};
|
||||
|
||||
static struct mouseHook mouseHook = { 0 };
|
||||
@ -85,6 +85,31 @@ static VOID WINAPI winEventProc(HWINEVENTHOOK hWinEventHook, DWORD event,
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD WINAPI updateThreadProc(LPVOID lParam)
|
||||
{
|
||||
HANDLE events[2] = {
|
||||
mouseHook.event,
|
||||
mouseHook.updateEvent
|
||||
};
|
||||
|
||||
while(true)
|
||||
{
|
||||
switch(WaitForMultipleObjects(2, events, FALSE, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
DEBUG_INFO("Mouse hook update thread received quit request");
|
||||
return 0;
|
||||
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
mouseHook.callback(mouseHook.x, mouseHook.y);
|
||||
|
||||
// limit this to 1000Hz, who has a mouse that updates faster anyway?
|
||||
Sleep(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD WINAPI threadProc(LPVOID lParam) {
|
||||
if (mouseHook.installed)
|
||||
{
|
||||
@ -143,11 +168,28 @@ void mouseHook_install(MouseHookFn callback)
|
||||
mouseHook.event = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
if (!mouseHook.event)
|
||||
{
|
||||
DEBUG_WINERROR("Failed to create mouse hook uninstall event", GetLastError());
|
||||
DEBUG_WINERROR("Failed to create mouse hook uninstall event",
|
||||
GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
mouseHook.thread = CreateThread(NULL, 0, threadProc, callback, 0, NULL);
|
||||
|
||||
if (!mouseHook.updateEvent)
|
||||
{
|
||||
mouseHook.updateEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
if (!mouseHook.event)
|
||||
{
|
||||
DEBUG_WINERROR("Failed to create mouse hook update event",
|
||||
GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mouseHook.thread =
|
||||
CreateThread(NULL, 0, threadProc, callback, 0, NULL);
|
||||
|
||||
mouseHook.updateThread =
|
||||
CreateThread(NULL, 0, updateThreadProc, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void mouseHook_remove(void)
|
||||
@ -156,8 +198,10 @@ void mouseHook_remove(void)
|
||||
return;
|
||||
|
||||
SetEvent(mouseHook.event);
|
||||
WaitForSingleObject(mouseHook.thread, INFINITE);
|
||||
WaitForSingleObject(mouseHook.thread , INFINITE);
|
||||
WaitForSingleObject(mouseHook.updateThread, INFINITE);
|
||||
CloseHandle(mouseHook.thread);
|
||||
CloseHandle(mouseHook.updateThread);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI mouseHook_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
@ -169,7 +213,7 @@ static LRESULT WINAPI mouseHook_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
mouseHook.x = msg->pt.x;
|
||||
mouseHook.y = msg->pt.y;
|
||||
mouseHook.callback(msg->pt.x, msg->pt.y);
|
||||
SetEvent(mouseHook.updateEvent);
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(mouseHook.hook, nCode, wParam, lParam);
|
||||
|
Loading…
Reference in New Issue
Block a user