/*****************************************************************************
* hotkeys.c: Hotkey handling for vlc
*****************************************************************************
- * Copyright (C) 2005 the VideoLAN team
+ * Copyright (C) 2005-2009 the VideoLAN team
* $Id$
*
* Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
#include <vlc_osd.h>
#include <vlc_playlist.h>
#include "vlc_keys.h"
+#include "math.h"
#define BUFFER_SIZE 10
#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
*****************************************************************************/
vout_thread_t * p_vout; /* pointer to vout object */
vlc_mutex_t lock; /* callback lock */
vlc_cond_t wait; /* callback event */
+ int i_mousewheel_mode;
};
/*****************************************************************************
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-#define BOOKMARK1_TEXT N_("Playlist bookmark 1")
-#define BOOKMARK2_TEXT N_("Playlist bookmark 2")
-#define BOOKMARK3_TEXT N_("Playlist bookmark 3")
-#define BOOKMARK4_TEXT N_("Playlist bookmark 4")
-#define BOOKMARK5_TEXT N_("Playlist bookmark 5")
-#define BOOKMARK6_TEXT N_("Playlist bookmark 6")
-#define BOOKMARK7_TEXT N_("Playlist bookmark 7")
-#define BOOKMARK8_TEXT N_("Playlist bookmark 8")
-#define BOOKMARK9_TEXT N_("Playlist bookmark 9")
-#define BOOKMARK10_TEXT N_("Playlist bookmark 10")
-#define BOOKMARK_LONGTEXT N_("Define playlist bookmarks.")
+
+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") )
set_capability( "interface", 0 )
set_callbacks( Open, Close )
+
+ 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 ()
/*****************************************************************************
p_sys->i_size = 0;
vlc_mutex_init( &p_sys->lock );
vlc_cond_init( &p_sys->wait );
+ p_intf->p_sys->i_mousewheel_mode =
+ config_GetInt( p_intf, "hotkeys-mousewheel-mode" );
var_AddCallback( p_intf->p_libvlc, "key-pressed", SpecialKeyEvent, p_intf );
var_AddCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf );
{
vout_thread_t *p_vout = NULL;
vlc_value_t val;
- int i;
playlist_t *p_playlist = pl_Hold( p_intf );
int canc = vlc_savecancel();
/* Update the vout */
p_last_vout = p_vout;
- p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
+ p_vout = p_input ? input_GetVout( p_input ) : NULL;
/* Register OSD channels */
if( p_vout && p_vout != p_last_vout )
{
+ int i;
for( i = 0; i < CHANNELS_NUMBER; i++ )
{
spu_Control( p_vout->p_spu, SPU_CHANNEL_REGISTER,
/* Video Output actions */
else if( i_action == ACTIONID_SNAPSHOT )
{
- if( p_vout ) vout_Control( p_vout, VOUT_SNAPSHOT );
+ if( p_vout ) var_TriggerCallback( p_vout, "video-snapshot" );
}
else if( i_action == ACTIONID_TOGGLE_FULLSCREEN )
{
{
msg_Warn( p_input,
"invalid current audio track, selecting 0" );
- var_Set( p_input, "audio-es",
- list.p_list->p_values[0] );
i = 0;
}
else if( i == i_count - 1 )
- {
- var_Set( p_input, "audio-es",
- list.p_list->p_values[1] );
i = 1;
- }
else
- {
- var_Set( p_input, "audio-es",
- list.p_list->p_values[i+1] );
i++;
- }
+ var_Set( p_input, "audio-es", list.p_list->p_values[i] );
vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
_("Audio track: %s"),
list2.p_list->p_values[i].psz_string );
{
msg_Warn( p_input,
"invalid current subtitle track, selecting 0" );
- var_Set( p_input, "spu-es", list.p_list->p_values[0] );
i = 0;
}
else if( i == i_count - 1 )
- {
- var_Set( p_input, "spu-es", list.p_list->p_values[0] );
i = 0;
- }
else
- {
- var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
- i = i + 1;
- }
+ i++;
+ var_Set( p_input, "spu-es", list.p_list->p_values[i] );
vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
_("Subtitle track: %s"),
list2.p_list->p_values[i].psz_string );
}
free( val.psz_string );
}
- else if( i_action == ACTIONID_TOGGLE_SCALING && p_vout )
+ else if( i_action == ACTIONID_TOGGLE_AUTOSCALE && p_vout )
+ {
+ float f_scalefactor = var_GetFloat( p_vout, "scale" );
+ if ( f_scalefactor != 1.0 )
+ {
+ var_SetFloat( p_vout, "scale", 1.0 );
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
+ _("Zooming reset") );
+ }
+ else
+ {
+ bool b_autoscale = !var_GetBool( p_vout, "autoscale" );
+ var_SetBool( p_vout, "autoscale", b_autoscale );
+ if( b_autoscale )
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
+ _("Scaled to screen") );
+ else
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
+ _("Original Size") );
+ }
+ }
+ else if( i_action == ACTIONID_SCALE_UP && p_vout )
{
- bool b_scaling = var_GetBool( p_vout, "scaling" );
- var_SetBool( p_vout, "scaling", !b_scaling );
+ float f_scalefactor;
+
+ f_scalefactor = var_GetFloat( p_vout, "scale" );
+ if( f_scalefactor < 10. )
+ f_scalefactor += .1;
+ var_SetFloat( p_vout, "scale", f_scalefactor );
+ }
+ else if( i_action == ACTIONID_SCALE_DOWN && p_vout )
+ {
+ float f_scalefactor;
+
+ f_scalefactor = var_GetFloat( p_vout, "scale" );
+ if( f_scalefactor > .3 )
+ f_scalefactor -= .1;
+ var_SetFloat( p_vout, "scale", f_scalefactor );
}
else if( i_action == ACTIONID_DEINTERLACE && p_vout )
{
vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
_("Slower") );
}
+ else if( i_action == ACTIONID_RATE_NORMAL )
+ {
+ var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT );
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
+ _("1.00x") );
+ }
+ else if( i_action == ACTIONID_RATE_FASTER_FINE ||
+ i_action == ACTIONID_RATE_SLOWER_FINE )
+ {
+ /* The playback rate is defined by INPUT_RATE_DEFAULT / "rate"
+ * and we want to increase/decrease it by 0.1 while making sure
+ * that the resulting playback rate is a multiple of 0.1
+ */
+ int i_rate = var_GetInteger( p_input, "rate" );
+ if( i_rate == 0 )
+ i_rate = INPUT_RATE_MIN;
+ int i_sign = i_rate < 0 ? -1 : 1;
+ const int i_dir = i_action == ACTIONID_RATE_FASTER_FINE ? 1 : -1;
+
+ const double f_speed = floor( ( (double)INPUT_RATE_DEFAULT / abs(i_rate) + 0.05 ) / 0.1 + i_dir ) * 0.1;
+ if( f_speed <= (double)INPUT_RATE_DEFAULT / INPUT_RATE_MAX ) /* Needed to avoid infinity */
+ i_rate = INPUT_RATE_MAX;
+ else
+ i_rate = INPUT_RATE_DEFAULT / f_speed + 0.5;
+
+ i_rate = i_sign * __MIN( __MAX( i_rate, INPUT_RATE_MIN ), INPUT_RATE_MAX );
+
+ var_SetInteger( p_input, "rate", i_rate );
+
+ char psz_msg[7+1];
+ snprintf( psz_msg, sizeof(psz_msg), _("%.2fx"), (double)INPUT_RATE_DEFAULT / i_rate );
+ vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, psz_msg );
+ }
else if( i_action == ACTIONID_POSITION && b_seekable )
{
DisplayPosition( p_intf, p_vout, p_input );
void *p_data )
{
intf_thread_t *p_intf = (intf_thread_t *)p_data;
- int i_action;
+ int i_action = 0;
- (void)libvlc;
(void)psz_var;
(void)oldval;
+ int i_mode = p_intf->p_sys->i_mousewheel_mode;
+
/* Special action for mouse event */
- /* FIXME: This should probably be configurable */
/* FIXME: rework hotkeys handling to allow more than 1 event
* to trigger one same action */
switch (newval.i_int & KEY_SPECIAL)
{
case KEY_MOUSEWHEELUP:
- i_action = ACTIONID_VOL_UP;
+ i_action = (i_mode == MOUSEWHEEL_VOLUME ) ? ACTIONID_VOL_UP
+ : ACTIONID_JUMP_FORWARD_EXTRASHORT;
break;
case KEY_MOUSEWHEELDOWN:
- i_action = ACTIONID_VOL_DOWN;
+ i_action = (i_mode == MOUSEWHEEL_VOLUME ) ? ACTIONID_VOL_DOWN
+ : ACTIONID_JUMP_BACKWARD_EXTRASHORT;
break;
case KEY_MOUSEWHEELLEFT:
- i_action = ACTIONID_JUMP_BACKWARD_EXTRASHORT;
+ i_action = (i_mode == MOUSEWHEEL_VOLUME ) ?
+ ACTIONID_JUMP_BACKWARD_EXTRASHORT : ACTIONID_VOL_DOWN;
break;
case KEY_MOUSEWHEELRIGHT:
- i_action = ACTIONID_JUMP_FORWARD_EXTRASHORT;
+ i_action = (i_mode == MOUSEWHEEL_VOLUME ) ?
+ ACTIONID_JUMP_FORWARD_EXTRASHORT : ACTIONID_VOL_UP;
+ break;
+ case KEY_MENU:
+ var_SetBool( libvlc, "intf-popupmenu", true );
break;
default:
return VLC_SUCCESS;
}
+ if( i_mode == NO_MOUSEWHEEL ) return VLC_SUCCESS;
+
if( i_action )
return PutAction( p_intf, i_action );
return VLC_SUCCESS;
static void PlayBookmark( intf_thread_t *p_intf, int i_num )
{
- vlc_value_t val;
- char psz_bookmark_name[11];
- playlist_t *p_playlist = pl_Hold( p_intf );
+ char *psz_bookmark_name;
+ if( asprintf( &psz_bookmark_name, "bookmark%i", i_num ) == -1 )
+ return;
- sprintf( psz_bookmark_name, "bookmark%i", i_num );
- var_Create( p_intf, psz_bookmark_name, VLC_VAR_STRING|VLC_VAR_DOINHERIT );
- var_Get( p_intf, psz_bookmark_name, &val );
+ playlist_t *p_playlist = pl_Hold( p_intf );
+ char *psz_bookmark = var_CreateGetString( p_intf, psz_bookmark_name );
- char *psz_bookmark = strdup( val.psz_string );
PL_LOCK;
FOREACH_ARRAY( playlist_item_t *p_item, p_playlist->items )
char *psz_uri = input_item_GetURI( p_item->p_input );
free( psz_uri );
FOREACH_END();
PL_UNLOCK;
+
free( psz_bookmark );
- vlc_object_release( p_playlist );
+ free( psz_bookmark_name );
+ pl_Release( p_intf );
}
static void SetBookmark( intf_thread_t *p_intf, int i_num )
{
+ char *psz_bookmark_name;
+ if( asprintf( &psz_bookmark_name, "bookmark%i", i_num ) == -1 )
+ return;
+
playlist_t *p_playlist = pl_Hold( p_intf );
- char psz_bookmark_name[11];
- sprintf( psz_bookmark_name, "bookmark%i", i_num );
var_Create( p_intf, psz_bookmark_name,
VLC_VAR_STRING|VLC_VAR_DOINHERIT );
playlist_item_t * p_item = playlist_CurrentPlayingItem( p_playlist );
free( psz_uri );
config_SaveConfigFile( p_intf, "hotkeys" );
}
+
pl_Release( p_intf );
+ free( psz_bookmark_name );
}
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 );
- vout_OSDMessage( p_input, POSITION_TEXT_CHAN, (char *) "%s / %s",
+ vout_OSDMessage( p_input, POSITION_TEXT_CHAN, "%s / %s",
psz_time, psz_duration );
}
else if( i_seconds > 0 )
{
- vout_OSDMessage( p_input, POSITION_TEXT_CHAN, psz_time );
+ vout_OSDMessage( p_input, POSITION_TEXT_CHAN, "%s", psz_time );
}
if( p_vout->b_fullscreen )