[vlc-devel] [PATCH v2 02/11] actions: Allow actions to be provided with a context

Hugo Beauzée-Luyssen hugo at beauzee.fr
Wed Aug 9 18:16:26 CEST 2017


---
 include/vlc_actions.h     | 197 +++++++-----
 include/vlc_plugin.h      |   4 +-
 modules/control/hotkeys.c |   8 +-
 src/misc/actions.c        | 798 ++++++++++++++++++++++++++++++++--------------
 4 files changed, 676 insertions(+), 331 deletions(-)

diff --git a/include/vlc_actions.h b/include/vlc_actions.h
index 0995d3db5c..bf03281461 100644
--- a/include/vlc_actions.h
+++ b/include/vlc_actions.h
@@ -118,46 +118,16 @@ VLC_API char *vlc_keycode2str(uint_fast32_t i_key, bool locale) VLC_USED;
 VLC_API uint_fast32_t vlc_str2keycode(const char *str) VLC_USED;
 
 typedef enum vlc_action_id {
+    /* Takes no extra parameter */
     ACTIONID_NONE = 0,
     ACTIONID_QUIT,
-    ACTIONID_PLAY_PAUSE,
-    ACTIONID_PLAY,
-    ACTIONID_PAUSE,
-    ACTIONID_STOP,
-    ACTIONID_PREV,
-    ACTIONID_NEXT,
-    ACTIONID_SLOWER,
-    ACTIONID_FASTER,
-    ACTIONID_TOGGLE_FULLSCREEN,
-    ACTIONID_VOL_UP,
-    ACTIONID_VOL_DOWN,
-    ACTIONID_NAV_ACTIVATE,
-    ACTIONID_NAV_UP,
-    ACTIONID_NAV_DOWN,
-    ACTIONID_NAV_LEFT,
-    ACTIONID_NAV_RIGHT,
-    ACTIONID_JUMP_BACKWARD_EXTRASHORT,
-    ACTIONID_JUMP_FORWARD_EXTRASHORT,
-    ACTIONID_JUMP_BACKWARD_SHORT,
-    ACTIONID_JUMP_FORWARD_SHORT,
-    ACTIONID_JUMP_BACKWARD_MEDIUM,
-    ACTIONID_JUMP_FORWARD_MEDIUM,
-    ACTIONID_JUMP_BACKWARD_LONG,
-    ACTIONID_JUMP_FORWARD_LONG,
-    ACTIONID_FRAME_NEXT,
-    ACTIONID_POSITION,
-    ACTIONID_VOL_MUTE,
-/* let ACTIONID_SET_BOOMARK* and ACTIONID_PLAY_BOOKMARK* be contiguous */
-    ACTIONID_SET_BOOKMARK1,
-    ACTIONID_SET_BOOKMARK2,
-    ACTIONID_SET_BOOKMARK3,
-    ACTIONID_SET_BOOKMARK4,
-    ACTIONID_SET_BOOKMARK5,
-    ACTIONID_SET_BOOKMARK6,
-    ACTIONID_SET_BOOKMARK7,
-    ACTIONID_SET_BOOKMARK8,
-    ACTIONID_SET_BOOKMARK9,
-    ACTIONID_SET_BOOKMARK10,
+    ACTIONID_INTF_TOGGLE_FSC,
+    ACTIONID_INTF_HIDE,
+    ACTIONID_INTF_BOSS,
+    ACTIONID_INTF_POPUP_MENU,
+
+    /* Playlist actions don't take extra parameter */
+    /* let ACTIONID_SET_BOOMARK* and ACTIONID_PLAY_BOOKMARK* be contiguous */
     ACTIONID_PLAY_BOOKMARK1,
     ACTIONID_PLAY_BOOKMARK2,
     ACTIONID_PLAY_BOOKMARK3,
@@ -168,84 +138,141 @@ typedef enum vlc_action_id {
     ACTIONID_PLAY_BOOKMARK8,
     ACTIONID_PLAY_BOOKMARK9,
     ACTIONID_PLAY_BOOKMARK10,
+    ACTIONID_SET_BOOKMARK1,
+    ACTIONID_SET_BOOKMARK2,
+    ACTIONID_SET_BOOKMARK3,
+    ACTIONID_SET_BOOKMARK4,
+    ACTIONID_SET_BOOKMARK5,
+    ACTIONID_SET_BOOKMARK6,
+    ACTIONID_SET_BOOKMARK7,
+    ACTIONID_SET_BOOKMARK8,
+    ACTIONID_SET_BOOKMARK9,
+    ACTIONID_SET_BOOKMARK10,
     /* end of contiguous zone */
+    ACTIONID_LOOP,
+    ACTIONID_RANDOM,
+    ACTIONID_NEXT,
+    ACTIONID_PREV,
+    ACTIONID_STOP,
+    ACTIONID_RATE_NORMAL,
+    ACTIONID_FASTER,
+    ACTIONID_SLOWER,
+    ACTIONID_RATE_FASTER_FINE,
+    ACTIONID_RATE_SLOWER_FINE,
     ACTIONID_PLAY_CLEAR,
-    ACTIONID_SUBDELAY_UP,
-    ACTIONID_SUBDELAY_DOWN,
+    ACTIONID_VOL_UP,
+    ACTIONID_VOL_DOWN,
+    ACTIONID_VOL_MUTE,
+    /* End of playlist related actions */
+
+    /*
+     * Audio output actions may take an audio_output_t* as 1st and only
+     * extra parameter. Omiting it or passing NULL will fallback to the current
+     * audio output
+     */
+    /* Cycle Through Audio Devices */
+    ACTIONID_AUDIODEVICE_CYCLE,
+    /* End of audio output related actions */
+
+    ACTIONID_PLAY_PAUSE,
+    ACTIONID_PLAY,
+    ACTIONID_PAUSE,
+    ACTIONID_RECORD,
+    ACTIONID_FRAME_NEXT,
     ACTIONID_SUBSYNC_MARKAUDIO,
     ACTIONID_SUBSYNC_MARKSUB,
     ACTIONID_SUBSYNC_APPLY,
     ACTIONID_SUBSYNC_RESET,
-    ACTIONID_SUBPOS_UP,
-    ACTIONID_SUBPOS_DOWN,
+    ACTIONID_SUBDELAY_DOWN,
+    ACTIONID_SUBDELAY_UP,
+    ACTIONID_AUDIODELAY_DOWN,
+    ACTIONID_AUDIODELAY_UP,
     ACTIONID_AUDIO_TRACK,
-    ACTIONID_SUBTITLE_REVERSE_TRACK,
     ACTIONID_SUBTITLE_TRACK,
+    ACTIONID_SUBTITLE_REVERSE_TRACK,
     ACTIONID_SUBTITLE_TOGGLE,
-    ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL,
-    ACTIONID_SUBTITLE_TEXT_SCALE_UP,
-    ACTIONID_SUBTITLE_TEXT_SCALE_DOWN,
-    ACTIONID_INTF_TOGGLE_FSC,
-    ACTIONID_INTF_HIDE,
-    ACTIONID_INTF_BOSS,
+    /* Cycle Through Program Service IDs */
+    ACTIONID_PROGRAM_SID_NEXT,
+    ACTIONID_PROGRAM_SID_PREV,
+    ACTIONID_JUMP_BACKWARD_EXTRASHORT,
+    ACTIONID_JUMP_FORWARD_EXTRASHORT,
+    ACTIONID_JUMP_BACKWARD_SHORT,
+    ACTIONID_JUMP_FORWARD_SHORT,
+    ACTIONID_JUMP_BACKWARD_MEDIUM,
+    ACTIONID_JUMP_FORWARD_MEDIUM,
+    ACTIONID_JUMP_BACKWARD_LONG,
+    ACTIONID_JUMP_FORWARD_LONG,
     /* chapter and title navigation */
     ACTIONID_TITLE_PREV,
     ACTIONID_TITLE_NEXT,
     ACTIONID_CHAPTER_PREV,
     ACTIONID_CHAPTER_NEXT,
     /* end of chapter and title navigation */
-    ACTIONID_AUDIODELAY_UP,
-    ACTIONID_AUDIODELAY_DOWN,
-    ACTIONID_SNAPSHOT,
-    ACTIONID_RECORD,
     ACTIONID_DISC_MENU,
+    ACTIONID_NAV_ACTIVATE,
+
+    /*
+     * Video output actions
+     * Those actions may take a vout_thread_t* as 1st and only extra parameter.
+     * Omiting it or passing NULL will fallback to the current video output
+     */
+    ACTIONID_WALLPAPER,
+    ACTIONID_SNAPSHOT,
+    ACTIONID_TOGGLE_FULLSCREEN,
+    ACTIONID_LEAVE_FULLSCREEN,
     ACTIONID_ASPECT_RATIO,
     ACTIONID_CROP,
-    ACTIONID_DEINTERLACE,
-    ACTIONID_DEINTERLACE_MODE,
-    ACTIONID_ZOOM,
-    ACTIONID_UNZOOM,
     ACTIONID_CROP_TOP,
     ACTIONID_UNCROP_TOP,
-    ACTIONID_CROP_LEFT,
-    ACTIONID_UNCROP_LEFT,
     ACTIONID_CROP_BOTTOM,
     ACTIONID_UNCROP_BOTTOM,
+    ACTIONID_CROP_LEFT,
+    ACTIONID_UNCROP_LEFT,
     ACTIONID_CROP_RIGHT,
-    ACTIONID_UNCROP_RIGHT,
-    ACTIONID_RANDOM,
-    ACTIONID_LOOP,
-    ACTIONID_WALLPAPER,
-    ACTIONID_LEAVE_FULLSCREEN,
+    ACTIONID_UNCROP_RIGHT,\
+    /* scaling */
+    ACTIONID_TOGGLE_AUTOSCALE,
+    ACTIONID_SCALE_UP,
+    ACTIONID_SCALE_DOWN,
     /* Zoom */
     ACTIONID_ZOOM_QUARTER,
     ACTIONID_ZOOM_HALF,
     ACTIONID_ZOOM_ORIGINAL,
     ACTIONID_ZOOM_DOUBLE,
-    /* Cycle Through Audio Devices */
-    ACTIONID_AUDIODEVICE_CYCLE,
-    /* scaling */
-    ACTIONID_TOGGLE_AUTOSCALE,
-    ACTIONID_SCALE_UP,
-    ACTIONID_SCALE_DOWN,
-    /* */
-    ACTIONID_RATE_NORMAL,
-    ACTIONID_RATE_SLOWER_FINE,
-    ACTIONID_RATE_FASTER_FINE,
-    /* Cycle Through Program Service IDs */
-    ACTIONID_PROGRAM_SID_NEXT,
-    ACTIONID_PROGRAM_SID_PREV,
-    ACTIONID_INTF_POPUP_MENU,
+    ACTIONID_ZOOM,
+    ACTIONID_UNZOOM,
+    /* Deinterlace */
+    ACTIONID_DEINTERLACE,
+    ACTIONID_DEINTERLACE_MODE,
+    /* Subtitles */
+    ACTIONID_SUBTITLE_TEXT_SCALE_DOWN,
+    ACTIONID_SUBTITLE_TEXT_SCALE_UP,
+    ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL,
+
+    /*
+     * Input & video_output actions
+     * Those actions may take at least 2 extra parameters:
+     * - An input_thread_t*
+     * - A vout_thread_t*
+     * Omiting them or passing NULL will fallback to the current input/vout
+     */
+    ACTIONID_POSITION,
+    /* Combo Actions */
+    ACTIONID_COMBO_VOL_FOV_UP,
+    ACTIONID_COMBO_VOL_FOV_DOWN,
+    /* Navigation */
+    ACTIONID_NAV_UP,
+    ACTIONID_NAV_DOWN,
+    ACTIONID_NAV_LEFT,
+    ACTIONID_NAV_RIGHT,
     /* Viewpoint */
     ACTIONID_VIEWPOINT_FOV_IN,
     ACTIONID_VIEWPOINT_FOV_OUT,
     ACTIONID_VIEWPOINT_ROLL_CLOCK,
     ACTIONID_VIEWPOINT_ROLL_ANTICLOCK,
-    ACTIONID_VIEWPOINT_UPDATE, /* Arg 1: vlc_viewpoint_t* */
-    /* Combo Actions */
-    ACTIONID_COMBO_VOL_FOV_UP,
-    ACTIONID_COMBO_VOL_FOV_DOWN,
-
+    ACTIONID_VIEWPOINT_UPDATE, /* Arg 3: vlc_viewpoint_t* */
+    ACTIONID_SUBPOS_DOWN,
+    ACTIONID_SUBPOS_UP
 } vlc_action_id_t;
 
 /**
@@ -283,8 +310,8 @@ vlc_actions_get_key_names(vlc_object_t *p_obj);
  */
 VLC_API int
 vlc_actions_do(vlc_object_t *p_obj, vlc_action_id_t i_action,
-               bool b_notify, ...);
-#define vlc_actions_do(a,b,c,...) vlc_actions_do(VLC_OBJECT(a),b,c, \
+               bool b_notify, unsigned int i_nb_args, ...);
+#define vlc_actions_do(a,b,c,d,...) vlc_actions_do(VLC_OBJECT(a),b,c,d, \
     ##__VA_ARGS__)
 
 #endif
