]> git.sesse.net Git - vlc/blobdiff - plugins/gtk/gtk_menu.c
* DirectX plugin by Gildas Bazin <gbazin@netcourrier.com>.
[vlc] / plugins / gtk / gtk_menu.c
index 1b57c85ccb677dadb3a64ed978fec4222aeb8c73..cefa5e44860d54e594cd1869e9263e5bf8150622 100644 (file)
@@ -2,7 +2,7 @@
  * gtk_menu.c : functions to handle menu items.
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: gtk_menu.c,v 1.1 2001/05/15 01:01:44 stef Exp $
+ * $Id: gtk_menu.c,v 1.9 2001/06/02 01:09:03 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -22,9 +22,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-#define MODULE_NAME gtk
-#include "modules_inner.h"
-
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
 
 #include "main.h"
 
+#include "modules_export.h"
+
+#ifdef WIN32
+#ifndef snprintf
+#define snprintf _snprintf
+#endif
+#endif
+
+/*
+ * Local Prototypes
+ */
+static gint GtkLanguageMenus( gpointer , GtkWidget *, es_descriptor_t *, gint,
+                        void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) );
+
+void GtkMenubarAudioToggle   ( GtkCheckMenuItem *, gpointer );
+void GtkPopupAudioToggle     ( GtkCheckMenuItem *, gpointer );
+void GtkMenubarSubtitleToggle( GtkCheckMenuItem *, gpointer );
+void GtkPopupSubtitleToggle  ( GtkCheckMenuItem *, gpointer );
+static gint GtkTitleMenu( gpointer, GtkWidget *, 
+                    void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) );
+static gint GtkRadioMenu( intf_thread_t *, GtkWidget *, GSList *,
+                          char *, int, int,
+                   void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) );
+void GtkMenubarAngleToggle( GtkCheckMenuItem *, gpointer );
+void GtkPopupAngleToggle( GtkCheckMenuItem *, gpointer );
+
+gint GtkSetupMenus( intf_thread_t * p_intf );
+
 /****************************************************************************
  * Gtk*Toggle: callbacks to toggle the value of a checkmenuitem
  ****************************************************************************
  * We need separate functions for menubar and popup here since we can't use
- * user_data to transmit intf_*
+ * user_data to transmit intf_* and we need to refresh the other menu.
  ****************************************************************************/
 
-#define GtkLangToggle( b_update )                                   \
-    es_descriptor_t *       p_es;                                   \
-                                                                    \
-    if( !b_update )                                                 \
-    {                                                               \
-        p_es = (es_descriptor_t*)user_data;                         \
-                                                                    \
-        input_ToggleES( p_intf->p_input, p_es, menuitem->active );  \
-                                                                    \
-        b_update = menuitem->active;                                \
-    }                                                               \
+#define GtkLangToggle( intf, window, menu, type, callback, b_update )   \
+    intf_thread_t *         p_intf;                                     \
+    GtkWidget *             p_menu;                                     \
+    es_descriptor_t *       p_es;                                       \
+                                                                        \
+    p_intf = GetIntf( GTK_WIDGET(menuitem), (intf) );                   \
+                                                                        \
+    if( !p_intf->p_sys->b_update )                                      \
+    {                                                                   \
+        p_menu = GTK_WIDGET( gtk_object_get_data(                       \
+                   GTK_OBJECT( p_intf->p_sys->window ), (menu) ) );     \
+        p_es = (es_descriptor_t*)user_data;                             \
+                                                                        \
+        input_ToggleES( p_intf->p_input, p_es, menuitem->active );      \
+                                                                        \
+        p_intf->p_sys->b_update = menuitem->active;                     \
+                                                                        \
+        if( p_intf->p_sys->b_update )                                   \
+        {                                                               \
+            GtkLanguageMenus( p_intf, p_menu, p_es, type, callback );   \
+        }                                                               \
+                                                                        \
+        p_intf->p_sys->b_update = 0;                                    \
+    }
 
 /*
  * Audio
 
 void GtkMenubarAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
-
-    GtkLangToggle( p_intf->p_sys->b_audio_update );
+    GtkLangToggle( "intf_window", p_popup, "popup_audio", AUDIO_ES,
+                   GtkPopupAudioToggle, b_audio_update );
 }
 
 void GtkPopupAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
-
-    GtkLangToggle( p_intf->p_sys->b_audio_update );
+    GtkLangToggle( "intf_popup", p_window, "menubar_audio", AUDIO_ES,
+                   GtkMenubarAudioToggle, b_audio_update );
 }
 
 /* 
  * Subtitles
  */ 
 
