]> git.sesse.net Git - vlc/blobdiff - modules/gui/wxwidgets/menus.cpp
Use pl_Release with the right argument.
[vlc] / modules / gui / wxwidgets / menus.cpp
index 0e6ebbe8e985278d3a5e6c3e220463ce1aebb5ff..ff0a99c1804131a7c0337f281c2bb3a2c3577aae 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <errno.h>                                                 /* ENOMEM */
-#include <string.h>                                            /* strerror() */
-#include <stdio.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
-#include <vlc/vlc.h>
-#include <vlc/intf.h>
+#include <vlc_common.h>
+#include <vlc_interface.h>
 
 #include "wxwidgets.hpp"
 #include "interface.hpp"
 
+#include <wx/dynarray.h>
+WX_DEFINE_ARRAY(int, ArrayOfInts);
+WX_DEFINE_ARRAY_PTR(const char *, ArrayOfStrings);
+
+
 class wxMenuItemExt: public wxMenuItem
 {
 public:
@@ -43,16 +44,12 @@ public:
                    const wxString& helpString, wxItemKind kind,
                    char *_psz_var, int _i_object_id, vlc_value_t _val,
                    int _i_val_type );
-
     virtual ~wxMenuItemExt();
 
     char *psz_var;
     int  i_val_type;
     int  i_object_id;
     vlc_value_t val;
-
-private:
-
 };
 
 class Menu: public wxMenu
@@ -62,13 +59,13 @@ public:
     Menu( intf_thread_t *p_intf, int i_start_id );
     virtual ~Menu();
 
-    void Populate( int i_count, char **ppsz_names, int *pi_objects );
+    void Populate( ArrayOfStrings &, ArrayOfInts &);
     void Clear();
 
 private:
     wxMenu *CreateDummyMenu();
-    void   CreateMenuItem( wxMenu *, char *, vlc_object_t * );
-    wxMenu *CreateChoicesMenu( char *, vlc_object_t *, bool );
+    void   CreateMenuItem( wxMenu *, const char *, vlc_object_t * );
+    wxMenu *CreateChoicesMenu( const char *, vlc_object_t *, bool );
 
     DECLARE_EVENT_TABLE();
 
@@ -81,8 +78,6 @@ private:
 /*****************************************************************************
  * Event Table.
  *****************************************************************************/
-
-/* IDs for the controls and the menu commands */
 enum
 {
     /* menu items */
@@ -126,6 +121,9 @@ BEGIN_EVENT_TABLE(MenuEvtHandler, wxEvtHandler)
     EVT_MENU(-1, MenuEvtHandler::OnMenuEvent)
 END_EVENT_TABLE()
 
+/*****************************************************************************
+ * Static menu helpers
+ *****************************************************************************/
 wxMenu *OpenStreamMenu( intf_thread_t *p_intf )
 {
     wxMenu *menu = new wxMenu;
@@ -147,215 +145,289 @@ wxMenu *MiscMenu( intf_thread_t *p_intf )
     return menu;
 }
 
-void PopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
-                const wxPoint& pos )
-{
-#define MAX_POPUP_ITEMS 45
+/*****************************************************************************
+ * Builders for the dynamic menus
+ *****************************************************************************/
+#define PUSH_VAR( var ) rs_varnames.Add( var ); \
+                        ri_objects.Add( p_object->i_object_id )
 
-    int minimal = config_GetInt( p_intf, "wx-minimal" );
+int InputAutoMenuBuilder( vlc_object_t *p_object, ArrayOfInts &ri_objects,
+                          ArrayOfStrings &rs_varnames )
+{
+    PUSH_VAR( "bookmark");
+    PUSH_VAR( "title" );
+    PUSH_VAR ("chapter" );
+    PUSH_VAR( "program" );
+    PUSH_VAR( "navigation" );
+    PUSH_VAR( "dvd_menus" );
+    return VLC_SUCCESS;
+}
 
-    vlc_object_t *p_object, *p_input;
-    char *ppsz_varnames[MAX_POPUP_ITEMS];
-    int pi_objects[MAX_POPUP_ITEMS];
-    int i = 0, i_last_separator = 0;
+int VideoAutoMenuBuilder( vlc_object_t *p_object, ArrayOfInts &ri_objects,
+                          ArrayOfStrings &rs_varnames )
+{
+    PUSH_VAR( "fullscreen" );
+    PUSH_VAR( "zoom" );
+    PUSH_VAR( "deinterlace" );
+    PUSH_VAR( "aspect-ratio" );
+    PUSH_VAR( "crop" );
+    PUSH_VAR( "video-on-top" );
+    PUSH_VAR( "directx-wallpaper" );
+    PUSH_VAR( "video-snapshot" );
+
+    vlc_object_t *p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
+                                                 VLC_OBJECT_DECODER,
+                                                 FIND_PARENT );
+    if( p_dec_obj != NULL )
+    {
+        vlc_object_t *p_object = p_dec_obj;
+        PUSH_VAR( "ffmpeg-pp-q" );
+        vlc_object_release( p_dec_obj );
+    }
+    return VLC_SUCCESS;
+}
 
-    /* Initializations */
-    memset( pi_objects, 0, MAX_POPUP_ITEMS * sizeof(int) );
+int AudioAutoMenuBuilder( vlc_object_t *p_object, ArrayOfInts &ri_objects,
+                          ArrayOfStrings &rs_varnames )
+{
+    PUSH_VAR( "audio-device" );
+    PUSH_VAR( "audio-channels" );
+    PUSH_VAR( "visual" );
+    PUSH_VAR( "equalizer" );
+    return VLC_SUCCESS;
+}
 
-    /* Input menu */
-    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
-                                                FIND_ANYWHERE );
+int IntfAutoMenuBuilder( intf_thread_t *p_intf, ArrayOfInts &ri_objects,
+                         ArrayOfStrings &rs_varnames, bool is_popup)
+{
+    /* vlc_object_find is needed because of the dialogs provider case */
+    vlc_object_t *p_object;
+    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INTF,
+                                                FIND_PARENT );
     if( p_object != NULL )
     {
-        ppsz_varnames[i] = "bookmark";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "title";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "chapter";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "program";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "navigation";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "dvd_menus";
-        pi_objects[i++] = p_object->i_object_id;
-
-        ppsz_varnames[i] = "video-es";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "audio-es";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "spu-es";
-        pi_objects[i++] = p_object->i_object_id;
+        PUSH_VAR( "intf-add" );
+        PUSH_VAR( "intf-skins" );
+        vlc_object_release( p_object );
     }
-    p_input = p_object;
-    if( !p_input ) goto interfacemenu;
-
-    /* Video menu */
-    if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
-    i_last_separator = i;
+    return VLC_SUCCESS;
+}
 
