[vlc-commits] [Git][videolan/npapi-vlc][master] 2 commits: Provide callback interface to observe mouse and key events

Jean-Baptiste Kempf gitlab at videolan.org
Wed Jul 11 16:03:50 CEST 2018


Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC Browser Plugins


Commits:
eedf2a6f by Pierre Lamot at 2018-07-11T16:03:47+02:00
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 <jb at videolan.org>

- - - - -
a206e1ec by Pierre Lamot at 2018-07-11T16:03:47+02:00
activex: expose mouse and keyboard events

Mouse and keyboard events are exposed through signal. It tries to follow the
  "stock event" API [1] as close as possible. It isn't possible to use COleControl helpers
  as the ActiveX component doesn't use MFC.

  fix: #20358

  [1] https://docs.microsoft.com/en-us/cpp/mfc/mfc-activex-controls-adding-stock-events-to-an-activex-control

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

- - - - -


6 changed files:

- activex/axvlc.idl
- activex/connectioncontainer.cpp
- activex/plugin.cpp
- activex/plugin.h
- common/win32_fullscreen.cpp
- common/win32_fullscreen.h


Changes:

=====================================
activex/axvlc.idl
=====================================
--- a/activex/axvlc.idl
+++ b/activex/axvlc.idl
@@ -28,6 +28,8 @@
 // playlist" and "current playlist" to "the playlist" [t]
 
 import "ocidl.idl";
+#include <olectl.h>
+#include <idispids.h>
 
 [
   uuid(DF2BBE39-40A8-433b-A279-073F48DA94B6),
@@ -149,6 +151,26 @@ library AXVLC
             void MediaPlayerUnmuted();
             [id(DISPID_MediaPlayerAudioVolumeEvent), helpstring("Audio volume changed")]
             void MediaPlayerAudioVolume([in] float volume);
+
+
+            [id(DISPID_CLICK)]
+            void Click();
+            [id(DISPID_DBLCLICK)]
+            void DblClick( );
+
+            [id(DISPID_KEYDOWN)]
+            void KeyDown( short* KeyCode, short Shift );
+            [id(DISPID_KEYPRESS)]
+            void KeyPress( short* KeyAscii );
+            [id(DISPID_KEYUP)]
+            void KeyUp( short* KeyCode, short Shift );
+
+            [id(DISPID_MOUSEDOWN)]
+            void MouseDown( short Button , short Shift , long x , long y);
+            [id(DISPID_MOUSEMOVE)]
+            void MouseMove( short Button , short Shift , long x , long y);
+            [id(DISPID_MOUSEUP)]
+            void MouseUp( short Button , short Shift , long x, long y);
     };
 
     [


=====================================
activex/connectioncontainer.cpp
=====================================
--- a/activex/connectioncontainer.cpp
+++ b/activex/connectioncontainer.cpp
@@ -346,7 +346,20 @@ VLCDispatchEvent::~VLCDispatchEvent()
     if( _dispParams.rgvarg != nullptr )
     {
         for(unsigned int c = 0; c < _dispParams.cArgs; ++c)
+        {
+            if ( (_dispParams.rgvarg[c].vt & VT_BYREF) )
+            {
+                switch ( _dispParams.rgvarg[c].vt ) {
+                case VT_I2|VT_BYREF:
+                    delete _dispParams.rgvarg[c].piVal;
+                    break;
+                case VT_I4|VT_BYREF:
+                    delete _dispParams.rgvarg[c].plVal;
+                    break;
+                }
+            }
             VariantClear(_dispParams.rgvarg + c);
+        }
         CoTaskMemFree(_dispParams.rgvarg);
     }
     if( _dispParams.rgdispidNamedArgs != nullptr )


=====================================
activex/plugin.cpp
=====================================
--- a/activex/plugin.cpp
+++ b/activex/plugin.cpp
@@ -51,9 +51,18 @@
 #include <servprov.h>
 #include <shlwapi.h>
 #include <wininet.h>
+#include <windowsx.h>
 
 using namespace std;
 
+#define LEFT_BUTTON     0x01
+#define RIGHT_BUTTON    0x02
+#define MIDDLE_BUTTON   0x04
+
+#define SHIFT_MASK      0x01
+#define CTRL_MASK       0x02
+#define ALT_MASK        0x04
+
 ////////////////////////////////////////////////////////////////////////
 //class factory
 
@@ -87,9 +96,14 @@ static LRESULT CALLBACK VLCInPlaceClassWndProc(HWND hWnd, UINT uMsg, WPARAM wPar
             }
             return 0L;
         }
