📄 menu.c
字号:
/***************************************************************************** * menu.c : functions to handle menu items. ***************************************************************************** * Copyright (C) 2000, 2001 VideoLAN * $Id: menu.c 10469 2005-03-28 23:23:51Z hartman $ * * Authors: Sam Hocevar <sam@zoy.org> * St閜hane Borel <stef@via.ecp.fr> * Johan Bilien <jobi@via.ecp.fr> * Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <sys/types.h> /* off_t */#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/input.h>#include <vlc/intf.h>#include <vlc/aout.h>#include <vlc/vout.h>#ifdef MODULE_NAME_IS_gnome# include <gnome.h>#else# include <gtk/gtk.h>#endif#include <string.h>#include "gtk_callbacks.h"#include "gtk_interface.h"#include "gtk_support.h"#include "playlist.h"#include "common.h"/* * 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, int, void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) );static void GtkMenubarDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data );static void GtkPopupDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data );static gint GtkDeinterlaceMenus( gpointer p_data, GtkWidget * p_root, void(*pf_toggle )( 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_* and we need to refresh the other menu. ****************************************************************************/#define GTKLANGTOGGLE( window, menu, type, var_name, callback, b_update )\ intf_thread_t * p_intf; \ GtkWidget * p_menu; \ es_descriptor_t * p_es; \ \ p_intf = GtkGetIntf( menuitem ); \ \ 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; \ if( p_es && menuitem->active ) \ var_SetInteger( p_intf->p_sys->p_input, var_name, p_es->i_id ); \ else \ var_SetInteger( p_intf->p_sys->p_input, var_name, -1 ); \ \ 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 = VLC_FALSE; \ }/* * Audio */void GtkMenubarAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_popup, "popup_language", AUDIO_ES, "audio-es", GtkPopupAudioToggle, b_audio_update );}void GtkPopupAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_window, "menubar_audio", AUDIO_ES, "audio-es", GtkMenubarAudioToggle, b_audio_update );}/* * Subtitles */void GtkMenubarSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_popup, "popup_subpictures", SPU_ES, "spu-es", GtkPopupSubtitleToggle, b_spu_update );}void GtkPopupSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_window, "menubar_subpictures", SPU_ES, "spu-es", GtkMenubarSubtitleToggle, b_spu_update );}#undef GTKLANGTOGGLE/* * Navigation */void GtkPopupNavigationToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ intf_thread_t * p_intf = GtkGetIntf( menuitem ); if( menuitem->active && !p_intf->p_sys->b_title_update && !p_intf->p_sys->b_chapter_update ) { input_area_t *p_area; guint i_title = DATA2TITLE( user_data ); guint i_chapter = DATA2CHAPTER( user_data ); /* FIXME use "navigation" variable */ var_SetInteger( p_intf->p_sys->p_input, "title", i_title ); var_SetInteger( p_intf->p_sys->p_input, "chapter", i_chapter ); p_intf->p_sys->b_title_update = VLC_TRUE; p_intf->p_sys->b_chapter_update = VLC_TRUE; vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); GtkSetupMenus( p_intf ); vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); }}/* * Program */#define GTKPROGRAMTOGGLE( ) \ intf_thread_t * p_intf = GtkGetIntf( menuitem ); \ \ if( menuitem->active && !p_intf->p_sys->b_program_update ) \ { \ int i_program_id = (ptrdiff_t)user_data; \ \ var_SetInteger( p_intf->p_sys->p_input, "program", i_program_id ); \ \ p_intf->p_sys->b_program_update = VLC_TRUE; \ \ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); \ GtkSetupMenus( p_intf ); \ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); \ \ p_intf->p_sys->b_program_update = VLC_FALSE; \ \ var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S ); \ }void GtkMenubarProgramToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKPROGRAMTOGGLE( );}void GtkPopupProgramToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKPROGRAMTOGGLE( );}/* * Title */void GtkMenubarTitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ intf_thread_t * p_intf = GtkGetIntf( menuitem ); if( menuitem->active && !p_intf->p_sys->b_title_update ) { guint i_title = (ptrdiff_t)user_data; var_SetInteger( p_intf->p_sys->p_input, "title", i_title ); p_intf->p_sys->b_title_update = VLC_TRUE; vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); GtkSetupMenus( p_intf ); vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); }}/* * Chapter */void GtkMenubarChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ intf_thread_t * p_intf; input_area_t * p_area; guint i_chapter; GtkWidget * p_popup_menu; p_intf = GtkGetIntf( menuitem ); p_area = p_intf->p_sys->p_input->stream.p_selected_area; i_chapter = (ptrdiff_t)user_data; if( menuitem->active && !p_intf->p_sys->b_chapter_update ) { var_SetInteger( p_intf->p_sys->p_input, "chapter", i_chapter ); p_intf->p_sys->b_chapter_update = VLC_TRUE; 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_sys->p_input->stream.stream_lock ); GtkTitleMenu( p_intf, p_popup_menu, GtkPopupNavigationToggle ); vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); p_intf->p_sys->b_chapter_update = VLC_FALSE; }}static void GtkPopupObjectToggle( GtkCheckMenuItem * menuitem, gpointer user_data, int i_object_type, char *psz_variable ){ intf_thread_t *p_intf = GtkGetIntf( menuitem ); GtkLabel *p_label; p_label = GTK_LABEL( ( GTK_BIN( menuitem )->child ) ); if( menuitem->active && !p_intf->p_sys->b_aout_update && !p_intf->p_sys->b_vout_update ) { vlc_object_t * p_obj; p_obj = (vlc_object_t *)vlc_object_find( p_intf, i_object_type, FIND_ANYWHERE ); if( p_obj ) { vlc_value_t val; if( user_data ) { val = (vlc_value_t)user_data; } else { gtk_label_get( p_label, &val.psz_string ); } if( var_Set( p_obj, psz_variable, val ) < 0 ) { msg_Warn( p_obj, "cannot set variable (%s)", val.psz_string ); } vlc_object_release( p_obj ); } }}static void GtkPopupAoutChannelsToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GtkPopupObjectToggle( menuitem, user_data, VLC_OBJECT_AOUT, "audio-channels" );}static void GtkPopupAoutDeviceToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GtkPopupObjectToggle( menuitem, user_data, VLC_OBJECT_AOUT, "audio-device" );}static void GtkPopupVoutDeviceToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GtkPopupObjectToggle( menuitem, user_data, VLC_OBJECT_VOUT, "video-device" );}static void GtkDeinterlaceUpdate( intf_thread_t *p_intf, char *psz_mode ){ char *psz_filter; unsigned int i; psz_filter = config_GetPsz( p_intf, "vout-filter" ); if( !strcmp( psz_mode, "None" ) ) { config_PutPsz( p_intf, "vout-filter", "" ); } else { if( !psz_filter || !*psz_filter ) { config_PutPsz( p_intf, "vout-filter", "deinterlace" ); } else { if( strstr( psz_filter, "deinterlace" ) == NULL ) { psz_filter = realloc( psz_filter, strlen( psz_filter ) + 20 ); strcat( psz_filter, ",deinterlace" ); } config_PutPsz( p_intf, "vout-filter", psz_filter ); } } if( psz_filter ) free( psz_filter ); /* now restart all video stream */ if( p_intf->p_sys->p_input ) { vout_thread_t *p_vout; vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); /* Warn the vout we are about to change the filter chain */ p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout ) { p_vout->b_filter_change = VLC_TRUE; vlc_object_release( p_vout ); }#define ES p_intf->p_sys->p_input->stream.pp_es[i] /* create a set of language buttons and append them to the container */ for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_es_number ; i++ ) { if( ( ES->i_cat == VIDEO_ES ) && ES->p_dec != NULL ) { input_UnselectES( p_intf->p_sys->p_input, ES ); input_SelectES( p_intf->p_sys->p_input, ES ); }#undef ES } vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); } if( strcmp( psz_mode, "None" ) ) { vout_thread_t *p_vout; p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout ) { vlc_value_t val; val.psz_string = psz_mode; if( var_Set( p_vout, "deinterlace-mode", val ) != VLC_SUCCESS )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -