]> git.sesse.net Git - vlc/blobdiff - modules/control/hotkeys.c
Remove vlc_input.h from vlc_playlist.h
[vlc] / modules / control / hotkeys.c
index 4547316d56d635d9fe910f9e396c23173ceefe23..d1a898f8bf370f274c0f6d7043a244fe4c12d7bf 100644 (file)
@@ -48,6 +48,13 @@ struct intf_sys_t
 {
     vout_thread_t      *p_last_vout;
     int slider_chan;
+
+    /*subtitle_delaybookmarks: placeholder for storing subtitle sync timestamps*/
+    struct
+    {
+        int64_t i_time_subtitle;
+        int64_t i_time_audio;
+    } subtitle_delaybookmarks;
 };
 
 /*****************************************************************************
@@ -101,6 +108,8 @@ static int Open( vlc_object_t *p_this )
     p_intf->p_sys = p_sys;
 
     p_sys->p_last_vout = NULL;
+    p_sys->subtitle_delaybookmarks.i_time_audio = 0;
+    p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;
 
     var_AddCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf );
     return VLC_SUCCESS;
@@ -163,22 +172,37 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
 
         /* Playlist actions (including audio) */
         case ACTIONID_LOOP:
+        {
             /* Toggle Normal -> Loop -> Repeat -> Normal ... */
+            const char *mode;
             if( var_GetBool( p_playlist, "repeat" ) )
+            {
                 var_SetBool( p_playlist, "repeat", false );
+                mode = N_("Off");
+            }
             else
             if( var_GetBool( p_playlist, "loop" ) )
             { /* FIXME: this is not atomic, we should use a real tristate */
                 var_SetBool( p_playlist, "loop", false );
                 var_SetBool( p_playlist, "repeat", true );
+                mode = N_("One");
             }
             else
+            {
                 var_SetBool( p_playlist, "loop", true );
+                mode = N_("All");
+            }
+            DisplayMessage( p_vout, _("Loop: %s"), vlc_gettext(mode) );
             break;
+        }
 
         case ACTIONID_RANDOM:
-            var_ToggleBool( p_playlist, "random" );
+        {
+            const bool state = var_ToggleBool( p_playlist, "random" );
+            DisplayMessage( p_vout, _("Random: %s"),
+                            vlc_gettext( state ? N_("On") : N_("Off") ) );
             break;
+        }
 
         case ACTIONID_NEXT:
             DisplayMessage( p_vout, _("Next") );
@@ -262,18 +286,24 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
             break;
         }
         case ACTIONID_VOL_MUTE:
-            if( playlist_MuteToggle( p_playlist ) == 0 )
+        {
+            int mute = playlist_MuteGet( p_playlist );
+            if( mute < 0 )
+                break;
+            mute = !mute;
+            if( playlist_MuteSet( p_playlist, mute ) )
+                break;
+
+            float vol = playlist_VolumeGet( p_playlist );
+            if( mute || vol == 0.f )
             {
-                float vol = playlist_VolumeGet( p_playlist );
-                if( playlist_MuteGet( p_playlist ) > 0 || vol == 0.f )
-                {
-                    ClearChannels( p_intf, p_vout );
-                    DisplayIcon( p_vout, OSD_MUTE_ICON );
-                }
-                else
-                    DisplayVolume( p_intf, p_vout, vol );
+                ClearChannels( p_intf, p_vout );
+                DisplayIcon( p_vout, OSD_MUTE_ICON );
             }
+            else
+                DisplayVolume( p_intf, p_vout, vol );
             break;
+        }
 
         case ACTIONID_AUDIODEVICE_CYCLE:
         {
@@ -326,9 +356,9 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
             break;
 
         case ACTIONID_PLAY:
-            if( p_input && var_GetFloat( p_input, "rate" ) != 1. )
+            if( p_input && var_GetFloat( p_input, "rate" ) != 1.f )
                 /* Return to normal speed */
-                var_SetFloat( p_input, "rate", 1. );
+                var_SetFloat( p_input, "rate", 1.f );
             else
             {
                 ClearChannels( p_intf, p_vout );
@@ -339,10 +369,10 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
 
         /* Playlist + video output actions */
         case ACTIONID_WALLPAPER:
-        {   /* FIXME: this is invalid if not using DirectX output!!! */
-            vlc_object_t *obj = p_vout ? VLC_OBJECT(p_vout)
-                                       : VLC_OBJECT(p_playlist);
-            var_ToggleBool( obj, "video-wallpaper" );
+        {
+            bool wp = var_ToggleBool( p_playlist, "video-wallpaper" );
+            if( p_vout )
+                var_SetBool( p_vout, "video-wallpaper", wp );
             break;
         }
 
@@ -373,18 +403,104 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
             }
             break;
 
+        case ACTIONID_SUBSYNC_MARKAUDIO:
+        {
+            p_sys->subtitle_delaybookmarks.i_time_audio = mdate();
+            DisplayMessage( p_vout, _("Sub sync: bookmarked audio time"));
+            break;
+        }
+        case ACTIONID_SUBSYNC_MARKSUB:
+            if( p_input )
+            {
+                vlc_value_t val, list, list2;
+                int i_count;
+                var_Get( p_input, "spu-es", &val );
+
+                var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
+                            &list, &list2 );
+                i_count = list.p_list->i_count;
+                if( i_count < 1 || val.i_int < 0 )
+                {
+                    DisplayMessage( p_vout, _("No active subtitle") );
+                    var_FreeList( &list, &list2 );
+                    break;
+                }
+                p_sys->subtitle_delaybookmarks.i_time_subtitle = mdate();
+                DisplayMessage( p_vout,
+                                _("Sub sync: bookmarked subtitle time"));
+                var_FreeList( &list, &list2 );
+            }
+            break;
+        case ACTIONID_SUBSYNC_APPLY:
+        {
+            /* Warning! Can yield a pause in the playback.
+             * For example, the following succession of actions will yield a 5 second delay :
+             * - Pressing Shift-H (ACTIONID_SUBSYNC_MARKAUDIO)
+             * - wait 5 second
+             * - Press Shift-J (ACTIONID_SUBSYNC_MARKSUB)
+             * - Press Shift-K (ACTIONID_SUBSYNC_APPLY)
+             * --> 5 seconds pause
+             * This is due to var_SetTime() (and ultimately UpdatePtsDelay())
+             * which causes the video to pause for an equivalent duration
+             * (This problem is also present in the "Track synchronization" window) */
+            if ( p_input )
+            {
+                if ( (p_sys->subtitle_delaybookmarks.i_time_audio == 0) || (p_sys->subtitle_delaybookmarks.i_time_subtitle == 0) )
+                {
+                    DisplayMessage( p_vout, _( "Sub sync: set bookmarks first!" ) );
+                }
+                else
+                {
+                    int64_t i_current_subdelay = var_GetTime( p_input, "spu-delay" );
+                    int64_t i_additional_subdelay = p_sys->subtitle_delaybookmarks.i_time_audio - p_sys->subtitle_delaybookmarks.i_time_subtitle;
+                    int64_t i_total_subdelay = i_current_subdelay + i_additional_subdelay;
+                    var_SetTime( p_input, "spu-delay", i_total_subdelay);
+                    ClearChannels( p_intf, p_vout );
+                    DisplayMessage( p_vout, _( "Sub sync: corrected %i ms (total delay = %i ms)" ),
+                                            (int)(i_additional_subdelay / 1000),
+                                            (int)(i_total_subdelay / 1000) );
+                    p_sys->subtitle_delaybookmarks.i_time_audio = 0;
+                    p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;
+                }
+            }
+            break;
+        }
+        case ACTIONID_SUBSYNC_RESET:
+        {
+            var_SetTime( p_input, "spu-delay", 0);
+            ClearChannels( p_intf, p_vout );
+            DisplayMessage( p_vout, _( "Sub sync: delay reset" ) );
+            p_sys->subtitle_delaybookmarks.i_time_audio = 0;
+            p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;
+            break;
+        }
+
         case ACTIONID_SUBDELAY_DOWN:
         case ACTIONID_SUBDELAY_UP:
         {
             int diff = (i_action == ACTIONID_SUBDELAY_UP) ? 50000 : -50000;
             if( p_input )
             {
+                vlc_value_t val, list, list2;
+                int i_count;
+                var_Get( p_input, "spu-es", &val );
+
+                var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
+                            &list, &list2 );
+                i_count = list.p_list->i_count;
+                if( i_count < 1 || val.i_int < 0 )
+                {
+                    DisplayMessage( p_vout, _("No active subtitle") );
+                    var_FreeList( &list, &list2 );
+                    break;
+                }
                 int64_t i_delay = var_GetTime( p_input, "spu-delay" ) + diff;
 
                 var_SetTime( p_input, "spu-delay", i_delay );
                 ClearChannels( p_intf, p_vout );
                 DisplayMessage( p_vout, _( "Subtitle delay %i ms" ),
                                 (int)(i_delay/1000) );
+                var_FreeList( &list, &list2 );
             }
             break;
         }
@@ -475,12 +591,63 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
                     i = 0;
                 else
                     i++;
-                var_Set( p_input, "spu-es", list.p_list->p_values[i] );
+                var_SetInteger( p_input, "spu-es", list.p_list->p_values[i].i_int );
+                var_SetInteger( p_input, "spu-choice", list.p_list->p_values[i].i_int );
                 DisplayMessage( p_vout, _("Subtitle track: %s"),
                                 list2.p_list->p_values[i].psz_string );
                 var_FreeList( &list, &list2 );
             }
             break;
+        case ACTIONID_SUBTITLE_TOGGLE:
+            if( p_input )
+            {
+                vlc_value_t list, list2;
+                int i_count, i_sel_index, i_sel_id, i_old_id, i_new_index;
+                i_old_id = var_GetInteger( p_input, "spu-es" );
+                i_sel_id = var_GetInteger( p_input, "spu-choice" );
+
+                var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
+                            &list, &list2 );
+                i_count = list.p_list->i_count;
+                if( i_count <= 1 )
+                {
+                    DisplayMessage( p_vout, _("Subtitle track: %s"),
+                                    _("N/A") );
+                    var_FreeList( &list, &list2 );
+                    break;
+                }
+                for( i_sel_index = 0; i_sel_index < i_count; i_sel_index++ )
+                {
+                    if( i_sel_id == list.p_list->p_values[i_sel_index].i_int )
+                    {
+                        break;
+                    }
+                }
+                /* if there is nothing to toggle choose the first track */
+                if( !i_sel_index ) {
+                    i_sel_index = 1;
+                    i_sel_id = list.p_list->p_values[1].i_int;
+                    var_SetInteger( p_input, "spu-choice", i_sel_id );
+                }
+
+                i_new_index = 0;
+                if( i_old_id != i_sel_id )
+                {
+                    if( i_sel_index >= i_count )
+                    {
+                        var_SetInteger( p_input, "spu-choice", list.p_list->p_values[0].i_int );
+                    }
+                    else
+                    {
+                        i_new_index = i_sel_index;
+                    }
+                }
+                var_SetInteger( p_input, "spu-es", list.p_list->p_values[i_new_index].i_int );
+                DisplayMessage( p_vout, _("Subtitle track: %s"),
+                                list2.p_list->p_values[i_new_index].psz_string );
+                var_FreeList( &list, &list2 );
+            }
+            break;
         case ACTIONID_PROGRAM_SID_NEXT:
         case ACTIONID_PROGRAM_SID_PREV:
             if( p_input )
@@ -617,9 +784,13 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
 
         case ACTIONID_TOGGLE_FULLSCREEN:
         {
-            bool fs = var_ToggleBool( p_playlist, "fullscreen" );
             if( p_vout )
-                var_SetBool( p_vout, "fullscreen", fs );
+            {
+                bool fs = var_ToggleBool( p_vout, "fullscreen" );
+                var_SetBool( p_playlist, "fullscreen", fs );
+            }
+            else
+                var_ToggleBool( p_playlist, "fullscreen" );
             break;
         }
 
@@ -829,7 +1000,7 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
 
                     char *psz_mode = var_GetString( p_vout, "deinterlace-mode" );
                     vlc_value_t vlist, tlist;
-                    if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ) >= 0 )
+                    if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ) )
                     {
                         const char *psz_text = NULL;
                         for( int i = 0; i < vlist.p_list->i_count; i++ )
@@ -854,7 +1025,7 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
             {
                 char *psz_mode = var_GetString( p_vout, "deinterlace-mode" );
                 vlc_value_t vlist, tlist;
-                if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ) >= 0 )
+                if( psz_mode && !var_Change( p_vout, "deinterlace-mode", VLC_VAR_GETCHOICES, &vlist, &tlist ))
                 {
                     const char *psz_text = NULL;
                     int i;
@@ -891,14 +1062,33 @@ static int PutAction( intf_thread_t *p_intf, int i_action )
         case ACTIONID_SUBPOS_DOWN:
         case ACTIONID_SUBPOS_UP:
         {
-            int i_pos;
-            if( i_action == ACTIONID_SUBPOS_DOWN )
-                i_pos = var_DecInteger( p_vout, "sub-margin" );
-            else
-                i_pos = var_IncInteger( p_vout, "sub-margin" );
+            if( p_input )
+            {
+                vlc_value_t val, list, list2;
+                int i_count;
+                var_Get( p_input, "spu-es", &val );
 
-            ClearChannels( p_intf, p_vout );
-            DisplayMessage( p_vout, _( "Subtitle position %d px" ), i_pos );
+                var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
+                            &list, &list2 );
+                i_count = list.p_list->i_count;
+                if( i_count < 1 || val.i_int < 0 )
+                {
+                    DisplayMessage( p_vout,
+                                    _("Subtitle position: no active subtitle") );
+                    var_FreeList( &list, &list2 );
+                    break;
+                }
+
+                int i_pos;
+                if( i_action == ACTIONID_SUBPOS_DOWN )
+                    i_pos = var_DecInteger( p_vout, "sub-margin" );
+                else
+                    i_pos = var_IncInteger( p_vout, "sub-margin" );
+
+                ClearChannels( p_intf, p_vout );
+                DisplayMessage( p_vout, _( "Subtitle position %d px" ), i_pos );
+                var_FreeList( &list, &list2 );
+            }
             break;
         }
 
@@ -1035,7 +1225,7 @@ static void DisplayVolume( intf_thread_t *p_intf, vout_thread_t *p_vout,
 
 static void DisplayRate( vout_thread_t *p_vout, float f_rate )
 {
-    DisplayMessage( p_vout, _("Speed: %.2fx"), f_rate );
+    DisplayMessage( p_vout, _("Speed: %.2fx"), (double) f_rate );
 }
 
 static float AdjustRateFine( vlc_object_t *p_obj, const int i_dir )