-    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
-                                                FIND_ANYWHERE );
-    if( p_object != NULL )
+#undef PUSH_VAR
+/*****************************************************************************
+ * Popup menus
+ *****************************************************************************/
+#define PUSH_VAR( var ) as_varnames.Add( var ); \
+                        ai_objects.Add( p_object->i_object_id )
+
+#define PUSH_SEPARATOR if( ai_objects.GetCount() != i_last_separator ) { \
+                            ai_objects.Add( 0 ); \
+                            as_varnames.Add( "" ); \
+                            i_last_separator = ai_objects.GetCount(); }
+
+#define POPUP_BOILERPLATE \
+    unsigned int i_last_separator = 0; \
+    ArrayOfInts ai_objects; \
+    ArrayOfStrings as_varnames; \
+    playlist_t *p_playlist = pl_Yield( p_intf ); \
+    if( !p_playlist ) \
+        return; \
+    input_thread_t *p_input = p_playlist->p_input
+
+#define CREATE_POPUP    \
+    Menu popupmenu( p_intf, PopupMenu_Events ); \
+    popupmenu.Populate( as_varnames, ai_objects ); \
+    p_intf->p_sys->p_popup_menu = &popupmenu; \
+    p_parent->PopupMenu( &popupmenu, pos.x, pos.y ); \
+    p_intf->p_sys->p_popup_menu = NULL; \
+    i_last_separator = 0 /* stop compiler warning */
+
+#define POPUP_STATIC_ENTRIES \
+    if( p_input != NULL ) \
+    { \
+        vlc_value_t val; \
+        popupmenu.InsertSeparator( 0 ); \
+        if (!minimal) \
+        { \
+        popupmenu.Insert( 0, Stop_Event, wxU(_("Stop")) ); \
+        popupmenu.Insert( 0, Previous_Event, wxU(_("Previous")) ); \
+        popupmenu.Insert( 0, Next_Event, wxU(_("Next")) ); \
+        } \
+         \
+        var_Get( p_input, "state", &val ); \
+        if( val.i_int == PAUSE_S ) \
+            popupmenu.Insert( 0, Play_Event, wxU(_("Play")) ); \
+        else \
+            popupmenu.Insert( 0, Pause_Event, wxU(_("Pause")) ); \
+         \
+        vlc_object_release( p_input ); \
+    } \
+    else \
+    { \
+        if( p_playlist && !playlist_IsEmpty( p_playlist ) ) \
+        { \
+            popupmenu.InsertSeparator( 0 ); \
+            popupmenu.Insert( 0, Play_Event, wxU(_("Play")) ); \
+        } \
+        if( p_playlist ) pl_Release( p_intf ); \
+    } \
+    \
+    popupmenu.Append( MenuDummy_Event, wxU(_("Miscellaneous")), \
+                      MiscMenu( p_intf ), wxT("") )
+
+
+void VideoPopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
+                     const wxPoint& pos )
+{
+    POPUP_BOILERPLATE;
+    if( p_input )
     {
-        vlc_object_t *p_dec_obj;
-
-        ppsz_varnames[i] = "fullscreen";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "zoom";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "deinterlace";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "aspect-ratio";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "crop";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "video-on-top";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "directx-wallpaper";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "video-snapshot";
-        pi_objects[i++] = p_object->i_object_id;
-
-        p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
-                                                     VLC_OBJECT_DECODER,
-                                                     FIND_PARENT );
-        if( p_dec_obj != NULL )
+        vlc_object_yield( p_input );
+        as_varnames.Add( "video-es" );
+        ai_objects.Add( p_input->i_object_id );
+        as_varnames.Add( "spu-es" );
+        ai_objects.Add( p_input->i_object_id );
+        vlc_object_t *p_vout = (vlc_object_t *)vlc_object_find( p_input,
+                                                VLC_OBJECT_VOUT, FIND_CHILD );
+        if( p_vout )
         {
-            ppsz_varnames[i] = "ffmpeg-pp-q";
-            pi_objects[i++] = p_dec_obj->i_object_id;
-            vlc_object_release( p_dec_obj );
+            VideoAutoMenuBuilder( p_vout, ai_objects, as_varnames );
+            vlc_object_release( p_vout );
         }
-
-        vlc_object_release( p_object );
+        vlc_object_release( p_input );
     }
+    pl_Release( p_intf );
+    CREATE_POPUP;
+}
 
-    /* Audio menu */
-    if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
-    i_last_separator  = i;
-
-    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
-                                                FIND_ANYWHERE );
-    if( p_object != NULL )
+void AudioPopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
+                     const wxPoint& pos )
+{
+    POPUP_BOILERPLATE;
+    if( p_input )
     {
-        ppsz_varnames[i] = "audio-device";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "audio-channels";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "visual";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "equalizer";
-        pi_objects[i++] = p_object->i_object_id;
-        vlc_object_release( p_object );
+        vlc_object_yield( p_input );
+        as_varnames.Add( "audio-es" );
+        ai_objects.Add( p_input->i_object_id );
+        vlc_object_t *p_aout = (vlc_object_t *)vlc_object_find( p_input,
+                                             VLC_OBJECT_AOUT, FIND_ANYWHERE );
+        if( p_aout )
+        {
+            AudioAutoMenuBuilder( p_aout, ai_objects, as_varnames );
+            vlc_object_release( p_aout );
+        }
+        vlc_object_release( p_input );
     }
+    pl_Release( p_intf );
+    CREATE_POPUP;
+}
 
