menu.c
来自「VLC媒体播放程序」· C语言 代码 · 共 1,580 行 · 第 1/4 页
C
1,580 行
/***************************************************************************** * menu.c : functions to handle menu items. ***************************************************************************** * Copyright (C) 2000, 2001 VideoLAN * $Id: menu.c,v 1.13 2003/12/22 14:32:56 sam Exp $ * * 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, 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; \ \ input_ToggleES( p_intf->p_sys->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 = VLC_FALSE; \ }/* * Audio */void GtkMenubarAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_popup, "popup_language", AUDIO_ES, GtkPopupAudioToggle, b_audio_update );}void GtkPopupAudioToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_window, "menubar_audio", AUDIO_ES, GtkMenubarAudioToggle, b_audio_update );}/* * Subtitles */void GtkMenubarSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_popup, "popup_subpictures", SPU_ES, GtkPopupSubtitleToggle, b_spu_update );}void GtkPopupSubtitleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ){ GTKLANGTOGGLE( p_window, "menubar_subpictures", 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 ); vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); p_area = p_intf->p_sys->p_input->stream.p_selected_area; i_title = __MIN( i_title, p_intf->p_sys->p_input->stream.i_area_nb - 1 ); i_title = __MAX( i_title, 1 ); if( p_area != p_intf->p_sys->p_input->stream.pp_areas[i_title] ) { p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title]; p_intf->p_sys->b_title_update = VLC_TRUE; } i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 ); i_chapter = __MAX( i_chapter, 1 ); p_area->i_part = i_chapter; vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 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 ); input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); }}/* * 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; \ \ input_ChangeProgram( p_intf->p_sys->p_input, 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; \ \ input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); \ }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; vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); i_title = __MIN( i_title, p_intf->p_sys->p_input->stream.i_area_nb - 1 ); i_title = __MAX( i_title, 1 ); vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); input_ChangeArea( p_intf->p_sys->p_input, p_intf->p_sys->p_input->stream.pp_areas[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 ); p_intf->p_sys->b_title_update = VLC_FALSE; input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); }}/* * 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 ) { vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 ); i_chapter = __MAX( i_chapter, 1 ); p_area->i_part = i_chapter; vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 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; input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); }}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, "filter" ); if( !strcmp( psz_mode, "None" ) ) { config_PutPsz( p_intf, "filter", "" ); } else { if( !psz_filter || !*psz_filter ) { config_PutPsz( p_intf, "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, "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 ); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?