diff --git a/include/vlc_plugin.h b/include/vlc_plugin.h
index 7e9e447d04..339d6b445f 100644
--- a/include/vlc_plugin.h
+++ b/include/vlc_plugin.h
@@ -188,8 +188,8 @@ enum vlc_module_properties
 /**
  * Current plugin ABI version
  */
-# define MODULE_SYMBOL 3_0_0f
-# define MODULE_SUFFIX "__3_0_0f"
+# define MODULE_SYMBOL 3_0_0g
+# define MODULE_SUFFIX "__3_0_0g"
 
 /*****************************************************************************
  * Add a few defines. You do not want to read this section. Really.
diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c
index 2a14bee628..c3913eefdc 100644
--- a/modules/control/hotkeys.c
+++ b/modules/control/hotkeys.c
@@ -97,7 +97,8 @@ static int MovedEvent( vlc_object_t *p_this, char const *psz_var,
             .pitch = -i_vertical   * 0.05f,
         };
 
-        vlc_actions_do( p_this, ACTIONID_VIEWPOINT_UPDATE, false, &viewpoint );
+        vlc_actions_do( p_this, ACTIONID_VIEWPOINT_UPDATE, false, 3, NULL, NULL,
+                        &viewpoint );
 
         p_sys->vrnav.x = newval.coords.x;
         p_sys->vrnav.y = newval.coords.y;
@@ -112,7 +113,8 @@ static int ViewpointMovedEvent( vlc_object_t *p_this, char const *psz_var,
 {
     (void) psz_var; (void) oldval; (void) p_data;
 
-    vlc_actions_do( p_this, ACTIONID_VIEWPOINT_UPDATE, false, newval.p_address );
+    vlc_actions_do( p_this, ACTIONID_VIEWPOINT_UPDATE, false, 3, NULL, NULL,
+                    newval.p_address );
 
     return VLC_SUCCESS;
 }
@@ -314,5 +316,5 @@ static int ActionEvent( vlc_object_t *libvlc, char const *psz_var,
     (void)oldval;
 
     vlc_object_t *p_this = p_data;
-    return vlc_actions_do( p_this, newval.i_int, true );
+    return vlc_actions_do( p_this, newval.i_int, true, 0 );
 }
diff --git a/src/misc/actions.c b/src/misc/actions.c
index 34f186e8bd..50b10382f5 100644
--- a/src/misc/actions.c
+++ b/src/misc/actions.c
@@ -801,25 +801,8 @@ static float adjust_rate_fine( playlist_t *p_playlist, const int i_dir )
     return f_rate;
 }
 
-static int
-vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
-                   va_list args )
+static void register_osd_channels( vlc_actions_t *p_as, vout_thread_t *p_vout )
 {
-    libvlc_int_t *p_libvlc = p_obj->obj.libvlc;
-    vlc_actions_t *p_as = libvlc_priv(p_libvlc)->actions;
-    playlist_t *p_playlist = libvlc_priv(p_libvlc)->playlist;
-    assert(p_as != NULL);
-
-    if( !p_playlist )
-        return VLC_EGENERIC;
-
-    /* Update the input */
-    input_thread_t *p_input = playlist_CurrentInput( p_playlist );
-
-    /* Update the vout */
-    vout_thread_t *p_vout = p_input ? input_GetVout( p_input ) : NULL;
-    vout_thread_t *p_notify_vout = b_notify ? p_vout : 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.
@@ -827,31 +810,51 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
     if( p_vout && p_vout != p_as->p_last_vout )
         p_as->slider_chan = vout_RegisterSubpictureChannel( p_vout );
     p_as->p_last_vout = p_vout;