-
 void GtkMenubarSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
-
-    GtkLangToggle( p_intf->p_sys->b_spu_update );
+    GtkLangToggle( "intf_window", p_popup, "popup_subpictures", SPU_ES,
+                   GtkPopupSubtitleToggle, b_spu_update );
 }
+
 void GtkPopupSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
-
-    GtkLangToggle( p_intf->p_sys->b_spu_update );
+    GtkLangToggle( "intf_popup", p_window, "menubar_subpictures", SPU_ES,
+                   GtkMenubarSubtitleToggle, b_spu_update );
 }
 
+#undef GtkLangToggle
+
 /*
  * Navigation
  */
+
 void GtkPopupNavigationToggle( GtkCheckMenuItem * menuitem,
                                gpointer user_data )
 {
@@ -127,11 +164,13 @@ void GtkPopupNavigationToggle( GtkCheckMenuItem * menuitem,
         !p_intf->p_sys->b_title_update &&
         !p_intf->p_sys->b_chapter_update )
     {
-        input_area_t   *p_area = p_intf->p_input->stream.p_selected_area;
+        input_area_t   *p_area;
 
         gint i_title   = DATA2TITLE( user_data );
         gint i_chapter = DATA2CHAPTER( user_data );
 
+        p_area = p_intf->p_input->stream.p_selected_area;
+
         if( p_area != p_intf->p_input->stream.pp_areas[i_title] )
         {
             p_area = p_intf->p_input->stream.pp_areas[i_title];
@@ -139,9 +178,13 @@ void GtkPopupNavigationToggle( GtkCheckMenuItem * menuitem,
         }
 
         p_area->i_part = i_chapter;
-        p_intf->p_sys->b_chapter_update = 1;
 
-        p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
+        input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
+
+        p_intf->p_sys->b_chapter_update = 1;
+        vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
+        GtkSetupMenus( p_intf );
+        vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
 
         input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
     }
@@ -151,101 +194,109 @@ void GtkPopupNavigationToggle( GtkCheckMenuItem * menuitem,
  * Title
  */
 
-#define GtkTitleToggle( intf )                                              \
-    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), (intf) );       \
-                                                                            \
-    if( menuitem->active && !p_intf->p_sys->b_title_update )                \
-    {                                                                       \
-        gint i_title = (gint)user_data;                                     \
-        p_intf->p_input->pf_set_area( p_intf->p_input,                      \
-            p_intf->p_input->stream.pp_areas[i_title] );                    \
-                                                                            \
-        input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );              \
-                                                                            \
-        p_intf->p_sys->b_title_update = 1;                                  \
-    }
-
 void GtkMenubarTitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    GtkTitleToggle( "intf_window" );
-}
+    intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
 
-void GtkPopupTitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
-{
-    GtkTitleToggle( "intf_popup" );
+    if( menuitem->active && !p_intf->p_sys->b_title_update )
+    {
+        gint i_title = (gint)user_data;
+        input_ChangeArea( p_intf->p_input,
+                          p_intf->p_input->stream.pp_areas[i_title] );
+
+        p_intf->p_sys->b_title_update = 1;
+        vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
+        GtkSetupMenus( p_intf );
+        vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
+        p_intf->p_sys->b_title_update = 0;
+
+        input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
+
+    }
 }
 
 /*
  * Chapter
  */
 
-#define GtkChapterToggle( intf )                                            \
-    intf_thread_t * p_intf;                                                 \
-    input_area_t *  p_area;                                                 \
-    gint            i_chapter;                                              \
-    char            psz_chapter[5];                                         \
-                                                                            \
-    p_intf    = GetIntf( GTK_WIDGET(menuitem), (intf) );                    \
-    p_area    = p_intf->p_input->stream.p_selected_area;                    \
-    i_chapter = (gint)user_data;                                            \
-                                                                            \
-    if( menuitem->active && !p_intf->p_sys->b_chapter_update )              \
-    {                                                                       \
-        p_area->i_part = i_chapter;                                         \
-        p_intf->p_input->pf_set_area( p_intf->p_input,                      \
-                                      (input_area_t*)p_area );              \
-                                                                            \
-        snprintf( psz_chapter, 3, "%02d", p_area->i_part );                 \
-        gtk_label_set_text( p_intf->p_sys->p_label_chapter, psz_chapter );  \
-                                                                            \
-        input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );              \
-                                                                            \
-        p_intf->p_sys->b_chapter_update = 1;                                \
-    }
-
-
 void GtkMenubarChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    GtkChapterToggle( "intf_window" );