- interfacemenu:
-    /* Interface menu */
-    if( i != i_last_separator ) ppsz_varnames[i++] = NULL; /* Separator */
-    i_last_separator = i;
-
-    /* vlc_object_find is needed because of the dialogs provider case */
-    p_object = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_INTF,
-                                                FIND_PARENT );
-    if( p_object != NULL )
+/* Navigation stuff, and general */
+void MiscPopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
+                    const wxPoint& pos )
+{
+    int minimal = 0;
+    POPUP_BOILERPLATE;
+    if( p_input )
     {
-#if 0
-#if (wxCHECK_VERSION(2,5,0))
-        ppsz_varnames[i] = "intf-switch";
-        pi_objects[i++] = p_object->i_object_id;
-#endif
-#endif
-        ppsz_varnames[i] = "intf-add";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "intf-skins";
-        pi_objects[i++] = p_object->i_object_id;
-
-        vlc_object_release( p_object );
+        vlc_object_yield( p_input );
+        as_varnames.Add( "audio-es" );
+        InputAutoMenuBuilder( VLC_OBJECT(p_input), ai_objects, as_varnames );
+        PUSH_SEPARATOR;
     }
+    IntfAutoMenuBuilder( p_intf, ai_objects, as_varnames, true );
 
-    /* Build menu */
     Menu popupmenu( p_intf, PopupMenu_Events );
-    popupmenu.Populate( i, ppsz_varnames, pi_objects );
+    popupmenu.Populate( as_varnames, ai_objects );
 
-    /* Add static entries */
-    if( p_input != NULL )
-    {
-        vlc_value_t val;
-        popupmenu.InsertSeparator( 0 );
-        if (!minimal)
-        {
-        popupmenu.Insert( 0, Stop_Event, wxU(_("Stop")) );
-        popupmenu.Insert( 0, Previous_Event, wxU(_("Previous")) );
-        popupmenu.Insert( 0, Next_Event, wxU(_("Next")) );
-        }
+    POPUP_STATIC_ENTRIES;
+    popupmenu.Append( MenuDummy_Event, wxU(_("Open")),
+                      OpenStreamMenu( p_intf ), wxT("") );
 
-        var_Get( p_input, "state", &val );
-        if( val.i_int == PAUSE_S )
-            popupmenu.Insert( 0, Play_Event, wxU(_("Play")) );
-        else
-            popupmenu.Insert( 0, Pause_Event, wxU(_("Pause")) );
+    p_intf->p_sys->p_popup_menu = &popupmenu;
+    p_parent->PopupMenu( &popupmenu, pos.x, pos.y );
+    p_intf->p_sys->p_popup_menu = NULL;
+    pl_Release( p_intf );
+}
 
-        vlc_object_release( p_input );
-    }
-    else
+void PopupMenu( intf_thread_t *p_intf, wxWindow *p_parent,
+                const wxPoint& pos )
+{
+    int minimal = config_GetInt( p_intf, "wx-minimal" );
+    POPUP_BOILERPLATE;
+    if( p_input )
     {
-        playlist_t * p_playlist =
-            (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                           FIND_ANYWHERE );
-        if( p_playlist && p_playlist->i_size )
+        vlc_object_yield( p_input );
+        InputAutoMenuBuilder( VLC_OBJECT(p_input), ai_objects, as_varnames );
+
+        /* Video menu */
+        PUSH_SEPARATOR;
+        as_varnames.Add( "video-es" );
+        ai_objects.Add( p_input->i_object_id );
+        as_varnames.Add( "spu-es" );
+        ai_objects.Add( p_input->i_object_id );
+        vlc_object_t *p_vout = (vlc_object_t *)vlc_object_find( p_input,
+                                                VLC_OBJECT_VOUT, FIND_CHILD );
+        if( p_vout )
+        {
+            VideoAutoMenuBuilder( p_vout, ai_objects, as_varnames );
+            vlc_object_release( p_vout );
+        }
+        /* Audio menu */
+        PUSH_SEPARATOR
+        as_varnames.Add( "audio-es" );
+        ai_objects.Add( p_input->i_object_id );
+        vlc_object_t *p_aout = (vlc_object_t *)vlc_object_find( p_input,
+                                             VLC_OBJECT_AOUT, FIND_ANYWHERE );
+        if( p_aout )
         {
-            popupmenu.InsertSeparator( 0 );
-            popupmenu.Insert( 0, Play_Event, wxU(_("Play")) );
+            AudioAutoMenuBuilder( p_aout, ai_objects, as_varnames );
+            vlc_object_release( p_aout );
         }
-        if( p_playlist ) vlc_object_release( p_playlist );
     }
 
-    popupmenu.Append( MenuDummy_Event, wxU(_("Miscellaneous")),
-                      MiscMenu( p_intf ), wxT("") );
+    /* Interface menu */
+    PUSH_SEPARATOR
+    IntfAutoMenuBuilder( p_intf, ai_objects, as_varnames, true );
+
+    /* Build menu */
+    Menu popupmenu( p_intf, PopupMenu_Events );
+    popupmenu.Populate( as_varnames, ai_objects );
+    POPUP_STATIC_ENTRIES;
+
     if (!minimal)
     {
-    popupmenu.Append( MenuDummy_Event, wxU(_("Open")),
-                      OpenStreamMenu( p_intf ), wxT("") );
+        popupmenu.Append( MenuDummy_Event, wxU(_("Open")),
+                          OpenStreamMenu( p_intf ), wxT("") );
     }
-
     p_intf->p_sys->p_popup_menu = &popupmenu;
     p_parent->PopupMenu( &popupmenu, pos.x, pos.y );
     p_intf->p_sys->p_popup_menu = NULL;
+    pl_Release( p_intf );
 }
 
