1 /*****************************************************************************
2 * gtk_menu.c : functions to handle menu items.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: gtk_menu.c,v 1.9 2001/06/02 01:09:03 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Stéphane Borel <stef@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
29 #include <sys/types.h> /* off_t */
41 #include "stream_control.h"
42 #include "input_ext-intf.h"
44 #include "interface.h"
45 #include "intf_playlist.h"
49 #include "video_output.h"
50 #include "audio_output.h"
52 #include "gtk_callbacks.h"
53 #include "gtk_interface.h"
54 #include "gtk_support.h"
55 #include "gtk_playlist.h"
60 #include "modules_export.h"
64 #define snprintf _snprintf
71 static gint
GtkLanguageMenus( gpointer
, GtkWidget
*, es_descriptor_t
*, gint
,
72 void(*pf_toggle
)( GtkCheckMenuItem
*, gpointer
) );
74 void GtkMenubarAudioToggle ( GtkCheckMenuItem
*, gpointer
);
75 void GtkPopupAudioToggle ( GtkCheckMenuItem
*, gpointer
);
76 void GtkMenubarSubtitleToggle( GtkCheckMenuItem
*, gpointer
);
77 void GtkPopupSubtitleToggle ( GtkCheckMenuItem
*, gpointer
);
78 static gint
GtkTitleMenu( gpointer
, GtkWidget
*,
79 void(*pf_toggle
)( GtkCheckMenuItem
*, gpointer
) );
80 static gint
GtkRadioMenu( intf_thread_t
*, GtkWidget
*, GSList
*,
82 void( *pf_toggle
)( GtkCheckMenuItem
*, gpointer
) );
83 void GtkMenubarAngleToggle( GtkCheckMenuItem
*, gpointer
);
84 void GtkPopupAngleToggle( GtkCheckMenuItem
*, gpointer
);
86 gint
GtkSetupMenus( intf_thread_t
* p_intf
);
88 /****************************************************************************
89 * Gtk*Toggle: callbacks to toggle the value of a checkmenuitem
90 ****************************************************************************
91 * We need separate functions for menubar and popup here since we can't use
92 * user_data to transmit intf_* and we need to refresh the other menu.
93 ****************************************************************************/
95 #define GtkLangToggle( intf, window, menu, type, callback, b_update ) \
96 intf_thread_t * p_intf; \
98 es_descriptor_t * p_es; \
100 p_intf = GetIntf( GTK_WIDGET(menuitem), (intf) ); \
102 if( !p_intf->p_sys->b_update ) \
104 p_menu = GTK_WIDGET( gtk_object_get_data( \
105 GTK_OBJECT( p_intf->p_sys->window ), (menu) ) ); \
106 p_es = (es_descriptor_t*)user_data; \
108 input_ToggleES( p_intf->p_input, p_es, menuitem->active ); \
110 p_intf->p_sys->b_update = menuitem->active; \
112 if( p_intf->p_sys->b_update ) \
114 GtkLanguageMenus( p_intf, p_menu, p_es, type, callback ); \
117 p_intf->p_sys->b_update = 0; \
124 void GtkMenubarAudioToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
126 GtkLangToggle( "intf_window", p_popup
, "popup_audio", AUDIO_ES
,
127 GtkPopupAudioToggle
, b_audio_update
);
130 void GtkPopupAudioToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
132 GtkLangToggle( "intf_popup", p_window
, "menubar_audio", AUDIO_ES
,
133 GtkMenubarAudioToggle
, b_audio_update
);
140 void GtkMenubarSubtitleToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
142 GtkLangToggle( "intf_window", p_popup
, "popup_subpictures", SPU_ES
,
143 GtkPopupSubtitleToggle
, b_spu_update
);
146 void GtkPopupSubtitleToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
148 GtkLangToggle( "intf_popup", p_window
, "menubar_subpictures", SPU_ES
,
149 GtkMenubarSubtitleToggle
, b_spu_update
);
158 void GtkPopupNavigationToggle( GtkCheckMenuItem
* menuitem
,
161 intf_thread_t
* p_intf
= GetIntf( GTK_WIDGET(menuitem
), "intf_popup" );
163 if( menuitem
->active
&&
164 !p_intf
->p_sys
->b_title_update
&&
165 !p_intf
->p_sys
->b_chapter_update
)
167 input_area_t
*p_area
;
169 gint i_title
= DATA2TITLE( user_data
);
170 gint i_chapter
= DATA2CHAPTER( user_data
);
172 p_area
= p_intf
->p_input
->stream
.p_selected_area
;
174 if( p_area
!= p_intf
->p_input
->stream
.pp_areas
[i_title
] )
176 p_area
= p_intf
->p_input
->stream
.pp_areas
[i_title
];
177 p_intf
->p_sys
->b_title_update
= 1;
180 p_area
->i_part
= i_chapter
;
182 input_ChangeArea( p_intf
->p_input
, (input_area_t
*)p_area
);
184 p_intf
->p_sys
->b_chapter_update
= 1;
185 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);
186 GtkSetupMenus( p_intf
);
187 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
189 input_SetStatus( p_intf
->p_input
, INPUT_STATUS_PLAY
);
197 void GtkMenubarTitleToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
199 intf_thread_t
* p_intf
= GetIntf( GTK_WIDGET(menuitem
), "intf_window" );
201 if( menuitem
->active
&& !p_intf
->p_sys
->b_title_update
)
203 gint i_title
= (gint
)user_data
;
204 input_ChangeArea( p_intf
->p_input
,
205 p_intf
->p_input
->stream
.pp_areas
[i_title
] );
207 p_intf
->p_sys
->b_title_update
= 1;
208 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);
209 GtkSetupMenus( p_intf
);
210 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
211 p_intf
->p_sys
->b_title_update
= 0;
213 input_SetStatus( p_intf
->p_input
, INPUT_STATUS_PLAY
);
222 void GtkMenubarChapterToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
224 intf_thread_t
* p_intf
;
225 input_area_t
* p_area
;
228 GtkWidget
* p_popup_menu
;
230 p_intf
= GetIntf( GTK_WIDGET(menuitem
), "intf_window" );
231 p_area
= p_intf
->p_input
->stream
.p_selected_area
;
232 i_chapter
= (gint
)user_data
;
234 if( menuitem
->active
&& !p_intf
->p_sys
->b_chapter_update
)
236 p_area
->i_part
= i_chapter
;
237 input_ChangeArea( p_intf
->p_input
, (input_area_t
*)p_area
);
239 snprintf( psz_chapter
, 4, "%02d", p_area
->i_part
);
240 psz_chapter
[ 4 ] = '\0';
241 gtk_label_set_text( p_intf
->p_sys
->p_label_chapter
, psz_chapter
);
243 p_intf
->p_sys
->b_chapter_update
= 1;
244 p_popup_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
245 p_intf
->p_sys
->p_popup
), "popup_navigation" ) );
247 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);
248 GtkTitleMenu( p_intf
, p_popup_menu
, GtkPopupNavigationToggle
);
249 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
251 p_intf
->p_sys
->b_chapter_update
= 0;
253 input_SetStatus( p_intf
->p_input
, INPUT_STATUS_PLAY
);
262 #define GtkAngleToggle( intf, window, menu, callback ) \
263 intf_thread_t * p_intf; \
264 GtkWidget * p_menu; \
265 input_area_t * p_area; \
267 p_intf = GetIntf( GTK_WIDGET(menuitem), (intf) ); \
269 if( menuitem->active && !p_intf->p_sys->b_angle_update ) \
271 p_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( \
272 p_intf->p_sys->window ), (menu) ) ); \
273 p_area = p_intf->p_input->stream.p_selected_area; \
274 p_area->i_angle = (gint)user_data; \
276 input_ChangeArea( p_intf->p_input, (input_area_t*)p_area ); \
278 p_intf->p_sys->b_angle_update = 1; \
279 vlc_mutex_lock( &p_intf->p_input->stream.stream_lock ); \
280 GtkRadioMenu( p_intf, p_menu, NULL, "Angle", \
281 p_area->i_angle_nb, p_area->i_angle, (callback) ); \
282 vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock ); \
283 p_intf->p_sys->b_angle_update = 0; \
286 void GtkMenubarAngleToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
288 GtkAngleToggle( "intf_window", p_popup
, "popup_angle",
289 GtkPopupAngleToggle
);
292 void GtkPopupAngleToggle( GtkCheckMenuItem
* menuitem
, gpointer user_data
)
294 GtkAngleToggle( "intf_popup", p_window
, "menubar_angle",
295 GtkMenubarAngleToggle
);
298 #undef GtkAngleToggle
300 /****************************************************************************
301 * Functions to generate menus
302 ****************************************************************************/
304 /*****************************************************************************
305 * GtkRadioMenu: update interactive menus of the interface
306 *****************************************************************************
307 * Sets up menus with information from input
308 * Warning: since this function is designed to be called by management
309 * function, the interface lock has to be taken
310 *****************************************************************************/
311 static gint
GtkRadioMenu( intf_thread_t
* p_intf
,
312 GtkWidget
* p_root
, GSList
* p_menu_group
,
313 char * psz_item_name
,
314 int i_nb
, int i_selected
,
315 void( *pf_toggle
)( GtkCheckMenuItem
*, gpointer
) )
317 char psz_name
[ GTK_MENU_LABEL_SIZE
];
319 GtkWidget
* p_submenu
;
320 GtkWidget
* p_item_group
;
322 GtkWidget
* p_item_selected
;
326 /* temporary hack to avoid blank menu when an open menu is removed */
327 if( GTK_MENU_ITEM(p_root
)->submenu
!= NULL
)
329 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root
)->submenu
) );
331 /* removes previous menu */
332 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root
) );
333 gtk_widget_set_sensitive( p_root
, FALSE
);
337 p_item_selected
= NULL
;
338 p_group
= p_menu_group
;
340 p_menu
= gtk_menu_new();
342 for( i_item
= 0 ; i_item
< i_nb
; i_item
++ )
344 /* we group chapters in packets of ten for small screens */
345 if( ( i_item
% 10 == 0 ) && ( i_nb
> 20 ) )
349 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_item_group
),
351 gtk_menu_append( GTK_MENU( p_menu
), p_item_group
);
354 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
,
355 "%ss %d to %d", psz_item_name
, i_item
+ 1, i_item
+ 10);
356 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
357 p_item_group
= gtk_menu_item_new_with_label( psz_name
);
358 gtk_widget_show( p_item_group
);
359 p_submenu
= gtk_menu_new();
362 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
, "%s %d",
363 psz_item_name
, i_item
+ 1 );
364 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
366 p_item
= gtk_radio_menu_item_new_with_label( p_group
, psz_name
);
367 p_group
= gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item
) );
369 if( i_selected
== i_item
+ 1 )
371 p_item_selected
= p_item
;
374 gtk_widget_show( p_item
);
376 /* setup signal hanling */
377 gtk_signal_connect( GTK_OBJECT( p_item
),
379 GTK_SIGNAL_FUNC( pf_toggle
),
380 (gpointer
)(i_item
+ 1) );
384 gtk_menu_append( GTK_MENU( p_submenu
), p_item
);
388 gtk_menu_append( GTK_MENU( p_menu
), p_item
);
394 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_item_group
), p_submenu
);
395 gtk_menu_append( GTK_MENU( p_menu
), p_item_group
);
398 /* link the new menu to the title menu item */
399 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root
), p_menu
);
401 /* toggle currently selected chapter
402 * We have to release the lock since input_ToggleES needs it */
403 if( p_item_selected
!= NULL
)
405 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
406 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_selected
),
408 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);
411 /* be sure that menu is sensitive, if there are several items */
414 gtk_widget_set_sensitive( p_root
, TRUE
);
420 /*****************************************************************************
421 * GtkLanguageMenus: update interactive menus of the interface
422 *****************************************************************************
423 * Sets up menus with information from input:
426 * Warning: since this function is designed to be called by management
427 * function, the interface lock has to be taken
428 *****************************************************************************/
429 static gint
GtkLanguageMenus( gpointer p_data
,
431 es_descriptor_t
* p_es
,
433 void(*pf_toggle
)( GtkCheckMenuItem
*, gpointer
) )
435 intf_thread_t
* p_intf
;
437 GtkWidget
* p_separator
;
439 GtkWidget
* p_item_active
;
441 char psz_name
[ GTK_MENU_LABEL_SIZE
];
448 p_intf
= (intf_thread_t
*)p_data
;
450 /* temporary hack to avoid blank menu when an open menu is removed */
451 if( GTK_MENU_ITEM(p_root
)->submenu
!= NULL
)
453 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root
)->submenu
) );
455 /* removes previous menu */
456 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root
) );
457 gtk_widget_set_sensitive( p_root
, FALSE
);
462 p_menu
= gtk_menu_new();
464 /* special case for "off" item */
465 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
, "None" );
466 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
468 p_item
= gtk_radio_menu_item_new_with_label( p_group
, psz_name
);
469 p_group
= gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item
) );
471 gtk_widget_show( p_item
);
473 /* signal hanling for off */
474 gtk_signal_connect( GTK_OBJECT( p_item
), "toggled",
475 GTK_SIGNAL_FUNC ( pf_toggle
), NULL
);
477 gtk_menu_append( GTK_MENU( p_menu
), p_item
);
479 p_separator
= gtk_menu_item_new();
480 gtk_widget_set_sensitive( p_separator
, FALSE
);
481 gtk_widget_show( p_separator
);
482 gtk_menu_append( GTK_MENU( p_menu
), p_separator
);
484 p_item_active
= NULL
;
487 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);
489 /* create a set of language buttons and append them to the container */
490 for( i
= 0 ; i
< p_intf
->p_input
->stream
.i_es_number
; i
++ )
492 if( p_intf
->p_input
->stream
.pp_es
[i
]->i_cat
== i_cat
)
495 strcpy( psz_name
, p_intf
->p_input
->stream
.pp_es
[i
]->psz_desc
);
496 if( psz_name
[0] == '\0' )
498 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
,
499 "Language %d", i_item
);
500 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
503 p_item
= gtk_radio_menu_item_new_with_label( p_group
, psz_name
);
505 gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item
) );
507 if( p_es
== p_intf
->p_input
->stream
.pp_es
[i
] )
509 /* don't lose p_item when we append into menu */
510 p_item_active
= p_item
;
513 gtk_widget_show( p_item
);
515 /* setup signal hanling */
516 gtk_signal_connect( GTK_OBJECT( p_item
), "toggled",
517 GTK_SIGNAL_FUNC( pf_toggle
),
518 (gpointer
)( p_intf
->p_input
->stream
.pp_es
[i
] ) );
520 gtk_menu_append( GTK_MENU( p_menu
), p_item
);
524 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
526 /* link the new menu to the menubar item */
527 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root
), p_menu
);
529 /* acitvation will call signals so we can only do it
530 * when submenu is attached to menu - to get intf_window
531 * We have to release the lock since input_ToggleES needs it */
532 if( p_item_active
!= NULL
)
534 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active
),
538 /* be sure that menu is sensitive if non empty */
541 gtk_widget_set_sensitive( p_root
, TRUE
);
547 /*****************************************************************************
548 * GtkTitleMenu: sets menus for titles and chapters selection
549 *****************************************************************************
550 * Generates two types of menus:
551 * -simple list of titles
552 * -cascaded lists of chapters for each title
553 *****************************************************************************/
554 static gint
GtkTitleMenu( gpointer p_data
,
555 GtkWidget
* p_navigation
,
556 void(*pf_toggle
)( GtkCheckMenuItem
*, gpointer
) )
558 intf_thread_t
* p_intf
;
559 char psz_name
[ GTK_MENU_LABEL_SIZE
];
560 GtkWidget
* p_title_menu
;
561 GtkWidget
* p_title_submenu
;
562 GtkWidget
* p_title_item
;
563 GtkWidget
* p_item_active
;
564 GtkWidget
* p_chapter_menu
;
565 GtkWidget
* p_chapter_submenu
;
566 GtkWidget
* p_title_menu_item
;
567 GtkWidget
* p_chapter_menu_item
;
569 GSList
* p_title_group
;
570 GSList
* p_chapter_group
;
577 p_intf
= (intf_thread_t
*)p_data
;
579 /* temporary hack to avoid blank menu when an open menu is removed */
580 if( GTK_MENU_ITEM(p_navigation
)->submenu
!= NULL
)
582 gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_navigation
)->submenu
) );
584 /* removes previous menu */
585 gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_navigation
) );
586 gtk_widget_set_sensitive( p_navigation
, FALSE
);
588 p_title_menu
= gtk_menu_new();
589 p_title_group
= NULL
;
590 p_title_submenu
= NULL
;
591 p_title_menu_item
= NULL
;
592 p_chapter_group
= NULL
;
593 p_chapter_submenu
= NULL
;
594 p_chapter_menu_item
= NULL
;
595 p_item_active
= NULL
;
596 i_title_nb
= p_intf
->p_input
->stream
.i_area_nb
;
599 for( i_title
= 1 ; i_title
< i_title_nb
; i_title
++ )
601 /* we group titles in packets of ten for small screens */
602 if( ( i_title
% 10 == 1 ) && ( i_title_nb
> 20 ) )
606 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item
),
608 gtk_menu_append( GTK_MENU( p_title_menu
), p_title_menu_item
);
611 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
,
612 "%d - %d", i_title
, i_title
+ 9 );
613 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
614 p_title_menu_item
= gtk_menu_item_new_with_label( psz_name
);
615 gtk_widget_show( p_title_menu_item
);
616 p_title_submenu
= gtk_menu_new();
619 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
, "Title %d (%d)", i_title
,
620 p_intf
->p_input
->stream
.pp_areas
[i_title
]->i_part_nb
);
621 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
623 if( pf_toggle
== on_menubar_title_toggle
)
625 p_title_item
= gtk_radio_menu_item_new_with_label( p_title_group
,
628 gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_title_item
) );
630 if( p_intf
->p_input
->stream
.pp_areas
[i_title
] ==
631 p_intf
->p_input
->stream
.p_selected_area
)
633 p_item_active
= p_title_item
;
636 /* setup signal hanling */
637 gtk_signal_connect( GTK_OBJECT( p_title_item
),
639 GTK_SIGNAL_FUNC( pf_toggle
),
640 (gpointer
)(p_intf
->p_input
->stream
.pp_areas
[i_title
]) );
642 if( p_intf
->p_input
->stream
.i_area_nb
> 1 )
644 /* be sure that menu is sensitive */
645 gtk_widget_set_sensitive( p_navigation
, TRUE
);
651 p_title_item
= gtk_menu_item_new_with_label( psz_name
);
654 p_chapter_menu
= gtk_menu_new();
656 p_intf
->p_input
->stream
.pp_areas
[i_title
]->i_part_nb
;
658 for( i_chapter
= 0 ; i_chapter
< i_chapter_nb
; i_chapter
++ )
660 /* we group chapters in packets of ten for small screens */
661 if( ( i_chapter
% 10 == 0 ) && ( i_chapter_nb
> 20 ) )
665 gtk_menu_item_set_submenu(
666 GTK_MENU_ITEM( p_chapter_menu_item
),
668 gtk_menu_append( GTK_MENU( p_chapter_menu
),
669 p_chapter_menu_item
);
672 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
,
673 "%d - %d", i_chapter
+ 1, i_chapter
+ 10 );
674 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
675 p_chapter_menu_item
=
676 gtk_menu_item_new_with_label( psz_name
);
677 gtk_widget_show( p_chapter_menu_item
);
678 p_chapter_submenu
= gtk_menu_new();
681 snprintf( psz_name
, GTK_MENU_LABEL_SIZE
,
682 "Chapter %d", i_chapter
+ 1 );
683 psz_name
[ GTK_MENU_LABEL_SIZE
- 1 ] = '\0';
685 p_item
= gtk_radio_menu_item_new_with_label(
686 p_chapter_group
, psz_name
);
687 p_chapter_group
= gtk_radio_menu_item_group(
688 GTK_RADIO_MENU_ITEM( p_item
) );
689 gtk_widget_show( p_item
);
691 #define p_area p_intf->p_input->stream.pp_areas[i_title]
692 if( ( p_area
== p_intf
->p_input
->stream
.p_selected_area
) &&
693 ( p_area
->i_part
== i_chapter
+ 1 ) )
695 p_item_active
= p_item
;
699 /* setup signal hanling */
700 gtk_signal_connect( GTK_OBJECT( p_item
),
702 GTK_SIGNAL_FUNC( pf_toggle
),
703 (gpointer
)POS2DATA( i_title
, i_chapter
+ 1) );
705 if( i_chapter_nb
> 20 )
707 gtk_menu_append( GTK_MENU( p_chapter_submenu
), p_item
);
711 gtk_menu_append( GTK_MENU( p_chapter_menu
), p_item
);
715 if( i_chapter_nb
> 20 )
717 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_chapter_menu_item
),
719 gtk_menu_append( GTK_MENU( p_chapter_menu
),
720 p_chapter_menu_item
);
723 /* link the new menu to the title menu item */
724 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_item
),
727 if( p_intf
->p_input
->stream
.pp_areas
[i_title
]->i_part_nb
> 1 )
729 /* be sure that menu is sensitive */
730 gtk_widget_set_sensitive( p_navigation
, TRUE
);
733 GtkRadioMenu( p_intf
, p_title_item
, p_chapter_group
, "Chapter",
734 p_intf
->p_input
->stream
.pp_areas
[i_title
]->i_part_nb
,
736 p_intf
->p_input
->stream
.p_selected_area
->i_part
+
737 p_intf
->p_input
->stream
.p_selected_area
->i_id
*100,
742 gtk_widget_show( p_title_item
);
744 if( i_title_nb
> 20 )
746 gtk_menu_append( GTK_MENU( p_title_submenu
), p_title_item
);
750 gtk_menu_append( GTK_MENU( p_title_menu
), p_title_item
);
754 if( i_title_nb
> 20 )
756 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item
),
758 gtk_menu_append( GTK_MENU( p_title_menu
), p_title_menu_item
);
761 /* be sure that menu is sensitive */
762 gtk_widget_set_sensitive( p_title_menu
, TRUE
);
764 /* link the new menu to the menubar item */
765 gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_navigation
), p_title_menu
);
767 /* Default selected chapter
768 * We have to release the lock since input_ToggleES needs it */
769 if( p_item_active
!= NULL
)
771 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
772 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active
),
774 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);
777 if( p_intf
->p_input
->stream
.i_area_nb
> 1 )
779 /* be sure that menu is sensitive */
780 gtk_widget_set_sensitive( p_navigation
, TRUE
);
787 /*****************************************************************************
788 * GtkSetupMenus: function that generates title/chapter/audio/subpic
789 * menus with help from preceding functions
790 *****************************************************************************/
791 gint
GtkSetupMenus( intf_thread_t
* p_intf
)
793 es_descriptor_t
* p_audio_es
;
794 es_descriptor_t
* p_spu_es
;
795 GtkWidget
* p_menubar_menu
;
796 GtkWidget
* p_popup_menu
;
799 p_intf
->p_sys
->b_chapter_update
|= p_intf
->p_sys
->b_title_update
;
800 p_intf
->p_sys
->b_angle_update
|= p_intf
->p_sys
->b_title_update
;
801 p_intf
->p_sys
->b_audio_update
|= p_intf
->p_sys
->b_title_update
;
802 p_intf
->p_sys
->b_spu_update
|= p_intf
->p_sys
->b_title_update
;
804 // vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
806 if( p_intf
->p_sys
->b_title_update
)
810 p_menubar_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
811 p_intf
->p_sys
->p_window
), "menubar_title" ) );
812 GtkRadioMenu( p_intf
, p_menubar_menu
, NULL
, "Title",
813 p_intf
->p_input
->stream
.i_area_nb
- 1,
814 p_intf
->p_input
->stream
.p_selected_area
->i_id
,
815 GtkMenubarTitleToggle
);
817 snprintf( psz_title
, 4, "%d",
818 p_intf
->p_input
->stream
.p_selected_area
->i_id
);
819 psz_title
[ 4 ] = '\0';
820 gtk_label_set_text( p_intf
->p_sys
->p_label_title
, psz_title
);
822 p_intf
->p_sys
->b_title_update
= 0;
825 if( p_intf
->p_sys
->b_chapter_update
)
829 p_popup_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
830 p_intf
->p_sys
->p_popup
), "popup_navigation" ) );
831 GtkTitleMenu( p_intf
, p_popup_menu
, GtkPopupNavigationToggle
);
833 GtkRadioMenu( p_intf
, p_menubar_menu
, NULL
, "Title",
834 p_intf
->p_input
->stream
.i_area_nb
- 1,
835 p_intf
->p_input
->stream
.p_selected_area
->i_id
,
836 on_menubar_chapter_toggle
);
839 p_menubar_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
840 p_intf
->p_sys
->p_window
), "menubar_chapter" ) );
841 GtkRadioMenu( p_intf
, p_menubar_menu
, NULL
, "Chapter",
842 p_intf
->p_input
->stream
.p_selected_area
->i_part_nb
,
843 p_intf
->p_input
->stream
.p_selected_area
->i_part
,
844 GtkMenubarChapterToggle
);
847 snprintf( psz_chapter
, 4, "%d",
848 p_intf
->p_input
->stream
.p_selected_area
->i_part
);
849 psz_chapter
[ 4 ] = '\0';
850 gtk_label_set_text( p_intf
->p_sys
->p_label_chapter
, psz_chapter
);
852 p_intf
->p_sys
->i_part
=
853 p_intf
->p_input
->stream
.p_selected_area
->i_part
;
855 p_intf
->p_sys
->b_chapter_update
= 0;
858 if( p_intf
->p_sys
->b_angle_update
)
860 p_menubar_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
861 p_intf
->p_sys
->p_window
), "menubar_angle" ) );
862 GtkRadioMenu( p_intf
, p_menubar_menu
, NULL
, "Angle",
863 p_intf
->p_input
->stream
.p_selected_area
->i_angle_nb
,
864 p_intf
->p_input
->stream
.p_selected_area
->i_angle
,
865 GtkMenubarAngleToggle
);
867 p_popup_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
868 p_intf
->p_sys
->p_popup
), "popup_angle" ) );
869 GtkRadioMenu( p_intf
, p_popup_menu
, NULL
, "Angle",
870 p_intf
->p_input
->stream
.p_selected_area
->i_angle_nb
,
871 p_intf
->p_input
->stream
.p_selected_area
->i_angle
,
872 GtkPopupAngleToggle
);
874 p_intf
->p_sys
->b_angle_update
= 0;
877 /* look for selected ES */
881 for( i
= 0 ; i
< p_intf
->p_input
->stream
.i_selected_es_number
; i
++ )
883 if( p_intf
->p_input
->stream
.pp_selected_es
[i
]->i_cat
== AUDIO_ES
)
885 p_audio_es
= p_intf
->p_input
->stream
.pp_selected_es
[i
];
888 if( p_intf
->p_input
->stream
.pp_selected_es
[i
]->i_cat
== SPU_ES
)
890 p_spu_es
= p_intf
->p_input
->stream
.pp_selected_es
[i
];
894 vlc_mutex_unlock( &p_intf
->p_input
->stream
.stream_lock
);
897 if( p_intf
->p_sys
->b_audio_update
)
899 /* find audio root menu */
900 p_menubar_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
901 p_intf
->p_sys
->p_window
), "menubar_audio" ) );
903 p_popup_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
904 p_intf
->p_sys
->p_popup
), "popup_audio" ) );
906 p_intf
->p_sys
->b_audio_update
= 1;
907 GtkLanguageMenus( p_intf
, p_menubar_menu
, p_audio_es
, AUDIO_ES
,
908 GtkMenubarAudioToggle
);
909 p_intf
->p_sys
->b_audio_update
= 1;
910 GtkLanguageMenus( p_intf
, p_popup_menu
, p_audio_es
, AUDIO_ES
,
911 GtkPopupAudioToggle
);
913 p_intf
->p_sys
->b_audio_update
= 0;
916 /* sub picture menus */
917 if( p_intf
->p_sys
->b_spu_update
)
919 /* find spu root menu */
920 p_menubar_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
921 p_intf
->p_sys
->p_window
), "menubar_subpictures" ) );
923 p_popup_menu
= GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
924 p_intf
->p_sys
->p_popup
), "popup_subpictures" ) );
926 p_intf
->p_sys
->b_spu_update
= 1;
927 GtkLanguageMenus( p_intf
, p_menubar_menu
, p_spu_es
, SPU_ES
,
928 GtkMenubarSubtitleToggle
);
929 p_intf
->p_sys
->b_spu_update
= 1;
930 GtkLanguageMenus( p_intf
, p_popup_menu
, p_spu_es
, SPU_ES
,
931 GtkPopupSubtitleToggle
);
933 p_intf
->p_sys
->b_spu_update
= 0;
936 vlc_mutex_lock( &p_intf
->p_input
->stream
.stream_lock
);