-}
+    intf_thread_t * p_intf;
+    input_area_t *  p_area;
+    gint            i_chapter;
+    char            psz_chapter[5];
+    GtkWidget *     p_popup_menu;
 
-void GtkPopupChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
-{
-    GtkChapterToggle( "intf_popup" );
+    p_intf    = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
+    p_area    = p_intf->p_input->stream.p_selected_area;
+    i_chapter = (gint)user_data;
+
+    if( menuitem->active && !p_intf->p_sys->b_chapter_update )
+    {
+        p_area->i_part = i_chapter;
+        input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
+
+        snprintf( psz_chapter, 4, "%02d", p_area->i_part );
+        psz_chapter[ 4 ] = '\0';
+        gtk_label_set_text( p_intf->p_sys->p_label_chapter, psz_chapter );
+
+        p_intf->p_sys->b_chapter_update = 1;
+        p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
+                             p_intf->p_sys->p_popup ), "popup_navigation" ) );
+
+        vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
+        GtkTitleMenu( p_intf, p_popup_menu, GtkPopupNavigationToggle );
+        vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
+
+        p_intf->p_sys->b_chapter_update = 0;
+
+        input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
+    }
 }
 
+
 /*
  * Angle
  */
 
-#define GtkAngleToggle( intf )                                              \
+#define GtkAngleToggle( intf, window, menu, callback )                      \
     intf_thread_t * p_intf;                                                 \
+    GtkWidget *     p_menu;                                                 \
     input_area_t *  p_area;                                                 \
-    gint            i_angle;                                                \
                                                                             \
     p_intf    = GetIntf( GTK_WIDGET(menuitem), (intf) );                    \
-    p_area    = p_intf->p_input->stream.p_selected_area;                    \
-    i_angle   = (gint)user_data;                                            \
                                                                             \
     if( menuitem->active && !p_intf->p_sys->b_angle_update )                \
     {                                                                       \
-        p_area->i_angle = i_angle;                                          \
-        p_intf->p_input->pf_set_area( p_intf->p_input,                      \
-                                     (input_area_t*)p_area );               \
+        p_menu    = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(            \
+                                p_intf->p_sys->window ), (menu) ) );        \
+        p_area    = p_intf->p_input->stream.p_selected_area;                \
+        p_area->i_angle = (gint)user_data;                                  \
+                                                                            \
+        input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );         \
                                                                             \
         p_intf->p_sys->b_angle_update = 1;                                  \
+        vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );             \
+        GtkRadioMenu( p_intf, p_menu, NULL, "Angle",                        \
+                      p_area->i_angle_nb, p_area->i_angle, (callback) );    \
+        vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );           \
+        p_intf->p_sys->b_angle_update = 0;                                  \
     }
 
 void GtkMenubarAngleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    GtkAngleToggle( "intf_window" )
+    GtkAngleToggle( "intf_window", p_popup, "popup_angle",
+                    GtkPopupAngleToggle );
 }
 
 void GtkPopupAngleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
 {
-    GtkAngleToggle( "intf_popup" )
+    GtkAngleToggle( "intf_popup", p_window, "menubar_angle",
+                    GtkMenubarAngleToggle );
 }
 
+#undef GtkAngleToggle
+
 /****************************************************************************
  * Functions to generate menus
  ****************************************************************************/
@@ -347,11 +398,14 @@ static gint GtkRadioMenu( intf_thread_t * p_intf,
     /* link the new menu to the title menu item */
     gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
 
-    /* toggle currently selected chapter */
+    /* toggle currently selected chapter
+     * We have to release the lock since input_ToggleES needs it */
     if( p_item_selected != NULL )
     {
+        vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
         gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_selected ),
                                         TRUE );
+        vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
     }
 
     /* be sure that menu is sensitive, if there are several items */
