1 /*****************************************************************************
2 * menu.c : functions to handle menu items.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
7 * Authors: Sam Hocevar <sam@zoy.org>
8 * Stéphane Borel <stef@via.ecp.fr>
9 * Johan Bilien <jobi@via.ecp.fr>
10 * Laurent Aimar <fenrir@via.ecp.fr>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
30 #include <sys/types.h> /* off_t */
34 #include <vlc/input.h>
39 #ifdef MODULE_NAME_IS_gnome
47 #include "gtk_callbacks.h"
48 #include "gtk_interface.h"
49 #include "gtk_support.h"
57 static gint GtkLanguageMenus( gpointer , GtkWidget *, es_descriptor_t *, gint,
58 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) );
60 void GtkMenubarAudioToggle ( GtkCheckMenuItem *, gpointer );
61 void GtkPopupAudioToggle ( GtkCheckMenuItem *, gpointer );
62 void GtkMenubarSubtitleToggle( GtkCheckMenuItem *, gpointer );
63 void GtkPopupSubtitleToggle ( GtkCheckMenuItem *, gpointer );
64 static gint GtkTitleMenu( gpointer, GtkWidget *,
65 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) );
66 static gint GtkRadioMenu( intf_thread_t *, GtkWidget *, GSList *,
67 char *, int, int, int,
68 void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) );
70 static void GtkMenubarDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data );
71 static void GtkPopupDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data );
72 static gint GtkDeinterlaceMenus( gpointer p_data,
74 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) );
76 gint GtkSetupMenus( intf_thread_t * p_intf );
78 /****************************************************************************
79 * Gtk*Toggle: callbacks to toggle the value of a checkmenuitem
80 ****************************************************************************
81 * We need separate functions for menubar and popup here since we can't use
82 * user_data to transmit intf_* and we need to refresh the other menu.
83 ****************************************************************************/
85 #define GTKLANGTOGGLE( window, menu, type, var_name, callback, b_update )\
86 intf_thread_t * p_intf; \
88 es_descriptor_t * p_es; \
90 p_intf = GtkGetIntf( menuitem ); \
92 if( !p_intf->p_sys->b_update ) \
94 p_menu = GTK_WIDGET( gtk_object_get_data( \
95 GTK_OBJECT( p_intf->p_sys->window ), (menu) ) ); \
96 p_es = (es_descriptor_t*)user_data; \
97 if( p_es && menuitem->active ) \
98 var_SetInteger( p_intf->p_sys->p_input, var_name, p_es->i_id ); \
100 var_SetInteger( p_intf->p_sys->p_input, var_name, -1 ); \
102 p_intf->p_sys->b_update = menuitem->active; \
104 if( p_intf->p_sys->b_update ) \
106 GtkLanguageMenus( p_intf, p_menu, p_es, type, callback ); \
109 p_intf->p_sys->b_update = VLC_FALSE; \
116 void GtkMenubarAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
118 GTKLANGTOGGLE( p_popup, "popup_language", AUDIO_ES, "audio-es",
119 GtkPopupAudioToggle, b_audio_update );
122 void GtkPopupAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
124 GTKLANGTOGGLE( p_window, "menubar_audio", AUDIO_ES, "audio-es",
125 GtkMenubarAudioToggle, b_audio_update );
132 void GtkMenubarSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
134 GTKLANGTOGGLE( p_popup, "popup_subpictures", SPU_ES, "spu-es",
135 GtkPopupSubtitleToggle, b_spu_update );
138 void GtkPopupSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
140 GTKLANGTOGGLE( p_window, "menubar_subpictures", SPU_ES, "spu-es",
141 GtkMenubarSubtitleToggle, b_spu_update );
150 void GtkPopupNavigationToggle( GtkCheckMenuItem * menuitem,
153 intf_thread_t * p_intf = GtkGetIntf( menuitem );
155 if( menuitem->active &&
156 !p_intf->p_sys->b_title_update &&
157 !p_intf->p_sys->b_chapter_update )
159 input_area_t *p_area;
161 guint i_title = DATA2TITLE( user_data );
162 guint i_chapter = DATA2CHAPTER( user_data );
164 /* FIXME use "navigation" variable */
165 var_SetInteger( p_intf->p_sys->p_input, "title", i_title );
166 var_SetInteger( p_intf->p_sys->p_input, "chapter", i_chapter );
168 p_intf->p_sys->b_title_update = VLC_TRUE;
169 p_intf->p_sys->b_chapter_update = VLC_TRUE;
171 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
172 GtkSetupMenus( p_intf );
173 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
180 #define GTKPROGRAMTOGGLE( ) \
181 intf_thread_t * p_intf = GtkGetIntf( menuitem ); \
183 if( menuitem->active && !p_intf->p_sys->b_program_update ) \
185 int i_program_id = (ptrdiff_t)user_data; \
187 var_SetInteger( p_intf->p_sys->p_input, "program", i_program_id ); \
189 p_intf->p_sys->b_program_update = VLC_TRUE; \
191 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); \
192 GtkSetupMenus( p_intf ); \
193 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); \
195 p_intf->p_sys->b_program_update = VLC_FALSE; \
197 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S ); \
200 void GtkMenubarProgramToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
205 void GtkPopupProgramToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
214 void GtkMenubarTitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
216 intf_thread_t * p_intf = GtkGetIntf( menuitem );
218 if( menuitem->active && !p_intf->p_sys->b_title_update )
220 guint i_title = (ptrdiff_t)user_data;
222 var_SetInteger( p_intf->p_sys->p_input, "title", i_title );
224 p_intf->p_sys->b_title_update = VLC_TRUE;
225 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
226 GtkSetupMenus( p_intf );
227 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
235 void GtkMenubarChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
237 intf_thread_t * p_intf;
238 input_area_t * p_area;
240 GtkWidget * p_popup_menu;
242 p_intf = GtkGetIntf( menuitem );
243 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
244 i_chapter = (ptrdiff_t)user_data;
246 if( menuitem->active && !p_intf->p_sys->b_chapter_update )
248 var_SetInteger( p_intf->p_sys->p_input, "chapter", i_chapter );
250 p_intf->p_sys->b_chapter_update = VLC_TRUE;
251 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
252 p_intf->p_sys->p_popup ), "popup_navigation" ) );
254 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
255 GtkTitleMenu( p_intf, p_popup_menu, GtkPopupNavigationToggle );
256 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
258 p_intf->p_sys->b_chapter_update = VLC_FALSE;
263 static void GtkPopupObjectToggle( GtkCheckMenuItem * menuitem,
264 gpointer user_data, int i_object_type, char *psz_variable )
266 intf_thread_t *p_intf = GtkGetIntf( menuitem );
269 p_label = GTK_LABEL( ( GTK_BIN( menuitem )->child ) );
271 if( menuitem->active && !p_intf->p_sys->b_aout_update &&
272 !p_intf->p_sys->b_vout_update )
274 vlc_object_t * p_obj;
276 p_obj = (vlc_object_t *)vlc_object_find( p_intf, i_object_type,
284 val = (vlc_value_t)user_data;
288 gtk_label_get( p_label, &val.psz_string );
291 if( var_Set( p_obj, psz_variable, val ) < 0 )
293 msg_Warn( p_obj, "cannot set variable (%s)", val.psz_string );
295 vlc_object_release( p_obj );
299 static void GtkPopupAoutChannelsToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
301 GtkPopupObjectToggle( menuitem, user_data, VLC_OBJECT_AOUT, "audio-channels" );
304 static void GtkPopupAoutDeviceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
306 GtkPopupObjectToggle( menuitem, user_data, VLC_OBJECT_AOUT, "audio-device" );
310 static void GtkPopupVoutDeviceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
312 GtkPopupObjectToggle( menuitem, user_data, VLC_OBJECT_VOUT, "video-device" );
316 static void GtkDeinterlaceUpdate( intf_thread_t *p_intf, char *psz_mode )
321 psz_filter = config_GetPsz( p_intf, "vout-filter" );
323 if( !strcmp( psz_mode, "None" ) )
325 config_PutPsz( p_intf, "vout-filter", "" );
329 if( !psz_filter || !*psz_filter )
331 config_PutPsz( p_intf, "vout-filter", "deinterlace" );
335 if( strstr( psz_filter, "deinterlace" ) == NULL )
337 psz_filter = realloc( psz_filter, strlen( psz_filter ) + 20 );
338 strcat( psz_filter, ",deinterlace" );
340 config_PutPsz( p_intf, "vout-filter", psz_filter );
347 /* now restart all video stream */
348 if( p_intf->p_sys->p_input )
350 vout_thread_t *p_vout;
351 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
353 /* Warn the vout we are about to change the filter chain */
354 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
358 p_vout->b_filter_change = VLC_TRUE;
359 vlc_object_release( p_vout );
362 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
363 /* create a set of language buttons and append them to the container */
364 for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_es_number ; i++ )
366 if( ( ES->i_cat == VIDEO_ES ) &&
369 input_UnselectES( p_intf->p_sys->p_input, ES );
370 input_SelectES( p_intf->p_sys->p_input, ES );
374 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
377 if( strcmp( psz_mode, "None" ) )
379 vout_thread_t *p_vout;
380 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
386 val.psz_string = psz_mode;
387 if( var_Set( p_vout, "deinterlace-mode", val ) != VLC_SUCCESS )
388 config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
390 vlc_object_release( p_vout );
393 config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
398 static void GtkMenubarDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
400 intf_thread_t *p_intf = GtkGetIntf( menuitem );
403 GtkWidget *p_popup_menu;
405 p_label = GTK_LABEL( ( GTK_BIN( menuitem )->child ) );
407 if( !p_intf->p_sys->b_deinterlace_update && menuitem->active )
409 gtk_label_get( p_label, &psz_mode );
410 GtkDeinterlaceUpdate( p_intf, psz_mode );
412 p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
414 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
415 p_intf->p_sys->p_popup ), "popup_deinterlace" ) );
417 GtkDeinterlaceMenus( p_intf, p_popup_menu, GtkPopupDeinterlaceToggle );
419 p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
424 static void GtkPopupDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
426 intf_thread_t *p_intf = GtkGetIntf( menuitem );
429 GtkWidget *p_menubar_menu;
431 p_label = GTK_LABEL( ( GTK_BIN( menuitem )->child ) );
433 if( !p_intf->p_sys->b_deinterlace_update && menuitem->active )
435 gtk_label_get( p_label, &psz_mode );
436 GtkDeinterlaceUpdate( p_intf, psz_mode );
438 p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
440 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
441 p_intf->p_sys->p_window ), "menubar_deinterlace" ) );
443 GtkDeinterlaceMenus( p_intf, p_menubar_menu, GtkMenubarDeinterlaceToggle );
445 p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
449 /****************************************************************************
450 * Functions to generate menus
451 ****************************************************************************/
453 /*****************************************************************************
454 * GtkRadioMenu: update interactive menus of the interface
455 *****************************************************************************
456 * Sets up menus with information from input
457 * Warning: since this function is designed to be called by management
458 * function, the interface lock has to be taken
459 *****************************************************************************/
460 static gint GtkRadioMenu( intf_thread_t * p_intf,
461 GtkWidget * p_root, GSList * p_menu_group,
462 char * psz_item_name,
463 int i_start, int i_end, int i_selected,
464 void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) )
466 char psz_name[ GTK_MENU_LABEL_SIZE ];
468 GtkWidget * p_submenu;
469 GtkWidget * p_item_group;
471 GtkWidget * p_item_selected;
475 /* temporary hack to avoid blank menu when an open menu is removed */
476 if( GTK_MENU_ITEM(p_root)->submenu != NULL )
478 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
480 /* removes previous menu */
481 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
482 gtk_widget_set_sensitive( p_root, FALSE );
486 p_item_selected = NULL;
487 p_group = p_menu_group;
489 p_menu = gtk_menu_new();
490 gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
492 for( i_item = i_start ; i_item <= i_end ; i_item++ )
494 /* we group chapters in packets of ten for small screens */
495 if( ( i_item % 10 == i_start ) && ( i_end > i_start + 20 ) )
497 if( i_item != i_start )
499 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_item_group ),
501 gtk_menu_append( GTK_MENU( p_menu ), p_item_group );
504 snprintf( psz_name, GTK_MENU_LABEL_SIZE,
505 "%ss %d to %d", psz_item_name, i_item, i_item + 9 );
506 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
507 p_item_group = gtk_menu_item_new_with_label( psz_name );
508 gtk_widget_show( p_item_group );
509 p_submenu = gtk_menu_new();
510 gtk_object_set_data( GTK_OBJECT( p_submenu ), "p_intf", p_intf );
513 snprintf( psz_name, GTK_MENU_LABEL_SIZE, "%s %d",
514 psz_item_name, i_item );
515 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
517 p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
518 p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
520 if( i_selected == i_item )
522 p_item_selected = p_item;
525 gtk_widget_show( p_item );
527 /* setup signal hanling */
528 gtk_signal_connect( GTK_OBJECT( p_item ),
530 GTK_SIGNAL_FUNC( pf_toggle ),
531 (gpointer)((long)(i_item)) );
533 if( i_end > i_start + 20 )
535 gtk_menu_append( GTK_MENU( p_submenu ), p_item );
539 gtk_menu_append( GTK_MENU( p_menu ), p_item );
543 if( i_end > i_start + 20 )
545 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_item_group ), p_submenu );
546 gtk_menu_append( GTK_MENU( p_menu ), p_item_group );
549 /* link the new menu to the title menu item */
550 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
552 /* toggle currently selected chapter
553 * We have to release the lock since input_ToggleES needs it */
554 if( p_item_selected != NULL )
556 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_selected ),
560 /* be sure that menu is sensitive, if there are several items */
561 if( i_end > i_start )
563 gtk_widget_set_sensitive( p_root, TRUE );
569 /*****************************************************************************
570 * GtkProgramMenu: update the programs menu of the interface
571 *****************************************************************************
572 * Builds the program menu according to what have been found in the PAT
573 * by the input. Usefull for multi-programs streams such as DVB ones.
574 *****************************************************************************/
575 static gint GtkProgramMenu( gpointer p_data,
577 pgrm_descriptor_t * p_pgrm,
578 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
580 intf_thread_t * p_intf;
583 GtkWidget * p_item_active;
585 char psz_name[ GTK_MENU_LABEL_SIZE ];
589 p_intf = (intf_thread_t *)p_data;
591 /* temporary hack to avoid blank menu when an open menu is removed */
592 if( GTK_MENU_ITEM(p_root)->submenu != NULL )
594 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
596 /* removes previous menu */
597 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
598 gtk_widget_set_sensitive( p_root, FALSE );
603 p_menu = gtk_menu_new();
604 gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
606 p_item_active = NULL;
608 /* create a set of program buttons and append them to the container */
609 for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_pgrm_number ; i++ )
611 snprintf( psz_name, GTK_MENU_LABEL_SIZE, "id %d",
612 p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
613 psz_name[GTK_MENU_LABEL_SIZE-1] = '\0';
615 p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
617 gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
619 if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
621 /* don't lose p_item when we append into menu */
622 p_item_active = p_item;
625 gtk_widget_show( p_item );
627 /* setup signal hanling */
628 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
629 GTK_SIGNAL_FUNC( pf_toggle ),
630 (gpointer)(ptrdiff_t)( p_intf->p_sys->p_input->
631 stream.pp_programs[i]->i_number ) );
633 gtk_menu_append( GTK_MENU( p_menu ), p_item );
636 /* link the new menu to the menubar item */
637 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
639 /* activation will call signals so we can only do it
640 * when submenu is attached to menu - to get intf_window
641 * We have to release the lock since input_ToggleES needs it */
642 if( p_item_active != NULL )
644 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
648 /* be sure that menu is sensitive if more than 1 program */
649 if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
651 gtk_widget_set_sensitive( p_root, TRUE );
657 /*****************************************************************************
658 * GtkLanguageMenus: update interactive menus of the interface
659 *****************************************************************************
660 * Sets up menus with information from input:
663 * Warning: since this function is designed to be called by management
664 * function, the interface lock has to be taken
665 *****************************************************************************/
666 static gint GtkLanguageMenus( gpointer p_data,
668 es_descriptor_t * p_es,
670 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
672 intf_thread_t * p_intf;
674 GtkWidget * p_separator;
676 GtkWidget * p_item_active;
678 char psz_name[ GTK_MENU_LABEL_SIZE ];
682 p_intf = (intf_thread_t *)p_data;
684 /* temporary hack to avoid blank menu when an open menu is removed */
685 if( GTK_MENU_ITEM(p_root)->submenu != NULL )
687 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
689 /* removes previous menu */
690 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
691 gtk_widget_set_sensitive( p_root, FALSE );
696 p_menu = gtk_menu_new();
697 gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
699 /* special case for "off" item */
700 snprintf( psz_name, GTK_MENU_LABEL_SIZE, _("None") );
701 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
703 p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
704 p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
706 gtk_widget_show( p_item );
708 /* signal hanling for off */
709 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
710 GTK_SIGNAL_FUNC ( pf_toggle ), NULL );
712 gtk_menu_append( GTK_MENU( p_menu ), p_item );
714 p_separator = gtk_menu_item_new();
715 gtk_widget_set_sensitive( p_separator, FALSE );
716 gtk_widget_show( p_separator );
717 gtk_menu_append( GTK_MENU( p_menu ), p_separator );
719 p_item_active = NULL;
722 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
724 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
725 /* create a set of language buttons and append them to the container */
726 for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_es_number ; i++ )
728 if( ( ES->i_cat == i_cat ) &&
731 p_intf->p_sys->p_input->stream.p_selected_program ) )
734 if( !p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc ||
735 !*p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc )
737 snprintf( psz_name, GTK_MENU_LABEL_SIZE,
738 "Language %d", i_item );
739 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
744 p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc );
747 p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
749 gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
751 if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
753 /* don't lose p_item when we append into menu */
754 p_item_active = p_item;
757 gtk_widget_show( p_item );
759 /* setup signal hanling */
760 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
761 GTK_SIGNAL_FUNC( pf_toggle ),
762 (gpointer)( p_intf->p_sys->p_input->stream.pp_es[i] ) );
764 gtk_menu_append( GTK_MENU( p_menu ), p_item );
768 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
770 /* link the new menu to the menubar item */
771 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
773 /* acitvation will call signals so we can only do it
774 * when submenu is attached to menu - to get intf_window
775 * We have to release the lock since input_ToggleES needs it */
776 if( p_item_active != NULL )
778 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
782 /* be sure that menu is sensitive if non empty */
785 gtk_widget_set_sensitive( p_root, TRUE );
791 /*****************************************************************************
792 * GtkTitleMenu: sets menus for titles and chapters selection
793 *****************************************************************************
794 * Generates two types of menus:
795 * -simple list of titles
796 * -cascaded lists of chapters for each title
797 *****************************************************************************/
798 static gint GtkTitleMenu( gpointer p_data,
799 GtkWidget * p_navigation,
800 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
802 intf_thread_t * p_intf;
803 char psz_name[ GTK_MENU_LABEL_SIZE ];
804 GtkWidget * p_title_menu;
805 GtkWidget * p_title_submenu;
806 GtkWidget * p_title_item;
807 GtkWidget * p_item_active;
808 GtkWidget * p_chapter_menu;
809 GtkWidget * p_chapter_submenu;
810 GtkWidget * p_title_menu_item;
811 GtkWidget * p_chapter_menu_item;
813 GSList * p_title_group;
814 GSList * p_chapter_group;
821 p_intf = (intf_thread_t*)p_data;
823 /* temporary hack to avoid blank menu when an open menu is removed */
824 if( GTK_MENU_ITEM(p_navigation)->submenu != NULL )
826 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_navigation)->submenu ) );
828 /* removes previous menu */
829 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_navigation ) );
830 gtk_widget_set_sensitive( p_navigation, FALSE );
832 p_title_menu = gtk_menu_new();
833 p_title_group = NULL;
834 p_title_submenu = NULL;
835 p_title_menu_item = NULL;
836 p_chapter_group = NULL;
837 p_chapter_submenu = NULL;
838 p_chapter_menu_item = NULL;
839 p_item_active = NULL;
840 i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb - 1;
842 gtk_object_set_data( GTK_OBJECT( p_title_menu ), "p_intf", p_intf );
845 for( i_title = 1 ; i_title <= i_title_nb ; i_title++ )
847 /* we group titles in packets of ten for small screens */
848 if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
852 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item ),
854 gtk_menu_append( GTK_MENU( p_title_menu ), p_title_menu_item );
857 snprintf( psz_name, GTK_MENU_LABEL_SIZE,
858 "%d - %d", i_title, i_title + 9 );
859 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
860 p_title_menu_item = gtk_menu_item_new_with_label( psz_name );
861 gtk_widget_show( p_title_menu_item );
862 p_title_submenu = gtk_menu_new();
863 gtk_object_set_data( GTK_OBJECT( p_title_submenu ),
867 snprintf( psz_name, GTK_MENU_LABEL_SIZE, _("Title %d (%d)"), i_title,
868 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1);
869 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
871 if( pf_toggle == on_menubar_title_toggle )
873 p_title_item = gtk_radio_menu_item_new_with_label( p_title_group,
876 gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_title_item ) );
878 if( p_intf->p_sys->p_input->stream.pp_areas[i_title] ==
879 p_intf->p_sys->p_input->stream.p_selected_area )
881 p_item_active = p_title_item;
884 /* setup signal hanling */
885 gtk_signal_connect( GTK_OBJECT( p_title_item ),
887 GTK_SIGNAL_FUNC( pf_toggle ),
888 (gpointer)(p_intf->p_sys->p_input->stream.pp_areas[i_title]) );
890 if( p_intf->p_sys->p_input->stream.i_area_nb > 1 )
892 /* be sure that menu is sensitive */
893 gtk_widget_set_sensitive( p_navigation, TRUE );
899 p_title_item = gtk_menu_item_new_with_label( psz_name );
902 p_chapter_menu = gtk_menu_new();
903 gtk_object_set_data( GTK_OBJECT( p_chapter_menu ),
906 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;
908 for( i_chapter = 1 ; i_chapter <= i_chapter_nb ; i_chapter++ )
910 /* we group chapters in packets of ten for small screens */
911 if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )
915 gtk_menu_item_set_submenu(
916 GTK_MENU_ITEM( p_chapter_menu_item ),
918 gtk_menu_append( GTK_MENU( p_chapter_menu ),
919 p_chapter_menu_item );
922 snprintf( psz_name, GTK_MENU_LABEL_SIZE,
923 "%d - %d", i_chapter, i_chapter + 9 );
924 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
925 p_chapter_menu_item =
926 gtk_menu_item_new_with_label( psz_name );
927 gtk_widget_show( p_chapter_menu_item );
928 p_chapter_submenu = gtk_menu_new();
929 gtk_object_set_data( GTK_OBJECT( p_chapter_submenu ),
933 snprintf( psz_name, GTK_MENU_LABEL_SIZE,
934 _("Chapter %d"), i_chapter );
935 psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
937 p_item = gtk_radio_menu_item_new_with_label(
938 p_chapter_group, psz_name );
939 p_chapter_group = gtk_radio_menu_item_group(
940 GTK_RADIO_MENU_ITEM( p_item ) );
941 gtk_widget_show( p_item );
943 #define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
945 p_intf->p_sys->p_input->stream.p_selected_area ) &&
946 ( p_area->i_part == i_chapter ) )
948 p_item_active = p_item;
952 /* setup signal hanling */
953 gtk_signal_connect( GTK_OBJECT( p_item ),
955 GTK_SIGNAL_FUNC( pf_toggle ),
956 (gpointer)POS2DATA( i_title, i_chapter ) );
958 if( i_chapter_nb > 20 )
960 gtk_menu_append( GTK_MENU( p_chapter_submenu ), p_item );
964 gtk_menu_append( GTK_MENU( p_chapter_menu ), p_item );
968 if( i_chapter_nb > 20 )
970 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_chapter_menu_item ),
972 gtk_menu_append( GTK_MENU( p_chapter_menu ),
973 p_chapter_menu_item );
976 /* link the new menu to the title menu item */
977 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_item ),
980 if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb > 1 )
982 /* be sure that menu is sensitive */
983 gtk_widget_set_sensitive( p_navigation, TRUE );
986 GtkRadioMenu( p_intf, p_title_item, p_chapter_group, _("Chapter"),
987 p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1,
989 p_intf->p_sys->p_input->stream.p_selected_area->i_part +
990 p_intf->p_sys->p_input->stream.p_selected_area->i_id *100,
995 gtk_widget_show( p_title_item );
997 if( i_title_nb > 20 )
999 gtk_menu_append( GTK_MENU( p_title_submenu ), p_title_item );
1003 gtk_menu_append( GTK_MENU( p_title_menu ), p_title_item );
1007 if( i_title_nb > 20 )
1009 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item ),
1011 gtk_menu_append( GTK_MENU( p_title_menu ), p_title_menu_item );
1014 /* be sure that menu is sensitive */
1015 gtk_widget_set_sensitive( p_title_menu, TRUE );
1017 /* link the new menu to the menubar item */
1018 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_navigation ), p_title_menu );
1020 /* Default selected chapter
1021 * We have to release the lock since input_ToggleES needs it */
1022 if( p_item_active != NULL )
1024 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
1028 if( p_intf->p_sys->p_input->stream.i_area_nb > 1 )
1030 /* be sure that menu is sensitive */
1031 gtk_widget_set_sensitive( p_navigation, TRUE );
1038 /*****************************************************************************
1040 *****************************************************************************
1042 *****************************************************************************/
1043 static gint GtkSetupVarMenu( intf_thread_t * p_intf,
1044 vlc_object_t * p_object,
1046 char * psz_variable,
1047 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
1049 vlc_value_t val, text, val_list, text_list;
1051 GSList * p_group = NULL;
1053 GtkWidget * p_item_active = NULL;
1057 /* temporary hack to avoid blank menu when an open menu is removed */
1058 if( GTK_MENU_ITEM(p_root)->submenu != NULL )
1060 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
1062 /* removes previous menu */
1063 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
1064 gtk_widget_set_sensitive( p_root, FALSE );
1066 /* Check the type of the object variable */
1067 i_type = var_Type( p_object, psz_variable );
1069 /* Make sure we want to display the variable */
1070 if( i_type & VLC_VAR_HASCHOICE )
1072 var_Change( p_object, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL );
1073 if( val.i_int == 0 ) return FALSE;
1076 /* Get the descriptive name of the variable */
1077 var_Change( p_object, psz_variable, VLC_VAR_GETTEXT, &text, NULL );
1079 /* get the current value */
1080 if( var_Get( p_object, psz_variable, &val ) < 0 )
1085 if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST,
1086 &val_list, &text_list ) < 0 )
1088 if( i_type == VLC_VAR_STRING ) free( val.psz_string );
1092 /* menu container */
1093 p_menu = gtk_menu_new();
1094 gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
1096 for( i_item = 0; i_item < val_list.p_list->i_count; i_item++ )
1098 switch( i_type & VLC_VAR_TYPE )
1100 case VLC_VAR_STRING:
1101 p_item = gtk_radio_menu_item_new_with_label( p_group,
1102 text_list.p_list->p_values[i_item].psz_string ?
1103 text_list.p_list->p_values[i_item].psz_string :
1104 val_list.p_list->p_values[i_item].psz_string );
1106 /* signal hanling for off */
1107 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
1108 GTK_SIGNAL_FUNC ( pf_toggle ),
1109 /* FIXME memory leak */
1110 strdup(val_list.p_list->p_values[i_item].psz_string) );
1112 if( !strcmp( val.psz_string,
1113 val_list.p_list->p_values[i_item].psz_string ) )
1115 p_item_active = p_item;
1118 case VLC_VAR_INTEGER:
1119 p_item = gtk_radio_menu_item_new_with_label( p_group,
1120 text_list.p_list->p_values[i_item].psz_string ?
1121 text_list.p_list->p_values[i_item].psz_string :
1124 /* signal hanling for off */
1125 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
1126 GTK_SIGNAL_FUNC ( pf_toggle ),
1127 (gpointer)val_list.p_list->p_values[i_item].i_int );
1129 if( val.i_int == val_list.p_list->p_values[i_item].i_int )
1131 p_item_active = p_item;
1139 p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
1141 gtk_widget_show( p_item );
1143 gtk_menu_append( GTK_MENU( p_menu ), p_item );
1146 /* link the new menu to the menubar item */
1147 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
1151 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(p_item_active),
1155 if( val_list.p_list->i_count > 0 )
1157 gtk_widget_set_sensitive( p_root, TRUE );
1160 /* clean up everything */
1161 if( i_type == VLC_VAR_STRING ) free( val.psz_string );
1162 var_Change( p_object, psz_variable, VLC_VAR_FREELIST,
1163 &val_list, &text_list );
1168 /*****************************************************************************
1169 * GtkDeinterlaceMenus: update interactive menus of the interface
1170 *****************************************************************************
1171 *****************************************************************************/
1172 static gint GtkDeinterlaceMenus( gpointer p_data,
1174 void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
1176 intf_thread_t * p_intf;
1178 GtkWidget * p_separator;
1180 GtkWidget * p_item_active;
1184 char *ppsz_deinterlace_mode[] = { "discard", "blend", "mean", "bob", "linear", NULL };
1185 char *psz_deinterlace_option;
1188 p_intf = (intf_thread_t *)p_data;
1190 /* temporary hack to avoid blank menu when an open menu is removed */
1191 if( GTK_MENU_ITEM(p_root)->submenu != NULL )
1193 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
1195 /* removes previous menu */
1196 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
1197 gtk_widget_set_sensitive( p_root, FALSE );
1201 /* menu container */
1202 p_menu = gtk_menu_new();
1203 gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
1205 /* special case for "off" item */
1206 p_item = gtk_radio_menu_item_new_with_label( p_group, "None" );
1207 p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
1209 gtk_widget_show( p_item );
1211 /* signal hanling for off */
1212 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
1213 GTK_SIGNAL_FUNC ( pf_toggle ), NULL );
1215 gtk_menu_append( GTK_MENU( p_menu ), p_item );
1217 p_separator = gtk_menu_item_new();
1218 gtk_widget_set_sensitive( p_separator, FALSE );
1219 gtk_widget_show( p_separator );
1220 gtk_menu_append( GTK_MENU( p_menu ), p_separator );
1223 /* search actual deinterlace mode */
1224 psz_filter = config_GetPsz( p_intf, "filter" );
1225 psz_deinterlace_option = strdup( "None" );
1227 if( psz_filter && *psz_filter )
1229 if( strstr ( psz_filter, "deinterlace" ) )
1232 vout_thread_t *p_vout;
1234 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1237 var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS )
1239 if( val.psz_string && *val.psz_string )
1241 free( psz_deinterlace_option );
1242 psz_deinterlace_option = val.psz_string;
1244 else if( val.psz_string ) free( val.psz_string );
1247 if( p_vout ) vlc_object_release( p_vout );
1253 p_item_active = NULL;
1256 /* create a set of deinteralce buttons and append them to the container */
1257 for( i = 0; ppsz_deinterlace_mode[i] != NULL; i++ )
1261 p_item = gtk_radio_menu_item_new_with_label( p_group, ppsz_deinterlace_mode[i] );
1262 p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
1263 gtk_widget_show( p_item );
1265 if( !strcmp( ppsz_deinterlace_mode[i], psz_deinterlace_option ) )
1267 p_item_active = p_item;
1269 /* setup signal hanling */
1270 gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
1271 GTK_SIGNAL_FUNC( pf_toggle ),
1274 gtk_menu_append( GTK_MENU( p_menu ), p_item );
1278 /* link the new menu to the menubar item */
1279 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
1281 /* acitvation will call signals so we can only do it
1282 * when submenu is attached to menu - to get intf_window
1283 * We have to release the lock since input_ToggleES needs it */
1284 if( p_item_active != NULL )
1286 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
1290 /* be sure that menu is sensitive if non empty */
1293 gtk_widget_set_sensitive( p_root, TRUE );
1301 /*****************************************************************************
1302 * GtkSetupMenus: function that generates title/chapter/audio/subpic
1303 * menus with help from preceding functions
1304 *****************************************************************************
1305 * Function called with the lock on stream
1306 *****************************************************************************/
1307 gint GtkSetupMenus( intf_thread_t * p_intf )
1309 es_descriptor_t * p_audio_es;
1310 es_descriptor_t * p_spu_es;
1311 GtkWidget * p_menubar_menu;
1312 GtkWidget * p_popup_menu;
1315 p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
1316 p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_title_update |
1317 p_intf->p_sys->b_program_update;
1318 p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_title_update |
1319 p_intf->p_sys->b_program_update;
1323 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1324 p_intf->p_sys->p_window ), "menubar_deinterlace" ) );
1325 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1326 p_intf->p_sys->p_popup ), "popup_deinterlace" ) );
1328 p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
1329 GtkDeinterlaceMenus( p_intf, p_menubar_menu, GtkMenubarDeinterlaceToggle );
1330 p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
1331 GtkDeinterlaceMenus( p_intf, p_popup_menu, GtkPopupDeinterlaceToggle );
1333 p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
1336 if( p_intf->p_sys->b_program_update )
1338 pgrm_descriptor_t * p_pgrm;
1340 if( p_intf->p_sys->p_input->stream.p_new_program )
1342 p_pgrm = p_intf->p_sys->p_input->stream.p_new_program;
1346 p_pgrm = p_intf->p_sys->p_input->stream.p_selected_program;
1349 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1350 p_intf->p_sys->p_window ), "menubar_program" ) );
1351 GtkProgramMenu( p_intf, p_menubar_menu, p_pgrm,
1352 GtkMenubarProgramToggle );
1354 p_intf->p_sys->b_program_update = VLC_TRUE;
1355 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1356 p_intf->p_sys->p_popup ), "popup_program" ) );
1357 GtkProgramMenu( p_intf, p_popup_menu, p_pgrm,
1358 GtkPopupProgramToggle );
1360 p_intf->p_sys->b_program_update = VLC_FALSE;
1363 if( p_intf->p_sys->b_title_update )
1367 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1368 p_intf->p_sys->p_window ), "menubar_title" ) );
1369 GtkRadioMenu( p_intf, p_menubar_menu, NULL, _("Title"), 1,
1370 p_intf->p_sys->p_input->stream.i_area_nb - 1,
1371 p_intf->p_sys->p_input->stream.p_selected_area->i_id,
1372 GtkMenubarTitleToggle );
1374 snprintf( psz_title, 4, "%d",
1375 p_intf->p_sys->p_input->stream.p_selected_area->i_id );
1376 psz_title[ 4 ] = '\0';
1377 gtk_label_set_text( p_intf->p_sys->p_label_title, psz_title );
1379 p_intf->p_sys->b_title_update = VLC_FALSE;
1382 if( p_intf->p_sys->b_chapter_update )
1384 char psz_chapter[5];
1386 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1387 p_intf->p_sys->p_popup ), "popup_navigation" ) );
1388 GtkTitleMenu( p_intf, p_popup_menu, GtkPopupNavigationToggle );
1390 GtkRadioMenu( p_intf, p_menubar_menu, NULL, _("Title"), 1,
1391 p_intf->p_sys->p_input->stream.i_area_nb - 1,
1392 p_intf->p_sys->p_input->stream.p_selected_area->i_id,
1393 on_menubar_chapter_toggle );
1396 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1397 p_intf->p_sys->p_window ), "menubar_chapter" ) );
1399 GtkRadioMenu( p_intf, p_menubar_menu, NULL, _("Chapter"), 1,
1400 p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb - 1,
1401 p_intf->p_sys->p_input->stream.p_selected_area->i_part,
1402 GtkMenubarChapterToggle );
1405 snprintf( psz_chapter, 4, "%d",
1406 p_intf->p_sys->p_input->stream.p_selected_area->i_part );
1407 psz_chapter[ 4 ] = '\0';
1408 gtk_label_set_text( p_intf->p_sys->p_label_chapter, psz_chapter );
1410 p_intf->p_sys->i_part =
1411 p_intf->p_sys->p_input->stream.p_selected_area->i_part;
1413 p_intf->p_sys->b_chapter_update = VLC_FALSE;
1416 /* look for selected ES */
1420 for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_selected_es_number ; i++ )
1422 if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
1424 p_audio_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
1427 if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
1429 p_spu_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
1433 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
1436 if( p_intf->p_sys->b_audio_update )
1438 /* find audio root menu */
1439 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1440 p_intf->p_sys->p_window ), "menubar_audio" ) );
1442 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1443 p_intf->p_sys->p_popup ), "popup_language" ) );
1445 p_intf->p_sys->b_audio_update = VLC_TRUE;
1446 GtkLanguageMenus( p_intf, p_menubar_menu, p_audio_es, AUDIO_ES,
1447 GtkMenubarAudioToggle );
1448 p_intf->p_sys->b_audio_update = VLC_TRUE;
1449 GtkLanguageMenus( p_intf, p_popup_menu, p_audio_es, AUDIO_ES,
1450 GtkPopupAudioToggle );
1452 p_intf->p_sys->b_audio_update = VLC_FALSE;
1455 /* sub picture menus */
1456 if( p_intf->p_sys->b_spu_update )
1458 /* find spu root menu */
1459 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1460 p_intf->p_sys->p_window ), "menubar_subpictures" ) );
1462 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1463 p_intf->p_sys->p_popup ), "popup_subpictures" ) );
1465 p_intf->p_sys->b_spu_update = VLC_TRUE;
1466 GtkLanguageMenus( p_intf, p_menubar_menu, p_spu_es, SPU_ES,
1467 GtkMenubarSubtitleToggle );
1468 p_intf->p_sys->b_spu_update = VLC_TRUE;
1469 GtkLanguageMenus( p_intf, p_popup_menu, p_spu_es, SPU_ES,
1470 GtkPopupSubtitleToggle );
1472 p_intf->p_sys->b_spu_update = VLC_FALSE;
1474 /* create audio channels and device menu (in menubar _and_ popup */
1475 if( p_intf->p_sys->b_aout_update )
1477 aout_instance_t *p_aout;
1479 p_aout = (aout_instance_t*)vlc_object_find( p_intf, VLC_OBJECT_AOUT, FIND_ANYWHERE );
1481 if( p_aout != NULL )
1484 val.b_bool = VLC_FALSE;
1486 var_Set( (vlc_object_t *)p_aout, "intf-change", val );
1488 /* audio-channels */
1489 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1490 p_intf->p_sys->p_window ), "menubar_audio_channels" ) );
1491 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1492 p_intf->p_sys->p_popup ), "popup_audio_channels" ) );
1493 GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_popup_menu,
1494 "audio-channels", GtkPopupAoutChannelsToggle );
1495 GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_menubar_menu,
1496 "audio-channels", GtkPopupAoutChannelsToggle );
1499 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1500 p_intf->p_sys->p_window ), "menubar_audio_device" ) );
1501 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1502 p_intf->p_sys->p_popup ), "popup_audio_device" ) );
1503 GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_popup_menu,
1504 "audio-device", GtkPopupAoutDeviceToggle );
1505 GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_menubar_menu,
1506 "audio-device", GtkPopupAoutDeviceToggle );
1508 vlc_object_release( (vlc_object_t *)p_aout );
1510 p_intf->p_sys->b_aout_update = VLC_FALSE;
1513 if( p_intf->p_sys->b_vout_update )
1515 vout_thread_t *p_vout;
1517 p_vout = (vout_thread_t*)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1519 if( p_vout != NULL )
1522 val.b_bool = VLC_FALSE;
1524 var_Set( (vlc_object_t *)p_vout, "intf-change", val );
1527 p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1528 p_intf->p_sys->p_window ), "menubar_video_device" ) );
1529 p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
1530 p_intf->p_sys->p_popup ), "popup_video_device" ) );
1531 GtkSetupVarMenu( p_intf, (vlc_object_t *)p_vout, p_popup_menu,
1532 "video-device", GtkPopupVoutDeviceToggle );
1533 GtkSetupVarMenu( p_intf, (vlc_object_t *)p_vout, p_menubar_menu,
1534 "video-device", GtkPopupVoutDeviceToggle );
1537 vlc_object_release( (vlc_object_t *)p_vout );
1539 p_intf->p_sys->b_vout_update = VLC_FALSE;
1541 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );