]> git.sesse.net Git - vlc/blobdiff - projects/activex/plugin.cpp
activex: stop playing on page reload
[vlc] / projects / activex / plugin.cpp
index 0d63f57affb9367a69aead04ee9d627f3e844ed8..1d9a23f79ed0262c0cda227fa73cc2b3624651ec 100644 (file)
@@ -1,9 +1,10 @@
 /*****************************************************************************
  * plugin.cpp: ActiveX control for VLC
  *****************************************************************************
- * Copyright (C) 2006 the VideoLAN team
+ * Copyright (C) 2006-2010 the VideoLAN team
  *
  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
+ *          Jean-Paul Saman <jpsaman@videolan.org>
  *
  * 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
@@ -47,6 +48,7 @@
 #include <servprov.h>
 #include <shlwapi.h>
 #include <wininet.h>
+#include <assert.h>
 
 using namespace std;
 
@@ -270,7 +272,15 @@ VLCPlugin::~VLCPlugin()
     SysFreeString(_bstr_mrl);
     SysFreeString(_bstr_baseurl);
 
-    if( _p_mplayer ) { libvlc_media_player_release(_p_mplayer); _p_mplayer=NULL; }
+    if( _p_mplayer )
+    {
+        if( isPlaying() )
+            playlist_stop();
+
+        player_unregister_events();
+        libvlc_media_player_release(_p_mplayer);
+        _p_mplayer=NULL;
+    }
     if( _p_mlist )   { libvlc_media_list_release(_p_mlist); _p_mlist=NULL; }
     if( _p_libvlc )  { libvlc_release(_p_libvlc); _p_libvlc=NULL; }
 
@@ -418,7 +428,6 @@ HRESULT VLCPlugin::onLoad(void)
     return S_OK;
 };
 
-
 void VLCPlugin::initVLC()
 {
     extern HMODULE DllGetModule();
@@ -475,35 +484,22 @@ void VLCPlugin::initVLC()
     ppsz_argv[ppsz_argc++] = "--no-one-instance";
 
     /* common settings */
+    ppsz_argv[ppsz_argc++] = "-vv";
     ppsz_argv[ppsz_argc++] = "--no-stats";
     ppsz_argv[ppsz_argc++] = "--no-media-library";
-    ppsz_argv[ppsz_argc++] = "--ignore-config";
     ppsz_argv[ppsz_argc++] = "--intf=dummy";
+    ppsz_argv[ppsz_argc++] = "--no-video-title-show";
+
 
     // loop mode is a configuration option only
     if( _b_autoloop )
         ppsz_argv[ppsz_argc++] = "--loop";
 
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
-
-    _p_libvlc = libvlc_new(ppsz_argc, ppsz_argv, &ex);
-    if( libvlc_exception_raised(&ex) )
+    _p_libvlc = libvlc_new(ppsz_argc, ppsz_argv);
+    if( !_p_libvlc )
         return;
 
-    _p_mlist = libvlc_media_list_new(_p_libvlc, &ex);
-    if( libvlc_exception_raised(&ex) )
-    {
-        libvlc_release(_p_libvlc);
-        return;
-    }
-
-    // initial volume setting
-    libvlc_audio_set_volume(_p_libvlc, _i_volume, NULL);
-    if( _b_mute )
-    {
-        libvlc_audio_set_mute(_p_libvlc, TRUE, NULL);
-    }
+    _p_mlist = libvlc_media_list_new(_p_libvlc);
 
     // initial playlist item
     if( SysStringLen(_bstr_mrl) > 0 )
@@ -545,7 +541,7 @@ void VLCPlugin::initVLC()
                 options[i_options++] = timeBuffer;
             }
             // add default target to playlist
-            playlist_add_extended_untrusted(psz_mrl, i_options, options, NULL);
+            playlist_add_extended_untrusted(psz_mrl, i_options, options);
             CoTaskMemFree(psz_mrl);
         }
     }