+}
 
-    int i_ret = VLC_SUCCESS;
-    /* Quit */
-    switch( i_action )
+static void
+handle_playlist_actions( playlist_t *p_playlist, vlc_action_id_t i_action,
+                         bool b_notify, vlc_actions_t *p_as )
+{
+    vout_thread_t *p_notify_vout = NULL;
+    if( b_notify == true )
     {
-        /* Libvlc / interface actions */
-        case ACTIONID_QUIT:
-            libvlc_Quit( p_libvlc );
+        input_thread_t *p_input = playlist_CurrentInput( p_playlist );
+        if( p_input != NULL )
+        {
+            p_notify_vout = input_GetVout( p_input );
+            vlc_object_release( p_input );
+        }
+    }
+    register_osd_channels( p_as, p_notify_vout );
 
-            clear_channels( p_as, p_notify_vout );
-            display_message( p_notify_vout, _( "Quit" ) );
+    switch( i_action )
+    {
+        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:
+            do_play_bookmark( p_playlist, i_action - ACTIONID_PLAY_BOOKMARK1 + 1 );
             break;
 
-        case ACTIONID_INTF_TOGGLE_FSC:
-        case ACTIONID_INTF_HIDE:
-            var_TriggerCallback( p_libvlc, "intf-toggle-fscontrol" );
-            break;
-        case ACTIONID_INTF_BOSS:
-            var_TriggerCallback( p_libvlc, "intf-boss" );
-            break;
-        case ACTIONID_INTF_POPUP_MENU:
-            var_TriggerCallback( p_libvlc, "intf-popupmenu" );
+        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:
+            do_set_bookmark( p_playlist, i_action - ACTIONID_SET_BOOKMARK1 + 1 );
             break;
-
-        /* Playlist actions (including audio) */
         case ACTIONID_LOOP:
         {
             /* Toggle Normal -> Loop -> Repeat -> Normal ... */
@@ -876,7 +879,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
             display_message( p_notify_vout, _("Loop: %s"), vlc_gettext(mode) );
             break;
         }
-
         case ACTIONID_RANDOM:
         {
             const bool state = var_ToggleBool( p_playlist, "random" );
@@ -884,7 +886,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                             vlc_gettext( state ? N_("On") : N_("Off") ) );
             break;
         }
-
         case ACTIONID_NEXT:
             display_message( p_notify_vout, _("Next") );
             playlist_Next( p_playlist );
@@ -920,32 +921,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
             display_rate( p_notify_vout, rate );
             break;
         }