-        default:
-            return DefWindowProc(hWnd, uMsg, wParam, lParam);
+        case WM_CHAR:
+        case WM_SYSKEYUP:
+        case WM_KEYUP:
+        case WM_SYSKEYDOWN:
+        case WM_KEYDOWN:
+            p_instance->OnKeyEvent(uMsg, wParam, lParam);
     }
+    return DefWindowProc(hWnd, uMsg, wParam, lParam);
 };
 
 VLCPluginClass::VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance, REFCLSID rclsid) :
@@ -219,7 +233,7 @@ extern HMODULE DllGetModule();
 
 VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) :
     _inplacewnd(NULL),
-    _WindowsManager(DllGetModule(), _ViewRC, &m_player, this),
+    _WindowsManager(DllGetModule(), _ViewRC, &m_player, this, this),
     _p_class(p_class),
     _i_ref(1UL),
     _i_codepage(CP_ACP),
@@ -579,6 +593,83 @@ BOOL VLCPlugin::isInPlaceActive(void)
     return (NULL != _inplacewnd);
 }
 
+static short _shiftState()
+{
+    short shift = (GetKeyState(VK_SHIFT) < 0) ? SHIFT_MASK : 0;
+    short ctrl  = (GetKeyState(VK_CONTROL) < 0) ? CTRL_MASK : 0;
+    short alt   = (GetKeyState(VK_MENU) < 0) ? ALT_MASK : 0;
+    return (shift | ctrl | alt);
+}
+
+void VLCPlugin::OnKeyEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam)
+{
+    USHORT nChar = (USHORT)wParam;
+    USHORT nShiftState = _shiftState();
+    switch (uKeyMsg) {
+        case WM_SYSKEYDOWN:
+        case WM_KEYDOWN:
+            fireKeyDownEvent(nChar , nShiftState);
+            break;
+        case WM_CHAR:
+            fireKeyPressEvent(nChar);
+            break;
+        case WM_SYSKEYUP:
+        case WM_KEYUP:
+            fireKeyUpEvent(nChar , nShiftState);
+            break;
+    }
+}
+
+void VLCPlugin::OnMouseEvent(UINT uMouseMsg, WPARAM wParam, LPARAM lParam)
+{
+    short state = _shiftState();
+    int x = GET_X_LPARAM(lParam);
+    int y = GET_Y_LPARAM(lParam);
+    switch (uMouseMsg) {
+        case WM_MOUSEMOVE:
+        {
+            short button = 0;
+            button |= (wParam & MK_LBUTTON) ? LEFT_BUTTON : 0;
+            button |= (wParam & MK_MBUTTON) ? MIDDLE_BUTTON : 0;
+            button |= (wParam & MK_RBUTTON) ? RIGHT_BUTTON : 0;
+            fireMouseMoveEvent( button, state, x, y );
+            break;
+        }
+
+        case WM_RBUTTONDBLCLK:
+        case WM_MBUTTONDBLCLK:
+        case WM_LBUTTONDBLCLK:
+            fireDblClickEvent();
+            break;
+
+        case WM_RBUTTONDOWN:
+            fireMouseDownEvent( RIGHT_BUTTON, state , x, y );
+            break;
+        case WM_MBUTTONDOWN:
+            fireMouseDownEvent( MIDDLE_BUTTON, state , x, y );
+            break;
+        case WM_LBUTTONDOWN:
+            fireMouseDownEvent( LEFT_BUTTON, state , x, y );
+            break;
+
+        case WM_RBUTTONUP:
+            fireMouseUpEvent( RIGHT_BUTTON, state , x, y );
+            fireClickEvent();
+            break;
+        case WM_MBUTTONUP:
+            fireMouseUpEvent( MIDDLE_BUTTON, state , x, y );
+            fireClickEvent();
+            break;
+        case WM_LBUTTONUP:
+            fireMouseUpEvent( LEFT_BUTTON, state , x, y );
+            fireClickEvent();
+            break;
+
+        default:
+            break;
+    }
+}
+
 HRESULT VLCPlugin::onActivateInPlace(LPMSG, HWND hwndParent, LPCRECT lprcPosRect, LPCRECT lprcClipRect)
 {
     RECT clipRect = *lprcClipRect;
@@ -1125,20 +1216,121 @@ void VLCPlugin::fireOnMediaPlayerLengthChangedEvent(long length)
     vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerLengthChangedEvent, &params);
 }
 
