X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fhotkeys.c;h=3e93d613813ee4d483dcd59a383c021b55835abb;hb=ead147e1fa4f86b668dca1a30c439fe9a510ea4f;hp=18b977f127e0fe5d82f8d9b0900a9f96c4f8331c;hpb=f016819850d9d4896a3944bd0e94b73f648ec85b;p=vlc diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c index 18b977f127..3e93d61381 100644 --- a/modules/control/hotkeys.c +++ b/modules/control/hotkeys.c @@ -30,7 +30,8 @@ # include "config.h" #endif -#include +#include +#include #include #include #include @@ -51,17 +52,15 @@ *****************************************************************************/ struct intf_sys_t { - vlc_mutex_t change_lock; /* mutex to keep the callback - * and the main loop from - * stepping on each others - * toes */ - int p_keys[ BUFFER_SIZE ]; /* buffer that contains - * keyevents */ + int p_actions[ BUFFER_SIZE ]; /* buffer that contains + * action events */ int i_size; /* number of events in buffer */ int p_channels[ CHANNELS_NUMBER ]; /* contains registered * channel IDs */ input_thread_t * p_input; /* pointer to input */ vout_thread_t * p_vout; /* pointer to vout object */ + vlc_mutex_t lock; /* callback lock */ + vlc_cond_t wait; /* callback event */ }; /***************************************************************************** @@ -70,11 +69,11 @@ struct intf_sys_t static int Open ( vlc_object_t * ); static void Close ( vlc_object_t * ); static void Run ( intf_thread_t * ); -static int GetKey ( intf_thread_t *); -static int KeyEvent( vlc_object_t *, char const *, - vlc_value_t, vlc_value_t, void * ); -static int ActionKeyCB( vlc_object_t *, char const *, +static int GetAction( intf_thread_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 * ); @@ -96,12 +95,12 @@ static void ClearChannels ( intf_thread_t *, vout_thread_t * ); #define BOOKMARK10_TEXT N_("Playlist bookmark 10") #define BOOKMARK_LONGTEXT N_("Define playlist bookmarks.") -vlc_module_begin(); - set_shortname( _("Hotkeys") ); - set_description( _("Hotkeys management interface") ); - set_capability( "interface", 0 ); - set_callbacks( Open, Close ); -vlc_module_end(); +vlc_module_begin () + set_shortname( N_("Hotkeys") ) + set_description( N_("Hotkeys management interface") ) + set_capability( "interface", 0 ) + set_callbacks( Open, Close ) +vlc_module_end () /***************************************************************************** * Open: initialize interface @@ -109,13 +108,20 @@ vlc_module_end(); static int Open( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; - MALLOC_ERR( p_intf->p_sys, intf_sys_t ); + intf_sys_t *p_sys; + p_sys = malloc( sizeof( intf_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; - vlc_mutex_init( p_intf, &p_intf->p_sys->change_lock ); - p_intf->p_sys->i_size = 0; + p_intf->p_sys = p_sys; p_intf->pf_run = Run; - var_AddCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf ); + p_sys->i_size = 0; + vlc_mutex_init( &p_sys->lock ); + vlc_cond_init( &p_sys->wait ); + + 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; } @@ -125,10 +131,14 @@ static int Open( vlc_object_t *p_this ) static void Close( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_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 ); - var_DelCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf ); + vlc_cond_destroy( &p_sys->wait ); + vlc_mutex_destroy( &p_sys->lock ); - vlc_mutex_destroy( &p_intf->p_sys->change_lock ); /* Destroy structure */ free( p_intf->p_sys ); } @@ -138,87 +148,35 @@ static void Close( vlc_object_t *p_this ) *****************************************************************************/ static void Run( intf_thread_t *p_intf ) { - input_thread_t *p_input = NULL; vout_thread_t *p_vout = NULL; - vout_thread_t *p_last_vout = NULL; - struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys; vlc_value_t val; int i; - playlist_t *p_playlist = pl_Yield( p_intf ); + playlist_t *p_playlist = pl_Hold( p_intf ); + int canc = vlc_savecancel(); + + vlc_cleanup_push( __pl_Release, p_intf ); /* Initialize hotkey structure */ - for( i = 0; p_hotkeys[i].psz_action != NULL; i++ ) + for( struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys; + p_hotkey->psz_action != NULL; + p_hotkey++ ) { - var_Create( p_intf->p_libvlc, p_hotkeys[i].psz_action, - VLC_VAR_HOTKEY | VLC_VAR_DOINHERIT ); - - var_AddCallback( p_intf->p_libvlc, p_hotkeys[i].psz_action, - ActionKeyCB, p_hotkeys + i ); - var_Get( p_intf->p_libvlc, p_hotkeys[i].psz_action, &val ); - var_Set( p_intf->p_libvlc, p_hotkeys[i].psz_action, val ); + p_hotkey->i_key = config_GetInt( p_intf, p_hotkey->psz_action ); } - for( vlc_bool_t b_quit = VLC_FALSE ; !b_quit; ) + for( ;; ) { - int i_key, i_action; - int i_times = 0; - - /* Sleep a bit */ - /* msleep( INTF_IDLE_SLEEP ); */ + input_thread_t *p_input; + vout_thread_t *p_last_vout; + int i_action; - i_action = 0; - i_key = GetKey( p_intf ); + vlc_restorecancel( canc ); + i_action = GetAction( p_intf ); - /* 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 (i_key & KEY_SPECIAL) - { - case KEY_MOUSEWHEELUP: - i_action = ACTIONID_VOL_UP; - break; - case KEY_MOUSEWHEELDOWN: - i_action = ACTIONID_VOL_DOWN; - break; - case KEY_MOUSEWHEELLEFT: - i_action = ACTIONID_JUMP_BACKWARD_EXTRASHORT; - break; - case KEY_MOUSEWHEELRIGHT: - i_action = ACTIONID_JUMP_FORWARD_EXTRASHORT; - break; - default: break; - } - - /* No mouse action, find action triggered by hotkey */ - if(!i_action) - { - for( i = 0; i_key != -1 && p_hotkeys[i].psz_action != NULL; i++ ) - { - if( p_hotkeys[i].i_key == i_key ) - { - i_action = p_hotkeys[i].i_action; - i_times = p_hotkeys[i].i_times; - /* times key pressed within max. delta time */ - p_hotkeys[i].i_times = 0; - break; - } - } - } - - if( !i_action ) - { - b_quit = vlc_object_lock_and_wait( p_intf ); - /* No key pressed, sleep a bit more */ - continue; - } + canc = vlc_savecancel(); /* Update the input */ - PL_LOCK; - p_input = p_playlist->p_input; - if( p_input ) - vlc_object_yield( p_input ); - PL_UNLOCK; + p_input = playlist_CurrentInput( p_playlist ); /* Update the vout */ p_last_vout = p_vout; @@ -237,10 +195,8 @@ static void Run( intf_thread_t *p_intf ) /* Quit */ if( i_action == ACTIONID_QUIT ) { - if( p_playlist ) - playlist_Stop( p_playlist ); vlc_object_kill( p_intf->p_libvlc ); - vlc_object_kill( p_intf ); + ClearChannels( p_intf, p_vout ); vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Quit" ) ); if( p_vout ) @@ -282,9 +238,9 @@ static void Run( intf_thread_t *p_intf ) } /* Interface showing */ else if( i_action == ACTIONID_INTF_SHOW ) - var_SetBool( p_playlist, "intf-show", VLC_TRUE ); + var_SetBool( p_intf->p_libvlc, "intf-show", true ); else if( i_action == ACTIONID_INTF_HIDE ) - var_SetBool( p_playlist, "intf-show", VLC_FALSE ); + var_SetBool( p_intf->p_libvlc, "intf-show", false ); /* Video Output actions */ else if( i_action == ACTIONID_SNAPSHOT ) { @@ -309,7 +265,7 @@ static void Run( intf_thread_t *p_intf ) { if( p_vout && var_GetBool( p_vout, "fullscreen" ) ) { - var_SetBool( p_vout, "fullscreen", VLC_FALSE ); + var_SetBool( p_vout, "fullscreen", false ); } } else if( i_action == ACTIONID_ZOOM_QUARTER || @@ -352,19 +308,19 @@ static void Run( intf_thread_t *p_intf ) vlc_value_t val2; var_Get( p_playlist, "loop", &val ); var_Get( p_playlist, "repeat", &val2 ); - if( val2.b_bool == VLC_TRUE ) + if( val2.b_bool == true ) { - val.b_bool = VLC_FALSE; - val2.b_bool = VLC_FALSE; + val.b_bool = false; + val2.b_bool = false; } - else if( val.b_bool == VLC_TRUE ) + else if( val.b_bool == true ) { - val.b_bool = VLC_FALSE; - val2.b_bool = VLC_TRUE; + val.b_bool = false; + val2.b_bool = true; } else { - val.b_bool = VLC_TRUE; + val.b_bool = true; } var_Set( p_playlist, "loop", val ); var_Set( p_playlist, "repeat", val2 ); @@ -453,11 +409,7 @@ static void Run( intf_thread_t *p_intf ) /* Input options */ else if( p_input ) { - /* FIXME --fenrir - * How to get a valid value ? - * That's not that easy with some special stream - */ - vlc_bool_t b_seekable = VLC_TRUE; + bool b_seekable = var_GetBool( p_input, "can-seek" ); int i_interval =0; if( i_action == ACTIONID_PAUSE ) @@ -478,8 +430,7 @@ static void Run( intf_thread_t *p_intf ) #define SET_TIME( a, b ) \ i_interval = config_GetInt( p_input, a "-jump-size" ); \ if( i_interval > 0 ) { \ - val.i_time = ( (mtime_t)(i_interval * b) * 1000000L \ - * ((mtime_t)(1 << i_times))); \ + val.i_time = (mtime_t)(i_interval * b) * 1000000L; \ var_Set( p_input, "time-offset", val ); \ DisplayPosition( p_intf, p_vout, p_input ); \ } @@ -625,6 +576,8 @@ static void Run( intf_thread_t *p_intf ) vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Aspect ratio: %s"), text_list.p_list->p_values[i].psz_string ); + + var_Change( p_vout, "aspect-ratio", VLC_VAR_FREELIST, &val_list, &text_list ); } free( val.psz_string ); } @@ -651,6 +604,8 @@ static void Run( intf_thread_t *p_intf ) vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Crop: %s"), text_list.p_list->p_values[i].psz_string ); + + var_Change( p_vout, "crop", VLC_VAR_FREELIST, &val_list, &text_list ); } free( val.psz_string ); } @@ -677,6 +632,8 @@ static void Run( intf_thread_t *p_intf ) vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Deinterlace mode: %s"), text_list.p_list->p_values[i].psz_string ); + + var_Change( p_vout, "deinterlace", VLC_VAR_FREELIST, &val_list, &text_list ); } free( val.psz_string ); } @@ -707,6 +664,8 @@ static void Run( intf_thread_t *p_intf ) vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Zoom mode: %s"), text_list.p_list->p_values[i].var.psz_name ); + + var_Change( p_vout, "zoom", VLC_VAR_FREELIST, &val_list, &text_list ); } } else if( i_action == ACTIONID_CROP_TOP && p_vout ) @@ -741,6 +700,12 @@ static void Run( intf_thread_t *p_intf ) { playlist_Stop( p_playlist ); } + else if( i_action == ACTIONID_FRAME_NEXT ) + { + var_SetVoid( p_input, "frame-next" ); + vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, + _("Next frame") ); + } else if( i_action == ACTIONID_FASTER ) { var_SetVoid( p_input, "rate-faster" ); @@ -863,97 +828,128 @@ static void Run( intf_thread_t *p_intf ) { osd_MenuActivate( VLC_OBJECT(p_intf) ); } + else if( i_action == ACTIONID_RECORD ) + { + if( var_GetBool( p_input, "can-record" ) ) + { + const bool b_record = !var_GetBool( p_input, "record" ); + + if( b_record ) + vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Recording") ); + else + vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Recording done") ); + var_SetBool( p_input, "record", b_record ); + } + } } if( p_vout ) vlc_object_release( p_vout ); if( p_input ) vlc_object_release( p_input ); } - pl_Release( p_intf ); + + /* dead code */ + abort(); + vlc_cleanup_pop(); } -static int GetKey( intf_thread_t *p_intf) +static int GetAction( intf_thread_t *p_intf ) { - vlc_mutex_lock( &p_intf->p_sys->change_lock ); - if ( p_intf->p_sys->i_size == 0 ) - { - vlc_mutex_unlock( &p_intf->p_sys->change_lock ); - return -1; - } + intf_sys_t *p_sys = p_intf->p_sys; + int i_ret; + + vlc_mutex_lock( &p_sys->lock ); + mutex_cleanup_push( &p_sys->lock ); + + while( p_sys->i_size == 0 ) + vlc_cond_wait( &p_sys->wait, &p_sys->lock ); + + i_ret = p_sys->p_actions[ 0 ]; + p_sys->i_size--; + for( int i = 0; i < p_sys->i_size; i++ ) + p_sys->p_actions[i] = p_sys->p_actions[i + 1]; + + vlc_cleanup_run(); + return i_ret; +} + +static int PutAction( intf_thread_t *p_intf, int i_action ) +{ + intf_sys_t *p_sys = p_intf->p_sys; + int i_ret = VLC_EGENERIC; + + vlc_mutex_lock( &p_sys->lock ); + if ( p_sys->i_size >= BUFFER_SIZE ) + msg_Warn( p_intf, "event buffer full, dropping key actions" ); else - { - int i_return = p_intf->p_sys->p_keys[ 0 ]; - int i; - p_intf->p_sys->i_size--; - for ( i = 0; i < BUFFER_SIZE - 1; i++) - { - p_intf->p_sys->p_keys[ i ] = p_intf->p_sys->p_keys[ i + 1 ]; - } - vlc_mutex_unlock( &p_intf->p_sys->change_lock ); - return i_return; - } + p_sys->p_actions[p_sys->i_size++] = i_action; + + vlc_cond_signal( &p_sys->wait ); + vlc_mutex_unlock( &p_sys->lock ); + return i_ret; } /***************************************************************************** - * KeyEvent: callback for keyboard events + * SpecialKeyEvent: callback for mouse events *****************************************************************************/ -static int KeyEvent( vlc_object_t *p_this, char const *psz_var, - vlc_value_t oldval, vlc_value_t newval, void *p_data ) +static int SpecialKeyEvent( vlc_object_t *libvlc, char const *psz_var, + vlc_value_t oldval, vlc_value_t newval, + void *p_data ) { - VLC_UNUSED(psz_var); VLC_UNUSED(oldval); intf_thread_t *p_intf = (intf_thread_t *)p_data; - if ( !newval.i_int ) - { - msg_Warn( p_this, "Received invalid key event %d", newval.i_int ); - return VLC_EGENERIC; - } - vlc_mutex_lock( &p_intf->p_sys->change_lock ); - if ( p_intf->p_sys->i_size == BUFFER_SIZE ) - { - msg_Warn( p_intf, "event buffer full, dropping keypress" ); - vlc_mutex_unlock( &p_intf->p_sys->change_lock ); - return VLC_EGENERIC; - } - else + int i_action; + + (void)libvlc; + (void)psz_var; + (void)oldval; + + /* 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) { - p_intf->p_sys->p_keys[ p_intf->p_sys->i_size ] = newval.i_int; - p_intf->p_sys->i_size++; + case KEY_MOUSEWHEELUP: + i_action = ACTIONID_VOL_UP; + break; + case KEY_MOUSEWHEELDOWN: + i_action = ACTIONID_VOL_DOWN; + break; + case KEY_MOUSEWHEELLEFT: + i_action = ACTIONID_JUMP_BACKWARD_EXTRASHORT; + break; + case KEY_MOUSEWHEELRIGHT: + i_action = ACTIONID_JUMP_FORWARD_EXTRASHORT; + break; + default: + return VLC_SUCCESS; } - vlc_mutex_lock( &p_intf->object_lock ); - vlc_cond_signal( &p_intf->object_wait ); - vlc_mutex_unlock( &p_intf->object_lock ); - vlc_mutex_unlock( &p_intf->p_sys->change_lock ); + if( i_action ) + return PutAction( p_intf, i_action ); return VLC_SUCCESS; } -static int ActionKeyCB( vlc_object_t *libvlc, char const *psz_var, +/***************************************************************************** + * ActionEvent: callback for hotkey actions + *****************************************************************************/ +static int ActionEvent( vlc_object_t *libvlc, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ) { - mtime_t i_date; - struct hotkey *p_hotkey = p_data; - - (void)libvlc; (void)psz_var; (void)oldval; - - p_hotkey->i_key = newval.i_int; + intf_thread_t *p_intf = (intf_thread_t *)p_data; - /* do hotkey accounting */ - i_date = mdate(); - if( (p_hotkey->i_delta_date > 0) && - (p_hotkey->i_delta_date <= (i_date - p_hotkey->i_last_date) ) ) - p_hotkey->i_times = 0; - else - p_hotkey->i_times++; - p_hotkey->i_last_date = i_date; + (void)libvlc; + (void)psz_var; + (void)oldval; - return VLC_SUCCESS; + return PutAction( p_intf, newval.i_int ); } 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_Yield( p_intf ); + playlist_t *p_playlist = pl_Hold( p_intf ); sprintf( psz_bookmark_name, "bookmark%i", i_num ); var_Create( p_intf, psz_bookmark_name, VLC_VAR_STRING|VLC_VAR_DOINHERIT ); @@ -966,7 +962,7 @@ static void PlayBookmark( intf_thread_t *p_intf, int i_num ) if( !strcmp( psz_bookmark, psz_uri ) ) { free( psz_uri ); - playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, + playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, NULL, p_item ); break; } @@ -974,19 +970,21 @@ static void PlayBookmark( intf_thread_t *p_intf, int i_num ) free( psz_uri ); FOREACH_END(); PL_UNLOCK; + free( psz_bookmark ); vlc_object_release( p_playlist ); } static void SetBookmark( intf_thread_t *p_intf, int i_num ) { - playlist_t *p_playlist = pl_Yield( p_intf ); + 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 ); - if( p_playlist->status.p_item ) + playlist_item_t * p_item = playlist_CurrentPlayingItem( p_playlist ); + if( p_item ) { - char *psz_uri = input_item_GetURI( p_playlist->status.p_item->p_input ); + char *psz_uri = input_item_GetURI( p_item->p_input ); config_PutPsz( p_intf, psz_bookmark_name, psz_uri); msg_Info( p_intf, "setting playlist bookmark %i to %s", i_num, psz_uri); free( psz_uri ); @@ -1023,7 +1021,7 @@ static void DisplayPosition( intf_thread_t *p_intf, vout_thread_t *p_vout, vout_OSDMessage( p_input, POSITION_TEXT_CHAN, psz_time ); } - if( !p_vout->p_parent_intf || p_vout->b_fullscreen ) + if( !p_vout->p_window || p_vout->b_fullscreen ) { var_Get( p_input, "position", &pos ); vout_OSDSlider( VLC_OBJECT( p_input ), POSITION_WIDGET_CHAN, @@ -1040,7 +1038,7 @@ static void DisplayVolume( intf_thread_t *p_intf, vout_thread_t *p_vout, } ClearChannels( p_intf, p_vout ); - if( !p_vout->p_parent_intf || p_vout->b_fullscreen ) + if( !p_vout->p_window || p_vout->b_fullscreen ) { vout_OSDSlider( VLC_OBJECT( p_vout ), VOLUME_WIDGET_CHAN, i_vol*100/AOUT_VOLUME_MAX, OSD_VERT_SLIDER );