@@ -654,14 +650,6 @@ HRESULT VLCPlugin::onClose(DWORD dwSaveOption)
     {
         libvlc_instance_t* p_libvlc = _p_libvlc;
 
-        IVLCLog *p_log;
-        if( SUCCEEDED(vlcControl2->get_log(&p_log)) )
-        {
-            // make sure the log is disabled
-            p_log->put_verbosity(-1);
-            p_log->Release();
-        }
-
         _p_libvlc = NULL;
         vlcDataObject->onClose();
 
@@ -679,8 +667,6 @@ BOOL VLCPlugin::isInPlaceActive(void)
 HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprcPosRect, LPCRECT lprcClipRect)
 {
     RECT clipRect = *lprcClipRect;
-    libvlc_exception_t ex;
-    libvlc_exception_init(&ex);
 
     /*
     ** record keeping of control geometry within container
@@ -725,9 +711,9 @@ HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprc
         if( FAILED(result) )
             return result;
 
-        if( _b_autoplay && playlist_select(0,NULL) )
+        if( _b_autoplay && playlist_select(0) )
         {
-            libvlc_media_player_play(_p_mplayer,NULL);
+            libvlc_media_player_play(_p_mplayer);
             fireOnPlayEvent();
         }
     }
@@ -740,9 +726,9 @@ HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprc
 
 HRESULT VLCPlugin::onInPlaceDeactivate(void)
 {
-    if( isPlaying(NULL) )
+    if( isPlaying() )
     {
-        playlist_stop(NULL);
+        playlist_stop();
         fireOnStopEvent();
     }
 
@@ -780,7 +766,10 @@ void VLCPlugin::setVolume(int volume)
         _i_volume = volume;
         if( isRunning() )
         {
-            libvlc_audio_set_volume(_p_libvlc, _i_volume, NULL);
+            libvlc_media_player_t *p_md;
+            HRESULT hr = getMD(&p_md);
+            if( SUCCEEDED(hr) )
+                libvlc_audio_set_volume(p_md, _i_volume);
         }
         setDirty(TRUE);
     }
@@ -809,7 +798,7 @@ void VLCPlugin::setTime(int seconds)
         setStartTime(_i_time);
         if( NULL != _p_mplayer )
         {
-            libvlc_media_player_set_time(_p_mplayer, _i_time, NULL);
+            libvlc_media_player_set_time(_p_mplayer, _i_time);
         }
     }
 };
@@ -1015,72 +1004,314 @@ void VLCPlugin::fireOnStopEvent(void)
     vlcConnectionPointContainer->fireEvent(DISPID_StopEvent, &dispparamsNoArgs);
 };
 
-bool VLCPlugin::playlist_select( int idx, libvlc_exception_t *ex )
+/*
+ * Async events
+ */
+void VLCPlugin::fireOnIdleEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_NothingSpecialEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnOpeningEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_OpeningEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnBufferingEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_BufferingEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnPlayingEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_PlayingEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnPausedEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_PausedEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnErrorEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_EncounteredErrorEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnEndedEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_EndReachedEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnStoppedEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_StoppedEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnForwardEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_ForwardEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnBackwardEvent()
+{
+    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+    vlcConnectionPointContainer->fireEvent(DISPID_BackwardEvent, &dispparamsNoArgs);
+};
+
+static void handle_input_state_event(const libvlc_event_t* event, void *param)
+{
+    VLCPlugin *plugin = (VLCPlugin*)param;
+    switch( event->type )
+    {
+        case libvlc_MediaPlayerNothingSpecial:
+            plugin->fireOnIdleEvent();
+            break;
+        case libvlc_MediaPlayerOpening:
+            plugin->fireOnOpeningEvent();
+            break;
+        case libvlc_MediaPlayerBuffering:
+            plugin->fireOnBufferingEvent();
+            break;
+        case libvlc_MediaPlayerPlaying:
+            plugin->fireOnPlayingEvent();
+            break;
+        case libvlc_MediaPlayerPaused:
+            plugin->fireOnPausedEvent();
+            break;
+        case libvlc_MediaPlayerStopped:
+            plugin->fireOnStoppedEvent();
+            break;
+        case libvlc_MediaPlayerForward:
+            plugin->fireOnForwardEvent();
+            break;
+        case libvlc_MediaPlayerBackward:
+            plugin->fireOnBackwardEvent();
+            break;
+        case libvlc_MediaPlayerEndReached:
+            plugin->fireOnEndedEvent();
+            break;
+        case libvlc_MediaPlayerEncounteredError:
+            plugin->fireOnErrorEvent();
+            break;
+    }
+}
+
+void VLCPlugin::fireOnTimeChangedEvent(long time)
+{
+    VARIANT varPos;
+    DISPPARAMS params = { &varPos, NULL, 1, 0 };
+    varPos.vt = VT_I4;
+    varPos.lVal = time;
+    vlcConnectionPointContainer->fireEvent(DISPID_TimeChangedEvent, &params);
+};
+
+static void handle_time_changed_event(const libvlc_event_t* event, void *param)
+{
+    VLCPlugin *plugin = (VLCPlugin*)param;
+    plugin->fireOnTimeChangedEvent(event->u.media_player_time_changed.new_time);
+}
+
+void VLCPlugin::fireOnPositionChangedEvent(long position)
+{
+    VARIANT varPos;
+    DISPPARAMS params = { &varPos, NULL, 1, 0 };
+    varPos.vt = VT_I4;
+    varPos.lVal = position;
+    vlcConnectionPointContainer->fireEvent(DISPID_PositionChangedEvent, &params);
+};
+
+static void handle_position_changed_event(const libvlc_event_t* event, void *param)
+{
+    VLCPlugin *plugin = (VLCPlugin*)param;
+    plugin->fireOnPositionChangedEvent(event->u.media_player_position_changed.new_position);
+}
+
+void VLCPlugin::fireOnSeekableChangedEvent(VARIANT_BOOL seekable)
+{
+    VARIANT varSeek;
+    DISPPARAMS params = { &varSeek, NULL, 1, 0 };
+    varSeek.vt = VT_BOOL;
+    varSeek.boolVal = seekable;
+    vlcConnectionPointContainer->fireEvent(DISPID_SeekableChangedEvent, &params);
+};
+
+static void handle_seekable_changed_event(const libvlc_event_t* event, void *param)
+{
+    VLCPlugin *plugin = (VLCPlugin*)param;
+    plugin->fireOnSeekableChangedEvent(event->u.media_player_seekable_changed.new_seekable);
+}
+
+void VLCPlugin::fireOnPausableChangedEvent(VARIANT_BOOL pausable)
+{
+    VARIANT varPause;
+    DISPPARAMS params = { &varPause, NULL, 1, 0 };
+    varPause.vt = VT_BOOL;
+    varPause.boolVal = pausable;
+    vlcConnectionPointContainer->fireEvent(DISPID_PausableChangedEvent, &params);
+};
+
+static void handle_pausable_changed_event(const libvlc_event_t* event, void *param)
+{
+    VLCPlugin *plugin = (VLCPlugin*)param;
+    plugin->fireOnPausableChangedEvent(event->u.media_player_pausable_changed.new_pausable);
+}
+
+/* */
+
+bool VLCPlugin::playlist_select( int idx )
 {
     libvlc_media_t *p_m = NULL;
 
+    assert(_p_mlist);
+
     libvlc_media_list_lock(_p_mlist);
 
-    int count = libvlc_media_list_count(_p_mlist,ex);
-    if( libvlc_exception_raised(ex) )
-        goto bad_unlock;
+    int count = libvlc_media_list_count(_p_mlist);
 
-    if( idx<0||idx>=count )
+    if( (idx < 0) || (idx >= count) )
         goto bad_unlock;
 
     _i_midx = idx;
 
-    p_m = libvlc_media_list_item_at_index(_p_mlist,_i_midx,ex);
+    p_m = libvlc_media_list_item_at_index(_p_mlist,_i_midx);
     libvlc_media_list_unlock(_p_mlist);
-
-    if( libvlc_exception_raised(ex) )
+    if( !p_m )
         return false;
 
     if( _p_mplayer )
     {
+        if( isPlaying() )
+            playlist_stop();
+        player_unregister_events();
         libvlc_media_player_release( _p_mplayer );
         _p_mplayer = NULL;
     }
 
-    _p_mplayer = libvlc_media_player_new_from_media(p_m,ex);
+    _p_mplayer = libvlc_media_player_new_from_media(p_m);
     if( _p_mplayer )
-        set_player_window(ex);
+    {
+        // initial volume setting
+        libvlc_audio_set_volume(_p_mplayer, _i_volume);
+        if( _b_mute )
+            libvlc_audio_set_mute(_p_mplayer, TRUE);
+        set_player_window();
+        player_register_events();
+    }
 
-    libvlc_media_release( p_m );
-    return !libvlc_exception_raised(ex);
+    libvlc_media_release(p_m);
+    return _p_mplayer ? true : false;
 
 bad_unlock:
     libvlc_media_list_unlock(_p_mlist);
     return false;
 }
 
-void VLCPlugin::set_player_window(libvlc_exception_t *ex)
+void VLCPlugin::set_player_window()
 {
     // XXX FIXME no idea if this is correct or not
-    libvlc_media_player_set_hwnd(_p_mplayer,getInPlaceWindow(),ex);
+    libvlc_media_player_set_hwnd(_p_mplayer,getInPlaceWindow());
+}
+
+void VLCPlugin::player_register_events()
+{
+    libvlc_event_manager_t *eventManager = NULL;
+    assert(_p_mplayer);
+
+    eventManager = libvlc_media_player_event_manager(_p_mplayer);
+    if(eventManager) {
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerNothingSpecial,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerOpening,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerPaused,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerStopped,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerForward,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerBackward,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached,
+                            handle_input_state_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError,
+                            handle_input_state_event, this);
+
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerTimeChanged,
+                            handle_time_changed_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerPositionChanged,
+                            handle_position_changed_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerSeekableChanged,
+                            handle_seekable_changed_event, this);
+        libvlc_event_attach(eventManager, libvlc_MediaPlayerPausableChanged,
+                            handle_pausable_changed_event, this);
+    }
+}
+
+void VLCPlugin::player_unregister_events()
+{
+    libvlc_event_manager_t *eventManager = NULL;
+    assert(_p_mplayer);
+
+    eventManager = libvlc_media_player_event_manager(_p_mplayer);
+    if(eventManager) {
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerNothingSpecial,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerOpening,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerBuffering,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerPlaying,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerPaused,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerStopped,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerForward,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerBackward,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerEndReached,
+                            handle_input_state_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerEncounteredError,
+                            handle_input_state_event, this);
+
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerTimeChanged,
+                            handle_time_changed_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerPositionChanged,
+                            handle_position_changed_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerSeekableChanged,
+                            handle_seekable_changed_event, this);
+        libvlc_event_detach(eventManager, libvlc_MediaPlayerPausableChanged,
+                            handle_pausable_changed_event, this);
+    }
 }
 