-#if LIBVLC_VERSION_INT >= LIBVLC_VERSION(3, 0, 0, 0)
-void VLCPlugin::fireOnMediaPlayerChapterChangedEvent(int chapter)
+void VLCPlugin::fireClickEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_CLICK, &dispparamsNoArgs);
+}
+
+void VLCPlugin::fireDblClickEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_DBLCLICK, &dispparamsNoArgs);
+}
+
+void VLCPlugin::fireMouseDownEvent(short nButton, short nShiftState, int x, int y)
+{
+    DISPPARAMS params;
+    params.cArgs = 4;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs);
+    memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    params.rgvarg[3].vt = VT_I2;
+    params.rgvarg[3].iVal = nButton;
+    params.rgvarg[2].vt = VT_I2;
+    params.rgvarg[2].iVal = nShiftState;
+    params.rgvarg[1].vt = VT_I4;
+    params.rgvarg[1].lVal = x;
+    params.rgvarg[0].vt = VT_I4;
+    params.rgvarg[0].lVal = y;
+    params.rgdispidNamedArgs = NULL;
+    params.cNamedArgs = 0;
+    vlcConnectionPointContainer->fireEvent(DISPID_MOUSEDOWN, &params);
+}
+
+void VLCPlugin::fireMouseMoveEvent(short nButton, short nShiftState, int x, int y)
+{
+    DISPPARAMS params;
+    params.cArgs = 4;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs);
+    memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    params.rgvarg[3].vt = VT_I2;
+    params.rgvarg[3].iVal = nButton;
+    params.rgvarg[2].vt = VT_I2;
+    params.rgvarg[2].iVal = nShiftState;
+    params.rgvarg[1].vt = VT_I4;
+    params.rgvarg[1].lVal = x;
+    params.rgvarg[0].vt = VT_I4;
+    params.rgvarg[0].lVal = y;
+    params.rgdispidNamedArgs = NULL;
+    params.cNamedArgs = 0;
+    vlcConnectionPointContainer->fireEvent(DISPID_MOUSEMOVE, &params);
+}
+
+
+void VLCPlugin::fireMouseUpEvent(short nButton, short nShiftState, int x, int y)
+{
+    DISPPARAMS params;
+    params.cArgs = 4;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs);
+    memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    params.rgvarg[3].vt = VT_I2;
+    params.rgvarg[3].iVal = nButton;
+    params.rgvarg[2].vt = VT_I2;
+    params.rgvarg[2].iVal = nShiftState;
+    params.rgvarg[1].vt = VT_I4;
+    params.rgvarg[1].lVal = x;
+    params.rgvarg[0].vt = VT_I4;
+    params.rgvarg[0].lVal = y;
+    params.rgdispidNamedArgs = NULL;
+    params.cNamedArgs = 0;
+    vlcConnectionPointContainer->fireEvent(DISPID_MOUSEUP, &params);
+}
+
+void VLCPlugin::fireKeyDownEvent(short nChar, short nShiftState)
+{
+    DISPPARAMS params;
+    params.cArgs = 2;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs);
+    memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    //freed by VLCDispatchEvent::~VLCDispatchEvent
+    params.rgvarg[1].vt = VT_I2 | VT_BYREF;
+    params.rgvarg[1].piVal = new short(nChar);
+    params.rgvarg[0].vt = VT_I2;
+    params.rgvarg[0].iVal = nShiftState;
+    params.rgdispidNamedArgs = NULL;
+    params.cNamedArgs = 0;
+    vlcConnectionPointContainer->fireEvent(DISPID_KEYDOWN, &params);
+}
+
+void VLCPlugin::fireKeyPressEvent(short nChar)
 {
     DISPPARAMS params;
     params.cArgs = 1;
-    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs);
     memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    //freed by VLCDispatchEvent::~VLCDispatchEvent
+    params.rgvarg[0].vt = VT_I2 | VT_BYREF;
+    params.rgvarg[0].piVal = new short(nChar);
+    params.rgdispidNamedArgs = NULL;
+    params.cNamedArgs = 0;
+    vlcConnectionPointContainer->fireEvent(DISPID_KEYPRESS, &params);
+}
+
+void VLCPlugin::fireKeyUpEvent(short nChar, short nShiftState)
+{
+    DISPPARAMS params;
+    params.cArgs = 2;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs);
+    memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    //freed by VLCDispatchEvent::~VLCDispatchEvent
+    params.rgvarg[1].vt = VT_I2 | VT_BYREF;
+    params.rgvarg[1].piVal = new short(nChar);
     params.rgvarg[0].vt = VT_I2;
-    params.rgvarg[0].iVal = chapter;
+    params.rgvarg[0].iVal = nShiftState;
     params.rgdispidNamedArgs = NULL;
     params.cNamedArgs = 0;
-    vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerChapterChangedEvent, &params);
+    vlcConnectionPointContainer->fireEvent(DISPID_KEYUP, &params);
 }
