mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-10-12 10:28:08 +00:00
[c-host] tons of windows specific fixes
This commit is contained in:
98
c-host/platform/Windows/src/mousehook.c
Normal file
98
c-host/platform/Windows/src/mousehook.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Looking Glass - KVM FrameRelay (KVMFR) Client
|
||||
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
|
||||
https://looking-glass.hostfission.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "windows/mousehook.h"
|
||||
#include "windows/windebug.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct mouseHook
|
||||
{
|
||||
bool installed;
|
||||
HHOOK hook;
|
||||
MouseHookFn callback;
|
||||
};
|
||||
|
||||
static struct mouseHook mouseHook = { 0 };
|
||||
|
||||
// forwards
|
||||
static LRESULT WINAPI mouseHook_hook(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT msg_callback(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void mouseHook_install(MouseHookFn callback)
|
||||
{
|
||||
struct MSG_CALL_FUNCTION cf;
|
||||
cf.fn = msg_callback;
|
||||
cf.wParam = 1;
|
||||
cf.lParam = (LPARAM)callback;
|
||||
sendAppMessage(WM_CALL_FUNCTION, 0, (LPARAM)&cf);
|
||||
}
|
||||
|
||||
void mouseHook_remove()
|
||||
{
|
||||
struct MSG_CALL_FUNCTION cf;
|
||||
cf.fn = msg_callback;
|
||||
cf.wParam = 0;
|
||||
cf.lParam = 0;
|
||||
sendAppMessage(WM_CALL_FUNCTION, 0, (LPARAM)&cf);
|
||||
}
|
||||
|
||||
static LRESULT msg_callback(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (wParam)
|
||||
{
|
||||
if (mouseHook.installed)
|
||||
{
|
||||
DEBUG_WARN("Mouse hook already installed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mouseHook.hook = SetWindowsHookEx(WH_MOUSE_LL, mouseHook_hook, NULL, 0);
|
||||
if (!mouseHook.hook)
|
||||
{
|
||||
DEBUG_WINERROR("Failed to install the mouse hook", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
mouseHook.installed = true;
|
||||
mouseHook.callback = (MouseHookFn)lParam;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mouseHook.installed)
|
||||
return 0;
|
||||
|
||||
UnhookWindowsHookEx(mouseHook.hook);
|
||||
mouseHook.installed = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI mouseHook_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode == HC_ACTION && wParam == WM_MOUSEMOVE)
|
||||
{
|
||||
MSLLHOOKSTRUCT *msg = (MSLLHOOKSTRUCT *)lParam;
|
||||
mouseHook.callback(msg->pt.x, msg->pt.y);
|
||||
}
|
||||
return CallNextHookEx(mouseHook.hook, nCode, wParam, lParam);
|
||||
}
|
@@ -17,6 +17,9 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "windows/platform.h"
|
||||
#include "windows/mousehook.h"
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
@@ -37,6 +40,7 @@ struct osThreadHandle
|
||||
void * opaque;
|
||||
HANDLE handle;
|
||||
DWORD threadID;
|
||||
|
||||
int resultCode;
|
||||
};
|
||||
|
||||
@@ -45,6 +49,7 @@ LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
switch(msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
mouseHook_remove();
|
||||
DestroyWindow(hwnd);
|
||||
break;
|
||||
|
||||
@@ -52,6 +57,12 @@ LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_CALL_FUNCTION:
|
||||
{
|
||||
struct MSG_CALL_FUNCTION * cf = (struct MSG_CALL_FUNCTION *)lParam;
|
||||
return cf->fn(cf->wParam, cf->lParam);
|
||||
}
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
@@ -65,6 +76,22 @@ static int appThread(void * opaque)
|
||||
return result;
|
||||
}
|
||||
|
||||
LRESULT sendAppMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return SendMessage(messageWnd, Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CtrlHandler(DWORD dwCtrlType)
|
||||
{
|
||||
if (dwCtrlType == CTRL_C_EVENT)
|
||||
{
|
||||
SendMessage(messageWnd, WM_CLOSE, 0, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
int result = 0;
|
||||
@@ -139,6 +166,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
free(infData);
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
|
||||
// setup a handler for ctrl+c
|
||||
SetConsoleCtrlHandler(CtrlHandler, TRUE);
|
||||
|
||||
// create a message window so that our message pump works
|
||||
WNDCLASSEX wx = {};
|
||||
wx.cbSize = sizeof(WNDCLASSEX);
|
||||
@@ -169,6 +199,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
}
|
||||
else if (bRet < 0)
|
||||
{
|
||||
@@ -312,6 +343,11 @@ osEventHandle * os_createEvent(bool autoReset)
|
||||
return (osEventHandle*)event;
|
||||
}
|
||||
|
||||
osEventHandle * os_wrapEvent(HANDLE event)
|
||||
{
|
||||
return (osEventHandle*)event;
|
||||
}
|
||||
|
||||
void os_freeEvent(osEventHandle * handle)
|
||||
{
|
||||
CloseHandle((HANDLE)handle);
|
||||
@@ -346,6 +382,42 @@ bool os_waitEvent(osEventHandle * handle, unsigned int timeout)
|
||||
}
|
||||
}
|
||||
|
||||
bool os_waitEvents(osEventHandle * handles[], int count, bool waitAll, unsigned int timeout)
|
||||
{
|
||||
const DWORD to = (timeout == TIMEOUT_INFINITE) ? INFINITE : (DWORD)timeout;
|
||||
while(true)
|
||||
{
|
||||
DWORD result = WaitForMultipleObjects(count, (HANDLE*)handles, waitAll, to);
|
||||
if (result >= WAIT_OBJECT_0 && result < count)
|
||||
{
|
||||
// null non signalled events from the handle list
|
||||
for(int i = 0; i < count; ++i)
|
||||
if (i != result && !os_waitEvent(handles[i], 0))
|
||||
handles[i] = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (result >= WAIT_ABANDONED_0 && result - WAIT_ABANDONED_0 < count)
|
||||
continue;
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case WAIT_TIMEOUT:
|
||||
if (timeout == TIMEOUT_INFINITE)
|
||||
continue;
|
||||
|
||||
return false;
|
||||
|
||||
case WAIT_FAILED:
|
||||
DEBUG_WINERROR("Wait for event failed", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_ERROR("Unknown wait event return code");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool os_signalEvent(osEventHandle * handle)
|
||||
{
|
||||
return SetEvent((HANDLE)handle);
|
||||
|
32
c-host/platform/Windows/src/platform.h
Normal file
32
c-host/platform/Windows/src/platform.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Looking Glass - KVM FrameRelay (KVMFR) Client
|
||||
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
|
||||
https://looking-glass.hostfission.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define WM_CALL_FUNCTION (WM_USER+1)
|
||||
|
||||
typedef LRESULT (*CallFunction)(WPARAM wParam, LPARAM lParam);
|
||||
struct MSG_CALL_FUNCTION
|
||||
{
|
||||
CallFunction fn;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
};
|
||||
|
||||
LRESULT sendAppMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
|
Reference in New Issue
Block a user