-int  VLCPlugin::playlist_add_extended_untrusted(const char *mrl, int optc, const char **optv, libvlc_exception_t *ex)
+int  VLCPlugin::playlist_add_extended_untrusted(const char *mrl, int optc, const char **optv)
 {
     int item = -1;
-    libvlc_media_t *p_m = libvlc_media_new(_p_libvlc,mrl,ex);
-    if( libvlc_exception_raised(ex) )
+    libvlc_media_t *p_m = libvlc_media_new_location(_p_libvlc,mrl);
+    if( !p_m )
         return -1;
 
     for( int i = 0; i < optc; ++i )
-    {
-        libvlc_media_add_option_untrusted(p_m, optv[i],ex);
-        if( libvlc_exception_raised(ex) )
-        {
-            libvlc_media_release(p_m);
-            return -1;
-        }
-    }
+        libvlc_media_add_option_flag(p_m, optv[i], libvlc_media_option_unique);
 
     libvlc_media_list_lock(_p_mlist);
-    libvlc_media_list_add_media(_p_mlist,p_m,ex);
-    if( !libvlc_exception_raised(ex) )
-        item = libvlc_media_list_count(_p_mlist,ex)-1;
+    if( libvlc_media_list_add_media(_p_mlist,p_m) == 0 )
+        item = libvlc_media_list_count(_p_mlist)-1;
     libvlc_media_list_unlock(_p_mlist);
     libvlc_media_release(p_m);