+/*****************************************************************************
+ * Auto menus
+ *****************************************************************************/
 wxMenu *AudioMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
 {
-#define MAX_AUDIO_ITEMS 10
-
     vlc_object_t *p_object;
-    char *ppsz_varnames[MAX_AUDIO_ITEMS];
-    int pi_objects[MAX_AUDIO_ITEMS];
-    int i = 0;
-
-    /* Initializations */
-    memset( pi_objects, 0, MAX_AUDIO_ITEMS * sizeof(int) );
+    ArrayOfInts ai_objects;
+    ArrayOfStrings as_varnames;
 
     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                 FIND_ANYWHERE );
     if( p_object != NULL )
     {
-        ppsz_varnames[i] = "audio-es";
-        pi_objects[i++] = p_object->i_object_id;
+        PUSH_VAR( "audio-es" );
         vlc_object_release( p_object );
     }
 
     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_AOUT,
                                                 FIND_ANYWHERE );
-    if( p_object != NULL )
+    if( p_object )
     {
-        ppsz_varnames[i] = "audio-device";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "audio-channels";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "visual";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "equalizer";
-        pi_objects[i++] = p_object->i_object_id;
+        AudioAutoMenuBuilder( p_object, ai_objects, as_varnames );
         vlc_object_release( p_object );
     }
 
@@ -366,31 +438,23 @@ wxMenu *AudioMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
     else
         p_vlc_menu->Clear();
 