-
-        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:
-            do_play_bookmark( p_playlist, i_action - ACTIONID_PLAY_BOOKMARK1 + 1 );
-            break;
-
-        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:
-            do_set_bookmark( p_playlist, i_action - ACTIONID_SET_BOOKMARK1 + 1 );
-            break;
         case ACTIONID_PLAY_CLEAR:
         {
             playlist_Clear( p_playlist, pl_Unlocked );
@@ -984,44 +959,34 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                 display_volume( p_as, p_notify_vout,  vol );
             break;
         }
+        default:
+            vlc_assert_unreachable();
+    }
+    if( p_notify_vout )
+        vlc_object_release( p_notify_vout );
+}
 
-        case ACTIONID_AUDIODEVICE_CYCLE:
-        {
-            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] ) )
-                display_message( p_notify_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;
-        }
+static void handle_input_actions( playlist_t *p_playlist, vlc_action_id_t i_action,
+                                  bool b_notify, vlc_actions_t *p_as,
+                                  unsigned int i_args, va_list args )
+{
+    input_thread_t *p_input = NULL;
+    bool b_release_input = false;
+    assert( i_args <= 1 );
+    if( i_args > 0 )
+        p_input = va_arg( args, input_thread_t* );
+    if( p_input == NULL )
+    {
+        p_input = playlist_CurrentInput( p_playlist );
+        b_release_input = p_input != NULL;
+    }
+    vout_thread_t *p_notify_vout  = NULL;
+    if( b_notify && p_input )
+        p_notify_vout = input_GetVout( p_input );
+    register_osd_channels( p_as, p_notify_vout );
 
-        /* Playlist + input actions */
+    switch( i_action )
+    {
         case ACTIONID_PLAY_PAUSE:
             if( p_input )
             {
@@ -1044,17 +1009,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                 playlist_Play( p_playlist );
             }
             break;
-
-        /* Playlist + video output actions */
-        case ACTIONID_WALLPAPER:
-        {
-            bool wp = var_ToggleBool( p_playlist, "video-wallpaper" );
-            if( p_vout )
-                var_SetBool( p_vout, "video-wallpaper", wp );
-            break;
-        }
-
-        /* Input actions */
         case ACTIONID_PAUSE:
             if( p_input && var_GetInteger( p_input, "state" ) != PAUSE_S )
             {
@@ -1144,7 +1098,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                     p_as->subtitle_delaybookmarks.i_time_subtitle = 0;
                 }
             }
-            break;
         }
         case ACTIONID_SUBSYNC_RESET:
         {
@@ -1461,45 +1414,51 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
             if( p_input )
                 input_Control( p_input, INPUT_NAV_ACTIVATE, NULL );
             break;
-        case ACTIONID_NAV_UP:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .pitch = -1.f },
-                                       false );
-            if( p_input )
-                input_Control( p_input, INPUT_NAV_UP, NULL );
-            break;
-        case ACTIONID_NAV_DOWN:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .pitch = 1.f },
-                                       false );
-            if( p_input )
-                input_Control( p_input, INPUT_NAV_DOWN, NULL );
-            break;
-        case ACTIONID_NAV_LEFT:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .yaw = -1.f },
-                                       false );
-            if( p_input )
-                input_Control( p_input, INPUT_NAV_LEFT, NULL );
-            break;
-        case ACTIONID_NAV_RIGHT:
+        default:
+            vlc_assert_unreachable();
+    }
+    if( p_notify_vout != NULL )
+        vlc_object_release( p_notify_vout );
+    if( b_release_input == true )
+        vlc_object_release( p_input );
+}
+
+static void
+handle_vout_actions( playlist_t *p_playlist, vlc_action_id_t i_action,
+                     bool b_notify, vlc_actions_t *p_as,
+                     unsigned int i_args, va_list args )
+{
+    vout_thread_t *p_vout = NULL;
+    bool b_release_vout = false;
+    assert( i_args <= 1);
+    if( i_args > 0 )
+        p_vout = va_arg( args, vout_thread_t* );
+    if( p_vout == NULL )
+    {
+        input_thread_t *p_input = playlist_CurrentInput( p_playlist );
+        if( p_input != NULL )
+        {
+            p_vout = input_GetVout( p_input );
+            b_release_vout = p_vout != NULL;
+            vlc_object_release( p_input );
+        }
+    }
+    vout_thread_t *p_notify_vout = b_notify ? p_vout : NULL;
+    register_osd_channels( p_as, p_notify_vout );
+
+    switch( i_action )
+    {
+        case ACTIONID_WALLPAPER:
+        {
+            bool wp = var_ToggleBool( p_playlist, "video-wallpaper" );
             if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .yaw = 1.f },
-                                       false );
-            if( p_input )
-                input_Control( p_input, INPUT_NAV_RIGHT, NULL );
+                var_SetBool( p_vout, "video-wallpaper", wp );
             break;
-
-        /* Video Output actions */
+        }
         case ACTIONID_SNAPSHOT:
             if( p_vout )
                 var_TriggerCallback( p_vout, "video-snapshot" );
             break;