-#endif
 
 void VLCPlugin::fireOnMediaPlayerVoutEvent(int count)
 {
@@ -1180,6 +1372,21 @@ void VLCPlugin::fireOnMediaPlayerAudioVolumeEvent(float volume)
 }
 #endif
 
+#if LIBVLC_VERSION_INT >= LIBVLC_VERSION(3, 0, 0, 0)
+void VLCPlugin::fireOnMediaPlayerChapterChangedEvent(int chapter)
+{
+    DISPPARAMS params;
+    params.cArgs = 1;
+    params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
+    memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
+    params.rgvarg[0].vt = VT_I2;
+    params.rgvarg[0].iVal = chapter;
+    params.rgdispidNamedArgs = NULL;
+    params.cNamedArgs = 0;
+    vlcConnectionPointContainer->fireEvent(DISPID_CLICK, &params);
+}
+#endif
+
 /* */
 
 void VLCPlugin::set_player_window()


=====================================
activex/plugin.h
=====================================
--- a/activex/plugin.h
+++ b/activex/plugin.h
@@ -73,7 +73,8 @@ private:
 };
 
 class VLCPlugin
-    : public IUnknown, private vlc_player_options
+    : public IUnknown, private vlc_player_options,
+      public VLCWindowsManager::InputObserver
 {
 public:
     VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter);
@@ -219,6 +220,10 @@ public:
 
     BOOL isInPlaceActive(void);
 
+    //VLCWindowsManager::InputObserver methods
+    virtual void OnKeyEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam) override;
+    virtual void OnMouseEvent(UINT uMouseMsg, WPARAM wParam, LPARAM lParam) override;
+
     /*
     ** container events
     */
@@ -270,6 +275,15 @@ public:
     void fireOnMediaPlayerAudioVolumeEvent(float volume);
 #endif
 
+    void fireClickEvent();
+    void fireDblClickEvent();
+    void fireMouseDownEvent(short nButton, short nShiftState, int x, int y);
+    void fireMouseMoveEvent(short nButton, short nShiftState, int x, int y);
+    void fireMouseUpEvent(short nButton, short nShiftState, int x, int y);
+    void fireKeyDownEvent(short nChar, short nShiftState);
+    void fireKeyPressEvent(short nChar);
+    void fireKeyUpEvent(short nchar, short shiftState);
+
     // controlling IUnknown interface
     LPUNKNOWN pUnkOuter;
 


=====================================
common/win32_fullscreen.cpp
=====================================
--- a/common/win32_fullscreen.cpp
+++ b/common/win32_fullscreen.cpp
@@ -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,20 +1078,34 @@ void VLCWindowsManager::OnKeyDownEvent(UINT uKeyMsg)
     }
 }
 
-void VLCWindowsManager::OnMouseEvent(UINT uMouseMsg)
+void VLCWindowsManager::OnKeyEvent(UINT uKeyMsg, WPARAM wParam, LPARAM lParam)
 {
-    switch(uMouseMsg){
-        case WM_LBUTTONDBLCLK:
-            ToggleFullScreen();
-            break;
-        case WM_MOUSEMOVE:{
-            DWORD MsgPos = GetMessagePos();
-            if(Last_WM_MOUSEMOVE_Pos != MsgPos){
-                Last_WM_MOUSEMOVE_Pos = MsgPos;
-                _HolderWnd->ControlWindow()->NeedShowControls();
+    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;
+            case WM_MOUSEMOVE:{
+                DWORD MsgPos = GetMessagePos();
+                if(Last_WM_MOUSEMOVE_Pos != MsgPos){
+                    Last_WM_MOUSEMOVE_Pos = MsgPos;
+                    _HolderWnd->ControlWindow()->NeedShowControls();
+                }
+                break;
             }
-            break;
         }
+        if (_InputObserver)
+            this->_InputObserver->OnMouseEvent(wParam, lParam, MsgPos);
     }
+    else if (_InputObserver)
+        this->_InputObserver->OnMouseEvent(uMouseMsg, wParam, lParam);
 }
 


=====================================
common/win32_fullscreen.h
=====================================
--- a/common/win32_fullscreen.h
+++ b/common/win32_fullscreen.h
@@ -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;
@@ -239,8 +250,18 @@ 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:



View it on GitLab: https://code.videolan.org/videolan/npapi-vlc/compare/52a8fbe36751606931682a72e949a2e0c3950078...a206e1ec527817da78d9568459d5560b37c37f4f

-- 
View it on GitLab: https://code.videolan.org/videolan/npapi-vlc/compare/52a8fbe36751606931682a72e949a2e0c3950078...a206e1ec527817da78d9568459d5560b37c37f4f
You're receiving this email because of your account on code.videolan.org.


More information about the vlc-commits mailing list