X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fhotkeys.c;h=49b9c4d8b1e4ea2c78616cf1896c667ea25d3149;hb=56220f86120b3d7b7d8c7b2957befede19f669b6;hp=c9b66396694e4a4ed2877892932cc176426411f5;hpb=57766ff3471c43f045921118dddc64e499547827;p=vlc diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c index c9b6639669..49b9c4d8b1 100644 --- a/modules/control/hotkeys.c +++ b/modules/control/hotkeys.c @@ -30,32 +30,32 @@ # include "config.h" #endif +#define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS #include #include #include #include -#include #include -#include +#include +#include #include #include #include "math.h" -#define CHANNELS_NUMBER 4 -#define VOLUME_TEXT_CHAN p_intf->p_sys->p_channels[ 0 ] -#define VOLUME_WIDGET_CHAN p_intf->p_sys->p_channels[ 1 ] -#define POSITION_TEXT_CHAN p_intf->p_sys->p_channels[ 2 ] -#define POSITION_WIDGET_CHAN p_intf->p_sys->p_channels[ 3 ] - /***************************************************************************** * intf_sys_t: description and status of FB interface *****************************************************************************/ struct intf_sys_t { vout_thread_t *p_last_vout; - int p_channels[ CHANNELS_NUMBER ]; /* contains registered - * channel IDs */ - int i_mousewheel_mode; + int slider_chan; + + /*subtitle_delaybookmarks: placeholder for storing subtitle sync timestamps*/ + struct + { + int64_t i_time_subtitle; + int64_t i_time_audio; + } subtitle_delaybookmarks; }; /***************************************************************************** @@ -65,18 +65,19 @@ static int Open ( vlc_object_t * ); static void Close ( vlc_object_t * ); static int ActionEvent( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); -static int SpecialKeyEvent( vlc_object_t *, char const *, - vlc_value_t, vlc_value_t, void * ); static void PlayBookmark( intf_thread_t *, int ); static void SetBookmark ( intf_thread_t *, int ); static void DisplayPosition( intf_thread_t *, vout_thread_t *, input_thread_t * ); -static void DisplayVolume ( intf_thread_t *, vout_thread_t *, audio_volume_t ); +static void DisplayVolume( intf_thread_t *, vout_thread_t *, float ); static void DisplayRate ( vout_thread_t *, float ); -static float AdjustRateFine( input_thread_t *, const int ); +static float AdjustRateFine( vlc_object_t *, const int ); static void ClearChannels ( intf_thread_t *, vout_thread_t * ); -#define DisplayMessage(vout, fmt, ...) \ - do { if(vout) vout_OSDMessage(vout, fmt, __VA_ARGS__); } while(0) +#define DisplayMessage(vout, ...) \ + do { \ + if (vout) \ + vout_OSDMessage(vout, SPU_DEFAULT_CHANNEL, __VA_ARGS__); \ + } while(0) #define DisplayIcon(vout, icon) \ do { if(vout) vout_OSDIcon(vout, SPU_DEFAULT_CHANNEL, icon); } while(0) @@ -84,18 +85,6 @@ static void ClearChannels ( intf_thread_t *, vout_thread_t * ); * Module descriptor *****************************************************************************/ -enum{ - MOUSEWHEEL_VOLUME, - MOUSEWHEEL_POSITION, - NO_MOUSEWHEEL, -}; - -static const int i_mode_list[] = - { MOUSEWHEEL_VOLUME, MOUSEWHEEL_POSITION, NO_MOUSEWHEEL }; - -static const char *const psz_mode_list_text[] = - { N_("Volume Control"), N_("Position Control"), N_("Ignore") }; - vlc_module_begin () set_shortname( N_("Hotkeys") ) set_description( N_("Hotkeys management interface") ) @@ -104,12 +93,6 @@ vlc_module_begin () set_category( CAT_INTERFACE ) set_subcategory( SUBCAT_INTERFACE_HOTKEYS ) - add_integer( "hotkeys-mousewheel-mode", MOUSEWHEEL_VOLUME, NULL, - N_("MouseWheel x-axis Control"), - N_("MouseWheel x-axis can control volume, position or " - "mousewheel event can be ignored"), false ) - change_integer_list( i_mode_list, psz_mode_list_text, NULL ) - vlc_module_end () /***************************************************************************** @@ -124,13 +107,11 @@ static int Open( vlc_object_t *p_this ) return VLC_ENOMEM; p_intf->p_sys = p_sys; - p_intf->pf_run = NULL; p_sys->p_last_vout = NULL; - p_intf->p_sys->i_mousewheel_mode = - var_InheritInteger( p_intf, "hotkeys-mousewheel-mode" ); + p_sys->subtitle_delaybookmarks.i_time_audio = 0; + p_sys->subtitle_delaybookmarks.i_time_subtitle = 0; - var_AddCallback( p_intf->p_libvlc, "key-pressed", SpecialKeyEvent, p_intf ); var_AddCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf ); return VLC_SUCCESS; } @@ -144,7 +125,6 @@ static void Close( vlc_object_t *p_this ) intf_sys_t *p_sys = p_intf->p_sys; var_DelCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf ); - var_DelCallback( p_intf->p_libvlc, "key-pressed", SpecialKeyEvent, p_intf ); /* Destroy structure */ free( p_sys ); @@ -161,165 +141,223 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) /* Update the vout */ vout_thread_t *p_vout = p_input ? input_GetVout( p_input ) : NULL; - /* Update the aout */ - aout_instance_t *p_aout = p_input ? input_GetAout( p_input ) : NULL; - /* Register OSD channels */ /* FIXME: this check can fail if the new vout is reallocated at the same * address as the old one... We should rather listen to vout events. * Alternatively, we should keep a reference to the vout thread. */ if( p_vout && p_vout != p_sys->p_last_vout ) - for( unsigned i = 0; i < CHANNELS_NUMBER; i++ ) - p_intf->p_sys->p_channels[i] = vout_RegisterSubpictureChannel( p_vout ); + p_sys->slider_chan = vout_RegisterSubpictureChannel( p_vout ); p_sys->p_last_vout = p_vout; /* Quit */ switch( i_action ) { + /* Libvlc / interface actions */ case ACTIONID_QUIT: libvlc_Quit( p_intf->p_libvlc ); ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Quit" ) ); + DisplayMessage( p_vout, _( "Quit" ) ); break; - /* Volume and audio actions */ - case ACTIONID_VOL_UP: - { - audio_volume_t i_newvol; - aout_VolumeUp( p_playlist, 1, &i_newvol ); - DisplayVolume( p_intf, p_vout, i_newvol ); + case ACTIONID_INTF_TOGGLE_FSC: + case ACTIONID_INTF_HIDE: + var_TriggerCallback( p_intf->p_libvlc, "intf-toggle-fscontrol" ); break; - } - - case ACTIONID_VOL_DOWN: - { - audio_volume_t i_newvol; - aout_VolumeDown( p_playlist, 1, &i_newvol ); - DisplayVolume( p_intf, p_vout, i_newvol ); + case ACTIONID_INTF_BOSS: + var_TriggerCallback( p_intf->p_libvlc, "intf-boss" ); + break; + case ACTIONID_INTF_POPUP_MENU: + var_TriggerCallback( p_intf->p_libvlc, "intf-popupmenu" ); break; - } - case ACTIONID_VOL_MUTE: + /* Playlist actions (including audio) */ + case ACTIONID_LOOP: { - audio_volume_t i_newvol = -1; - aout_ToggleMute( p_playlist, &i_newvol ); - if( p_vout ) + /* Toggle Normal -> Loop -> Repeat -> Normal ... */ + const char *mode; + if( var_GetBool( p_playlist, "repeat" ) ) { - if( i_newvol == 0 ) - { - ClearChannels( p_intf, p_vout ); - DisplayIcon( p_vout, OSD_MUTE_ICON ); - } - else - DisplayVolume( p_intf, p_vout, i_newvol ); + 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; } - /* Interface showing */ - case ACTIONID_INTF_SHOW: - var_SetBool( p_intf->p_libvlc, "intf-show", true ); + case ACTIONID_RANDOM: + { + const bool state = var_ToggleBool( p_playlist, "random" ); + DisplayMessage( p_vout, _("Random: %s"), + vlc_gettext( state ? N_("On") : N_("Off") ) ); break; + } - case ACTIONID_INTF_HIDE: - var_SetBool( p_intf->p_libvlc, "intf-show", false ); + case ACTIONID_NEXT: + DisplayMessage( p_vout, _("Next") ); + playlist_Next( p_playlist ); + break; + case ACTIONID_PREV: + DisplayMessage( p_vout, _("Previous") ); + playlist_Prev( p_playlist ); break; - /* Video Output actions */ - case ACTIONID_SNAPSHOT: - if( p_vout ) - var_TriggerCallback( p_vout, "video-snapshot" ); + case ACTIONID_STOP: + playlist_Stop( p_playlist ); break; - case ACTIONID_TOGGLE_FULLSCREEN: + case ACTIONID_RATE_NORMAL: + var_SetFloat( p_playlist, "rate", 1.f ); + DisplayRate( p_vout, 1.f ); + break; + case ACTIONID_FASTER: + var_TriggerCallback( p_playlist, "rate-faster" ); + DisplayRate( p_vout, var_GetFloat( p_playlist, "rate" ) ); + break; + case ACTIONID_SLOWER: + var_TriggerCallback( p_playlist, "rate-slower" ); + DisplayRate( p_vout, var_GetFloat( p_playlist, "rate" ) ); + break; + case ACTIONID_RATE_FASTER_FINE: + case ACTIONID_RATE_SLOWER_FINE: { - bool fs = var_ToggleBool( p_playlist, "fullscreen" ); - if( p_vout ) - var_SetBool( p_vout, "fullscreen", fs ); + const int i_dir = i_action == ACTIONID_RATE_FASTER_FINE ? 1 : -1; + float rate = AdjustRateFine( VLC_OBJECT(p_playlist), i_dir ); + + var_SetFloat( p_playlist, "rate", rate ); + DisplayRate( p_vout, rate ); break; } - case ACTIONID_LEAVE_FULLSCREEN: - if( p_vout ) - var_SetBool( p_vout, "fullscreen", false ); - var_SetBool( p_playlist, "fullscreen", false ); + case ACTIONID_PLAY_BOOKMARK1: + case ACTIONID_PLAY_BOOKMARK2: + case ACTIONID_PLAY_BOOKMARK3: + case ACTIONID_PLAY_BOOKMARK4: + case ACTIONID_PLAY_BOOKMARK5: + case ACTIONID_PLAY_BOOKMARK6: + case ACTIONID_PLAY_BOOKMARK7: + case ACTIONID_PLAY_BOOKMARK8: + case ACTIONID_PLAY_BOOKMARK9: + case ACTIONID_PLAY_BOOKMARK10: + PlayBookmark( p_intf, i_action - ACTIONID_PLAY_BOOKMARK1 + 1 ); break; - case ACTIONID_ZOOM_QUARTER: - case ACTIONID_ZOOM_HALF: - case ACTIONID_ZOOM_ORIGINAL: - case ACTIONID_ZOOM_DOUBLE: - if( p_vout ) - { - float f; - switch( i_action ) - { - case ACTIONID_ZOOM_QUARTER: f = 0.25; break; - case ACTIONID_ZOOM_HALF: f = 0.5; break; - case ACTIONID_ZOOM_ORIGINAL: f = 1.; break; - /*case ACTIONID_ZOOM_DOUBLE:*/ - default: f = 2.; break; - } - var_SetFloat( p_vout, "zoom", f ); - } + case ACTIONID_SET_BOOKMARK1: + case ACTIONID_SET_BOOKMARK2: + case ACTIONID_SET_BOOKMARK3: + case ACTIONID_SET_BOOKMARK4: + case ACTIONID_SET_BOOKMARK5: + case ACTIONID_SET_BOOKMARK6: + case ACTIONID_SET_BOOKMARK7: + case ACTIONID_SET_BOOKMARK8: + case ACTIONID_SET_BOOKMARK9: + case ACTIONID_SET_BOOKMARK10: + SetBookmark( p_intf, i_action - ACTIONID_SET_BOOKMARK1 + 1 ); break; - - 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" ); + case ACTIONID_PLAY_CLEAR: + { + playlist_t *p_playlist = pl_Get( p_intf ); + playlist_Clear( p_playlist, pl_Unlocked ); + break; + } + case ACTIONID_VOL_UP: + { + float vol; + if( playlist_VolumeUp( p_playlist, 1, &vol ) == 0 ) + DisplayVolume( p_intf, p_vout, vol ); + break; + } + case ACTIONID_VOL_DOWN: + { + float vol; + if( playlist_VolumeDown( p_playlist, 1, &vol ) == 0 ) + DisplayVolume( p_intf, p_vout, vol ); break; } + case ACTIONID_VOL_MUTE: + { + int mute = playlist_MuteGet( p_playlist ); + if( mute < 0 ) + break; + mute = !mute; + if( playlist_MuteSet( p_playlist, mute ) ) + break; - /* Playlist actions */ - case ACTIONID_LOOP: - /* Toggle Normal -> Loop -> Repeat -> Normal ... */ - if( var_GetBool( p_playlist, "repeat" ) ) - var_SetBool( p_playlist, "repeat", false ); - 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 ); + float vol = playlist_VolumeGet( p_playlist ); + if( mute || vol == 0.f ) + { + ClearChannels( p_intf, p_vout ); + DisplayIcon( p_vout, OSD_MUTE_ICON ); } else - var_SetBool( p_playlist, "loop", true ); + DisplayVolume( p_intf, p_vout, vol ); break; + } - case ACTIONID_RANDOM: + case ACTIONID_AUDIODEVICE_CYCLE: { - var_ToggleBool( p_playlist, "random" ); + audio_output_t *p_aout = playlist_GetAout( p_playlist ); + if( p_aout == NULL ) + break; + + char **ids, **names; + int n = aout_DevicesList( p_aout, &ids, &names ); + if( n == -1 ) + break; + + char *dev = aout_DeviceGet( p_aout ); + const char *devstr = (dev != NULL) ? dev : ""; + + int idx = 0; + for( int i = 0; i < n; i++ ) + { + if( !strcmp(devstr, ids[i]) ) + idx = (i + 1) % n; + } + free( dev ); + + if( !aout_DeviceSet( p_aout, ids[idx] ) ) + DisplayMessage( p_vout, _("Audio Device: %s"), names[idx] ); + vlc_object_release( p_aout ); + + for( int i = 0; i < n; i++ ) + { + free( ids[i] ); + free( names[i] ); + } + free( ids ); + free( names ); break; } + /* Playlist + input actions */ case ACTIONID_PLAY_PAUSE: if( p_input ) { ClearChannels( p_intf, p_vout ); int state = var_GetInteger( p_input, "state" ); - if( state != PAUSE_S ) - { - DisplayIcon( p_vout, OSD_PAUSE_ICON ); - state = PAUSE_S; - } - else - { - DisplayIcon( p_vout, OSD_PLAY_ICON ); - state = PLAYING_S; - } - var_SetInteger( p_input, "state", state ); + DisplayIcon( p_vout, state != PAUSE_S ? OSD_PAUSE_ICON : OSD_PLAY_ICON ); } - else - playlist_Play( p_playlist ); + playlist_TogglePause( p_playlist ); 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 ); @@ -328,116 +366,161 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) } break; - case ACTIONID_AUDIODEVICE_CYCLE: + /* Playlist + video output actions */ + case ACTIONID_WALLPAPER: { - if( !p_aout ) - break; + bool wp = var_ToggleBool( p_playlist, "video-wallpaper" ); + if( p_vout ) + var_SetBool( p_vout, "video-wallpaper", wp ); + break; + } - vlc_value_t val, list, list2; - int i_count, i; + /* Input actions */ + case ACTIONID_PAUSE: + if( p_input && var_GetInteger( p_input, "state" ) != PAUSE_S ) + { + ClearChannels( p_intf, p_vout ); + DisplayIcon( p_vout, OSD_PAUSE_ICON ); + var_SetInteger( p_input, "state", PAUSE_S ); + } + break; - var_Get( p_aout, "audio-device", &val ); - var_Change( p_aout, "audio-device", VLC_VAR_GETCHOICES, - &list, &list2 ); - i_count = list.p_list->i_count; + case ACTIONID_RECORD: + if( p_input && var_GetBool( p_input, "can-record" ) ) + { + const bool on = var_ToggleBool( p_input, "record" ); + DisplayMessage( p_vout, vlc_gettext(on + ? N_("Recording") : N_("Recording done")) ); + } + break; - if( i_count > 1 ) + case ACTIONID_FRAME_NEXT: + if( p_input ) { - for( i = 0; i < i_count; i++ ) - { - if( val.i_int == list.p_list->p_values[i].i_int ) - { - break; - } - } - if( i == i_count ) + var_TriggerCallback( p_input, "frame-next" ); + DisplayMessage( p_vout, _("Next frame") ); + } + 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 ) { - msg_Warn( p_aout, - "invalid current audio device, selecting 0" ); - var_Set( p_aout, "audio-device", - list.p_list->p_values[0] ); - i = 0; + DisplayMessage( p_vout, _("No active subtitle") ); + var_FreeList( &list, &list2 ); + break; } - else if( i == i_count -1 ) + 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) ) { - var_Set( p_aout, "audio-device", - list.p_list->p_values[0] ); - i = 0; + DisplayMessage( p_vout, _( "Sub sync: set bookmarks first!" ) ); } else { - var_Set( p_aout, "audio-device", - list.p_list->p_values[i+1] ); - i++; + 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; } - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Audio Device: %s"), - list2.p_list->p_values[i].psz_string); } - var_FreeList( &list, &list2 ); break; } - - /* Input options */ - default: + case ACTIONID_SUBSYNC_RESET: { - if( !p_input ) - break; - - bool b_seekable = var_GetBool( p_input, "can-seek" ); - int i_interval =0; + 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; + } - if( i_action == ACTIONID_PAUSE ) + case ACTIONID_SUBDELAY_DOWN: + case ACTIONID_SUBDELAY_UP: + { + int diff = (i_action == ACTIONID_SUBDELAY_UP) ? 50000 : -50000; + if( p_input ) { - if( var_GetInteger( p_input, "state" ) != PAUSE_S ) + 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 ) { - ClearChannels( p_intf, p_vout ); - DisplayIcon( p_vout, OSD_PAUSE_ICON ); - var_SetInteger( p_input, "state", PAUSE_S ); + 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 ); } - else if( i_action == ACTIONID_JUMP_BACKWARD_EXTRASHORT - && b_seekable ) - { -#define SET_TIME( a, b ) \ - i_interval = var_InheritInteger( p_input, a "-jump-size" ); \ - if( i_interval > 0 ) { \ - mtime_t i_time = (mtime_t)(i_interval * b) * 1000000L; \ - var_SetTime( p_input, "time-offset", i_time ); \ - DisplayPosition( p_intf, p_vout, p_input ); \ - } - SET_TIME( "extrashort", -1 ); - } - else if( i_action == ACTIONID_JUMP_FORWARD_EXTRASHORT && b_seekable ) - { - SET_TIME( "extrashort", 1 ); - } - else if( i_action == ACTIONID_JUMP_BACKWARD_SHORT && b_seekable ) - { - SET_TIME( "short", -1 ); - } - else if( i_action == ACTIONID_JUMP_FORWARD_SHORT && b_seekable ) - { - SET_TIME( "short", 1 ); - } - else if( i_action == ACTIONID_JUMP_BACKWARD_MEDIUM && b_seekable ) - { - SET_TIME( "medium", -1 ); - } - else if( i_action == ACTIONID_JUMP_FORWARD_MEDIUM && b_seekable ) - { - SET_TIME( "medium", 1 ); - } - else if( i_action == ACTIONID_JUMP_BACKWARD_LONG && b_seekable ) - { - SET_TIME( "long", -1 ); - } - else if( i_action == ACTIONID_JUMP_FORWARD_LONG && b_seekable ) + break; + } + case ACTIONID_AUDIODELAY_DOWN: + case ACTIONID_AUDIODELAY_UP: + { + int diff = (i_action == ACTIONID_AUDIODELAY_UP) ? 50000 : -50000; + if( p_input ) { - SET_TIME( "long", 1 ); -#undef SET_TIME + int64_t i_delay = var_GetTime( p_input, "audio-delay" ) + diff; + + var_SetTime( p_input, "audio-delay", i_delay ); + ClearChannels( p_intf, p_vout ); + DisplayMessage( p_vout, _( "Audio delay %i ms" ), + (int)(i_delay/1000) ); } - else if( i_action == ACTIONID_AUDIO_TRACK ) + break; + } + + case ACTIONID_AUDIO_TRACK: + if( p_input ) { vlc_value_t val, list, list2; int i_count, i; @@ -466,13 +549,14 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) else i++; var_Set( p_input, "audio-es", list.p_list->p_values[i] ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Audio track: %s"), + DisplayMessage( p_vout, _("Audio track: %s"), list2.p_list->p_values[i].psz_string ); } var_FreeList( &list, &list2 ); } - else if( i_action == ACTIONID_SUBTITLE_TRACK ) + break; + case ACTIONID_SUBTITLE_TRACK: + if( p_input ) { vlc_value_t val, list, list2; int i_count, i; @@ -483,10 +567,10 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) i_count = list.p_list->i_count; if( i_count <= 1 ) { - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Subtitle track: %s"), _("N/A") ); + DisplayMessage( p_vout, _("Subtitle track: %s"), + _("N/A") ); var_FreeList( &list, &list2 ); - goto cleanup_and_continue; + break; } for( i = 0; i < i_count; i++ ) { @@ -506,45 +590,251 @@ 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] ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Subtitle track: %s"), + 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 ); } - else if( i_action == ACTIONID_ASPECT_RATIO && p_vout ) + break; + case ACTIONID_SUBTITLE_TOGGLE: + if( p_input ) { - vlc_value_t val={0}, val_list, text_list; - var_Get( p_vout, "aspect-ratio", &val ); - if( var_Change( p_vout, "aspect-ratio", VLC_VAR_GETLIST, - &val_list, &text_list ) >= 0 ) + 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 ) { - int i; - for( i = 0; i < val_list.p_list->i_count; i++ ) + 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 ) { - if( !strcmp( val_list.p_list->p_values[i].psz_string, - val.psz_string ) ) - { - i++; - break; - } + break; } - if( i == val_list.p_list->i_count ) i = 0; - var_SetString( p_vout, "aspect-ratio", - val_list.p_list->p_values[i].psz_string ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Aspect ratio: %s"), - text_list.p_list->p_values[i].psz_string ); + } + /* 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 ); + } - var_FreeList( &val_list, &text_list ); + 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 ) + { + vlc_value_t val, list, list2; + int i_count, i; + var_Get( p_input, "program", &val ); + + var_Change( p_input, "program", VLC_VAR_GETCHOICES, + &list, &list2 ); + i_count = list.p_list->i_count; + if( i_count <= 1 ) + { + DisplayMessage( p_vout, _("Program Service ID: %s"), + _("N/A") ); + var_FreeList( &list, &list2 ); + break; + } + for( i = 0; i < i_count; i++ ) + { + if( val.i_int == list.p_list->p_values[i].i_int ) + { + break; + } + } + /* value of program sid was not in choices list */ + if( i == i_count ) + { + msg_Warn( p_input, + "invalid current program SID, selecting 0" ); + i = 0; + } + else if( i_action == ACTIONID_PROGRAM_SID_NEXT ) { + if( i == i_count - 1 ) + i = 0; + else + i++; + } + else { /* ACTIONID_PROGRAM_SID_PREV */ + if( i == 0 ) + i = i_count - 1; + else + i--; + } + var_Set( p_input, "program", list.p_list->p_values[i] ); + DisplayMessage( p_vout, _("Program Service ID: %s"), + list2.p_list->p_values[i].psz_string ); + var_FreeList( &list, &list2 ); + } + break; + + case ACTIONID_JUMP_BACKWARD_EXTRASHORT: + case ACTIONID_JUMP_FORWARD_EXTRASHORT: + case ACTIONID_JUMP_BACKWARD_SHORT: + case ACTIONID_JUMP_FORWARD_SHORT: + case ACTIONID_JUMP_BACKWARD_MEDIUM: + case ACTIONID_JUMP_FORWARD_MEDIUM: + case ACTIONID_JUMP_BACKWARD_LONG: + case ACTIONID_JUMP_FORWARD_LONG: + { + if( p_input == NULL || !var_GetBool( p_input, "can-seek" ) ) + break; + + const char *varname; + int sign = +1; + switch( i_action ) + { + case ACTIONID_JUMP_BACKWARD_EXTRASHORT: + sign = -1; + case ACTIONID_JUMP_FORWARD_EXTRASHORT: + varname = "extrashort-jump-size"; + break; + case ACTIONID_JUMP_BACKWARD_SHORT: + sign = -1; + case ACTIONID_JUMP_FORWARD_SHORT: + varname = "short-jump-size"; + break; + case ACTIONID_JUMP_BACKWARD_MEDIUM: + sign = -1; + case ACTIONID_JUMP_FORWARD_MEDIUM: + varname = "medium-jump-size"; + break; + case ACTIONID_JUMP_BACKWARD_LONG: + sign = -1; + case ACTIONID_JUMP_FORWARD_LONG: + varname = "long-jump-size"; + break; + } + + mtime_t it = var_InheritInteger( p_input, varname ); + if( it < 0 ) + break; + var_SetTime( p_input, "time-offset", it * sign * CLOCK_FREQ ); + DisplayPosition( p_intf, p_vout, p_input ); + break; + } + + /* Input navigation */ + case ACTIONID_TITLE_PREV: + if( p_input ) + var_TriggerCallback( p_input, "prev-title" ); + break; + case ACTIONID_TITLE_NEXT: + if( p_input ) + var_TriggerCallback( p_input, "next-title" ); + break; + case ACTIONID_CHAPTER_PREV: + if( p_input ) + var_TriggerCallback( p_input, "prev-chapter" ); + break; + case ACTIONID_CHAPTER_NEXT: + if( p_input ) + var_TriggerCallback( p_input, "next-chapter" ); + break; + case ACTIONID_DISC_MENU: + if( p_input ) + var_SetInteger( p_input, "title 0", 2 ); + break; + case ACTIONID_NAV_ACTIVATE: + case ACTIONID_NAV_UP: + case ACTIONID_NAV_DOWN: + case ACTIONID_NAV_LEFT: + case ACTIONID_NAV_RIGHT: + if( p_input ) + input_Control( p_input, i_action - ACTIONID_NAV_ACTIVATE + + INPUT_NAV_ACTIVATE, NULL ); + break; + + /* Video Output actions */ + case ACTIONID_SNAPSHOT: + if( p_vout ) + var_TriggerCallback( p_vout, "video-snapshot" ); + break; + + case ACTIONID_TOGGLE_FULLSCREEN: + { + if( p_vout ) + { + bool fs = var_ToggleBool( p_vout, "fullscreen" ); + var_SetBool( p_playlist, "fullscreen", fs ); + } + else + var_ToggleBool( p_playlist, "fullscreen" ); + break; + } + + case ACTIONID_LEAVE_FULLSCREEN: + if( p_vout ) + var_SetBool( p_vout, "fullscreen", false ); + var_SetBool( p_playlist, "fullscreen", false ); + break; + + case ACTIONID_ASPECT_RATIO: + if( p_vout ) + { + vlc_value_t val={0}, val_list, text_list; + var_Get( p_vout, "aspect-ratio", &val ); + if( var_Change( p_vout, "aspect-ratio", VLC_VAR_GETCHOICES, + &val_list, &text_list ) >= 0 ) + { + int i; + for( i = 0; i < val_list.p_list->i_count; i++ ) + { + if( !strcmp( val_list.p_list->p_values[i].psz_string, + val.psz_string ) ) + { + i++; + break; + } + } + if( i == val_list.p_list->i_count ) i = 0; + var_SetString( p_vout, "aspect-ratio", + val_list.p_list->p_values[i].psz_string ); + DisplayMessage( p_vout, _("Aspect ratio: %s"), + text_list.p_list->p_values[i].psz_string ); + + var_FreeList( &val_list, &text_list ); } free( val.psz_string ); } - else if( i_action == ACTIONID_CROP && p_vout ) + break; + + case ACTIONID_CROP: + if( p_vout ) { vlc_value_t val={0}, val_list, text_list; var_Get( p_vout, "crop", &val ); - if( var_Change( p_vout, "crop", VLC_VAR_GETLIST, + if( var_Change( p_vout, "crop", VLC_VAR_GETCHOICES, &val_list, &text_list ) >= 0 ) { int i; @@ -560,61 +850,148 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) if( i == val_list.p_list->i_count ) i = 0; var_SetString( p_vout, "crop", val_list.p_list->p_values[i].psz_string ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Crop: %s"), + DisplayMessage( p_vout, _("Crop: %s"), text_list.p_list->p_values[i].psz_string ); var_FreeList( &val_list, &text_list ); } free( val.psz_string ); } - else if( i_action == ACTIONID_TOGGLE_AUTOSCALE && p_vout ) + break; + case ACTIONID_CROP_TOP: + if( p_vout ) + var_IncInteger( p_vout, "crop-top" ); + break; + case ACTIONID_UNCROP_TOP: + if( p_vout ) + var_DecInteger( p_vout, "crop-top" ); + break; + case ACTIONID_CROP_BOTTOM: + if( p_vout ) + var_IncInteger( p_vout, "crop-bottom" ); + break; + case ACTIONID_UNCROP_BOTTOM: + if( p_vout ) + var_DecInteger( p_vout, "crop-bottom" ); + break; + case ACTIONID_CROP_LEFT: + if( p_vout ) + var_IncInteger( p_vout, "crop-left" ); + break; + case ACTIONID_UNCROP_LEFT: + if( p_vout ) + var_DecInteger( p_vout, "crop-left" ); + break; + case ACTIONID_CROP_RIGHT: + if( p_vout ) + var_IncInteger( p_vout, "crop-right" ); + break; + case ACTIONID_UNCROP_RIGHT: + if( p_vout ) + var_DecInteger( p_vout, "crop-right" ); + break; + + case ACTIONID_TOGGLE_AUTOSCALE: + if( p_vout ) { - float f_scalefactor = var_GetFloat( p_vout, "scale" ); - if ( f_scalefactor != 1.0 ) + float f_scalefactor = var_GetFloat( p_vout, "zoom" ); + if ( f_scalefactor != 1.f ) { - var_SetFloat( p_vout, "scale", 1.0 ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s", _("Zooming reset") ); + var_SetFloat( p_vout, "zoom", 1.f ); + DisplayMessage( p_vout, _("Zooming reset") ); } else { bool b_autoscale = !var_GetBool( p_vout, "autoscale" ); var_SetBool( p_vout, "autoscale", b_autoscale ); if( b_autoscale ) - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s", _("Scaled to screen") ); + DisplayMessage( p_vout, _("Scaled to screen") ); else - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s", _("Original Size") ); + DisplayMessage( p_vout, _("Original Size") ); } } - else if( i_action == ACTIONID_SCALE_UP && p_vout ) + break; + case ACTIONID_SCALE_UP: + if( p_vout ) { - float f_scalefactor; + float f_scalefactor = var_GetFloat( p_vout, "zoom" ); - f_scalefactor = var_GetFloat( p_vout, "scale" ); - if( f_scalefactor < 10. ) - f_scalefactor += .1; - var_SetFloat( p_vout, "scale", f_scalefactor ); + if( f_scalefactor < 10.f ) + f_scalefactor += .1f; + var_SetFloat( p_vout, "zoom", f_scalefactor ); } - else if( i_action == ACTIONID_SCALE_DOWN && p_vout ) + break; + case ACTIONID_SCALE_DOWN: + if( p_vout ) { - float f_scalefactor; + float f_scalefactor = var_GetFloat( p_vout, "zoom" ); - f_scalefactor = var_GetFloat( p_vout, "scale" ); - if( f_scalefactor > .3 ) - f_scalefactor -= .1; - var_SetFloat( p_vout, "scale", f_scalefactor ); + if( f_scalefactor > .3f ) + f_scalefactor -= .1f; + var_SetFloat( p_vout, "zoom", f_scalefactor ); } - else if( i_action == ACTIONID_DEINTERLACE && p_vout ) + break; + + case ACTIONID_ZOOM_QUARTER: + case ACTIONID_ZOOM_HALF: + case ACTIONID_ZOOM_ORIGINAL: + case ACTIONID_ZOOM_DOUBLE: + if( p_vout ) + { + float f; + switch( i_action ) + { + case ACTIONID_ZOOM_QUARTER: f = 0.25; break; + case ACTIONID_ZOOM_HALF: f = 0.5; break; + case ACTIONID_ZOOM_ORIGINAL: f = 1.; break; + /*case ACTIONID_ZOOM_DOUBLE:*/ + default: f = 2.; break; + } + var_SetFloat( p_vout, "zoom", f ); + } + break; + case ACTIONID_ZOOM: + case ACTIONID_UNZOOM: + if( p_vout ) + { + vlc_value_t val={0}, val_list, text_list; + var_Get( p_vout, "zoom", &val ); + if( var_Change( p_vout, "zoom", VLC_VAR_GETCHOICES, + &val_list, &text_list ) >= 0 ) + { + int i; + for( i = 0; i < val_list.p_list->i_count; i++ ) + { + if( val_list.p_list->p_values[i].f_float + == val.f_float ) + { + if( i_action == ACTIONID_ZOOM ) + i++; + else /* ACTIONID_UNZOOM */ + i--; + break; + } + } + if( i == val_list.p_list->i_count ) i = 0; + if( i == -1 ) i = val_list.p_list->i_count-1; + var_SetFloat( p_vout, "zoom", + val_list.p_list->p_values[i].f_float ); + DisplayMessage( p_vout, _("Zoom mode: %s"), + text_list.p_list->p_values[i].psz_string ); + + var_FreeList( &val_list, &text_list ); + } + } + break; + + case ACTIONID_DEINTERLACE: + if( p_vout ) { int i_deinterlace = var_GetInteger( p_vout, "deinterlace" ); if( i_deinterlace != 0 ) { var_SetInteger( p_vout, "deinterlace", 0 ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s", _("Deinterlace off") ); + DisplayMessage( p_vout, _("Deinterlace off") ); } else { @@ -622,7 +999,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++ ) @@ -633,159 +1010,74 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) break; } } - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s (%s)", _("Deinterlace on"), psz_text ? psz_text : psz_mode ); + DisplayMessage( p_vout, "%s (%s)", _("Deinterlace on"), + psz_text ? psz_text : psz_mode ); var_FreeList( &vlist, &tlist ); } free( psz_mode ); } } - else if( ( i_action == ACTIONID_ZOOM || - i_action == ACTIONID_UNZOOM ) && p_vout ) + break; + case ACTIONID_DEINTERLACE_MODE: + if( p_vout ) { - vlc_value_t val={0}, val_list, text_list; - var_Get( p_vout, "zoom", &val ); - if( var_Change( p_vout, "zoom", VLC_VAR_GETLIST, - &val_list, &text_list ) >= 0 ) + 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 )) { + const char *psz_text = NULL; int i; - for( i = 0; i < val_list.p_list->i_count; i++ ) + for( i = 0; i < vlist.p_list->i_count; i++ ) { - if( val_list.p_list->p_values[i].f_float - == val.f_float ) + if( !strcmp( vlist.p_list->p_values[i].psz_string, psz_mode ) ) { - if( i_action == ACTIONID_ZOOM ) - i++; - else /* ACTIONID_UNZOOM */ - i--; + i++; break; } } - if( i == val_list.p_list->i_count ) i = 0; - if( i == -1 ) i = val_list.p_list->i_count-1; - var_SetFloat( p_vout, "zoom", - val_list.p_list->p_values[i].f_float ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _("Zoom mode: %s"), - text_list.p_list->p_values[i].psz_string ); + if( i == vlist.p_list->i_count ) i = 0; + psz_text = tlist.p_list->p_values[i].psz_string; + var_SetString( p_vout, "deinterlace-mode", vlist.p_list->p_values[i].psz_string ); - var_FreeList( &val_list, &text_list ); + int i_deinterlace = var_GetInteger( p_vout, "deinterlace" ); + if( i_deinterlace != 0 ) + { + DisplayMessage( p_vout, "%s (%s)", _("Deinterlace on"), + psz_text ? psz_text : psz_mode ); + } + else + { + DisplayMessage( p_vout, "%s (%s)", _("Deinterlace off"), + psz_text ? psz_text : psz_mode ); + } + + var_FreeList( &vlist, &tlist ); } + free( psz_mode ); } - else if( i_action == ACTIONID_CROP_TOP && p_vout ) - var_IncInteger( p_vout, "crop-top" ); - else if( i_action == ACTIONID_UNCROP_TOP && p_vout ) - var_DecInteger( p_vout, "crop-top" ); - else if( i_action == ACTIONID_CROP_BOTTOM && p_vout ) - var_IncInteger( p_vout, "crop-bottom" ); - else if( i_action == ACTIONID_UNCROP_BOTTOM && p_vout ) - var_DecInteger( p_vout, "crop-bottom" ); - else if( i_action == ACTIONID_CROP_LEFT && p_vout ) - var_IncInteger( p_vout, "crop-left" ); - else if( i_action == ACTIONID_UNCROP_LEFT && p_vout ) - var_DecInteger( p_vout, "crop-left" ); - else if( i_action == ACTIONID_CROP_RIGHT && p_vout ) - var_IncInteger( p_vout, "crop-right" ); - else if( i_action == ACTIONID_UNCROP_RIGHT && p_vout ) - var_DecInteger( p_vout, "crop-right" ); - - else if( i_action == ACTIONID_NEXT ) - { - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _("Next") ); - playlist_Next( p_playlist ); - } - else if( i_action == ACTIONID_PREV ) - { - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", - _("Previous") ); - playlist_Prev( p_playlist ); - } - else if( i_action == ACTIONID_STOP ) - { - playlist_Stop( p_playlist ); - } - else if( i_action == ACTIONID_FRAME_NEXT ) - { - var_TriggerCallback( p_input, "frame-next" ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s", _("Next frame") ); - } - else if( i_action == ACTIONID_RATE_NORMAL ) - { - var_SetFloat( p_playlist, "rate", 1. ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - "%s", _("1.00x") ); - } - else if( i_action == ACTIONID_FASTER ) - { - var_TriggerCallback( p_playlist, "rate-faster" ); - DisplayRate( p_vout, var_GetFloat( p_input, "rate" ) ); - } - else if( i_action == ACTIONID_SLOWER ) - { - var_TriggerCallback( p_playlist, "rate-slower" ); - DisplayRate( p_vout, var_GetFloat( p_input, "rate" ) ); - } - else if( i_action == ACTIONID_RATE_FASTER_FINE || - i_action == ACTIONID_RATE_SLOWER_FINE ) - { - const int i_dir = i_action == ACTIONID_RATE_FASTER_FINE ? 1 : -1; - float f_newrate = AdjustRateFine( p_input, i_dir ); + break; - var_SetFloat( p_playlist, "rate", f_newrate ); - DisplayRate( p_vout, f_newrate ); - } - else if( i_action == ACTIONID_POSITION ) - { - if( ( !p_vout || vout_OSDEpg( p_vout, input_GetItem( p_input ) ) ) && b_seekable ) - DisplayPosition( p_intf, p_vout, p_input ); - } - else if( i_action >= ACTIONID_PLAY_BOOKMARK1 && - i_action <= ACTIONID_PLAY_BOOKMARK10 ) - { - PlayBookmark( p_intf, i_action - ACTIONID_PLAY_BOOKMARK1 + 1 ); - } - else if( i_action >= ACTIONID_SET_BOOKMARK1 && - i_action <= ACTIONID_SET_BOOKMARK10 ) + case ACTIONID_SUBPOS_DOWN: + case ACTIONID_SUBPOS_UP: + { + if( p_input ) { - SetBookmark( p_intf, i_action - ACTIONID_SET_BOOKMARK1 + 1 ); - } - /* Only makes sense with DVD */ - else if( i_action == ACTIONID_TITLE_PREV ) - var_TriggerCallback( p_input, "prev-title" ); - else if( i_action == ACTIONID_TITLE_NEXT ) - var_TriggerCallback( p_input, "next-title" ); - else if( i_action == ACTIONID_CHAPTER_PREV ) - var_TriggerCallback( p_input, "prev-chapter" ); - else if( i_action == ACTIONID_CHAPTER_NEXT ) - var_TriggerCallback( p_input, "next-chapter" ); - else if( i_action == ACTIONID_DISC_MENU ) - var_SetInteger( p_input, "title 0", 2 ); + 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, + _("Subtitle position: no active subtitle") ); + var_FreeList( &list, &list2 ); + break; + } - else if( i_action == ACTIONID_SUBDELAY_DOWN ) - { - int64_t i_delay = var_GetTime( p_input, "spu-delay" ); - i_delay -= 50000; /* 50 ms */ - var_SetTime( p_input, "spu-delay", i_delay ); - ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _( "Subtitle delay %i ms" ), - (int)(i_delay/1000) ); - } - else if( i_action == ACTIONID_SUBDELAY_UP ) - { - int64_t i_delay = var_GetTime( p_input, "spu-delay" ); - i_delay += 50000; /* 50 ms */ - var_SetTime( p_input, "spu-delay", i_delay ); - ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _( "Subtitle delay %i ms" ), - (int)(i_delay/1000) ); - } - else if( ( i_action == ACTIONID_SUBPOS_DOWN || - i_action == ACTIONID_SUBPOS_UP ) && p_vout ) - { int i_pos; if( i_action == ACTIONID_SUBPOS_DOWN ) i_pos = var_DecInteger( p_vout, "sub-margin" ); @@ -793,75 +1085,19 @@ static int PutAction( intf_thread_t *p_intf, int i_action ) i_pos = var_IncInteger( p_vout, "sub-margin" ); ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _( "Subtitle position %i px" ), - (int)(i_pos) ); - } - else if( i_action == ACTIONID_AUDIODELAY_DOWN ) - { - int64_t i_delay = var_GetTime( p_input, "audio-delay" ); - i_delay -= 50000; /* 50 ms */ - var_SetTime( p_input, "audio-delay", i_delay ); - ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _( "Audio delay %i ms" ), - (int)(i_delay/1000) ); - } - else if( i_action == ACTIONID_AUDIODELAY_UP ) - { - int64_t i_delay = var_GetTime( p_input, "audio-delay" ); - i_delay += 50000; /* 50 ms */ - var_SetTime( p_input, "audio-delay", i_delay ); - ClearChannels( p_intf, p_vout ); - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, - _( "Audio delay %i ms" ), - (int)(i_delay/1000) ); - } - else if( i_action == ACTIONID_MENU_ON ) - { - osd_MenuShow( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_MENU_OFF ) - { - osd_MenuHide( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_MENU_LEFT ) - { - osd_MenuPrev( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_MENU_RIGHT ) - { - osd_MenuNext( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_MENU_UP ) - { - osd_MenuUp( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_MENU_DOWN ) - { - osd_MenuDown( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_MENU_SELECT ) - { - osd_MenuActivate( VLC_OBJECT(p_intf) ); - } - else if( i_action == ACTIONID_RECORD ) - { - if( var_GetBool( p_input, "can-record" ) ) - { - const bool b_record = var_ToggleBool( p_input, "record" ); - - if( b_record ) - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _("Recording") ); - else - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _("Recording done") ); - } + DisplayMessage( p_vout, _( "Subtitle position %d px" ), i_pos ); + var_FreeList( &list, &list2 ); } + break; } + + /* Input + video output */ + case ACTIONID_POSITION: + if( p_vout && vout_OSDEpg( p_vout, input_GetItem( p_input ) ) ) + DisplayPosition( p_intf, p_vout, p_input ); + break; } -cleanup_and_continue: - if( p_aout ) - vlc_object_release( p_aout ); + if( p_vout ) vlc_object_release( p_vout ); if( p_input ) @@ -869,54 +1105,6 @@ cleanup_and_continue: return VLC_SUCCESS; } -/***************************************************************************** - * SpecialKeyEvent: callback for mouse events - *****************************************************************************/ -static int SpecialKeyEvent( vlc_object_t *libvlc, char const *psz_var, - vlc_value_t oldval, vlc_value_t newval, - void *p_data ) -{ - intf_thread_t *p_intf = (intf_thread_t *)p_data; - int i_action = 0; - - (void)psz_var; - (void)oldval; - - int i_mode = p_intf->p_sys->i_mousewheel_mode; - - /* Special action for mouse event */ - /* FIXME: rework hotkeys handling to allow more than 1 event - * to trigger one same action */ - switch (newval.i_int & ~KEY_MODIFIER) - { - case KEY_MOUSEWHEELUP: - i_action = (i_mode == MOUSEWHEEL_VOLUME ) ? ACTIONID_VOL_UP - : ACTIONID_JUMP_FORWARD_EXTRASHORT; - break; - case KEY_MOUSEWHEELDOWN: - i_action = (i_mode == MOUSEWHEEL_VOLUME ) ? ACTIONID_VOL_DOWN - : ACTIONID_JUMP_BACKWARD_EXTRASHORT; - break; - case KEY_MOUSEWHEELLEFT: - i_action = (i_mode == MOUSEWHEEL_VOLUME ) ? - ACTIONID_JUMP_BACKWARD_EXTRASHORT : ACTIONID_VOL_DOWN; - break; - case KEY_MOUSEWHEELRIGHT: - i_action = (i_mode == MOUSEWHEEL_VOLUME ) ? - ACTIONID_JUMP_FORWARD_EXTRASHORT : ACTIONID_VOL_UP; - break; - case KEY_MENU: - var_SetBool( libvlc, "intf-popupmenu", true ); - break; - } - - if( i_mode == NO_MOUSEWHEEL ) return VLC_SUCCESS; - - if( i_action ) - return PutAction( p_intf, i_action ); - return VLC_SUCCESS; -} - /***************************************************************************** * ActionEvent: callback for hotkey actions *****************************************************************************/ @@ -980,7 +1168,6 @@ static void SetBookmark( intf_thread_t *p_intf, int i_num ) { config_PutPsz( p_intf, psz_bookmark_name, psz_uri); msg_Info( p_intf, "setting playlist bookmark %i to %s", i_num, psz_uri); - config_SaveConfigFile( p_intf, "hotkeys" ); } free( psz_uri ); @@ -1007,53 +1194,44 @@ static void DisplayPosition( intf_thread_t *p_intf, vout_thread_t *p_vout, if( time.i_time > 0 ) { secstotimestr( psz_duration, time.i_time / 1000000 ); - DisplayMessage( p_vout, POSITION_TEXT_CHAN, "%s / %s", - psz_time, psz_duration ); + DisplayMessage( p_vout, "%s / %s", psz_time, psz_duration ); } else if( i_seconds > 0 ) { - DisplayMessage( p_vout, POSITION_TEXT_CHAN, "%s", psz_time ); + DisplayMessage( p_vout, "%s", psz_time ); } if( var_GetBool( p_vout, "fullscreen" ) ) { var_Get( p_input, "position", &pos ); - vout_OSDSlider( p_vout, POSITION_WIDGET_CHAN, + vout_OSDSlider( p_vout, p_intf->p_sys->slider_chan, pos.f_float * 100, OSD_HOR_SLIDER ); } } static void DisplayVolume( intf_thread_t *p_intf, vout_thread_t *p_vout, - audio_volume_t i_vol ) + float vol ) { if( p_vout == NULL ) - { return; - } ClearChannels( p_intf, p_vout ); if( var_GetBool( p_vout, "fullscreen" ) ) - { - vout_OSDSlider( p_vout, VOLUME_WIDGET_CHAN, - i_vol*100/AOUT_VOLUME_MAX, OSD_VERT_SLIDER ); - } - else - { - DisplayMessage( p_vout, VOLUME_TEXT_CHAN, _( "Volume %d%%" ), - i_vol*400/AOUT_VOLUME_MAX ); - } + vout_OSDSlider( p_vout, p_intf->p_sys->slider_chan, + lroundf(vol * 100.f), OSD_VERT_SLIDER ); + DisplayMessage( p_vout, _( "Volume %ld%%" ), lroundf(vol * 100.f) ); } static void DisplayRate( vout_thread_t *p_vout, float f_rate ) { - DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL, _("Speed: %.2fx"), f_rate ); + DisplayMessage( p_vout, _("Speed: %.2fx"), (double) f_rate ); } -static float AdjustRateFine( input_thread_t *p_input, const int i_dir ) +static float AdjustRateFine( vlc_object_t *p_obj, const int i_dir ) { const float f_rate_min = (float)INPUT_RATE_DEFAULT / INPUT_RATE_MAX; const float f_rate_max = (float)INPUT_RATE_DEFAULT / INPUT_RATE_MIN; - float f_rate = var_GetFloat( p_input, "rate" ); + float f_rate = var_GetFloat( p_obj, "rate" ); int i_sign = f_rate < 0 ? -1 : 1; @@ -1073,7 +1251,6 @@ static void ClearChannels( intf_thread_t *p_intf, vout_thread_t *p_vout ) if( p_vout ) { vout_FlushSubpictureChannel( p_vout, SPU_DEFAULT_CHANNEL ); - for( int i = 0; i < CHANNELS_NUMBER; i++ ) - vout_FlushSubpictureChannel( p_vout, p_intf->p_sys->p_channels[i] ); + vout_FlushSubpictureChannel( p_vout, p_intf->p_sys->slider_chan ); } }