-    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
+    p_vlc_menu->Populate(  as_varnames, ai_objects );
 
     return p_vlc_menu;
 }
 
 wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
 {
-#define MAX_VIDEO_ITEMS 15
-
     vlc_object_t *p_object;
-    char *ppsz_varnames[MAX_VIDEO_ITEMS];
-    int pi_objects[MAX_VIDEO_ITEMS];
-    int i = 0;
-
-    /* Initializations */
-    memset( pi_objects, 0, MAX_VIDEO_ITEMS * sizeof(int) );
+    ArrayOfInts ai_objects;
+    ArrayOfStrings as_varnames;
 
     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                 FIND_ANYWHERE );
     if( p_object != NULL )
     {
-        ppsz_varnames[i] = "video-es";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "spu-es";
-        pi_objects[i++] = p_object->i_object_id;
+        PUSH_VAR( "video-es" );
+        PUSH_VAR( "spu-es" );
         vlc_object_release( p_object );
     }
 
@@ -398,35 +462,7 @@ wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
                                                 FIND_ANYWHERE );
     if( p_object != NULL )
     {
-        vlc_object_t *p_dec_obj;
-
-        ppsz_varnames[i] = "fullscreen";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "zoom";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "deinterlace";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "aspect-ratio";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "crop";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "video-on-top";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "directx-wallpaper";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "video-snapshot";
-        pi_objects[i++] = p_object->i_object_id;
-
-        p_dec_obj = (vlc_object_t *)vlc_object_find( p_object,
-                                                     VLC_OBJECT_DECODER,
-                                                     FIND_PARENT );
-        if( p_dec_obj != NULL )
-        {
-            ppsz_varnames[i] = "ffmpeg-pp-q";
-            pi_objects[i++] = p_dec_obj->i_object_id;
-            vlc_object_release( p_dec_obj );
-        }
-
+        VideoAutoMenuBuilder( p_object, ai_objects, as_varnames );
         vlc_object_release( p_object );
     }
 
@@ -437,49 +473,23 @@ wxMenu *VideoMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
     else
         p_vlc_menu->Clear();
 
-    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
-
+    p_vlc_menu->Populate(  as_varnames, ai_objects );
     return p_vlc_menu;
 }
 
 wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
 {
-#define MAX_NAVIG_ITEMS 15
-
     vlc_object_t *p_object;
-    char *ppsz_varnames[MAX_NAVIG_ITEMS];
-    int pi_objects[MAX_NAVIG_ITEMS];
-    int i = 0;
-
-    /* Initializations */
-    memset( pi_objects, 0, MAX_NAVIG_ITEMS * sizeof(int) );
+    ArrayOfInts ai_objects;
+    ArrayOfStrings as_varnames;
 
     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INPUT,
                                                 FIND_ANYWHERE );
     if( p_object != NULL )
     {
-        ppsz_varnames[i] = "bookmark";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "title";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "chapter";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "program";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "navigation";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "dvd_menus";
-        pi_objects[i++] = p_object->i_object_id;
-
-        ppsz_varnames[i] = "prev-title";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "next-title";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "prev-chapter";
-        pi_objects[i++] = p_object->i_object_id;
-        ppsz_varnames[i] = "next-chapter";
-        pi_objects[i++] = p_object->i_object_id;
-
+        InputAutoMenuBuilder( p_object, ai_objects, as_varnames );
+        PUSH_VAR( "prev-title"); PUSH_VAR ( "next-title" );
+        PUSH_VAR( "prev-chapter"); PUSH_VAR( "next-chapter" );
         vlc_object_release( p_object );
     }
 
@@ -490,7 +500,7 @@ wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
     else
         p_vlc_menu->Clear();
 
-    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
+    p_vlc_menu->Populate( as_varnames, ai_objects );
 
     return p_vlc_menu;
 }