-
         case ACTIONID_TOGGLE_FULLSCREEN:
         {
             if( p_vout )
@@ -1511,7 +1470,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                 var_ToggleBool( p_playlist, "fullscreen" );
             break;
         }
-
         case ACTIONID_LEAVE_FULLSCREEN:
             if( p_vout )
                 var_SetBool( p_vout, "fullscreen", false );
@@ -1609,43 +1567,7 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
             if( p_vout )
                 var_DecInteger( p_vout, "crop-right" );
             break;
-        case ACTIONID_VIEWPOINT_FOV_IN:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .fov = -1.f },
-                                       false );
-            break;
-        case ACTIONID_VIEWPOINT_FOV_OUT:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .fov = 1.f },
-                                       false );
-            break;
-
-        case ACTIONID_VIEWPOINT_ROLL_CLOCK:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .roll = -1.f },
-                                       false );
-            break;
-        case ACTIONID_VIEWPOINT_ROLL_ANTICLOCK:
-            if( p_vout )
-                input_UpdateViewpoint( p_input,
-                                       &(vlc_viewpoint_t) { .roll = 1.f },
-                                       false );
-            break;
-        case ACTIONID_VIEWPOINT_UPDATE:
-        {
-            if ( p_vout )
-            {
-                vlc_viewpoint_t* viewpoint = va_arg( args, vlc_viewpoint_t* );
-                input_UpdateViewpoint( p_input, viewpoint, false );
-            }
-            break;
-        }
-
-
-         case ACTIONID_TOGGLE_AUTOSCALE:
+        case ACTIONID_TOGGLE_AUTOSCALE:
             if( p_vout )
             {
                 float f_scalefactor = var_GetFloat( p_vout, "zoom" );
@@ -1737,7 +1659,6 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                 }
             }
             break;
-
         case ACTIONID_DEINTERLACE:
             if( p_vout )
             {
@@ -1812,49 +1733,15 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
             }
             break;
 
-        case ACTIONID_SUBPOS_DOWN:
-        case ACTIONID_SUBPOS_UP:
-        {
-            if( p_input && p_vout )
+        case ACTIONID_SUBTITLE_TEXT_SCALE_DOWN:
+        case ACTIONID_SUBTITLE_TEXT_SCALE_UP:
+        case ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL:
+            if( p_vout )
             {
-                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 )
+                int i_scale;
+                if( i_action == ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL )
                 {
-                    display_message( p_notify_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" );
-
-                clear_channels( p_as, p_notify_vout );
-                display_message( p_notify_vout, _( "Subtitle position %d px" ), i_pos );
-                var_FreeList( &list, &list2 );
-            }
-            break;
-        }
-
-        case ACTIONID_SUBTITLE_TEXT_SCALE_DOWN:
-        case ACTIONID_SUBTITLE_TEXT_SCALE_UP:
-        case ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL:
-        {
-            if( p_vout )
-            {
-                int i_scale;
-                if( i_action == ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL )
-                {
-                    i_scale = 100;
+                    i_scale = 100;
                 }
                 else
                 {
@@ -1866,21 +1753,58 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
                 display_message( p_notify_vout, _( "Subtitle text scale %d%%" ), i_scale );
             }
             break;
-        }
+        default:
+            vlc_assert_unreachable();
+    }
+    if( b_release_vout == true )
+        vlc_object_release( p_vout );
+}
 
