+
+/*
+ * Async events
+ */
+void VLCPlugin::fireOnMediaPlayerNothingSpecialEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerNothingSpecialEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerOpeningEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerOpeningEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerBufferingEvent(long cache)
+{
+ 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_I4;
+ params.rgvarg[0].lVal = cache;
+ params.rgdispidNamedArgs = NULL;
+ params.cNamedArgs = 0;
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerBufferingEvent, ¶ms);
+};
+
+void VLCPlugin::fireOnMediaPlayerPlayingEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPlayingEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerPausedEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausedEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerEncounteredErrorEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerEncounteredErrorEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerEndReachedEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerEndReachedEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerStoppedEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerStoppedEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerForwardEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerForwardEvent, &dispparamsNoArgs);
+};
+
+void VLCPlugin::fireOnMediaPlayerBackwardEvent()
+{
+ DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerBackwardEvent, &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->fireOnMediaPlayerNothingSpecialEvent();
+ break;
+ case libvlc_MediaPlayerOpening:
+ plugin->fireOnMediaPlayerOpeningEvent();
+ break;
+ case libvlc_MediaPlayerBuffering:
+ plugin->fireOnMediaPlayerBufferingEvent(event->u.media_player_buffering.new_cache);
+ break;
+ case libvlc_MediaPlayerPlaying:
+ plugin->fireOnMediaPlayerPlayingEvent();
+ break;
+ case libvlc_MediaPlayerPaused:
+ plugin->fireOnMediaPlayerPausedEvent();
+ break;
+ case libvlc_MediaPlayerStopped:
+ plugin->fireOnMediaPlayerStoppedEvent();
+ break;
+ case libvlc_MediaPlayerForward:
+ plugin->fireOnMediaPlayerForwardEvent();
+ break;
+ case libvlc_MediaPlayerBackward:
+ plugin->fireOnMediaPlayerBackwardEvent();
+ break;
+ case libvlc_MediaPlayerEndReached:
+ plugin->fireOnMediaPlayerEndReachedEvent();
+ break;
+ case libvlc_MediaPlayerEncounteredError:
+ plugin->fireOnMediaPlayerEncounteredErrorEvent();
+ break;
+ }
+}
+
+void VLCPlugin::fireOnMediaPlayerTimeChangedEvent(long time)
+{
+ 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_I4;
+ params.rgvarg[0].lVal = time;
+ params.rgdispidNamedArgs = NULL;
+ params.cNamedArgs = 0;
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerTimeChangedEvent, ¶ms);
+};
+
+static void handle_time_changed_event(const libvlc_event_t* event, void *param)
+{
+ VLCPlugin *plugin = (VLCPlugin*)param;
+ plugin->fireOnMediaPlayerTimeChangedEvent(event->u.media_player_time_changed.new_time);
+}
+
+void VLCPlugin::fireOnMediaPlayerPositionChangedEvent(long position)
+{
+ 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_I4;
+ params.rgvarg[0].lVal = position;
+ params.rgdispidNamedArgs = NULL;
+ params.cNamedArgs = 0;
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPositionChangedEvent, ¶ms);
+};
+
+static void handle_position_changed_event(const libvlc_event_t* event, void *param)
+{
+ VLCPlugin *plugin = (VLCPlugin*)param;
+ plugin->fireOnMediaPlayerPositionChangedEvent(event->u.media_player_position_changed.new_position);
+}
+
+#define B(val) ((val) ? 0xFFFF : 0x0000)
+void VLCPlugin::fireOnMediaPlayerSeekableChangedEvent(VARIANT_BOOL seekable)
+{
+ 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_BOOL;
+ params.rgvarg[0].boolVal = seekable;
+ params.rgdispidNamedArgs = NULL;
+ params.cNamedArgs = 0;
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerSeekableChangedEvent, ¶ms);
+};
+
+static void handle_seekable_changed_event(const libvlc_event_t* event, void *param)
+{
+ VLCPlugin *plugin = (VLCPlugin*)param;
+ plugin->fireOnMediaPlayerSeekableChangedEvent(B(event->u.media_player_seekable_changed.new_seekable));
+}
+
+void VLCPlugin::fireOnMediaPlayerPausableChangedEvent(VARIANT_BOOL pausable)
+{
+ 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_BOOL;
+ params.rgvarg[0].boolVal = pausable;
+ params.rgdispidNamedArgs = NULL;
+ params.cNamedArgs = 0;
+ vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausableChangedEvent, ¶ms);
+};
+
+static void handle_pausable_changed_event(const libvlc_event_t* event, void *param)
+{
+ VLCPlugin *plugin = (VLCPlugin*)param;
+ plugin->fireOnMediaPlayerPausableChangedEvent(B(event->u.media_player_pausable_changed.new_pausable));
+}
+#undef B
+
+/* */
+
+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);
+
+ if( (idx < 0) || (idx >= count) )
+ goto bad_unlock;
+
+ _i_midx = idx;
+
+ p_m = libvlc_media_list_item_at_index(_p_mlist,_i_midx);
+ libvlc_media_list_unlock(_p_mlist);
+ 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);
+ if( _p_mplayer )
+ {
+ // 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 _p_mplayer ? true : false;
+
+bad_unlock:
+ libvlc_media_list_unlock(_p_mlist);
+ return false;
+}
+
+void VLCPlugin::set_player_window()
+{
+ // XXX FIXME no idea if this is correct or not
+ 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)
+{
+ int item = -1;
+ 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_flag(p_m, optv[i], libvlc_media_option_unique);
+
+ libvlc_media_list_lock(_p_mlist);
+ 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);
+
+ return item;
+}