@@ -498,28 +508,15 @@ wxMenu *NavigMenu( intf_thread_t *_p_intf, wxWindow *p_parent, wxMenu *p_menu )
 wxMenu *SettingsMenu( intf_thread_t *_p_intf, wxWindow *p_parent,
                       wxMenu *p_menu )
 {
-#define MAX_SETTINGS_ITEMS 10
-
     vlc_object_t *p_object;
-    char *ppsz_varnames[MAX_SETTINGS_ITEMS];
-    int pi_objects[MAX_SETTINGS_ITEMS];
-    int i = 0;
-
-    /* Initializations */
-    memset( pi_objects, 0, MAX_SETTINGS_ITEMS * sizeof(int) );
+    ArrayOfInts ai_objects;
+    ArrayOfStrings as_varnames;
 
     p_object = (vlc_object_t *)vlc_object_find( _p_intf, VLC_OBJECT_INTF,
                                                 FIND_PARENT );
     if( p_object != NULL )
     {
-#if 0
-#if (wxCHECK_VERSION(2,5,0))
-        ppsz_varnames[i] = "intf-switch";
-        pi_objects[i++] = p_object->i_object_id;
-#endif
-#endif
-        ppsz_varnames[i] = "intf-add";
-        pi_objects[i++] = p_object->i_object_id;
+        PUSH_VAR( "intf-add" );
         vlc_object_release( p_object );
     }
 
@@ -530,7 +527,7 @@ wxMenu *SettingsMenu( intf_thread_t *_p_intf, wxWindow *p_parent,
     else
         p_vlc_menu->Clear();
 
-    p_vlc_menu->Populate( i, ppsz_varnames, pi_objects );
+    p_vlc_menu->Populate( as_varnames, ai_objects );
 
     return p_vlc_menu;
 }
@@ -552,41 +549,41 @@ Menu::~Menu()
 /*****************************************************************************
  * Public methods.
  *****************************************************************************/
-void Menu::Populate( int i_count, char **ppsz_varnames, int *pi_objects )
+void Menu::Populate( ArrayOfStrings & ras_varnames,
+                     ArrayOfInts & rai_objects )
 {
     vlc_object_t *p_object;
-    vlc_bool_t b_section_empty = VLC_FALSE;
+    bool b_section_empty = false;
     int i;
 
     i_item_id = i_start_id;
 
-    for( i = 0; i < i_count; i++ )
+    for( i = 0; i < (int)rai_objects.GetCount() ; i++ )
     {
-        if( !ppsz_varnames[i] )
+        if( !ras_varnames[i] || !*ras_varnames[i] )
         {
             if( b_section_empty )
             {
                 Append( MenuDummy_Event + i, wxU(_("Empty")) );
                 Enable( MenuDummy_Event + i, FALSE );
             }
-
             AppendSeparator();
-            b_section_empty = VLC_TRUE;
+            b_section_empty = true;
             continue;
         }
 
-        if( !pi_objects[i] )
+        if( rai_objects[i] == 0  )
         {
-            Append( MenuDummy_Event, wxU(ppsz_varnames[i]) );
-            b_section_empty = VLC_FALSE;
+            Append( MenuDummy_Event, wxU(ras_varnames[i]) );
+            b_section_empty = false;
             continue;
         }
 
-        p_object = (vlc_object_t *)vlc_object_get( p_intf, pi_objects[i] );
+        p_object = (vlc_object_t *)vlc_object_get( rai_objects[i] );
         if( p_object == NULL ) continue;
 
-        b_section_empty = VLC_FALSE;
-        CreateMenuItem( this, ppsz_varnames[i], p_object );
+        b_section_empty = false;
+        CreateMenuItem( this, ras_varnames[i], p_object );
         vlc_object_release( p_object );
     }
 
@@ -625,7 +622,7 @@ void Menu::Clear( )
 /*****************************************************************************
  * Private methods.
  *****************************************************************************/
-static bool IsMenuEmpty( char *psz_var, vlc_object_t *p_object,
+static bool IsMenuEmpty( const char *psz_var, vlc_object_t *p_object,
                          bool b_root = TRUE )
 {
     vlc_value_t val, val_list;
@@ -668,7 +665,7 @@ static bool IsMenuEmpty( char *psz_var, vlc_object_t *p_object,
     return i_result;
 }
 
-void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
+void Menu::CreateMenuItem( wxMenu *menu, const char *psz_var,
                            vlc_object_t *p_object )
 {
     wxMenuItemExt *menuitem;
@@ -693,7 +690,7 @@ void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
     }
 
     /* Make sure we want to display the variable */
-    if( IsMenuEmpty( psz_var, p_object ) ) return;
+    if( IsMenuEmpty( psz_var, p_object ) )  return;
 
     /* Get the descriptive name of the variable */
     var_Change( p_object, psz_var, VLC_VAR_GETTEXT, &text, NULL );
@@ -705,7 +702,7 @@ void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
                       CreateChoicesMenu( psz_var, p_object, TRUE ),
                       wxT("")/* Nothing for now (maybe use a GETLONGTEXT) */ );
 
-        if( text.psz_string ) free( text.psz_string );
+        free( text.psz_string );
         return;
     }
 
@@ -735,10 +732,10 @@ void Menu::CreateMenuItem( wxMenu *menu, char *psz_var,
         break;
     }
 
-    if( text.psz_string ) free( text.psz_string );
+    free( text.psz_string );
 }
 
-wxMenu *Menu::CreateChoicesMenu( char *psz_var, vlc_object_t *p_object,
+wxMenu *Menu::CreateChoicesMenu( const char *psz_var, vlc_object_t *p_object,
                                  bool b_root )
 {
     vlc_value_t val, val_list, text_list;
@@ -810,7 +807,7 @@ wxMenu *Menu::CreateChoicesMenu( char *psz_var, vlc_object_t *p_object,
                        val_list.p_list->p_values[i].psz_string ) )
               menu->Check( i_item_id, TRUE );
 
-          if( val.psz_string ) free( val.psz_string );
+          free( val.psz_string );
           break;
 
         case VLC_VAR_INTEGER:
@@ -939,9 +936,7 @@ void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
     if( event.GetId() >= Play_Event && event.GetId() <= Stop_Event )
     {
         input_thread_t *p_input;
-        playlist_t * p_playlist =
-            (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                           FIND_ANYWHERE );
+        playlist_t * p_playlist = pl_Yield( p_intf );
         if( !p_playlist ) return;
 
         switch( event.GetId() )
@@ -972,8 +967,7 @@ void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
             playlist_Next( p_playlist );
             break;
         }
-
-        vlc_object_release( p_playlist );
+        pl_Release( p_intf );
         return;
     }
 
@@ -991,10 +985,10 @@ void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
         vlc_value_t val;
 
         val.i_int =
-            p_intf->p_vlc->p_hotkeys[event.GetId() - i_hotkey_event].i_key;
+            p_intf->p_libvlc->p_hotkeys[event.GetId() - i_hotkey_event].i_key;
 
         /* Get the key combination and send it to the hotkey handler */
-        var_Set( p_intf->p_vlc, "key-pressed", val );
+        var_Set( p_intf->p_libvlc, "key-pressed", val );
         return;
     }
 
@@ -1014,8 +1008,7 @@ void MenuEvtHandler::OnMenuEvent( wxCommandEvent& event )
         wxMenuItemExt *p_menuitemext = (wxMenuItemExt *)p_menuitem;
         vlc_object_t *p_object;
 
-        p_object = (vlc_object_t *)vlc_object_get( p_intf,
-                                       p_menuitemext->i_object_id );
+        p_object = (vlc_object_t *)vlc_object_get( p_menuitemext->i_object_id );
         if( p_object == NULL ) return;
 
         wxMutexGuiLeave(); // We don't want deadlocks
@@ -1046,7 +1039,7 @@ wxMenuItemExt::wxMenuItemExt( wxMenu* parentMenu, int id, const wxString& text,
 
 wxMenuItemExt::~wxMenuItemExt()
 {
-    if( psz_var ) free( psz_var );
-    if( ((i_val_type & VLC_VAR_TYPE) == VLC_VAR_STRING)
-        && val.psz_string ) free( val.psz_string );
+    free( psz_var );
+    if( ( i_val_type & VLC_VAR_TYPE ) == VLC_VAR_STRING )
+        free( val.psz_string );
 };