@@ -427,10 +481,11 @@ static gint GtkLanguageMenus( gpointer          p_data,
     gtk_widget_show( p_separator );
     gtk_menu_append( GTK_MENU( p_menu ), p_separator );
 
-    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
     p_item_active = NULL;
     i_item = 0;
 
+    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
+
     /* create a set of language buttons and append them to the container */
     for( i = 0 ; i < p_intf->p_input->stream.i_es_number ; i++ )
     {
@@ -472,7 +527,8 @@ static gint GtkLanguageMenus( gpointer          p_data,
     gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
 
     /* acitvation will call signals so we can only do it
-     * when submenu is attached to menu - to get intf_window */
+     * when submenu is attached to menu - to get intf_window 
+     * We have to release the lock since input_ToggleES needs it */
     if( p_item_active != NULL )
     {
         gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
@@ -487,7 +543,7 @@ static gint GtkLanguageMenus( gpointer          p_data,
 
     return TRUE;
 }
-#if 1
+
 /*****************************************************************************
  * GtkTitleMenu: sets menus for titles and chapters selection
  *****************************************************************************
@@ -708,10 +764,14 @@ static gint GtkTitleMenu( gpointer       p_data,
     /* link the new menu to the menubar item */
     gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_navigation ), p_title_menu );
 
+    /* Default selected chapter
+     * We have to release the lock since input_ToggleES needs it */
     if( p_item_active != NULL )
     {
+        vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
         gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
                                         TRUE );
+        vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
     }
 #if 0
     if( p_intf->p_input->stream.i_area_nb > 1 )
@@ -723,12 +783,12 @@ static gint GtkTitleMenu( gpointer       p_data,
 
     return TRUE;
 }
-#endif
+
 /*****************************************************************************
- * GtkSetupMenu: function that generates title/chapter/audio/subpic
+ * GtkSetupMenus: function that generates title/chapter/audio/subpic
  * menus with help from preceding functions
  *****************************************************************************/
-gint GtkSetupMenu( intf_thread_t * p_intf )
+gint GtkSetupMenus( intf_thread_t * p_intf )
 {
     es_descriptor_t *   p_audio_es;
     es_descriptor_t *   p_spu_es;
@@ -741,6 +801,8 @@ gint GtkSetupMenu( intf_thread_t * p_intf )
     p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_title_update;
     p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_title_update;
 
+//    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
+
     if( p_intf->p_sys->b_title_update )
     { 
         char            psz_title[5];
@@ -748,9 +810,9 @@ gint GtkSetupMenu( intf_thread_t * p_intf )
         p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
                             p_intf->p_sys->p_window ), "menubar_title" ) );
         GtkRadioMenu( p_intf, p_menubar_menu, NULL, "Title",
-                        p_intf->p_input->stream.i_area_nb - 1,
-                        p_intf->p_input->stream.p_selected_area->i_id,
-                        GtkMenubarTitleToggle );
+                      p_intf->p_input->stream.i_area_nb - 1,
+                      p_intf->p_input->stream.p_selected_area->i_id,
+                      GtkMenubarTitleToggle );
 
         snprintf( psz_title, 4, "%d",
                   p_intf->p_input->stream.p_selected_area->i_id );
@@ -829,6 +891,8 @@ gint GtkSetupMenu( intf_thread_t * p_intf )
         }
     }
 
+    vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
+
     /* audio menus */
     if( p_intf->p_sys->b_audio_update )
     {
@@ -839,11 +903,13 @@ gint GtkSetupMenu( intf_thread_t * p_intf )
         p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
                      p_intf->p_sys->p_popup ), "popup_audio" ) );
     
+        p_intf->p_sys->b_audio_update = 1;
         GtkLanguageMenus( p_intf, p_menubar_menu, p_audio_es, AUDIO_ES,
                             GtkMenubarAudioToggle );
+        p_intf->p_sys->b_audio_update = 1;
         GtkLanguageMenus( p_intf, p_popup_menu, p_audio_es, AUDIO_ES,
                             GtkPopupAudioToggle );
-
+    
         p_intf->p_sys->b_audio_update = 0;
     }
     
@@ -857,29 +923,17 @@ gint GtkSetupMenu( intf_thread_t * p_intf )
         p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
                      p_intf->p_sys->p_popup ), "popup_subpictures" ) );
     
+        p_intf->p_sys->b_spu_update = 1;
         GtkLanguageMenus( p_intf, p_menubar_menu, p_spu_es, SPU_ES,
                             GtkMenubarSubtitleToggle  );
+        p_intf->p_sys->b_spu_update = 1;
         GtkLanguageMenus( p_intf, p_popup_menu, p_spu_es, SPU_ES,
                             GtkPopupSubtitleToggle );
-
+    
         p_intf->p_sys->b_spu_update = 0;
     }
 
-    /* handle fullscreen check items */
-    if( p_vout_bank->i_count )
-    {
-        p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
-                          p_intf->p_sys->p_window ), "menubar_fullscreen" ) );
-    
-        p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( 
-                     p_intf->p_sys->p_popup ), "popup_fullscreen" ) );
-
-        gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_menubar_menu ),
-                                        p_vout_bank->pp_vout[0]->b_fullscreen );
-        gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_popup_menu ),
-                                        p_vout_bank->pp_vout[0]->b_fullscreen );
-
-    }
+    vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
 
     return TRUE;
 }