Commit eedf2a6f authored by Pierre Lamot's avatar Pierre Lamot Committed by Jean-Baptiste Kempf

Provide callback interface to observe mouse and key events

Forward mouse and key events from windowed, fullscreen and
  video widget.
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent 52a8fbe3
......@@ -580,6 +580,7 @@ LRESULT VLCHolderWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
}
case WM_SET_MOUSE_HOOK:{
MouseHook(true);
KeyboardHook(true);
break;
}
case WM_PAINT:{
......@@ -616,6 +617,7 @@ LRESULT VLCHolderWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
}
break;
case WM_MOUSEMOVE:
WM().OnMouseEvent(uMsg, wParam, lParam);
if (_CtrlsWnd && (_oldMouseCoords.x != GET_X_LPARAM(lParam) ||
_oldMouseCoords.y != GET_Y_LPARAM(lParam)))
{
......@@ -623,9 +625,28 @@ LRESULT VLCHolderWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
_oldMouseCoords = MAKEPOINTS(lParam);
}
break;
case WM_MBUTTONDBLCLK:
case WM_LBUTTONDBLCLK:
WM().OnMouseEvent(uMsg);
case WM_RBUTTONDBLCLK:
case WM_XBUTTONDBLCLK:
case WM_MBUTTONUP:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_XBUTTONUP:
case WM_MBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_XBUTTONDOWN:
WM().OnMouseEvent(uMsg, wParam, lParam);
return VLCWnd::WindowProc(uMsg, wParam, lParam);
break;
case WM_CHAR:
case WM_KEYUP:
case WM_KEYDOWN:
WM().OnKeyEvent(uMsg, wParam, lParam);
return VLCWnd::WindowProc(uMsg, wParam, lParam);
case WM_MOUSE_EVENT_NOTIFY:{
// This is called synchronously, though handling it directly from the mouse hook
// deadlocks (quite likely because we're destroying the windows we're being called from)
......@@ -634,7 +655,32 @@ LRESULT VLCHolderWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
return WM_MOUSE_EVENT_NOTIFY_SUCCESS;
}
case WM_MOUSE_EVENT_REPOST:
WM().OnMouseEvent(wParam);
{
//on click set focus to the parent of MP to receice key events
switch (wParam) {
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_LBUTTONUP:
case WM_XBUTTONUP:
{
HWND mphwnd = FindMP_hWnd();
if (mphwnd)
SetFocus(GetParent(mphwnd));
break;
}
}
WM().OnMouseEvent(uMsg, wParam, lParam);
break;
}
case WM_KEYBOARD_EVENT_NOTIFY:{
PostMessage(hWnd(), WM_KEYBOARD_EVENT_REPOST, wParam, lParam);
return WM_KEYBOARD_EVENT_NOTIFY_SUCCESS;
}
case WM_KEYBOARD_EVENT_REPOST:
if ((lParam & 0xA0000000) == 0)
WM().OnKeyEvent(WM_KEYDOWN, wParam, lParam);
else
WM().OnKeyEvent(WM_KEYUP, wParam, lParam);
break;
default:
return VLCWnd::WindowProc(uMsg, wParam, lParam);
......@@ -655,11 +701,22 @@ void VLCHolderWnd::DestroyWindow()
LRESULT CALLBACK VLCHolderWnd::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
bool AllowReceiveMessage = true;
if(nCode >= 0){
switch(wParam){
case WM_MOUSEMOVE:
case WM_LBUTTONDBLCLK:{
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_LBUTTONDBLCLK:
case WM_XBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_XBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_LBUTTONUP:
case WM_XBUTTONUP:
{
MOUSEHOOKSTRUCT* mhs = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam);
//try to find HolderWnd and notify it
......@@ -669,20 +726,32 @@ LRESULT CALLBACK VLCHolderWnd::MouseHookProc(int nCode, WPARAM wParam, LPARAM lP
hNotifyWnd = GetParent(hNotifyWnd);
SMRes = ::SendMessage(hNotifyWnd, WM_MOUSE_EVENT_NOTIFY, wParam, 0);
}
AllowReceiveMessage = WM_MOUSEMOVE==wParam || (WM_MOUSE_EVENT_NOTIFY_SUCCESS != SMRes);
break;
}
}
}
LRESULT NHRes = CallNextHookEx(NULL, nCode, wParam, lParam);
if(AllowReceiveMessage)
return NHRes;
else
return 1;
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LRESULT CALLBACK VLCHolderWnd::KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode != HC_ACTION)
return CallNextHookEx(NULL, nCode, wParam, lParam);
//try to find HolderWnd and notify it
HWND hNotifyWnd = ::GetFocus();
LRESULT SMRes = ::SendMessage(hNotifyWnd, WM_KEYBOARD_EVENT_NOTIFY, wParam, lParam);
while( hNotifyWnd && WM_KEYBOARD_EVENT_NOTIFY_SUCCESS != SMRes){
hNotifyWnd = GetParent(hNotifyWnd);
SMRes = ::SendMessage(hNotifyWnd, WM_KEYBOARD_EVENT_NOTIFY, wParam, lParam);
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
void VLCHolderWnd::MouseHook(bool SetHook)
{
if(SetHook){
......@@ -709,6 +778,33 @@ void VLCHolderWnd::MouseHook(bool SetHook)
}
}
void VLCHolderWnd::KeyboardHook(bool SetHook)
{
if(SetHook){
HWND hMPWnd = FindMP_hWnd();
const DWORD WndThreadID = (hMPWnd) ? GetWindowThreadProcessId(hMPWnd, NULL) : 0;
if( _hKeyboardHook &&( !hMPWnd || WndThreadID != _KeyboardHookThreadId) ){
//unhook if something changed
KeyboardHook(false);
}
if(!_hKeyboardHook && hMPWnd && WndThreadID){
_KeyboardHookThreadId = WndThreadID;
_hKeyboardHook =
SetWindowsHookEx(WH_KEYBOARD, VLCHolderWnd::KeyboardHookProc,
NULL, WndThreadID);
}
}
else{
if(_hKeyboardHook){
UnhookWindowsHookEx(_hKeyboardHook);
_KeyboardHookThreadId=0;
_hKeyboardHook = 0;
}
}
}
HWND VLCHolderWnd::FindMP_hWnd()
{
if(_CtrlsWnd)
......@@ -800,10 +896,20 @@ LRESULT CALLBACK VLCFullScreenWnd::FSWndWindowProc(HWND hWnd, UINT uMsg, WPARAM
}
break;
}
case WM_KEYDOWN: {
case WM_CHAR:
case WM_SYSKEYUP:
case WM_KEYUP:
if (fs_data)
fs_data->_WindowsManager->OnKeyDownEvent(wParam);
break;
fs_data->_WindowsManager->OnKeyEvent(uMsg, wParam, lParam);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
case WM_SYSKEYDOWN:
case WM_KEYDOWN: {
if (fs_data) {
fs_data->_WindowsManager->OnKeyEvent(uMsg, wParam, lParam);
fs_data->_WindowsManager->OnKeyDownEvent(uMsg, wParam, lParam);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
......@@ -832,9 +938,10 @@ VLCFullScreenWnd* VLCFullScreenWnd::CreateFSWindow(VLCWindowsManager* WM)
//VLCWindowsManager
///////////////////////
VLCWindowsManager::VLCWindowsManager(HMODULE hModule, const VLCViewResources& rc,
vlc_player* player, const vlc_player_options* po)
vlc_player* player, const vlc_player_options* po,
InputObserver* observer)
:_rc(rc), _hModule(hModule), _po(po), _hWindowedParentWnd(0), _vp(player),
_HolderWnd(0), _FSWnd(0), _b_new_messages_flag(false), Last_WM_MOUSEMOVE_Pos(0)
_HolderWnd(0), _FSWnd(0), _InputObserver(observer), _b_new_messages_flag(false), Last_WM_MOUSEMOVE_Pos(0)
{
VLCFullScreenWnd::RegisterWndClassName(hModule);
}
......@@ -960,9 +1067,9 @@ bool VLCWindowsManager::IsFullScreen()
return 0!=_FSWnd && 0!=_HolderWnd && GetParent(_HolderWnd->hWnd())==_FSWnd->getHWND();
}
void VLCWindowsManager::OnKeyDownEvent(UINT uKeyMsg)
void VLCWindowsManager::OnKeyDownEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam)
{
switch(uKeyMsg){
switch(wParam){
case VK_ESCAPE:
case 'F':
EndFullScreen();
......@@ -971,9 +1078,18 @@ void VLCWindowsManager::OnKeyDownEvent(UINT uKeyMsg)
}
}
void VLCWindowsManager::OnMouseEvent(UINT uMouseMsg)
void VLCWindowsManager::OnKeyEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMouseMsg){
if (_InputObserver)
this->_InputObserver->OnKeyEvent(uKeyMsg, wParam, lParam);
}
void VLCWindowsManager::OnMouseEvent(UINT uMouseMsg, WPARAM wParam, LPARAM lParam)
{
if (uMouseMsg == WM_MOUSE_EVENT_REPOST)
{
DWORD MsgPos = GetMessagePos();
switch(wParam){
case WM_LBUTTONDBLCLK:
ToggleFullScreen();
break;
......@@ -986,5 +1102,10 @@ void VLCWindowsManager::OnMouseEvent(UINT uMouseMsg)
break;
}
}
if (_InputObserver)
this->_InputObserver->OnMouseEvent(wParam, lParam, MsgPos);
}
else if (_InputObserver)
this->_InputObserver->OnMouseEvent(uMouseMsg, wParam, lParam);
}
......@@ -33,8 +33,11 @@
enum{
WM_MOUSE_EVENT_NOTIFY = WM_APP + 1,
WM_MOUSE_EVENT_REPOST,
WM_KEYBOARD_EVENT_NOTIFY,
WM_KEYBOARD_EVENT_REPOST,
WM_SET_MOUSE_HOOK,
WM_MOUSE_EVENT_NOTIFY_SUCCESS = 0xFF
WM_MOUSE_EVENT_NOTIFY_SUCCESS = 0xFE,
WM_KEYBOARD_EVENT_NOTIFY_SUCCESS = 0xFF
};
......@@ -154,7 +157,9 @@ public:
protected:
VLCHolderWnd(HINSTANCE hInstance, VLCWindowsManager* WM)
: VLCWnd(hInstance), _hMouseHook(NULL), _MouseHookThreadId(0),
: VLCWnd(hInstance),
_hMouseHook(NULL), _MouseHookThreadId(0),
_hKeyboardHook(NULL), _KeyboardHookThreadId(0),
_wm(WM), _hBgBrush(0), _CtrlsWnd(0), _oldMouseCoords() {}
bool Create(HWND hWndParent);
......@@ -171,6 +176,7 @@ public:
private:
static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam);
HWND FindMP_hWnd();
......@@ -178,6 +184,11 @@ private:
DWORD _MouseHookThreadId;
void MouseHook(bool SetHook);
HHOOK _hKeyboardHook;
DWORD _KeyboardHookThreadId;
void KeyboardHook(bool SetHook);
VLCWindowsManager& WM()
{return *_wm;}
inline vlc_player* VP() const;
......@@ -238,9 +249,19 @@ private:
///////////////////////
class VLCWindowsManager
{
public:
class InputObserver
{
public:
virtual ~InputObserver() {}
virtual void OnKeyEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam) = 0;
virtual void OnMouseEvent(UINT uMouseMsg, WPARAM wParam, LPARAM lParam) = 0;
};
public:
VLCWindowsManager(HMODULE hModule, const VLCViewResources& rc,
vlc_player* player, const vlc_player_options* = 0);
vlc_player* player, const vlc_player_options* = 0,
InputObserver* observer = 0);
~VLCWindowsManager();
VLCWindowsManager(const VLCWindowsManager&) = delete;
VLCWindowsManager& operator=(const VLCWindowsManager&) = delete;
......@@ -266,8 +287,9 @@ public:
bool getNewMessageFlag() const
{return _b_new_messages_flag;};
public:
void OnKeyDownEvent(UINT uKeyMsg);
void OnMouseEvent(UINT uMouseMsg);
void OnKeyEvent(UINT uMouseMsg, WPARAM wParam, LPARAM lParam);
void OnKeyDownEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam);
void OnMouseEvent(UINT uMouseMsg, WPARAM wParam, LPARAM lParam);
private:
const VLCViewResources& _rc;
......@@ -281,6 +303,8 @@ private:
VLCHolderWnd* _HolderWnd;
VLCFullScreenWnd* _FSWnd;
InputObserver* _InputObserver;
bool _b_new_messages_flag;
private:
......
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