X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fqt4%2Finput_manager.cpp;h=919f154a0c91b31b7045b1b9a620ca469b664db2;hb=8f3c41de941849f4ff5f2ae5975754c1907637c9;hp=312dce101a950b3442f5159ae5cc9a51358ea29f;hpb=ef65c9987986aac9563131c9cb74930ed067102f;p=vlc diff --git a/modules/gui/qt4/input_manager.cpp b/modules/gui/qt4/input_manager.cpp index 312dce101a..919f154a0c 100644 --- a/modules/gui/qt4/input_manager.cpp +++ b/modules/gui/qt4/input_manager.cpp @@ -29,6 +29,7 @@ #include "input_manager.hpp" #include +#include #include @@ -38,8 +39,22 @@ static int ItemChanged( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); static int PLItemChanged( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); +static int PLItemAppended( vlc_object_t *, const char *, + vlc_value_t, vlc_value_t, void * ); +static int PLItemRemoved( vlc_object_t *, const char *, + vlc_value_t, vlc_value_t, void * ); static int VolumeChanged( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); +static int SoundMuteChanged( vlc_object_t *, const char *, + vlc_value_t, vlc_value_t, void * ); + +static int RandomChanged( vlc_object_t *, const char *, + vlc_value_t, vlc_value_t, void * ); +static int LoopChanged( vlc_object_t *, const char *, + vlc_value_t, vlc_value_t, void * ); +static int RepeatChanged( vlc_object_t *, const char *, + vlc_value_t, vlc_value_t, void * ); + static int InputEvent( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); @@ -62,7 +77,7 @@ InputManager::InputManager( QObject *parent, intf_thread_t *_p_intf) : artUrl = ""; p_input = NULL; i_rate = 0; - i_input_id = 0; + p_item = NULL; b_video = false; timeA = 0; timeB = 0; @@ -92,12 +107,12 @@ void InputManager::setInput( input_thread_t *_p_input ) UpdateNavigation(); UpdateVout(); addCallbacks(); - i_input_id = input_GetItem( p_input )->i_id; + p_item = input_GetItem( p_input ); } else { p_input = NULL; - i_input_id = 0; + p_item = NULL; emit rateChanged( INPUT_RATE_DEFAULT ); } } @@ -112,7 +127,7 @@ void InputManager::delInput() delCallbacks(); i_old_playing_status = END_S; - i_input_id = 0; + p_item = NULL; oldName = ""; artUrl = ""; b_video = false; @@ -137,9 +152,10 @@ void InputManager::delInput() /* Reset all InfoPanels but stats */ emit artChanged( NULL ); emit infoChanged( NULL ); - emit metaChanged( (input_item_t *)NULL ); + emit currentMetaChanged( (input_item_t *)NULL ); emit encryptionChanged( false ); + emit recordingStateChanged( false ); } /* Convert the event from the callbacks in actions */ @@ -148,16 +164,12 @@ void InputManager::customEvent( QEvent *event ) int i_type = event->type(); IMEvent *ple = static_cast(event); + if( i_type == ItemChanged_Type ) + UpdateMeta( ple->p_item ); + if( !hasInput() ) return; -#ifndef NDEBUG - if( i_type != PositionUpdate_Type && - i_type != StatisticsUpdate_Type && - i_type != ItemChanged_Type ) - msg_Dbg( p_intf, "New Event: type %i", i_type ); -#endif - /* Actions */ switch( i_type ) { @@ -169,14 +181,13 @@ void InputManager::customEvent( QEvent *event ) break; case ItemChanged_Type: /* Ignore ItemChanged_Type event that does not apply to our input */ - if( i_input_id == ple->i_id ) + if( p_item == ple->p_item ) { UpdateStatus(); // UpdateName(); UpdateArt(); /* Update duration of file */ } - UpdateMeta( ple->i_id ); break; case ItemStateChanged_Type: // TODO: Fusion with above state @@ -254,8 +265,9 @@ static int ItemChanged( vlc_object_t *p_this, const char *psz_var, vlc_value_t oldval, vlc_value_t newval, void *param ) { InputManager *im = (InputManager*)param; + input_item_t *p_item = static_cast(newval.p_address); - IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int ); + IMEvent *event = new IMEvent( ItemChanged_Type, p_item ); QApplication::postEvent( im, event ); return VLC_SUCCESS; } @@ -269,73 +281,74 @@ static int InputEvent( vlc_object_t *p_this, const char *, switch( newval.i_int ) { case INPUT_EVENT_STATE: - event = new IMEvent( ItemStateChanged_Type, 0 ); + event = new IMEvent( ItemStateChanged_Type ); break; case INPUT_EVENT_RATE: - event = new IMEvent( ItemRateChanged_Type, 0 ); + event = new IMEvent( ItemRateChanged_Type ); break; - case INPUT_EVENT_TIMES: - event = new IMEvent( PositionUpdate_Type, 0 ); + case INPUT_EVENT_POSITION: + //case INPUT_EVENT_LENGTH: + event = new IMEvent( PositionUpdate_Type ); break; case INPUT_EVENT_TITLE: case INPUT_EVENT_CHAPTER: - event = new IMEvent( ItemTitleChanged_Type, 0 ); + event = new IMEvent( ItemTitleChanged_Type ); break; case INPUT_EVENT_ES: - event = new IMEvent( ItemEsChanged_Type, 0 ); + event = new IMEvent( ItemEsChanged_Type ); break; case INPUT_EVENT_TELETEXT: - event = new IMEvent( ItemTeletextChanged_Type, 0 ); + event = new IMEvent( ItemTeletextChanged_Type ); break; case INPUT_EVENT_STATISTICS: - event = new IMEvent( StatisticsUpdate_Type, 0 ); + event = new IMEvent( StatisticsUpdate_Type ); break; case INPUT_EVENT_VOUT: - event = new IMEvent( InterfaceVoutUpdate_Type, 0 ); + event = new IMEvent( InterfaceVoutUpdate_Type ); break; case INPUT_EVENT_AOUT: - event = new IMEvent( InterfaceAoutUpdate_Type, 0 ); + event = new IMEvent( InterfaceAoutUpdate_Type ); break; case INPUT_EVENT_ITEM_META: /* Codec MetaData + Art */ - event = new IMEvent( MetaChanged_Type, 0 ); + event = new IMEvent( MetaChanged_Type ); break; case INPUT_EVENT_ITEM_INFO: /* Codec Info */ - event = new IMEvent( InfoChanged_Type, 0 ); + event = new IMEvent( InfoChanged_Type ); break; case INPUT_EVENT_ITEM_NAME: - event = new IMEvent( NameChanged_Type, 0 ); + event = new IMEvent( NameChanged_Type ); break; case INPUT_EVENT_AUDIO_DELAY: case INPUT_EVENT_SUBTITLE_DELAY: - event = new IMEvent( SynchroChanged_Type, 0 ); + event = new IMEvent( SynchroChanged_Type ); break; case INPUT_EVENT_CACHE: - event = new IMEvent( CachingEvent_Type, 0 ); + event = new IMEvent( CachingEvent_Type ); break; case INPUT_EVENT_BOOKMARK: - event = new IMEvent( BookmarksChanged_Type, 0 ); + event = new IMEvent( BookmarksChanged_Type ); break; case INPUT_EVENT_RECORD: - event = new IMEvent( RecordingEvent_Type, 0 ); + event = new IMEvent( RecordingEvent_Type ); break; case INPUT_EVENT_PROGRAM: /* This is for PID changes */ - event = new IMEvent( ProgramChanged_Type, 0 ); + event = new IMEvent( ProgramChanged_Type ); break; case INPUT_EVENT_SIGNAL: /* This is for capture-card signals */ - /* event = new IMEvent( SignalChanged_Type, 0 ); + /* event = new IMEvent( SignalChanged_Type ); break; */ default: event = NULL; @@ -351,7 +364,7 @@ static int VbiEvent( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void *param ) { InputManager *im = (InputManager*)param; - IMEvent *event = new IMEvent( ItemTeletextChanged_Type, 0 ); + IMEvent *event = new IMEvent( ItemTeletextChanged_Type ); QApplication::postEvent( im, event ); return VLC_SUCCESS; @@ -393,19 +406,18 @@ void InputManager::UpdateNavigation() void InputManager::UpdateStatus() { /* Update playing status */ - vlc_value_t val; val.i_int = 0; - var_Get( p_input, "state", &val ); - if( i_old_playing_status != val.i_int ) + int state = var_GetInteger( p_input, "state" ); + if( i_old_playing_status != state ) { - i_old_playing_status = val.i_int; - emit statusChanged( val.i_int ); + i_old_playing_status = state; + emit statusChanged( state ); } } void InputManager::UpdateRate() { /* Update Rate */ - int i_new_rate = var_GetInteger( p_input, "rate"); + int i_new_rate = INPUT_RATE_DEFAULT / var_GetFloat( p_input, "rate" ); if( i_new_rate != i_rate ) { i_rate = i_new_rate; @@ -420,12 +432,7 @@ void InputManager::UpdateName() QString text; /* Try to get the Title, then the Name */ - char *psz_name = input_item_GetTitle( input_GetItem( p_input ) ); - if( EMPTY_STR( psz_name ) ) - { - free( psz_name ); - psz_name = input_item_GetName( input_GetItem( p_input ) ); - } + char *psz_name = input_item_GetTitleFbName( input_GetItem( p_input ) ); /* Try to get the nowplaying */ char *psz_nowplaying = @@ -593,12 +600,20 @@ void InputManager::UpdateArt() if( hasInput() ) { char *psz_art = input_item_GetArtURL( input_GetItem( p_input ) ); - url = psz_art; + if( psz_art && !strncmp( psz_art, "file://", 7 ) && + decode_URI( psz_art + 7 ) ) +#ifdef WIN32 + url = qfu( psz_art + 8 ); // Remove extra / starting on Win32. +#else + url = qfu( psz_art + 7 ); +#endif free( psz_art ); + + url = url.replace( "file://", "" ); + /* Taglib seems to define a attachment://, It won't work yet */ + url = url.replace( "attachment://", "" ); } - url = url.replace( "file://", QString("" ) ); - /* Taglib seems to define a attachment://, It won't work yet */ - url = url.replace( "attachment://", QString("" ) ); + /* Update Art meta */ emit artChanged( url ); } @@ -608,14 +623,14 @@ inline void InputManager::UpdateStats() emit statisticsUpdated( input_GetItem( p_input ) ); } -inline void InputManager::UpdateMeta( int id ) +inline void InputManager::UpdateMeta( input_item_t *p_item ) { - emit metaChanged( id ); + emit metaChanged( p_item ); } inline void InputManager::UpdateMeta() { - emit metaChanged( input_GetItem( p_input ) ); + emit currentMetaChanged( input_GetItem( p_input ) ); } inline void InputManager::UpdateInfo() @@ -664,8 +679,8 @@ void InputManager::sectionPrev() if( hasInput() ) { int i_type = var_Type( p_input, "next-chapter" ); - var_SetBool( p_input, (i_type & VLC_VAR_TYPE) != 0 ? - "prev-chapter":"prev-title", true ); + var_TriggerCallback( p_input, (i_type & VLC_VAR_TYPE) != 0 ? + "prev-chapter":"prev-title" ); } } @@ -674,8 +689,8 @@ void InputManager::sectionNext() if( hasInput() ) { int i_type = var_Type( p_input, "next-chapter" ); - var_SetBool( p_input, (i_type & VLC_VAR_TYPE) != 0 ? - "next-chapter":"next-title", true ); + var_TriggerCallback( p_input, (i_type & VLC_VAR_TYPE) != 0 ? + "next-chapter":"next-title" ); } } @@ -695,7 +710,7 @@ void InputManager::sectionMenu() if( !strcmp( text.p_list->p_values[i].psz_string, "Title" ) ) root = i; } - var_Change( p_input, "title 0", VLC_VAR_FREELIST, &val, &text ); + var_FreeList( &val, &text ); var_SetInteger( p_input, "title 0", root ); } @@ -763,7 +778,7 @@ void InputManager::activateTeletext( bool b_enable ) i = 0; var_SetInteger( p_input, "spu-es", b_enable ? list.p_list->p_values[i].i_int : -1 ); } - var_Change( p_input, "teletext-es", VLC_VAR_FREELIST, &list, &text ); + var_FreeList( &list, &text ); } } @@ -771,21 +786,21 @@ void InputManager::reverse() { if( hasInput() ) { - int i_rate = var_GetInteger( p_input, "rate" ); - var_SetInteger( p_input, "rate", -i_rate ); + float f_rate = var_GetFloat( p_input, "rate" ); + var_SetFloat( p_input, "rate", -f_rate ); } } void InputManager::slower() { if( hasInput() ) - var_SetVoid( p_input, "rate-slower" ); + var_TriggerCallback( p_input, "rate-slower" ); } void InputManager::faster() { if( hasInput() ) - var_SetVoid( p_input, "rate-faster" ); + var_TriggerCallback( p_input, "rate-faster" ); } void InputManager::littlefaster() @@ -801,13 +816,14 @@ void InputManager::littleslower() void InputManager::normalRate() { if( hasInput() ) - var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT ); + var_SetFloat( p_input, "rate", 1. ); } void InputManager::setRate( int new_rate ) { if( hasInput() ) - var_SetInteger( p_input, "rate", new_rate ); + var_SetFloat( p_input, "rate", + (float)INPUT_RATE_DEFAULT / (float)new_rate ); } void InputManager::jumpFwd() @@ -880,20 +896,32 @@ MainInputManager::MainInputManager( intf_thread_t *_p_intf ) var_AddCallback( THEPL, "item-change", ItemChanged, im ); var_AddCallback( THEPL, "item-current", PLItemChanged, this ); var_AddCallback( THEPL, "activity", PLItemChanged, this ); + var_AddCallback( THEPL, "playlist-item-append", PLItemAppended, this ); + var_AddCallback( THEPL, "playlist-item-deleted", PLItemRemoved, this ); + var_AddCallback( THEPL, "random", RandomChanged, this ); + var_AddCallback( THEPL, "repeat", RepeatChanged, this ); + var_AddCallback( THEPL, "loop", LoopChanged, this ); var_AddCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this ); + var_AddCallback( p_intf->p_libvlc, "volume-muted", SoundMuteChanged, this ); /* Warn our embedded IM about input changes */ CONNECT( this, inputChanged( input_thread_t * ), im, setInput( input_thread_t * ) ); - /* emit check if playlist has allready started playing */ - vlc_value_t val; - var_Change( THEPL, "item-current", VLC_VAR_CHOICESCOUNT, &val, NULL ); - - IMEvent *event = new IMEvent( ItemChanged_Type, val.i_int); - customEvent( event ); - delete event; + /* emit check if playlist has already started playing */ + input_thread_t *p_input = playlist_CurrentInput( THEPL ); + if( p_input ) + { + input_item_t *p_item = input_GetItem( p_input ); + if( p_item ) + { + IMEvent *event = new IMEvent( ItemChanged_Type, p_item ); + customEvent( event ); + delete event; + } + vlc_object_release( p_input ); + } } MainInputManager::~MainInputManager() @@ -906,11 +934,18 @@ MainInputManager::~MainInputManager() } var_DelCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this ); + var_DelCallback( p_intf->p_libvlc, "volume-muted", SoundMuteChanged, this ); var_DelCallback( THEPL, "activity", PLItemChanged, this ); var_DelCallback( THEPL, "item-change", ItemChanged, im ); var_DelCallback( THEPL, "item-current", PLItemChanged, this ); + var_DelCallback( THEPL, "playlist-item-append", PLItemAppended, this ); + var_DelCallback( THEPL, "playlist-item-deleted", PLItemRemoved, this ); + var_DelCallback( THEPL, "random", RandomChanged, this ); + var_DelCallback( THEPL, "repeat", RepeatChanged, this ); + var_DelCallback( THEPL, "loop", LoopChanged, this ); + } vout_thread_t* MainInputManager::getVout() @@ -926,27 +961,46 @@ aout_instance_t * MainInputManager::getAout() void MainInputManager::customEvent( QEvent *event ) { int type = event->type(); - if ( type != ItemChanged_Type && type != VolumeChanged_Type ) - return; + + PLEvent *plEv; // msg_Dbg( p_intf, "New MainIM Event of type: %i", type ); - if( type == VolumeChanged_Type ) + switch( type ) { + case VolumeChanged_Type: emit volumeChanged(); return; + case SoundMuteChanged_Type: + emit soundMuteChanged(); + return; + case PLItemAppended_Type: + plEv = static_cast( event ); + emit playlistItemAppended( plEv->i_item, plEv->i_parent ); + return; + case PLItemRemoved_Type: + plEv = static_cast( event ); + emit playlistItemRemoved( plEv->i_item ); + return; + case RandomChanged_Type: + emit randomChanged( var_GetBool( THEPL, "random" ) ); + return; + case LoopChanged_Type: + case RepeatChanged_Type: + notifyRepeatLoop(); + return; + default: + if( type != ItemChanged_Type ) return; } /* Should be PLItemChanged Event */ if( !p_intf->p_sys->b_isDialogProvider ) { - vlc_mutex_lock( &p_intf->change_lock ); if( p_input && ( p_input->b_dead || !vlc_object_alive (p_input) ) ) { emit inputChanged( p_input ); var_DelCallback( p_input, "state", PLItemChanged, this ); vlc_object_release( p_input ); p_input = NULL; - vlc_mutex_unlock( &p_intf->change_lock ); return; } @@ -959,7 +1013,6 @@ void MainInputManager::customEvent( QEvent *event ) emit inputChanged( p_input ); } } - vlc_mutex_unlock( &p_intf->change_lock ); } else { @@ -1005,18 +1058,48 @@ void MainInputManager::togglePlayPause() getIM()->togglePlayPause(); } +void MainInputManager::toggleRandom() +{ + var_ToggleBool( THEPL, "random" ); +} + +void MainInputManager::notifyRepeatLoop() +{ + int i_value = var_GetBool( THEPL, "loop" ) * REPEAT_ONE + + var_GetBool( THEPL, "repeat" ) * REPEAT_ALL; + + emit repeatLoopChanged( i_value ); +} + +void MainInputManager::loopRepeatLoopStatus() +{ + /* Toggle Normal -> Loop -> Repeat -> Normal ... */ + if( var_GetBool( THEPL, "repeat" ) ) + var_SetBool( THEPL, "repeat", false ); + else if( var_GetBool( THEPL, "loop" ) ) + { + var_SetBool( THEPL, "loop", false ); + var_SetBool( THEPL, "repeat", true ); + } + else + var_SetBool( THEPL, "loop", true ); +} + void MainInputManager::activatePlayQuit( bool b_exit ) { var_SetBool( THEPL, "play-and-exit", b_exit ); } -/* Static callbacks for MIM */ + +/**************************** + * Static callbacks for MIM * + ****************************/ static int PLItemChanged( vlc_object_t *p_this, const char *psz_var, - vlc_value_t oldval, vlc_value_t newval, void *param ) + vlc_value_t oldval, vlc_value_t, void *param ) { MainInputManager *mim = (MainInputManager*)param; - IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int ); + IMEvent *event = new IMEvent( ItemChanged_Type ); QApplication::postEvent( mim, event ); return VLC_SUCCESS; } @@ -1026,8 +1109,68 @@ static int VolumeChanged( vlc_object_t *p_this, const char *psz_var, { MainInputManager *mim = (MainInputManager*)param; - IMEvent *event = new IMEvent( VolumeChanged_Type, newval.i_int ); + IMEvent *event = new IMEvent( VolumeChanged_Type ); + QApplication::postEvent( mim, event ); + return VLC_SUCCESS; +} + +static int SoundMuteChanged( vlc_object_t *p_this, const char *psz_var, + vlc_value_t oldval, vlc_value_t newval, void *param ) +{ + MainInputManager *mim = (MainInputManager*)param; + + IMEvent *event = new IMEvent( SoundMuteChanged_Type ); + QApplication::postEvent( mim, event ); + return VLC_SUCCESS; +} + +static int PLItemAppended +( vlc_object_t * obj, const char *var, vlc_value_t old, vlc_value_t cur, void *data ) +{ + MainInputManager *mim = static_cast(data); + playlist_add_t *p_add = static_cast( cur.p_address ); + + PLEvent *event = new PLEvent( PLItemAppended_Type, p_add->i_item, p_add->i_node ); + QApplication::postEvent( mim, event ); + return VLC_SUCCESS; +} +static int PLItemRemoved +( vlc_object_t * obj, const char *var, vlc_value_t old, vlc_value_t cur, void *data ) +{ + MainInputManager *mim = static_cast(data); + + PLEvent *event = new PLEvent( PLItemRemoved_Type, cur.i_int, 0 ); QApplication::postEvent( mim, event ); return VLC_SUCCESS; } +static int RandomChanged +( vlc_object_t * obj, const char *var, vlc_value_t old, vlc_value_t cur, void *data ) +{ + MainInputManager *mim = static_cast(data); + + IMEvent *event = new IMEvent( RandomChanged_Type ); + QApplication::postEvent( mim, event ); + return VLC_SUCCESS; +} + +/* Probably could be merged with next callback */ +static int LoopChanged +( vlc_object_t * obj, const char *var, vlc_value_t old, vlc_value_t cur, void *data ) +{ + MainInputManager *mim = static_cast(data); + + IMEvent *event = new IMEvent( LoopChanged_Type ); + QApplication::postEvent( mim, event ); + return VLC_SUCCESS; +} + +static int RepeatChanged +( vlc_object_t * obj, const char *var, vlc_value_t old, vlc_value_t cur, void *data ) +{ + MainInputManager *mim = static_cast(data); + + IMEvent *event = new IMEvent( RepeatChanged_Type ); + QApplication::postEvent( mim, event ); + return VLC_SUCCESS; +}