-        /* Input + video output */
+static void
+handle_input_vout_actions( playlist_t *p_playlist, vlc_action_id_t i_action,
+                           bool b_notify, vlc_actions_t *p_as,
+                           unsigned int i_args, va_list args )
+{
+    vout_thread_t *p_vout = NULL;
+    bool b_release_vout = false;
+    input_thread_t *p_input = NULL;
+    bool b_release_input = false;
+    if( i_args > 0 )
+    {
+        p_input = va_arg( args, input_thread_t* );
+        if( i_args > 1 )
+            p_vout = va_arg( args, vout_thread_t* );
+    }
+    if( p_input == NULL )
+    {
+        p_input = playlist_CurrentInput( p_playlist );
+        b_release_input = p_input != NULL;
+    }
+    if( p_vout == NULL && p_input != NULL )
+    {
+        p_vout = input_GetVout( p_input );
+        b_release_vout = p_vout != NULL;
+    }
+    vout_thread_t *p_notify_vout = b_notify ? p_vout : NULL;
+    register_osd_channels( p_as, p_notify_vout );
+
+    switch( i_action )
+    {
         case ACTIONID_POSITION:
+        {
             if( p_vout && vout_OSDEpg( p_vout, input_GetItem( p_input ) ) )
                 display_position( p_as, p_notify_vout, p_input );
             break;
+        }
         case ACTIONID_COMBO_VOL_FOV_UP:
         {
             bool b_vrnav = p_vout && var_GetBool( p_vout,
                                                   "viewpoint-changeable" );
             if( b_vrnav )
-                vlc_actions_do( p_obj, ACTIONID_VIEWPOINT_FOV_IN, b_notify );
+                vlc_actions_do( p_playlist, ACTIONID_VIEWPOINT_FOV_IN, b_notify,
+                                i_args, p_input, p_vout );
             else
-                vlc_actions_do( p_obj, ACTIONID_VOL_UP, b_notify );
+                vlc_actions_do( p_playlist, ACTIONID_VOL_UP, b_notify, 0 );
             break;
         }
         case ACTIONID_COMBO_VOL_FOV_DOWN:
@@ -1888,32 +1812,424 @@ vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
             bool b_vrnav = p_vout && var_GetBool( p_vout,
                                               "viewpoint-changeable" );
             if( b_vrnav )
-                vlc_actions_do( p_obj, ACTIONID_VIEWPOINT_FOV_OUT, b_notify );
+                vlc_actions_do( p_playlist, ACTIONID_VIEWPOINT_FOV_OUT, b_notify,
+                                i_args, p_input, p_vout );
             else
-                vlc_actions_do( p_obj, ACTIONID_VOL_DOWN, b_notify );
+                vlc_actions_do( p_playlist, ACTIONID_VOL_DOWN, b_notify, 0 );
             break;
         }
-        case ACTIONID_NONE:
-            i_ret = VLC_EGENERIC;
+        case ACTIONID_NAV_UP:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .pitch = -1.f },
+                                       false );
+            if( p_input )
+                input_Control( p_input, INPUT_NAV_UP, NULL );
             break;
-    }
+        }
+        case ACTIONID_NAV_DOWN:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .pitch = 1.f },
+                                       false );
+            if( p_input )
+                input_Control( p_input, INPUT_NAV_DOWN, NULL );
+            break;
+        }
+        case ACTIONID_NAV_LEFT:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .yaw = -1.f },
+                                       false );
+            if( p_input )
+                input_Control( p_input, INPUT_NAV_LEFT, NULL );
+            break;
+        }
+        case ACTIONID_NAV_RIGHT:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .yaw = 1.f },
+                                       false );
+            if( p_input )
+                input_Control( p_input, INPUT_NAV_RIGHT, NULL );
+            break;
+        }
+        case ACTIONID_VIEWPOINT_FOV_IN:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .fov = -1.f },
+                                       false );
+            break;
+        }
+        case ACTIONID_VIEWPOINT_FOV_OUT:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .fov = 1.f },
+                                       false );
+            break;
+        }
 
-    if( p_vout )
+        case ACTIONID_VIEWPOINT_ROLL_CLOCK:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .roll = -1.f },
+                                       false );
+            break;
+        }
+        case ACTIONID_VIEWPOINT_ROLL_ANTICLOCK:
+        {
+            if( p_vout )
+                input_UpdateViewpoint( p_input,
+                                       &(vlc_viewpoint_t) { .roll = 1.f },
+                                       false );
+            break;
+        }
+        case ACTIONID_VIEWPOINT_UPDATE:
+        {
+            if ( p_vout )
+            {
+                assert( i_args == 3 );
+                vlc_viewpoint_t* viewpoint = va_arg( args, vlc_viewpoint_t* );
+                input_UpdateViewpoint( p_input, viewpoint, false );
+            }
+            break;
+        }
+        case ACTIONID_SUBPOS_DOWN:
+        case ACTIONID_SUBPOS_UP:
+        {
+            if( p_input && p_vout )
+            {
+                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 )
+                {
+                    display_message( p_notify_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" );
+
+                clear_channels( p_as, p_notify_vout );
+                display_message( p_notify_vout, _( "Subtitle position %d px" ), i_pos );
+                var_FreeList( &list, &list2 );
+            }
+            break;
+        }
+        default:
+            vlc_assert_unreachable();
+    }
+    if( b_release_vout == true )
         vlc_object_release( p_vout );
-    if( p_input )
+    if( b_release_input == true )
         vlc_object_release( p_input );
-    return i_ret;
+}
+
+static void
+handle_aout_actions( playlist_t *p_playlist, vlc_action_id_t i_action,
+                     bool b_notify, vlc_actions_t* p_as,
+                     unsigned int i_args, va_list args )
+{
+    audio_output_t *p_aout = NULL;
+    bool b_release_aout = false;
+    assert( i_args <= 1 );
+    if( i_args > 0 )
+        p_aout = va_arg( args, audio_output_t* );
+    if( p_aout == NULL )
+    {
+        p_aout = playlist_GetAout( p_playlist );
+        b_release_aout = true;
+    }
+    vout_thread_t *p_notify_vout = NULL;
+    if( b_notify == true )
+    {
+        input_thread_t *p_input = playlist_CurrentInput( p_playlist );
+        if( p_input != NULL )
+        {
+            p_notify_vout = input_GetVout( p_input );
+            vlc_object_release( p_input );
+        }
+    }
+    register_osd_channels( p_as, p_notify_vout );
+
+    switch( i_action )
+    {
+        case ACTIONID_AUDIODEVICE_CYCLE:
+        {
+            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] ) )
+                display_message( p_notify_vout, _("Audio Device: %s"), names[idx] );
+
+            for( int i = 0; i < n; i++ )
+            {
+                free( ids[i] );
+                free( names[i] );
+            }
+            free( ids );
+            free( names );
+            break;
+        }
+        default:
+            vlc_assert_unreachable();
+    }
+    if( p_notify_vout != NULL )
+        vlc_object_release( p_notify_vout );
+    if( b_release_aout == true )
+        vlc_object_release( p_aout );
+}
+
+static void
+handle_misc_actions( playlist_t *p_playlist, vlc_action_id_t i_action,
+                     bool b_notify, vlc_actions_t* p_as )
+{
+    libvlc_int_t *p_libvlc = p_playlist->obj.libvlc;
+    switch( i_action )
+    {
+        /* Libvlc / interface actions */
+        case ACTIONID_QUIT:
+        {
+            vout_thread_t *p_notify_vout = NULL;
+            if( b_notify )
+            {
+                input_thread_t *p_input = playlist_CurrentInput( p_playlist );
+                if( p_input )
+                {
+                    p_notify_vout = input_GetVout( p_input );
+                    vlc_object_release( p_input );
+                }
+            }
+
+            libvlc_Quit( p_libvlc );
+
+            clear_channels( p_as, p_notify_vout );
+            display_message( p_notify_vout, _( "Quit" ) );
+            if( p_notify_vout )
+                vlc_object_release( p_notify_vout );
+            break;
+        }
+        case ACTIONID_INTF_TOGGLE_FSC:
+        case ACTIONID_INTF_HIDE:
+            var_TriggerCallback( p_libvlc, "intf-toggle-fscontrol" );
+            break;
+        case ACTIONID_INTF_BOSS:
+            var_TriggerCallback( p_libvlc, "intf-boss" );
+            break;
+        case ACTIONID_INTF_POPUP_MENU:
+            var_TriggerCallback( p_libvlc, "intf-popupmenu" );
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+}
+
+static int
+vlc_actions_do_va( vlc_object_t *p_obj, vlc_action_id_t i_action, bool b_notify,
+                   unsigned int i_args, va_list args )
+{
+    libvlc_int_t *p_libvlc = p_obj->obj.libvlc;
+    vlc_actions_t *p_as = libvlc_priv(p_libvlc)->actions;
+    playlist_t *p_playlist = libvlc_priv(p_obj->obj.libvlc)->playlist;
+
+    assert(p_as != NULL);
+
+    if( !p_playlist )
+        return VLC_EGENERIC;
+
+    /* Quit */
+    switch( i_action )
+    {
+        /* Libvlc / interface actions */
+        case ACTIONID_QUIT:
+        case ACTIONID_INTF_TOGGLE_FSC:
+        case ACTIONID_INTF_HIDE:
+        case ACTIONID_INTF_BOSS:
+        case ACTIONID_INTF_POPUP_MENU:
+            handle_misc_actions( p_playlist, i_action, b_notify, p_as );
+            break;
+
+        /* Playlist actions (including audio) */
+        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:
+        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:
+        case ACTIONID_LOOP:
+        case ACTIONID_RANDOM:
+        case ACTIONID_NEXT:
+        case ACTIONID_PREV:
+        case ACTIONID_STOP:
+        case ACTIONID_RATE_NORMAL:
+        case ACTIONID_FASTER:
+        case ACTIONID_SLOWER:
+        case ACTIONID_RATE_FASTER_FINE:
+        case ACTIONID_RATE_SLOWER_FINE:
+        case ACTIONID_PLAY_CLEAR:
+        case ACTIONID_VOL_UP:
+        case ACTIONID_VOL_DOWN:
+        case ACTIONID_VOL_MUTE:
+            handle_playlist_actions( p_playlist, i_action, b_notify, p_as );
+            break;
+
+        case ACTIONID_AUDIODEVICE_CYCLE:
+            handle_aout_actions( p_playlist, i_action, b_notify, p_as,
+                                 i_args, args );
+            break;
+
+        /* Input actions */
+        case ACTIONID_PLAY_PAUSE:
+        case ACTIONID_PLAY:
+        case ACTIONID_PAUSE:
+        case ACTIONID_RECORD:
+        case ACTIONID_FRAME_NEXT:
+        case ACTIONID_SUBSYNC_MARKAUDIO:
+        case ACTIONID_SUBSYNC_MARKSUB:
+        case ACTIONID_SUBSYNC_APPLY:
+        case ACTIONID_SUBSYNC_RESET:
+        case ACTIONID_SUBDELAY_DOWN:
+        case ACTIONID_SUBDELAY_UP:
+        case ACTIONID_AUDIODELAY_DOWN:
+        case ACTIONID_AUDIODELAY_UP:
+        case ACTIONID_AUDIO_TRACK:
+        case ACTIONID_SUBTITLE_TRACK:
+        case ACTIONID_SUBTITLE_REVERSE_TRACK:
+        case ACTIONID_SUBTITLE_TOGGLE:
+        case ACTIONID_PROGRAM_SID_NEXT:
+        case ACTIONID_PROGRAM_SID_PREV:
+        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:
+        case ACTIONID_TITLE_PREV:
+        case ACTIONID_TITLE_NEXT:
+        case ACTIONID_CHAPTER_PREV:
+        case ACTIONID_CHAPTER_NEXT:
+        case ACTIONID_DISC_MENU:
+        case ACTIONID_NAV_ACTIVATE:
+            handle_input_actions( p_playlist, i_action, b_notify,
+                                  p_as, i_args, args );
+            break;
+
+        /* Video Output actions */
+        case ACTIONID_WALLPAPER:
+        case ACTIONID_SNAPSHOT:
+        case ACTIONID_TOGGLE_FULLSCREEN:
+        case ACTIONID_LEAVE_FULLSCREEN:
+        case ACTIONID_ASPECT_RATIO:
+        case ACTIONID_CROP:
+        case ACTIONID_CROP_TOP:
+        case ACTIONID_UNCROP_TOP:
+        case ACTIONID_CROP_BOTTOM:
+        case ACTIONID_UNCROP_BOTTOM:
+        case ACTIONID_CROP_LEFT:
+        case ACTIONID_UNCROP_LEFT:
+        case ACTIONID_CROP_RIGHT:
+        case ACTIONID_UNCROP_RIGHT:
+        case ACTIONID_TOGGLE_AUTOSCALE:
+        case ACTIONID_SCALE_UP:
+        case ACTIONID_SCALE_DOWN:
+        case ACTIONID_ZOOM_QUARTER:
+        case ACTIONID_ZOOM_HALF:
+        case ACTIONID_ZOOM_ORIGINAL:
+        case ACTIONID_ZOOM_DOUBLE:
+        case ACTIONID_ZOOM:
+        case ACTIONID_UNZOOM:
+        case ACTIONID_DEINTERLACE:
+        case ACTIONID_DEINTERLACE_MODE:
+        case ACTIONID_SUBTITLE_TEXT_SCALE_DOWN:
+        case ACTIONID_SUBTITLE_TEXT_SCALE_UP:
+        case ACTIONID_SUBTITLE_TEXT_SCALE_NORMAL:
+            handle_vout_actions( p_playlist, i_action, b_notify,
+                                 p_as, i_args, args );
+            break;
+
+        /* Input + video output */
+        case ACTIONID_POSITION:
+        case ACTIONID_COMBO_VOL_FOV_UP:
+        case ACTIONID_COMBO_VOL_FOV_DOWN:
+        case ACTIONID_NAV_UP:
+        case ACTIONID_NAV_DOWN:
+        case ACTIONID_NAV_LEFT:
+        case ACTIONID_NAV_RIGHT:
+        case ACTIONID_VIEWPOINT_FOV_IN:
+        case ACTIONID_VIEWPOINT_FOV_OUT:
+        case ACTIONID_VIEWPOINT_ROLL_CLOCK:
+        case ACTIONID_VIEWPOINT_ROLL_ANTICLOCK:
+        case ACTIONID_VIEWPOINT_UPDATE:
+        case ACTIONID_SUBPOS_DOWN:
+        case ACTIONID_SUBPOS_UP:
+            handle_input_vout_actions( p_playlist, i_action, b_notify,
+                                       p_as, i_args, args );
+            break;
+
+        case ACTIONID_NONE:
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
 }
 
 #undef vlc_actions_do
 int vlc_actions_do(vlc_object_t *p_obj, vlc_action_id_t i_action,
-                   bool b_notify, ...)
+                   bool b_notify, unsigned int i_nb_args, ...)
 {
     va_list args;
     int     i_result;
 
-    va_start( args, b_notify );
-    i_result = vlc_actions_do_va( p_obj, i_action, b_notify, args );
+    va_start( args, i_nb_args );
+    i_result = vlc_actions_do_va( p_obj, i_action, b_notify, i_nb_args, args );
     va_end( args );
     return i_result;
 }
-- 
2.11.0




More information about the vlc-devel mailing list