Commit 68126455 authored by Clément Stenac's avatar Clément Stenac

Remove gtk, gtk2, qt and kde plugins

If you want them, take them back from the svn attic, fix them and reintroduce them. I didn't remove the configure.ac snippets, they are still in but commented
parent 063cb8b6
...@@ -4568,12 +4568,8 @@ AC_CONFIG_FILES([ ...@@ -4568,12 +4568,8 @@ AC_CONFIG_FILES([
modules/gui/Makefile modules/gui/Makefile
modules/gui/beos/Makefile modules/gui/beos/Makefile
modules/gui/pda/Makefile modules/gui/pda/Makefile
modules/gui/gtk/Makefile
modules/gui/gtk2/Makefile
modules/gui/kde/Makefile
modules/gui/macosx/Makefile modules/gui/macosx/Makefile
modules/gui/qnx/Makefile modules/gui/qnx/Makefile
modules/gui/qt/Makefile
modules/gui/skins2/Makefile modules/gui/skins2/Makefile
modules/gui/wxwidgets/Makefile modules/gui/wxwidgets/Makefile
modules/gui/wince/Makefile modules/gui/wince/Makefile
......
COMMON_gtk = \
display.c \
open.c \
sout.c \
control.c \
menu.c \
playlist.c \
modules.c \
preferences.c \
gtk_callbacks.c \
$(NULL)
SOURCES_gtk = \
gtk.c \
gtk_interface.c \
gtk_support.c \
$(COMMON_gtk)
SOURCES_gnome = \
gnome.c \
gnome_interface.c \
gnome_support.c \
$(COMMON_gtk)
noinst_HEADERS += \
common.h \
control.h \
gnome_callbacks.h \
gnome_interface.h \
gnome_support.h \
gtk_callbacks.h \
display.h \
menu.h \
modules.h \
open.h \
gtk_interface.h \
playlist.h \
preferences.h \
gtk_support.h \
$(NULL)
EXTRA_DIST += \
gtk.glade \
gnome.glade \
gnome_callbacks.c \
$(NULL)
/*****************************************************************************
* gtk_common.h: private Gtk+ interface description
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* Drag'n'drop stuff
*****************************************************************************/
#define DROP_ACCEPT_TEXT_URI_LIST 0
#define DROP_ACCEPT_TEXT_PLAIN 1
#define DROP_ACCEPT_STRING 2
#define DROP_ACCEPT_END 3
/*****************************************************************************
* intf_sys_t: description and status of Gtk+ interface
*****************************************************************************/
struct intf_sys_t
{
/* the gtk_main module */
module_t * p_gtk_main;
/* special actions */
vlc_bool_t b_playing;
vlc_bool_t b_popup_changed; /* display menu ? */
vlc_bool_t b_window_changed; /* window display toggled ? */
vlc_bool_t b_playlist_changed; /* playlist display toggled ? */
vlc_bool_t b_slider_free; /* slider status */
vlc_bool_t b_deinterlace_update;
/* menus handlers */
vlc_bool_t b_aout_update;
vlc_bool_t b_vout_update;
vlc_bool_t b_program_update; /* do we need to update programs
menu */
vlc_bool_t b_title_update; /* do we need to update title menus */
vlc_bool_t b_chapter_update; /* do we need to update
chapter menus */
vlc_bool_t b_audio_update; /* do we need to update audio menus */
vlc_bool_t b_spu_update; /* do we need to update spu menus */
/* windows and widgets */
GtkWidget * p_window; /* main window */
GtkWidget * p_popup; /* popup menu */
GtkWidget * p_playwin; /* playlist */
GtkWidget * p_modules; /* module manager */
GtkWidget * p_about; /* about window */
GtkWidget * p_open; /* multiopen window */
GtkWidget * p_jump; /* jump window */
GtkWidget * p_sout; /* stream output */
GtkTooltips * p_tooltips; /* tooltips */
/* The input thread */
input_thread_t * p_input;
/* The slider */
GtkFrame * p_slider_frame;
GtkAdjustment * p_adj; /* slider adjustment object */
float f_adj_oldvalue; /* previous value */
/* The messages window */
GtkWidget * p_messages; /* messages window */
GtkText * p_messages_text; /* messages frame */
msg_subscription_t* p_sub; /* message bank subscription */
/* Playlist management */
int i_playing; /* playlist selected item */
/* The window labels for DVD mode */
GtkLabel * p_label_title;
GtkLabel * p_label_chapter;
guint i_part; /* current chapter */
/* audio part */
vlc_bool_t b_mute;
};
/*****************************************************************************
* Prototypes
*****************************************************************************/
gint E_(GtkModeManage) ( intf_thread_t * p_intf );
void E_(GtkDisplayDate) ( GtkAdjustment *p_adj );
/*****************************************************************************
* Useful macro
****************************************************************************/
#define GtkGetIntf( widget ) E_(__GtkGetIntf)( GTK_WIDGET( widget ) )
void * E_(__GtkGetIntf)( GtkWidget * );
/*****************************************************************************
* control.c : functions to handle stream control buttons.
*****************************************************************************
* Copyright (C) 2000, 2001 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@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/intf.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"
/****************************************************************************
* Control functions: this is where the functions are defined
****************************************************************************
* These functions are button-items callbacks, and are used
* by other callbacks
****************************************************************************/
gboolean GtkControlBack( GtkWidget *widget,
gpointer user_data )
{
return FALSE;
}
gboolean GtkControlStop( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
playlist_Stop( p_playlist );
vlc_object_release( p_playlist );
return TRUE;
}
gboolean GtkControlPlay( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
GtkFileOpenShow( widget, user_data );
return TRUE;
}
/* If the playlist is empty, open a file requester instead */
vlc_mutex_lock( &p_playlist->object_lock );
if( p_playlist->i_size )
{
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play( p_playlist );
vlc_object_release( p_playlist );
}
else
{
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
GtkFileOpenShow( widget, user_data );
}
return TRUE;
}
gboolean GtkControlPause( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
if( p_intf->p_sys->p_input == NULL )
{
return FALSE;
}
var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
return TRUE;
}
gboolean GtkControlSlow( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
if( p_intf->p_sys->p_input == NULL )
{
return FALSE;
}
var_SetVoid( p_intf->p_sys->p_input, "rate-slower" );
return TRUE;
}
gboolean GtkControlFast( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
if( p_intf->p_sys->p_input == NULL )
{
return FALSE;
}
var_SetVoid( p_intf->p_sys->p_input, "rate-faster" );
return TRUE;
}
/*****************************************************************************
* gtk_control.h: prototypes for control functions
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@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.
*****************************************************************************/
gboolean GtkControlBack ( GtkWidget *, gpointer );
gboolean GtkControlStop ( GtkWidget *, gpointer );
gboolean GtkControlPlay ( GtkWidget *, gpointer );
gboolean GtkControlPause( GtkWidget *, gpointer );
gboolean GtkControlSlow ( GtkWidget *, gpointer );
gboolean GtkControlFast ( GtkWidget *, gpointer );
/*****************************************************************************
* display.c: Gtk+ tools for main interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2003 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@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 <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#ifdef MODULE_NAME_IS_gnome
# include <gnome.h>
#else
# include <gtk/gtk.h>
#endif
#include "gtk_callbacks.h"
#include "gtk_interface.h"
#include "gtk_support.h"
#include "menu.h"
#include "display.h"
#include "common.h"
/*****************************************************************************
* GtkDisplayDate: display stream date
*****************************************************************************
* This function displays the current date related to the position in
* the stream. It is called whenever the slider changes its value.
* The lock has to be taken before you call the function.
*****************************************************************************/
void E_(GtkDisplayDate)( GtkAdjustment *p_adj )
{
intf_thread_t *p_intf;
p_intf = gtk_object_get_data( GTK_OBJECT( p_adj ), "p_intf" );
if( p_intf->p_sys->p_input )
{
char psz_time[ MSTRTIME_MAX_SIZE ];
int64_t i_seconds;
i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
secstotimestr( psz_time, i_seconds );
gtk_frame_set_label( GTK_FRAME( p_intf->p_sys->p_slider_frame ),
psz_time );
}
}
/*****************************************************************************
* GtkModeManage: actualize the aspect of the interface whenever the input
* changes.
*****************************************************************************
* The lock has to be taken before you call the function.
*****************************************************************************/
gint E_(GtkModeManage)( intf_thread_t * p_intf )
{
GtkWidget * p_dvd_box;
GtkWidget * p_file_box;
GtkWidget * p_network_box;
GtkWidget * p_slider;
GtkWidget * p_label;
vlc_bool_t b_control;
#define GETWIDGET( ptr, name ) GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( \
p_intf->p_sys->ptr ) , ( name ) ) )
/* hide all boxes except default file box */
p_file_box = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "file_box" ) );
gtk_widget_hide( GTK_WIDGET( p_file_box ) );
p_network_box = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "network_box" ) );
gtk_widget_hide( GTK_WIDGET( p_network_box ) );
p_dvd_box = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "dvd_box" ) );
gtk_widget_hide( GTK_WIDGET( p_dvd_box ) );
/* hide slider */
p_slider = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "slider_frame" ) );
gtk_widget_hide( GTK_WIDGET( p_slider ) );
/* controls unavailable */
b_control = 0;
/* show the box related to current input mode */
if( p_intf->p_sys->p_input )
{
switch( p_intf->p_sys->p_input->stream.i_method & 0xf0 )
{
case INPUT_METHOD_FILE:
gtk_widget_show( GTK_WIDGET( p_file_box ) );
p_label = gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ),
"label_status" );
gtk_label_set_text( GTK_LABEL( p_label ),
p_intf->p_sys->p_input->psz_source );
break;
case INPUT_METHOD_DISC:
gtk_widget_show( GTK_WIDGET( p_dvd_box ) );
break;
case INPUT_METHOD_NETWORK:
gtk_widget_show( GTK_WIDGET( p_network_box ) );
p_label = gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ),
"network_address_label" );
gtk_label_set_text( GTK_LABEL( p_label ),
p_intf->p_sys->p_input->psz_source );
break;
default:
msg_Warn( p_intf, "cannot determine input method" );
gtk_widget_show( GTK_WIDGET( p_file_box ) );
p_label = gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ),
"label_status" );
gtk_label_set_text( GTK_LABEL( p_label ),
p_intf->p_sys->p_input->psz_source );
break;
}
/* initialize and show slider for seekable streams */
if( p_intf->p_sys->p_input->stream.b_seekable )
{
p_intf->p_sys->p_adj->value = p_intf->p_sys->f_adj_oldvalue = 0;
gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
"value_changed" );
gtk_widget_show( GTK_WIDGET( p_slider ) );
}
/* control buttons for free pace streams */
b_control = p_intf->p_sys->p_input->stream.b_pace_control;
/* get ready for menu regeneration */
p_intf->p_sys->b_program_update = 1;
p_intf->p_sys->b_title_update = 1;
p_intf->p_sys->b_chapter_update = 1;
p_intf->p_sys->b_audio_update = 1;
p_intf->p_sys->b_spu_update = 1;
p_intf->p_sys->i_part = 0;
#if 0
p_intf->p_sys->b_aout_update = 1;
p_intf->p_sys->b_vout_update = 1;
#endif
p_intf->p_sys->p_input->stream.b_changed = 0;
msg_Dbg( p_intf, "stream has changed, refreshing interface" );
}
else
{
/* default mode */
p_label = gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "label_status" );
gtk_label_set_text( GTK_LABEL( p_label ), "" );
gtk_widget_show( GTK_WIDGET( p_file_box ) );
/* unsensitize menus */
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_program"),
FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_title"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_chapter"),
FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_audio"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_subpictures"),
FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_navigation"),
FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_language"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_subpictures"),
FALSE );
}
/* set control items */
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_back"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_eject"), !b_control);
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_pause"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_slow"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_window, "toolbar_fast"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_popup, "popup_back"), FALSE );
gtk_widget_set_sensitive( GETWIDGET(p_popup, "popup_pause"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_popup, "popup_slow"), b_control );
gtk_widget_set_sensitive( GETWIDGET(p_popup, "popup_fast"), b_control );
#undef GETWIDGET
return TRUE;
}
/*****************************************************************************
* GtkHideTooltips: show or hide the tooltips depending on the configuration
* option gnome-tooltips
*****************************************************************************/
int E_(GtkHideTooltips)( vlc_object_t *p_this, const char *psz_name,
vlc_value_t oldval, vlc_value_t val, void *p_data )
{
intf_thread_t *p_intf;
int i_index;
vlc_list_t *p_list = vlc_list_find( p_this, VLC_OBJECT_INTF,
FIND_ANYWHERE );
vlc_bool_t b_enable = config_GetInt( p_this, "gnome-tooltips" );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_intf = (intf_thread_t *)p_list->p_values[i_index].p_object ;
if( strcmp( MODULE_STRING, p_intf->p_module->psz_object_name ) )
{
continue;
}
if( b_enable )
{
gtk_tooltips_enable( p_intf->p_sys->p_tooltips );
}
else
{
gtk_tooltips_disable( p_intf->p_sys->p_tooltips );
}
}
vlc_list_release( p_list );
return VLC_SUCCESS;
}
#ifdef MODULE_NAME_IS_gnome
/*****************************************************************************
* GtkHideToolbartext: show or hide the tooltips depending on the
* configuration option gnome-toolbartext
*****************************************************************************
* FIXME: GNOME only because of missing icons in gtk interface
*****************************************************************************/
int GtkHideToolbarText( vlc_object_t *p_this, const char *psz_name,
vlc_value_t oldval, vlc_value_t val, void *p_data )
{
GtkToolbarStyle style;
GtkToolbar * p_toolbar;
intf_thread_t *p_intf;
int i_index;
vlc_list_t *p_list = vlc_list_find( p_this, VLC_OBJECT_INTF,
FIND_ANYWHERE );
style = config_GetInt( p_this, "gnome-toolbartext" )
? GTK_TOOLBAR_BOTH
: GTK_TOOLBAR_ICONS;
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_intf = (intf_thread_t *)p_list->p_values[i_index].p_object ;
if( strcmp( MODULE_STRING, p_intf->p_module->psz_object_name ) )
{
continue;
}
p_toolbar = GTK_TOOLBAR(lookup_widget( p_intf->p_sys->p_window,
"toolbar" ));
gtk_toolbar_set_style( p_toolbar, style );
}
vlc_list_release( p_list );
return VLC_SUCCESS;
}
#endif
/*****************************************************************************
* display.h: Gtk+ tools for main interface.
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stéphane Borel <stef@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.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
gint E_(GtkModeManage) ( intf_thread_t * p_intf );
void E_(GtkDisplayDate) ( GtkAdjustment *p_adj );
int E_(GtkHideTooltips) ( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void * );
int GtkHideToolbarText ( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void * );
/*****************************************************************************
* gnome.c : Gnome plugin for vlc
*****************************************************************************
* Copyright (C) 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <gnome.h>
#include "gnome_callbacks.h"
#include "gnome_interface.h"
#include "gnome_support.h"
#include "display.h"
#include "common.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
static void Manage ( intf_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define TOOLTIPS_TEXT N_("Show tooltips")
#define TOOLTIPS_LONGTEXT N_("Show tooltips for configuration options.")
#define TOOLBAR_TEXT N_("Show text on toolbar buttons")
#define TOOLBAR_LONGTEXT N_("Show the text below icons on the toolbar.")
#define PREFS_MAXH_TEXT N_("Maximum height for the configuration windows")
#define PREFS_MAXH_LONGTEXT N_( \
"You can set the maximum height that the configuration windows in the " \
"preferences menu will occupy.")
#define PATH_TEXT N_("Interface default search path")
#define PATH_LONGTEXT N_( \
"This option allows you to set the default path that the interface will " \
"open when looking for a file.")
vlc_module_begin();
#ifdef WIN32
int i = 90;
#else
int i = getenv( "DISPLAY" ) == NULL ? 15 : 100;
#endif
set_description( _("GNOME interface") );
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_GENERAL );
add_bool( "gnome-tooltips", 1, E_(GtkHideTooltips),
TOOLTIPS_TEXT, TOOLTIPS_LONGTEXT, VLC_FALSE );
add_bool( "gnome-toolbartext", 1, GtkHideToolbarText, TOOLBAR_TEXT,
TOOLBAR_LONGTEXT, VLC_FALSE );
add_integer( "gnome-prefs-maxh", 480, NULL,
PREFS_MAXH_TEXT, PREFS_MAXH_LONGTEXT, VLC_TRUE );
add_directory( "gnome-search-path", NULL, NULL, PATH_TEXT,
PATH_LONGTEXT, VLC_TRUE );
set_capability( "interface", i );
set_callbacks( Open, Close );
set_program( "gnome-vlc" );
vlc_module_end();
/*****************************************************************************
* Open: initialize and create window
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return VLC_ENOMEM;
}
p_intf->p_sys->p_gtk_main =
module_Need( p_this, "gui-helper", "gnome", VLC_TRUE );
if( p_intf->p_sys->p_gtk_main == NULL )
{
free( p_intf->p_sys );
return VLC_ENOMOD;
}
p_intf->pf_run = Run;
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
/* Initialize Gnome thread */
p_intf->p_sys->b_playing = VLC_FALSE;
p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
p_intf->p_sys->b_aout_update = VLC_FALSE;
p_intf->p_sys->b_vout_update = VLC_FALSE;
p_intf->p_sys->b_popup_changed = VLC_FALSE;
p_intf->p_sys->b_window_changed = VLC_FALSE;
p_intf->p_sys->b_playlist_changed = VLC_FALSE;
p_intf->p_sys->b_program_update = VLC_FALSE;
p_intf->p_sys->b_title_update = VLC_FALSE;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
p_intf->p_sys->b_spu_update = VLC_FALSE;
p_intf->p_sys->b_audio_update = VLC_FALSE;
p_intf->p_sys->p_input = NULL;
p_intf->p_sys->i_playing = -1;
p_intf->p_sys->b_slider_free = VLC_TRUE;
p_intf->p_sys->i_part = 0;
p_intf->p_sys->b_mute = VLC_FALSE;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: destroy interface window
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
module_Unneed( p_intf, p_intf->p_sys->p_gtk_main );
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: Gnome thread
*****************************************************************************
* this part of the interface is in a separate thread so that we can call
* gtk_main() from within it without annoying the rest of the program.
* XXX: the approach may look kludgy, and probably is, but I could not find
* a better way to dynamically load a Gnome interface at runtime.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
/* The data types we are allowed to receive */
static GtkTargetEntry target_table[] =
{
{ "STRING", 0, DROP_ACCEPT_STRING },
{ "text/uri-list", 0, DROP_ACCEPT_TEXT_URI_LIST },
{ "text/plain", 0, DROP_ACCEPT_TEXT_PLAIN }
};
char *psz_sout;
GString * p_target;
gdk_threads_enter();
/* Create some useful widgets that will certainly be used */
p_intf->p_sys->p_window = create_intf_window( );
p_intf->p_sys->p_popup = create_intf_popup( );
p_intf->p_sys->p_playwin = create_intf_playlist();
p_intf->p_sys->p_messages = create_intf_messages();
p_intf->p_sys->p_tooltips = gtk_tooltips_new();
p_intf->p_sys->p_sout = create_intf_sout();
/* Set the title of the main window */
gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
VOUT_TITLE " (Gnome interface)");
/* Accept file drops on the main window */
gtk_drag_dest_set( GTK_WIDGET( p_intf->p_sys->p_window ),
GTK_DEST_DEFAULT_ALL, target_table,
DROP_ACCEPT_END, GDK_ACTION_COPY );
/* Accept file drops on the playlist window */
gtk_drag_dest_set( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist") ),
GTK_DEST_DEFAULT_ALL, target_table,
DROP_ACCEPT_END, GDK_ACTION_COPY );
/* Get the slider object */
p_intf->p_sys->p_slider_frame = gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "slider_frame" );
/* Configure the log window */
p_intf->p_sys->p_messages_text = GTK_TEXT( gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_messages ), "messages_textbox" ) );
gtk_text_set_line_wrap( p_intf->p_sys->p_messages_text, TRUE);
gtk_text_set_word_wrap( p_intf->p_sys->p_messages_text, FALSE);
/* Get the interface labels */
#define P_LABEL( name ) GTK_LABEL( gtk_object_get_data( \
GTK_OBJECT( p_intf->p_sys->p_window ), name ) )
p_intf->p_sys->p_label_title = P_LABEL( "title_label" );
p_intf->p_sys->p_label_chapter = P_LABEL( "chapter_label" );
#undef P_LABEL
/* Connect the date display to the slider */
#define P_SLIDER GTK_RANGE( gtk_object_get_data( \
GTK_OBJECT( p_intf->p_sys->p_window ), "slider" ) )
p_intf->p_sys->p_adj = gtk_range_get_adjustment( P_SLIDER );
gtk_signal_connect ( GTK_OBJECT( p_intf->p_sys->p_adj ), "value_changed",
GTK_SIGNAL_FUNC( E_(GtkDisplayDate) ), NULL );
p_intf->p_sys->f_adj_oldvalue = 0;
#undef P_SLIDER
/* We don't create these ones yet because we perhaps won't need them */
p_intf->p_sys->p_about = NULL;
p_intf->p_sys->p_modules = NULL;
p_intf->p_sys->p_open = NULL;
p_intf->p_sys->p_jump = NULL;
/* Hide tooltips if the option is set */
if( !config_GetInt( p_intf, "gnome-tooltips" ) )
{
gtk_tooltips_disable( p_intf->p_sys->p_tooltips );
}
/* Hide toolbar text of the option is set */
if( !config_GetInt( p_intf, "gnome-toolbartext" ) )
{
gtk_toolbar_set_style(
GTK_TOOLBAR(lookup_widget( p_intf->p_sys->p_window, "toolbar" )),
GTK_TOOLBAR_ICONS );
}
/* Store p_intf to keep an eye on it */
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_popup),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_popup),
"popup_audio" ) ), "p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_popup),
"popup_video" ) ), "p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_playwin ),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_messages ),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_adj),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_sout ),
"p_intf", p_intf );
psz_sout = config_GetPsz( p_intf, "sout" );
p_target = g_string_new( psz_sout ? psz_sout : "" );
if( psz_sout ) free( psz_sout );
gtk_entry_set_text( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_sout ), "sout_entry_target" ), p_target->str );
g_string_free( p_target, TRUE );
/* FIXME it's to be sure that only file entry is selected */
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_sout ),
"sout_access_udp" ), TRUE );
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_sout ),
"sout_access_file" ), TRUE );
/* Show the control window */
gtk_widget_show( p_intf->p_sys->p_window );
while( !p_intf->b_die )
{
Manage( p_intf );
/* Sleep to avoid using all CPU - since some interfaces need to
* access keyboard events, a 100ms delay is a good compromise */
gdk_threads_leave();
msleep( INTF_IDLE_SLEEP );
gdk_threads_enter();
}
/* Destroy the Tooltips structure */
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_tooltips) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_messages) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_playwin) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_popup) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_window) );
gdk_threads_leave();
}
/* following functions are local */
/*****************************************************************************
* Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
static void Manage( intf_thread_t *p_intf )
{
int i_start, i_stop;
vlc_mutex_lock( &p_intf->change_lock );
/* If the "display popup" flag has changed */
if( p_intf->b_menu_change )
{
if( !GTK_IS_WIDGET( p_intf->p_sys->p_popup ) )
{
p_intf->p_sys->p_popup = create_intf_popup();
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_popup ),
"p_popup", p_intf );
}
gnome_popup_menu_do_popup( p_intf->p_sys->p_popup,
NULL, NULL, NULL, NULL, NULL );
p_intf->b_menu_change = 0;
}
/* Update the log window */
vlc_mutex_lock( p_intf->p_sys->p_sub->p_lock );
i_stop = *p_intf->p_sys->p_sub->pi_stop;
vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
if( p_intf->p_sys->p_sub->i_start != i_stop )
{
static GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
static GdkColor gray = { 0, 0xaaaa, 0xaaaa, 0xaaaa };
static GdkColor yellow = { 0, 0xffff, 0xffff, 0x6666 };
static GdkColor red = { 0, 0xffff, 0x6666, 0x6666 };
static const char * ppsz_type[4] = { ": ", " error: ", " warning: ",
" debug: " };
static GdkColor * pp_color[4] = { &white, &red, &yellow, &gray };
for( i_start = p_intf->p_sys->p_sub->i_start;
i_start != i_stop;
i_start = (i_start+1) % VLC_MSG_QSIZE )
{
/* Append all messages to log window */
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL, &gray,
NULL, p_intf->p_sys->p_sub->p_msg[i_start].psz_module, -1 );
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL, &gray,
NULL, ppsz_type[p_intf->p_sys->p_sub->p_msg[i_start].i_type],
-1 );
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL,
pp_color[p_intf->p_sys->p_sub->p_msg[i_start].i_type], NULL,
p_intf->p_sys->p_sub->p_msg[i_start].psz_msg, -1 );
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL, &gray,
NULL, "\n", -1 );
}
vlc_mutex_lock( p_intf->p_sys->p_sub->p_lock );
p_intf->p_sys->p_sub->i_start = i_start;
vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
/* If the messages list becomes too big, just clean half of it. */
if( gtk_text_get_length( p_intf->p_sys->p_messages_text ) >
VLC_MSG_QSIZE * 1000 )
{
gtk_text_set_point( p_intf->p_sys->p_messages_text, 0 );
gtk_text_forward_delete( p_intf->p_sys->p_messages_text,
gtk_text_get_length( p_intf->p_sys->p_messages_text ) / 2 );
}
gtk_text_set_point( p_intf->p_sys->p_messages_text,
gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
}
/* Update the playlist */
GtkPlayListManage( p_intf );
/* Update the input */
if( p_intf->p_sys->p_input != NULL )
{
if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
}
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
FIND_ANYWHERE );
}
if( p_intf->p_sys->p_input )
{
input_thread_t *p_input = p_intf->p_sys->p_input;
aout_instance_t *p_aout = NULL;
vout_thread_t *p_vout = NULL;
vlc_bool_t b_need_menus = VLC_FALSE;
vlc_mutex_lock( &p_input->stream.stream_lock );
if( !p_input->b_die )
{
/* New input or stream map change */
if( p_input->stream.b_changed )
{
E_(GtkModeManage)( p_intf );
GtkSetupMenus( p_intf );
p_intf->p_sys->b_playing = 1;
}
/* Manage the slider */
if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )
{
float newvalue = p_intf->p_sys->p_adj->value;
#define p_area p_input->stream.p_selected_area
/* If the user hasn't touched the slider since the last time,
* then the input can safely change it */
if( newvalue == p_intf->p_sys->f_adj_oldvalue )
{
/* Update the value */
p_intf->p_sys->p_adj->value =
p_intf->p_sys->f_adj_oldvalue =
( 100. * p_area->i_tell ) / p_area->i_size;
gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
"value_changed" );
}
/* Otherwise, send message to the input if the user has
* finished dragging the slider.
* Beware, the hack below is needed by the dvdplay plugin! */
else if( p_intf->p_sys->b_slider_free
/* hack -> */ && (p_intf->p_sys->f_adj_oldvalue < 100.) )
{
if( newvalue >= 0. && newvalue < 100. )
{
double f_fpos = (double)newvalue / 100.0;
/* release the lock to be able to seek */
vlc_mutex_unlock( &p_input->stream.stream_lock );
var_SetFloat( p_input, "position", f_fpos );
vlc_mutex_lock( &p_input->stream.stream_lock );
}
/* Update the old value */
p_intf->p_sys->f_adj_oldvalue = newvalue;
}
#undef p_area
}
if( p_intf->p_sys->i_part !=
p_input->stream.p_selected_area->i_part )
{
p_intf->p_sys->b_chapter_update = 1;
b_need_menus = VLC_TRUE;
}
/* Does the audio output require to update the menus ? */
p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
if( var_Get( (vlc_object_t *)p_aout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_aout_update = 1;
b_need_menus = 1;
}
vlc_object_release( (vlc_object_t *)p_aout );
}
/* Does the video output require to update the menus ? */
p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
if( var_Get( (vlc_object_t *)p_vout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_vout_update = 1;
b_need_menus = 1;
}
vlc_object_release( (vlc_object_t *)p_vout );
}
if( b_need_menus )
{
GtkSetupMenus( p_intf );
}
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
E_(GtkModeManage)( p_intf );
p_intf->p_sys->b_playing = 0;
}
vlc_mutex_unlock( &p_intf->change_lock );
return;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*****************************************************************************
* This file is not used: everything is in gtk_callbacks.c
*****************************************************************************/
void
GtkDiscOpenCDDA (GtkToggleButton *togglebutton,
gpointer user_data)
{
}
/*****************************************************************************
* This file is not needed: everything is in gtk_callbacks.h
*****************************************************************************/
#include "gtk_callbacks.h"
void
GtkDiscOpenCDDA (GtkToggleButton *togglebutton,
gpointer user_data);
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
GtkWidget* create_intf_window (void);
GtkWidget* create_intf_popup (void);
GtkWidget* create_intf_about (void);
GtkWidget* create_intf_open (void);
GtkWidget* create_intf_file (void);
GtkWidget* create_intf_modules (void);
GtkWidget* create_intf_playlist (void);
GtkWidget* create_intf_jump (void);
GtkWidget* create_intf_messages (void);
GtkWidget* create_intf_sout (void);
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <gnome.h>
#include "gnome_support.h"
/* This is an internally used function to create pixmaps. */
static GtkWidget* create_dummy_pixmap (GtkWidget *widget,
gboolean gnome_pixmap);
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
/* This is a dummy pixmap we use when a pixmap can't be found. */
static char *dummy_pixmap_xpm[] = {
/* columns rows colors chars-per-pixel */
"1 1 1 1",
" c None",
/* pixels */
" ",
" "
};
/* This is an internally used function to create pixmaps. */
static GtkWidget*
create_dummy_pixmap (GtkWidget *widget,
gboolean gnome_pixmap)
{
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
if (gnome_pixmap)
{
return gnome_pixmap_new_from_xpm_d (dummy_pixmap_xpm);
}
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
NULL, dummy_pixmap_xpm);
if (gdkpixmap == NULL)
g_error ("Couldn't create replacement pixmap.");
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename,
gboolean gnome_pixmap)
{
GtkWidget *pixmap;
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
gchar *pathname;
if (!filename || !filename[0])
return create_dummy_pixmap (widget, gnome_pixmap);
pathname = gnome_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return create_dummy_pixmap (widget, gnome_pixmap);
}
if (gnome_pixmap)
{
pixmap = gnome_pixmap_new_from_file (pathname);
g_free (pathname);
return pixmap;
}
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
NULL, pathname);
if (gdkpixmap == NULL)
{
g_warning (_("Couldn't create pixmap from file: %s"), pathname);
g_free (pathname);
return create_dummy_pixmap (widget, gnome_pixmap);
}
g_free (pathname);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
/* This is an internally used function to create imlib images. */
#if 0
GdkImlibImage*
create_image (const gchar *filename)
{
GdkImlibImage *image;
gchar *pathname;
pathname = gnome_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return NULL;
}
image = gdk_imlib_load_image (pathname);
g_free (pathname);
return image;
}
#endif
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#include <gnome.h>
/*
* Public Functions.
*/
/*
* This function returns a widget in a component created by Glade.
* Call it with the toplevel widget in the component (i.e. a window/dialog),
* or alternatively any widget in the component, and the name of the widget
* you want returned.
*/
GtkWidget* lookup_widget (GtkWidget *widget,
const gchar *widget_name);
/* get_widget() is deprecated. Use lookup_widget instead. */
#define get_widget lookup_widget
/*
* Private Functions.
*/
/* This is used to create the pixmaps in the interface. */
GtkWidget* create_pixmap (GtkWidget *widget,
const gchar *filename,
gboolean gnome_pixmap);
//GdkImlibImage* create_image (const gchar *filename);
/*****************************************************************************
* gtk.c : Gtk+ plugin for vlc
*****************************************************************************
* Copyright (C) 2000-2001 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <gtk/gtk.h>
#include "gtk_callbacks.h"
#include "gtk_interface.h"
#include "gtk_support.h"
#include "menu.h"
#include "display.h"
#include "common.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
static int Manage ( intf_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define TOOLTIPS_TEXT N_("Show tooltips")
#define TOOLTIPS_LONGTEXT N_("Show tooltips for configuration options.")
#define PREFS_MAXH_TEXT N_("Maximum height for the configuration windows")
#define PREFS_MAXH_LONGTEXT N_( \
"You can set the maximum height that the configuration windows in the " \
"preferences menu will occupy.")
#define PATH_TEXT N_("Interface default search path")
#define PATH_LONGTEXT N_( \
"This option allows you to set the default path that the interface will " \
"open when looking for a file.")
vlc_module_begin();
#ifdef WIN32
int i = 90;
#else
int i = getenv( "DISPLAY" ) == NULL ? 10 : 90;
#endif
set_description( _("Gtk+ interface") );
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_GENERAL );
add_bool( "gtk-tooltips", 1, E_(GtkHideTooltips),
TOOLTIPS_TEXT, TOOLTIPS_LONGTEXT, VLC_FALSE );
add_integer( "gtk-prefs-maxh", 480, NULL,
PREFS_MAXH_TEXT, PREFS_MAXH_LONGTEXT, VLC_TRUE );
add_directory( "gtk-search-path", NULL, NULL, PATH_TEXT,
PATH_LONGTEXT, VLC_TRUE );
set_capability( "interface", i );
set_callbacks( Open, Close );
add_shortcut( "gtk" );
set_program( "gvlc" );
vlc_module_end();
/*****************************************************************************
* Open: initialize and create window
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return VLC_ENOMEM;
}
#ifdef NEED_GTK_MAIN
p_intf->p_sys->p_gtk_main =
module_Need( p_this, "gui-helper", "gtk", VLC_TRUE );
if( p_intf->p_sys->p_gtk_main == NULL )
{
free( p_intf->p_sys );
return VLC_ENOMOD;
}
#endif
p_intf->pf_run = Run;
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
/* Initialize Gtk+ thread */
p_intf->p_sys->b_playing = VLC_FALSE;
p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
p_intf->p_sys->b_aout_update = VLC_FALSE;
p_intf->p_sys->b_vout_update = VLC_FALSE;
p_intf->p_sys->b_popup_changed = VLC_FALSE;
p_intf->p_sys->b_window_changed = VLC_FALSE;
p_intf->p_sys->b_playlist_changed = VLC_FALSE;
p_intf->p_sys->b_program_update = VLC_FALSE;
p_intf->p_sys->b_title_update = VLC_FALSE;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
p_intf->p_sys->b_spu_update = VLC_FALSE;
p_intf->p_sys->b_audio_update = VLC_FALSE;
p_intf->p_sys->p_input = NULL;
p_intf->p_sys->i_playing = -1;
p_intf->p_sys->b_slider_free = VLC_TRUE;
p_intf->p_sys->i_part = 0;
p_intf->p_sys->b_mute = VLC_FALSE;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: destroy interface window
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
#ifdef NEED_GTK_MAIN
module_Unneed( p_intf, p_intf->p_sys->p_gtk_main );
#endif
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: Gtk+ thread
*****************************************************************************
* this part of the interface is in a separate thread so that we can call
* gtk_main() from within it without annoying the rest of the program.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
/* The data types we are allowed to receive */
static GtkTargetEntry target_table[] =
{
{ "STRING", 0, DROP_ACCEPT_STRING },
{ "text/uri-list", 0, DROP_ACCEPT_TEXT_URI_LIST },
{ "text/plain", 0, DROP_ACCEPT_TEXT_PLAIN }
};
char *psz_sout;
GString * p_target;
#ifdef NEED_GTK_MAIN
gdk_threads_enter();
#else
/* gtk_init needs to know the command line. We don't care, so we
* give it an empty one */
char *p_args[] = { "", NULL };
char **pp_args = p_args;
int i_args = 1;
int i_dummy;
gtk_init( &i_args, &pp_args );
#endif
/* Create some useful widgets that will certainly be used */
p_intf->p_sys->p_window = create_intf_window();
p_intf->p_sys->p_popup = create_intf_popup();
p_intf->p_sys->p_playwin = create_intf_playlist();
p_intf->p_sys->p_messages = create_intf_messages();
p_intf->p_sys->p_tooltips = gtk_tooltips_new();
p_intf->p_sys->p_sout = create_intf_sout();
/* Set the title of the main window */
gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
VOUT_TITLE " (Gtk+ interface)");
/* Accept file drops on the main window */
gtk_drag_dest_set( GTK_WIDGET( p_intf->p_sys->p_window ),
GTK_DEST_DEFAULT_ALL, target_table,
DROP_ACCEPT_END, GDK_ACTION_COPY );
/* Accept file drops on the playlist window */
gtk_drag_dest_set( GTK_WIDGET( lookup_widget( p_intf->p_sys->p_playwin,
"playlist_clist") ),
GTK_DEST_DEFAULT_ALL, target_table,
DROP_ACCEPT_END, GDK_ACTION_COPY );
/* Get the slider object */
p_intf->p_sys->p_slider_frame = GTK_FRAME( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "slider_frame" ) );
/* Configure the log window */
p_intf->p_sys->p_messages_text = GTK_TEXT( gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_messages ), "messages_textbox" ) );
gtk_text_set_line_wrap( p_intf->p_sys->p_messages_text, TRUE);
gtk_text_set_word_wrap( p_intf->p_sys->p_messages_text, FALSE);
/* Get the interface labels */
#define P_LABEL( name ) GTK_LABEL( gtk_object_get_data( \
GTK_OBJECT( p_intf->p_sys->p_window ), name ) )
p_intf->p_sys->p_label_title = P_LABEL( "title_label" );
p_intf->p_sys->p_label_chapter = P_LABEL( "chapter_label" );
#undef P_LABEL
/* Connect the date display to the slider */
#define P_SLIDER GTK_RANGE( gtk_object_get_data( \
GTK_OBJECT( p_intf->p_sys->p_window ), "slider" ) )
p_intf->p_sys->p_adj = gtk_range_get_adjustment( P_SLIDER );
gtk_signal_connect ( GTK_OBJECT( p_intf->p_sys->p_adj ), "value_changed",
GTK_SIGNAL_FUNC( E_(GtkDisplayDate) ), NULL );
p_intf->p_sys->f_adj_oldvalue = 0;
#undef P_SLIDER
/* We don't create these ones yet because we perhaps won't need them */
p_intf->p_sys->p_about = NULL;
p_intf->p_sys->p_modules = NULL;
p_intf->p_sys->p_open = NULL;
p_intf->p_sys->p_jump = NULL;
/* Hide tooltips if the option is set */
if( !config_GetInt( p_intf, "gtk-tooltips" ) )
{
gtk_tooltips_disable( p_intf->p_sys->p_tooltips );
}
/* Store p_intf to keep an eye on it */
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_popup),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_popup),
"popup_audio" ) ), "p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_popup),
"popup_video" ) ), "p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_playwin ),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_messages ),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_adj),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_sout ),
"p_intf", p_intf );
psz_sout = config_GetPsz( p_intf, "sout" );
p_target = g_string_new( psz_sout ? psz_sout : "" );
if( psz_sout ) free( psz_sout );
gtk_entry_set_text( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_sout ), "sout_entry_target" ), p_target->str );
g_string_free( p_target, TRUE );
/* FIXME it's to be sure that only file entry is selected */
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_sout ),
"sout_access_udp" ), TRUE );
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_sout ),
"sout_access_file" ), TRUE );
/* Show the control window */
gtk_widget_show( p_intf->p_sys->p_window );
#ifdef NEED_GTK_MAIN
while( !p_intf->b_die )
{
Manage( p_intf );
/* Sleep to avoid using all CPU - since some interfaces need to
* access keyboard events, a 100ms delay is a good compromise */
gdk_threads_leave();
msleep( INTF_IDLE_SLEEP );
gdk_threads_enter();
}
#else
/* Sleep to avoid using all CPU - since some interfaces needs to access
* keyboard events, a 100ms delay is a good compromise */
i_dummy = gtk_timeout_add( INTF_IDLE_SLEEP / 1000, (GtkFunction)Manage,
p_intf );
/* Enter Gtk mode */
gtk_main();
/* Remove the timeout */
gtk_timeout_remove( i_dummy );
#endif
/* Destroy the Tooltips structure */
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_tooltips) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_messages) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_playwin) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_popup) );
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_window) );
#ifdef NEED_GTK_MAIN
gdk_threads_leave();
#endif
}
/* following functions are local */
/*****************************************************************************
* Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
static int Manage( intf_thread_t *p_intf )
{
int i_start, i_stop;
vlc_mutex_lock( &p_intf->change_lock );
/* If the "display popup" flag has changed */
if( p_intf->b_menu_change )
{
if( !GTK_IS_WIDGET( p_intf->p_sys->p_popup ) )
{
p_intf->p_sys->p_popup = create_intf_popup();
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_popup ),
"p_intf", p_intf );
}
gtk_menu_popup( GTK_MENU( p_intf->p_sys->p_popup ),
NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME );
p_intf->b_menu_change = 0;
}
/* Update the log window */
vlc_mutex_lock( p_intf->p_sys->p_sub->p_lock );
i_stop = *p_intf->p_sys->p_sub->pi_stop;
vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
if( p_intf->p_sys->p_sub->i_start != i_stop )
{
static GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
static GdkColor gray = { 0, 0xaaaa, 0xaaaa, 0xaaaa };
static GdkColor yellow = { 0, 0xffff, 0xffff, 0x6666 };
static GdkColor red = { 0, 0xffff, 0x6666, 0x6666 };
static const char * ppsz_type[4] = { ": ", " error: ", " warning: ",
" debug: " };
static GdkColor * pp_color[4] = { &white, &red, &yellow, &gray };
for( i_start = p_intf->p_sys->p_sub->i_start;
i_start != i_stop;
i_start = (i_start+1) % VLC_MSG_QSIZE )
{
/* Append all messages to log window */
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL, &gray,
NULL, p_intf->p_sys->p_sub->p_msg[i_start].psz_module, -1 );
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL, &gray,
NULL, ppsz_type[p_intf->p_sys->p_sub->p_msg[i_start].i_type],
-1 );
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL,
pp_color[p_intf->p_sys->p_sub->p_msg[i_start].i_type], NULL,
p_intf->p_sys->p_sub->p_msg[i_start].psz_msg, -1 );
gtk_text_insert( p_intf->p_sys->p_messages_text, NULL, &gray,
NULL, "\n", -1 );
}
vlc_mutex_lock( p_intf->p_sys->p_sub->p_lock );
p_intf->p_sys->p_sub->i_start = i_start;
vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
/* If the messages list becomes too big, just clean half of it. */
if( gtk_text_get_length( p_intf->p_sys->p_messages_text ) >
VLC_MSG_QSIZE * 1000 )
{
gtk_text_set_point( p_intf->p_sys->p_messages_text, 0 );
gtk_text_forward_delete( p_intf->p_sys->p_messages_text,
gtk_text_get_length( p_intf->p_sys->p_messages_text ) / 2 );
}
gtk_text_set_point( p_intf->p_sys->p_messages_text,
gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
}
/* Update the playlist */
GtkPlayListManage( p_intf );
/* Update the input */
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
FIND_ANYWHERE );
}
else if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
if( p_intf->p_sys->p_input )
{
input_thread_t *p_input = p_intf->p_sys->p_input;
aout_instance_t *p_aout = NULL;
vout_thread_t *p_vout = NULL;
vlc_bool_t b_need_menus = VLC_FALSE;
//vlc_mutex_lock( &p_input->stream.stream_lock );
if( !p_input->b_die )
{
/* New input or stream map change */
if( p_input->stream.b_changed )
{
E_(GtkModeManage)( p_intf );
GtkSetupMenus( p_intf );
p_intf->p_sys->b_playing = 1;
}
/* Manage the slider */
if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )
{
float newvalue = p_intf->p_sys->p_adj->value;
#define p_area p_input->stream.p_selected_area
/* If the user hasn't touched the slider since the last time,
* then the input can safely change it */
if( newvalue == p_intf->p_sys->f_adj_oldvalue )
{
/* Update the value */
p_intf->p_sys->p_adj->value =
p_intf->p_sys->f_adj_oldvalue =
( 100. * p_area->i_tell ) / p_area->i_size;
gtk_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
"value_changed" );
}
/* Otherwise, send message to the input if the user has
* finished dragging the slider.
* Beware, the hack below is needed by the dvdplay plugin! */
else if( p_intf->p_sys->b_slider_free
/* hack -> */ && (p_intf->p_sys->f_adj_oldvalue < 100.) )
{
if( newvalue >= 0. && newvalue < 100. )
{
double f_fpos = (double)newvalue / 100.0;
/* release the lock to be able to seek */
//vlc_mutex_unlock( &p_input->stream.stream_lock );
var_SetFloat( p_input, "position", f_fpos );
//vlc_mutex_lock( &p_input->stream.stream_lock );
}
/* Update the old value */
p_intf->p_sys->f_adj_oldvalue = newvalue;
}
#undef p_area
}
if( p_intf->p_sys->i_part !=
p_input->stream.p_selected_area->i_part )
{
p_intf->p_sys->b_chapter_update = 1;
b_need_menus = VLC_TRUE;
}
/* Does the audio output require to update the menus ? */
p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
if( var_Get( (vlc_object_t *)p_aout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_aout_update = 1;
b_need_menus = 1;
}
vlc_object_release( (vlc_object_t *)p_aout );
}
/* Does the video output require to update the menus ? */
p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
if( var_Get( (vlc_object_t *)p_vout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_vout_update = 1;
b_need_menus = 1;
}
vlc_object_release( (vlc_object_t *)p_vout );
}
if( b_need_menus )
{
GtkSetupMenus( p_intf );
}
}
//vlc_mutex_unlock( &p_input->stream.stream_lock );
}
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
E_(GtkModeManage)( p_intf );
p_intf->p_sys->b_playing = 0;
}
#ifndef NEED_GTK_MAIN
if( p_intf->b_die )
{
vlc_mutex_unlock( &p_intf->change_lock );
/* Prepare to die, young Skywalker */
gtk_main_quit();
return FALSE;
}
#endif
vlc_mutex_unlock( &p_intf->change_lock );
return TRUE;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*****************************************************************************
* gtk_callbacks.c : Callbacks for the Gtk+ plugin.
*****************************************************************************
* Copyright (C) 2000, 2001, 2003 the VideoLAN team
* $Id$
*
* Authors: Sam Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr>
* Julien BLACHE <jb@technologeek.org>
*
* 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/intf.h>
#include <vlc/vout.h>
#include <vlc/aout.h>
#include <unistd.h>
#include <gtk/gtk.h>
#include <string.h>
#include "gtk_callbacks.h"
#include "gtk_interface.h"
#include "gtk_support.h"
#include "common.h"
#ifdef HAVE_CDDAX
#define CDDA_MRL "cddax://"
#else
#define CDDA_MRL "cdda://"
#endif
#ifdef HAVE_VCDX
#define VCD_MRL "vcdx://"
#else
#define VCD_MRL "vcdx://"
#endif
/*****************************************************************************
* Useful function to retrieve p_intf
****************************************************************************/
void * E_(__GtkGetIntf)( GtkWidget * widget )
{
void *p_data;
if( GTK_IS_MENU_ITEM( widget ) )
{
/* Look for a GTK_MENU */
while( widget->parent && !GTK_IS_MENU( widget ) )
{
widget = widget->parent;
}
/* Maybe this one has the data */
p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
if( p_data )
{
return p_data;
}
/* Otherwise, the parent widget has it */
widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
if( p_data )
{
return p_data;
}
}
/* We look for the top widget */
widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
return p_data;
}
/*****************************************************************************
* Callbacks
*****************************************************************************/
/*
* Main interface callbacks
*/
#ifdef MODULE_NAME_IS_gtk
# define GTKEXIT GtkExit
#else
# define GTKEXIT GnomeExit
#endif
gboolean GTKEXIT( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( widget );
vlc_mutex_lock( &p_intf->change_lock );
p_intf->p_vlc->b_die = VLC_TRUE;
vlc_mutex_unlock( &p_intf->change_lock );
return TRUE;
}
void GtkClose( GtkMenuItem *menuitem,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
p_intf->b_die = VLC_TRUE;
}
gboolean GtkWindowDelete( GtkWidget *widget,
GdkEvent *event,
gpointer user_data )
{
GTKEXIT( GTK_WIDGET( widget ), user_data );
return TRUE;
}
gboolean GtkWindowToggle( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( widget );
if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
{
gtk_widget_hide( p_intf->p_sys->p_window);
}
else
{
gtk_widget_show( p_intf->p_sys->p_window );
}
return TRUE;
}
gboolean GtkFullscreen( GtkWidget *widget,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( widget );
vout_thread_t *p_vout;
if( p_intf->p_sys->p_input == NULL )
{
return FALSE;
}
p_vout = vlc_object_find( p_intf->p_sys->p_input,
VLC_OBJECT_VOUT, FIND_CHILD );
if( p_vout == NULL )
{
return FALSE;
}
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
vlc_object_release( p_vout );
return TRUE;
}
void GtkWindowDrag( GtkWidget *widget,
GdkDragContext *drag_context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( widget );
GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
}
/****************************************************************************
* Slider management
****************************************************************************/
gboolean GtkSliderRelease( GtkWidget *widget,
GdkEventButton *event,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( widget );
vlc_mutex_lock( &p_intf->change_lock );
p_intf->p_sys->b_slider_free = VLC_TRUE;
vlc_mutex_unlock( &p_intf->change_lock );
return FALSE;
}
gboolean GtkSliderPress( GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( widget );
vlc_mutex_lock( &p_intf->change_lock );
p_intf->p_sys->b_slider_free = VLC_FALSE;
vlc_mutex_unlock( &p_intf->change_lock );
return FALSE;
}
/****************************************************************************
* DVD specific items
****************************************************************************/
void GtkTitlePrev( GtkButton * button, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
var_SetVoid( p_intf->p_sys->p_input, "prev-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 );
}
void GtkTitleNext( GtkButton * button, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
var_SetVoid( p_intf->p_sys->p_input, "next-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 );
}
void GtkChapterPrev( GtkButton * button, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
var_SetVoid( p_intf->p_sys->p_input, "prev-chapter" );
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 );
}
void GtkChapterNext( GtkButton * button, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
var_SetVoid( p_intf->p_sys->p_input, "next-chapter" );
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 );
}
/****************************************************************************
* About box
****************************************************************************/
gboolean GtkAboutShow( GtkWidget *widget,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( widget );
if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
{
p_intf->p_sys->p_about = create_intf_about();
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
"p_intf", p_intf );
}
gtk_widget_show( p_intf->p_sys->p_about );
gdk_window_raise( p_intf->p_sys->p_about->window );
return TRUE;
}
void GtkAboutOk( GtkButton * button, gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( button );
gtk_widget_hide( p_intf->p_sys->p_about );
}
/****************************************************************************
* Jump box
****************************************************************************/
gboolean GtkJumpShow( GtkWidget *widget,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( widget );
if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
{
p_intf->p_sys->p_jump = create_intf_jump();
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
"p_intf", p_intf );
}
gtk_widget_show( p_intf->p_sys->p_jump );
gdk_window_raise( p_intf->p_sys->p_jump->window );
return FALSE;
}
void GtkJumpOk( GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
int i_hours, i_minutes, i_seconds;
if( p_intf->p_sys->p_input == NULL )
{
return;
}
#define GET_VALUE( name ) \
gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
i_hours = GET_VALUE( "jump_hour_spinbutton" );
i_minutes = GET_VALUE( "jump_minute_spinbutton" );
i_seconds = GET_VALUE( "jump_second_spinbutton" );
#undef GET_VALUE
var_SetTime( p_intf->p_sys->p_input, "time",
(int64_t)(i_seconds+60*i_minutes+3600*i_hours)*I64C(1000000));
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
void GtkJumpCancel( GtkButton *button,
gpointer user_data)
{
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
/****************************************************************************
* Callbacks for disc ejection
****************************************************************************/
gboolean GtkDiscEject ( GtkWidget *widget, gpointer user_data )
{
char *psz_device = NULL;
char *psz_parser;
char *psz_current;
intf_thread_t *p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
vlc_mutex_lock( &p_playlist->object_lock );
if( p_playlist->i_index < 0 )
{
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
return FALSE;
}
psz_current = p_playlist->pp_items[ p_playlist->i_index ]->input.psz_name;
/*
* Get the active input
* Determine whether we can eject a media, ie it's a VCD or DVD
* If it's neither a VCD nor a DVD, then return
*/
/*
* Don't really know if I must lock the stuff here, we're using it read-only
*/
if( psz_current != NULL )
{
if( !strncmp(psz_current, "dvd://", 4) )
{
switch( psz_current[strlen("dvd://")] )
{
case '\0':
case '@':
psz_device = config_GetPsz( p_intf, "dvd" );
break;
default:
/* Omit the first MRL-selector characters */
psz_device = strdup( psz_current + strlen("dvd://" ) );
break;
}
}
else if( !strncmp(psz_current, "vcd:", strlen("vcd:")) )
{
switch( psz_current[strlen("vcd:")] )
{
case '\0':
case '@':
psz_device = config_GetPsz( p_intf, VCD_MRL );
break;
default:
/* Omit the beginning MRL-selector characters */
psz_device = strdup( psz_current + strlen(VCD_MRL) );
break;
}
}
else if( !strncmp(psz_current, CDDA_MRL, strlen(CDDA_MRL) ) )
{
switch( psz_current[strlen(CDDA_MRL)] )
{
case '\0':
case '@':
psz_device = config_GetPsz( p_intf, "cd-audio" );
break;
default:
/* Omit the beginning MRL-selector characters */
psz_device = strdup( psz_current + strlen(CDDA_MRL) );
break;
}
}
else
{
psz_device = strdup( psz_current );
}
}
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
if( psz_device == NULL )
{
return TRUE;
}
/* Remove what we have after @ */
psz_parser = psz_device;
for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
{
if( *psz_parser == '@' )
{
*psz_parser = '\0';
break;
}
}
/* If there's a stream playing, we aren't allowed to eject ! */
if( p_intf->p_sys->p_input == NULL )
{
msg_Dbg( p_intf, "ejecting %s", psz_device );
intf_Eject( p_intf, psz_device );
}
free(psz_device);
return TRUE;
}
/****************************************************************************
* Messages window
****************************************************************************/
gboolean GtkMessagesShow( GtkWidget *widget,
gpointer user_data)
{
static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
static GdkColormap *colormap;
intf_thread_t *p_intf = GtkGetIntf( widget );
gtk_widget_show( p_intf->p_sys->p_messages );
colormap = gdk_colormap_get_system ();
gdk_color_alloc( colormap, &black );
gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
&black );
gdk_window_raise( p_intf->p_sys->p_messages->window );
gtk_text_set_point( p_intf->p_sys->p_messages_text,
gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
return TRUE;
}
void
GtkMessagesOk (GtkButton *button,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( button );
gtk_widget_hide( p_intf->p_sys->p_messages );
}
gboolean
GtkMessagesDelete (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( widget );
gtk_widget_hide( p_intf->p_sys->p_messages );
return TRUE;
}
void
GtkOpenNotebookChanged (GtkNotebook *notebook,
GtkNotebookPage *page,
gint page_num,
gpointer user_data)
{
GtkOpenChanged( GTK_WIDGET( notebook ), user_data );
}
/****************************************************************************
* Audio management
****************************************************************************/
void GtkVolumeUp ( GtkMenuItem *menuitem,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
audio_volume_t i_volume;
aout_VolumeUp( p_intf, 1, &i_volume );
p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
}
void GtkVolumeDown ( GtkMenuItem *menuitem,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
audio_volume_t i_volume;
aout_VolumeDown( p_intf, 1, &i_volume );
p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
}
void GtkVolumeMute ( GtkMenuItem *menuitem,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
audio_volume_t i_volume;
aout_VolumeMute( p_intf, &i_volume );
p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
}
void
GtkMenubarDeinterlace ( GtkMenuItem *menuitem,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
if( p_intf )
msg_Dbg( p_intf, "GtkMenubarDeinterlace" );
}
void
GtkPopupDeinterlace (GtkRadioMenuItem *radiomenuitem,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( radiomenuitem );
if( p_intf )
msg_Dbg( p_intf, "GtkPopupDeinterlace" );
}
/*****************************************************************************
* gtk_callbacks.h : Callbacks for the gtk plugin.
*****************************************************************************
* Copyright (C) 2000, 2001 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@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 <gtk/gtk.h>
#include "config.h"
#include "control.h"
#include "menu.h"
#include "open.h"
#include "modules.h"
#include "playlist.h"
#include "preferences.h"
/* General glade callbacks */
/*****************************************************************************
* main window callbacks: specific prototypes are in headers listed before
*****************************************************************************/
#ifdef MODULE_NAME_IS_gtk
gboolean GtkExit ( GtkWidget *, gpointer );
#else
gboolean GnomeExit ( GtkWidget *, gpointer );
#endif
gboolean GtkWindowToggle ( GtkWidget *, gpointer );
gboolean GtkFullscreen ( GtkWidget *, gpointer );
gboolean GtkSliderRelease ( GtkWidget *, GdkEventButton *, gpointer );
gboolean GtkSliderPress ( GtkWidget *, GdkEventButton *, gpointer );
gboolean GtkWindowDelete ( GtkWidget * widget, GdkEvent *, gpointer );
gboolean GtkJumpShow ( GtkWidget *, gpointer );
gboolean GtkAboutShow ( GtkWidget *, gpointer );
gboolean GtkMessagesShow ( GtkWidget *, gpointer );
void GtkTitlePrev ( GtkButton * button, gpointer );
void GtkTitleNext ( GtkButton * button, gpointer );
void GtkChapterPrev ( GtkButton *, gpointer );
void GtkChapterNext ( GtkButton * button, gpointer );
void GtkAboutOk ( GtkButton *, gpointer );
void GtkWindowDrag ( GtkWidget *, GdkDragContext *,
gint, gint, GtkSelectionData *,
guint , guint, gpointer );
void GtkJumpOk ( GtkButton * button, gpointer );
void GtkJumpCancel ( GtkButton * button, gpointer user_data );
void GtkNetworkOpenChannel ( GtkToggleButton *, gpointer );
gboolean
GtkDiscEject (GtkWidget *widget,
gpointer user_data);
void
GtkMessagesOk (GtkButton *button,
gpointer user_data);
gboolean
GtkMessagesDelete (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
gboolean
GtkSatOpenShow (GtkWidget *widget,
gpointer user_data);
void
GtkSatOpenOk (GtkButton *button,
gpointer user_data);
void
GtkSatOpenCancel (GtkButton *button,
gpointer user_data);
void
GtkNetworkOpenUDP (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkNetworkOpenMulticast (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkNetworkOpenCS (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkNetworkOpenHTTP (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkNetworkOpenChannel (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkOpenOk (GtkButton *button,
gpointer user_data);
void
GtkOpenCancel (GtkButton *button,
gpointer user_data);
void
GtkOpenChanged (GtkWidget *button,
gpointer user_data);
void
GtkOpenNotebookChanged (GtkNotebook *notebook,
GtkNotebookPage *page,
gint page_num,
gpointer user_data);
void
GtkSatOpenToggle (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkFileShow (GtkButton *button,
gpointer user_data);
void
GtkFileOk (GtkButton *button,
gpointer user_data);
void
GtkFileCancel (GtkButton *button,
gpointer user_data);
void
GtkClose (GtkMenuItem *menuitem,
gpointer user_data);
void
GtkVolumeUp (GtkMenuItem *menuitem,
gpointer user_data);
void
GtkVolumeDown (GtkMenuItem *menuitem,
gpointer user_data);
void
GtkVolumeMute (GtkMenuItem *menuitem,
gpointer user_data);
void
GtkMenubarDeinterlace (GtkMenuItem *menuitem,
gpointer user_data);
void
GtkPopupDeinterlace (GtkRadioMenuItem *radiomenuitem,
gpointer user_data);
void
GtkOpenSubtitleShow (GtkButton *button,
gpointer user_data);
void
GtkSoutSettings (GtkButton *button,
gpointer user_data);
void
GtkSoutSettingsCancel (GtkButton *button,
gpointer user_data);
void
GtkSoutSettingsChanged (GtkWidget *button,
gpointer user_data);
void
GtkSoutSettingsOk (GtkButton *button,
gpointer user_data);
void
GtkSoutSettingsAccessFile (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkSoutSettingsAccessUdp (GtkToggleButton *togglebutton,
gpointer user_data);
void
GtkOpenSoutShow (GtkButton *button,
gpointer user_data);
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
GtkWidget* create_intf_window (void);
GtkWidget* create_intf_popup (void);
GtkWidget* create_intf_about (void);
GtkWidget* create_intf_open (void);
GtkWidget* create_intf_file (void);
GtkWidget* create_intf_jump (void);
GtkWidget* create_intf_playlist (void);
GtkWidget* create_intf_messages (void);
GtkWidget* create_intf_sout (void);
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <gtk/gtk.h>
#include "gtk_support.h"
/* This is an internally used function to check if a pixmap file exists. */
static gchar* check_file_exists (const gchar *directory,
const gchar *filename);
/* This is an internally used function to create pixmaps. */
static GtkWidget* create_dummy_pixmap (GtkWidget *widget);
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
/* This is a dummy pixmap we use when a pixmap can't be found. */
static char *dummy_pixmap_xpm[] = {
/* columns rows colors chars-per-pixel */
"1 1 1 1",
" c None",
/* pixels */
" "
};
/* This is an internally used function to create pixmaps. */
static GtkWidget*
create_dummy_pixmap (GtkWidget *widget)
{
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
NULL, dummy_pixmap_xpm);
if (gdkpixmap == NULL)
g_error ("Couldn't create replacement pixmap.");
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
static GList *pixmaps_directories = NULL;
/* Use this function to set the directory containing installed pixmaps. */
void
add_pixmap_directory (const gchar *directory)
{
pixmaps_directories = g_list_prepend (pixmaps_directories,
g_strdup (directory));
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename)
{
gchar *found_filename = NULL;
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
GList *elem;
if (!filename || !filename[0])
return create_dummy_pixmap (widget);
/* We first try any pixmaps directories set by the application. */
elem = pixmaps_directories;
while (elem)
{
found_filename = check_file_exists ((gchar*)elem->data, filename);
if (found_filename)
break;
elem = elem->next;
}
/* If we haven't found the pixmap, try the source directory. */
if (!found_filename)
{
found_filename = check_file_exists ("pixmaps", filename);
}
if (!found_filename)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return create_dummy_pixmap (widget);
}
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
NULL, found_filename);
if (gdkpixmap == NULL)
{
g_warning (_("Error loading pixmap file: %s"), found_filename);
g_free (found_filename);
return create_dummy_pixmap (widget);
}
g_free (found_filename);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
/* This is an internally used function to check if a pixmap file exists. */
static gchar*
check_file_exists (const gchar *directory,
const gchar *filename)
{
gchar *full_filename;
struct stat s;
gint status;
full_filename = (gchar*) g_malloc (strlen (directory) + 1
+ strlen (filename) + 1);
strcpy (full_filename, directory);
strcat (full_filename, G_DIR_SEPARATOR_S);
strcat (full_filename, filename);
status = stat (full_filename, &s);
if (status == 0 && S_ISREG (s.st_mode))
return full_filename;
g_free (full_filename);
return NULL;
}
/*
* Created by glade, fixed by bootstrap
*/
#ifdef HAVE_CONFIG_H
# include <vlc/vlc.h>
#endif
#include <gtk/gtk.h>
/*
* Standard gettext macros.
*/
#if 0 /* Disabled by bootstrap */
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
/* #else */
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif
/*
* Public Functions.
*/
/*
* This function returns a widget in a component created by Glade.
* Call it with the toplevel widget in the component (i.e. a window/dialog),
* or alternatively any widget in the component, and the name of the widget
* you want returned.
*/
GtkWidget* lookup_widget (GtkWidget *widget,
const gchar *widget_name);
/* get_widget() is deprecated. Use lookup_widget instead. */
#define get_widget lookup_widget
/* Use this function to set the directory containing installed pixmaps. */
void add_pixmap_directory (const gchar *directory);
/*
* Private Functions.
*/
/* This is used to create the pixmaps in the interface. */
GtkWidget* create_pixmap (GtkWidget *widget,
const gchar *filename);
/*****************************************************************************
* menu.c : functions to handle menu items.
*****************************************************************************
* Copyright (C) 2000, 2001 the VideoLAN team
* $Id$
*
* Authors: Sam Hocevar <sam@zoy.org>
* Stphane 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 )
config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
vlc_object_release( p_vout );
}
else
config_PutPsz( p_intf, "deinterlace-mode", psz_mode );
}
}
static void GtkMenubarDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
GtkLabel *p_label;
char *psz_mode;
GtkWidget *p_popup_menu;
p_label = GTK_LABEL( ( GTK_BIN( menuitem )->child ) );
if( !p_intf->p_sys->b_deinterlace_update && menuitem->active )
{
gtk_label_get( p_label, &psz_mode );
GtkDeinterlaceUpdate( p_intf, psz_mode );
p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_deinterlace" ) );
GtkDeinterlaceMenus( p_intf, p_popup_menu, GtkPopupDeinterlaceToggle );
p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
}
}
static void GtkPopupDeinterlaceToggle( GtkCheckMenuItem * menuitem, gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( menuitem );
GtkLabel *p_label;
char *psz_mode;
GtkWidget *p_menubar_menu;
p_label = GTK_LABEL( ( GTK_BIN( menuitem )->child ) );
if( !p_intf->p_sys->b_deinterlace_update && menuitem->active )
{
gtk_label_get( p_label, &psz_mode );
GtkDeinterlaceUpdate( p_intf, psz_mode );
p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_deinterlace" ) );
GtkDeinterlaceMenus( p_intf, p_menubar_menu, GtkMenubarDeinterlaceToggle );
p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
}
}
/****************************************************************************
* Functions to generate menus
****************************************************************************/
/*****************************************************************************
* GtkRadioMenu: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
static gint GtkRadioMenu( intf_thread_t * p_intf,
GtkWidget * p_root, GSList * p_menu_group,
char * psz_item_name,
int i_start, int i_end, int i_selected,
void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{
char psz_name[ GTK_MENU_LABEL_SIZE ];
GtkWidget * p_menu;
GtkWidget * p_submenu;
GtkWidget * p_item_group;
GtkWidget * p_item;
GtkWidget * p_item_selected;
GSList * p_group;
gint i_item;
/* temporary hack to avoid blank menu when an open menu is removed */
if( GTK_MENU_ITEM(p_root)->submenu != NULL )
{
gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
}
/* removes previous menu */
gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
gtk_widget_set_sensitive( p_root, FALSE );
p_item_group = NULL;
p_submenu = NULL;
p_item_selected = NULL;
p_group = p_menu_group;
p_menu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
for( i_item = i_start ; i_item <= i_end ; i_item++ )
{
/* we group chapters in packets of ten for small screens */
if( ( i_item % 10 == i_start ) && ( i_end > i_start + 20 ) )
{
if( i_item != i_start )
{
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_item_group ),
p_submenu );
gtk_menu_append( GTK_MENU( p_menu ), p_item_group );
}
snprintf( psz_name, GTK_MENU_LABEL_SIZE,
"%ss %d to %d", psz_item_name, i_item, i_item + 9 );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
p_item_group = gtk_menu_item_new_with_label( psz_name );
gtk_widget_show( p_item_group );
p_submenu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_submenu ), "p_intf", p_intf );
}
snprintf( psz_name, GTK_MENU_LABEL_SIZE, "%s %d",
psz_item_name, i_item );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
if( i_selected == i_item )
{
p_item_selected = p_item;
}
gtk_widget_show( p_item );
/* setup signal hanling */
gtk_signal_connect( GTK_OBJECT( p_item ),
"toggled",
GTK_SIGNAL_FUNC( pf_toggle ),
(gpointer)((long)(i_item)) );
if( i_end > i_start + 20 )
{
gtk_menu_append( GTK_MENU( p_submenu ), p_item );
}
else
{
gtk_menu_append( GTK_MENU( p_menu ), p_item );
}
}
if( i_end > i_start + 20 )
{
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_item_group ), p_submenu );
gtk_menu_append( GTK_MENU( p_menu ), p_item_group );
}
/* 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
* We have to release the lock since input_ToggleES needs it */
if( p_item_selected != NULL )
{
gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_selected ),
TRUE );
}
/* be sure that menu is sensitive, if there are several items */
if( i_end > i_start )
{
gtk_widget_set_sensitive( p_root, TRUE );
}
return TRUE;
}
/*****************************************************************************
* GtkProgramMenu: update the programs menu of the interface
*****************************************************************************
* Builds the program menu according to what have been found in the PAT
* by the input. Usefull for multi-programs streams such as DVB ones.
*****************************************************************************/
static gint GtkProgramMenu( gpointer p_data,
GtkWidget * p_root,
pgrm_descriptor_t * p_pgrm,
void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{
intf_thread_t * p_intf;
GtkWidget * p_menu;
GtkWidget * p_item;
GtkWidget * p_item_active;
GSList * p_group;
char psz_name[ GTK_MENU_LABEL_SIZE ];
guint i;
/* cast */
p_intf = (intf_thread_t *)p_data;
/* temporary hack to avoid blank menu when an open menu is removed */
if( GTK_MENU_ITEM(p_root)->submenu != NULL )
{
gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
}
/* removes previous menu */
gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
gtk_widget_set_sensitive( p_root, FALSE );
p_group = NULL;
/* menu container */
p_menu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
p_item_active = NULL;
/* create a set of program buttons and append them to the container */
for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_pgrm_number ; i++ )
{
snprintf( psz_name, GTK_MENU_LABEL_SIZE, "id %d",
p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
psz_name[GTK_MENU_LABEL_SIZE-1] = '\0';
p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
p_group =
gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
{
/* don't lose p_item when we append into menu */
p_item_active = p_item;
}
gtk_widget_show( p_item );
/* setup signal hanling */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC( pf_toggle ),
(gpointer)(ptrdiff_t)( p_intf->p_sys->p_input->
stream.pp_programs[i]->i_number ) );
gtk_menu_append( GTK_MENU( p_menu ), p_item );
}
/* link the new menu to the menubar item */
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
/* activation will call signals so we can only do it
* 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 ),
TRUE );
}
/* be sure that menu is sensitive if more than 1 program */
if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
{
gtk_widget_set_sensitive( p_root, TRUE );
}
return TRUE;
}
/*****************************************************************************
* GtkLanguageMenus: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input:
* -languages
* -sub-pictures
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
static gint GtkLanguageMenus( gpointer p_data,
GtkWidget * p_root,
es_descriptor_t * p_es,
gint i_cat,
void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{
intf_thread_t * p_intf;
GtkWidget * p_menu;
GtkWidget * p_separator;
GtkWidget * p_item;
GtkWidget * p_item_active;
GSList * p_group;
char psz_name[ GTK_MENU_LABEL_SIZE ];
guint i_item;
guint i;
p_intf = (intf_thread_t *)p_data;
/* temporary hack to avoid blank menu when an open menu is removed */
if( GTK_MENU_ITEM(p_root)->submenu != NULL )
{
gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
}
/* removes previous menu */
gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
gtk_widget_set_sensitive( p_root, FALSE );
p_group = NULL;
/* menu container */
p_menu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
/* special case for "off" item */
snprintf( psz_name, GTK_MENU_LABEL_SIZE, _("None") );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
gtk_widget_show( p_item );
/* signal hanling for off */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC ( pf_toggle ), NULL );
gtk_menu_append( GTK_MENU( p_menu ), p_item );
p_separator = gtk_menu_item_new();
gtk_widget_set_sensitive( p_separator, FALSE );
gtk_widget_show( p_separator );
gtk_menu_append( GTK_MENU( p_menu ), p_separator );
p_item_active = NULL;
i_item = 0;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
#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 == i_cat ) &&
( !ES->p_pgrm ||
ES->p_pgrm ==
p_intf->p_sys->p_input->stream.p_selected_program ) )
{
i_item++;
if( !p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc ||
!*p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc )
{
snprintf( psz_name, GTK_MENU_LABEL_SIZE,
"Language %d", i_item );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
}
else
{
strcpy( psz_name,
p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc );
}
p_item = gtk_radio_menu_item_new_with_label( p_group, psz_name );
p_group =
gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
{
/* don't lose p_item when we append into menu */
p_item_active = p_item;
}
gtk_widget_show( p_item );
/* setup signal hanling */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC( pf_toggle ),
(gpointer)( p_intf->p_sys->p_input->stream.pp_es[i] ) );
gtk_menu_append( GTK_MENU( p_menu ), p_item );
}
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
/* link the new menu to the menubar item */
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
* 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 ),
TRUE );
}
/* be sure that menu is sensitive if non empty */
if( i_item > 0 )
{
gtk_widget_set_sensitive( p_root, TRUE );
}
return TRUE;
}
/*****************************************************************************
* GtkTitleMenu: sets menus for titles and chapters selection
*****************************************************************************
* Generates two types of menus:
* -simple list of titles
* -cascaded lists of chapters for each title
*****************************************************************************/
static gint GtkTitleMenu( gpointer p_data,
GtkWidget * p_navigation,
void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{
intf_thread_t * p_intf;
char psz_name[ GTK_MENU_LABEL_SIZE ];
GtkWidget * p_title_menu;
GtkWidget * p_title_submenu;
GtkWidget * p_title_item;
GtkWidget * p_item_active;
GtkWidget * p_chapter_menu;
GtkWidget * p_chapter_submenu;
GtkWidget * p_title_menu_item;
GtkWidget * p_chapter_menu_item;
GtkWidget * p_item;
GSList * p_title_group;
GSList * p_chapter_group;
guint i_title;
guint i_chapter;
guint i_title_nb;
guint i_chapter_nb;
/* cast */
p_intf = (intf_thread_t*)p_data;
/* temporary hack to avoid blank menu when an open menu is removed */
if( GTK_MENU_ITEM(p_navigation)->submenu != NULL )
{
gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_navigation)->submenu ) );
}
/* removes previous menu */
gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_navigation ) );
gtk_widget_set_sensitive( p_navigation, FALSE );
p_title_menu = gtk_menu_new();
p_title_group = NULL;
p_title_submenu = NULL;
p_title_menu_item = NULL;
p_chapter_group = NULL;
p_chapter_submenu = NULL;
p_chapter_menu_item = NULL;
p_item_active = NULL;
i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb - 1;
gtk_object_set_data( GTK_OBJECT( p_title_menu ), "p_intf", p_intf );
/* loop on titles */
for( i_title = 1 ; i_title <= i_title_nb ; i_title++ )
{
/* we group titles in packets of ten for small screens */
if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
{
if( i_title != 1 )
{
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item ),
p_title_submenu );
gtk_menu_append( GTK_MENU( p_title_menu ), p_title_menu_item );
}
snprintf( psz_name, GTK_MENU_LABEL_SIZE,
"%d - %d", i_title, i_title + 9 );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
p_title_menu_item = gtk_menu_item_new_with_label( psz_name );
gtk_widget_show( p_title_menu_item );
p_title_submenu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_title_submenu ),
"p_intf", p_intf );
}
snprintf( psz_name, GTK_MENU_LABEL_SIZE, _("Title %d (%d)"), i_title,
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1);
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
#if 0
if( pf_toggle == on_menubar_title_toggle )
{
p_title_item = gtk_radio_menu_item_new_with_label( p_title_group,
psz_name );
p_title_group =
gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_title_item ) );
if( p_intf->p_sys->p_input->stream.pp_areas[i_title] ==
p_intf->p_sys->p_input->stream.p_selected_area )
{
p_item_active = p_title_item;
}
/* setup signal hanling */
gtk_signal_connect( GTK_OBJECT( p_title_item ),
"toggled",
GTK_SIGNAL_FUNC( pf_toggle ),
(gpointer)(p_intf->p_sys->p_input->stream.pp_areas[i_title]) );
if( p_intf->p_sys->p_input->stream.i_area_nb > 1 )
{
/* be sure that menu is sensitive */
gtk_widget_set_sensitive( p_navigation, TRUE );
}
}
else
#endif
{
p_title_item = gtk_menu_item_new_with_label( psz_name );
#if 1
p_chapter_menu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_chapter_menu ),
"p_intf", p_intf );
i_chapter_nb =
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;
for( i_chapter = 1 ; i_chapter <= i_chapter_nb ; i_chapter++ )
{
/* we group chapters in packets of ten for small screens */
if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )
{
if( i_chapter != 1 )
{
gtk_menu_item_set_submenu(
GTK_MENU_ITEM( p_chapter_menu_item ),
p_chapter_submenu );
gtk_menu_append( GTK_MENU( p_chapter_menu ),
p_chapter_menu_item );
}
snprintf( psz_name, GTK_MENU_LABEL_SIZE,
"%d - %d", i_chapter, i_chapter + 9 );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
p_chapter_menu_item =
gtk_menu_item_new_with_label( psz_name );
gtk_widget_show( p_chapter_menu_item );
p_chapter_submenu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_chapter_submenu ),
"p_intf", p_intf );
}
snprintf( psz_name, GTK_MENU_LABEL_SIZE,
_("Chapter %d"), i_chapter );
psz_name[ GTK_MENU_LABEL_SIZE - 1 ] = '\0';
p_item = gtk_radio_menu_item_new_with_label(
p_chapter_group, psz_name );
p_chapter_group = gtk_radio_menu_item_group(
GTK_RADIO_MENU_ITEM( p_item ) );
gtk_widget_show( p_item );
#define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
if( ( p_area ==
p_intf->p_sys->p_input->stream.p_selected_area ) &&
( p_area->i_part == i_chapter ) )
{
p_item_active = p_item;
}
#undef p_area
/* setup signal hanling */
gtk_signal_connect( GTK_OBJECT( p_item ),
"toggled",
GTK_SIGNAL_FUNC( pf_toggle ),
(gpointer)POS2DATA( i_title, i_chapter ) );
if( i_chapter_nb > 20 )
{
gtk_menu_append( GTK_MENU( p_chapter_submenu ), p_item );
}
else
{
gtk_menu_append( GTK_MENU( p_chapter_menu ), p_item );
}
}
if( i_chapter_nb > 20 )
{
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_chapter_menu_item ),
p_chapter_submenu );
gtk_menu_append( GTK_MENU( p_chapter_menu ),
p_chapter_menu_item );
}
/* link the new menu to the title menu item */
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_item ),
p_chapter_menu );
if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb > 1 )
{
/* be sure that menu is sensitive */
gtk_widget_set_sensitive( p_navigation, TRUE );
}
#else
GtkRadioMenu( p_intf, p_title_item, p_chapter_group, _("Chapter"),
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1,
1, i_title * 100,
p_intf->p_sys->p_input->stream.p_selected_area->i_part +
p_intf->p_sys->p_input->stream.p_selected_area->i_id *100,
pf_toggle );
#endif
}
gtk_widget_show( p_title_item );
if( i_title_nb > 20 )
{
gtk_menu_append( GTK_MENU( p_title_submenu ), p_title_item );
}
else
{
gtk_menu_append( GTK_MENU( p_title_menu ), p_title_item );
}
}
if( i_title_nb > 20 )
{
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_title_menu_item ),
p_title_submenu );
gtk_menu_append( GTK_MENU( p_title_menu ), p_title_menu_item );
}
/* be sure that menu is sensitive */
gtk_widget_set_sensitive( p_title_menu, TRUE );
/* 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 )
{
gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
TRUE );
}
#if 0
if( p_intf->p_sys->p_input->stream.i_area_nb > 1 )
{
/* be sure that menu is sensitive */
gtk_widget_set_sensitive( p_navigation, TRUE );
}
#endif
return TRUE;
}
/*****************************************************************************
* GtkSetupVarMenu :
*****************************************************************************
*
*****************************************************************************/
static gint GtkSetupVarMenu( intf_thread_t * p_intf,
vlc_object_t * p_object,
GtkWidget *p_root,
char * psz_variable,
void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{
vlc_value_t val, text, val_list, text_list;
GtkWidget * p_menu;
GSList * p_group = NULL;
GtkWidget * p_item;
GtkWidget * p_item_active = NULL;
int i_item, i_type;
/* temporary hack to avoid blank menu when an open menu is removed */
if( GTK_MENU_ITEM(p_root)->submenu != NULL )
{
gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
}
/* removes previous menu */
gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
gtk_widget_set_sensitive( p_root, FALSE );
/* Check the type of the object variable */
i_type = var_Type( p_object, psz_variable );
/* Make sure we want to display the variable */
if( i_type & VLC_VAR_HASCHOICE )
{
var_Change( p_object, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL );
if( val.i_int == 0 ) return FALSE;
}
/* Get the descriptive name of the variable */
var_Change( p_object, psz_variable, VLC_VAR_GETTEXT, &text, NULL );
/* get the current value */
if( var_Get( p_object, psz_variable, &val ) < 0 )
{
return FALSE;
}
if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST,
&val_list, &text_list ) < 0 )
{
if( i_type == VLC_VAR_STRING ) free( val.psz_string );
return FALSE;
}
/* menu container */
p_menu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
for( i_item = 0; i_item < val_list.p_list->i_count; i_item++ )
{
switch( i_type & VLC_VAR_TYPE )
{
case VLC_VAR_STRING:
p_item = gtk_radio_menu_item_new_with_label( p_group,
text_list.p_list->p_values[i_item].psz_string ?
text_list.p_list->p_values[i_item].psz_string :
val_list.p_list->p_values[i_item].psz_string );
/* signal hanling for off */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC ( pf_toggle ),
/* FIXME memory leak */
strdup(val_list.p_list->p_values[i_item].psz_string) );
if( !strcmp( val.psz_string,
val_list.p_list->p_values[i_item].psz_string ) )
{
p_item_active = p_item;
}
break;
case VLC_VAR_INTEGER:
p_item = gtk_radio_menu_item_new_with_label( p_group,
text_list.p_list->p_values[i_item].psz_string ?
text_list.p_list->p_values[i_item].psz_string :
NULL /* FIXME */ );
/* signal hanling for off */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC ( pf_toggle ),
(gpointer)val_list.p_list->p_values[i_item].i_int );
if( val.i_int == val_list.p_list->p_values[i_item].i_int )
{
p_item_active = p_item;
}
break;
default:
/* FIXME */
return FALSE;
}
p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
gtk_widget_show( p_item );
gtk_menu_append( GTK_MENU( p_menu ), p_item );
}
/* link the new menu to the menubar item */
gtk_menu_item_set_submenu( GTK_MENU_ITEM( p_root ), p_menu );
if( p_item_active )
{
gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(p_item_active),
TRUE );
}
if( val_list.p_list->i_count > 0 )
{
gtk_widget_set_sensitive( p_root, TRUE );
}
/* clean up everything */
if( i_type == VLC_VAR_STRING ) free( val.psz_string );
var_Change( p_object, psz_variable, VLC_VAR_FREELIST,
&val_list, &text_list );
return TRUE;
}
/*****************************************************************************
* GtkDeinterlaceMenus: update interactive menus of the interface
*****************************************************************************
*****************************************************************************/
static gint GtkDeinterlaceMenus( gpointer p_data,
GtkWidget * p_root,
void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) )
{
intf_thread_t * p_intf;
GtkWidget * p_menu;
GtkWidget * p_separator;
GtkWidget * p_item;
GtkWidget * p_item_active;
GSList * p_group;
guint i_item;
guint i;
char *ppsz_deinterlace_mode[] = { "discard", "blend", "mean", "bob", "linear", NULL };
char *psz_deinterlace_option;
char *psz_filter;
p_intf = (intf_thread_t *)p_data;
/* temporary hack to avoid blank menu when an open menu is removed */
if( GTK_MENU_ITEM(p_root)->submenu != NULL )
{
gtk_menu_popdown( GTK_MENU( GTK_MENU_ITEM(p_root)->submenu ) );
}
/* removes previous menu */
gtk_menu_item_remove_submenu( GTK_MENU_ITEM( p_root ) );
gtk_widget_set_sensitive( p_root, FALSE );
p_group = NULL;
/* menu container */
p_menu = gtk_menu_new();
gtk_object_set_data( GTK_OBJECT( p_menu ), "p_intf", p_intf );
/* special case for "off" item */
p_item = gtk_radio_menu_item_new_with_label( p_group, "None" );
p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
gtk_widget_show( p_item );
/* signal hanling for off */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC ( pf_toggle ), NULL );
gtk_menu_append( GTK_MENU( p_menu ), p_item );
p_separator = gtk_menu_item_new();
gtk_widget_set_sensitive( p_separator, FALSE );
gtk_widget_show( p_separator );
gtk_menu_append( GTK_MENU( p_menu ), p_separator );
/* search actual deinterlace mode */
psz_filter = config_GetPsz( p_intf, "filter" );
psz_deinterlace_option = strdup( "None" );
if( psz_filter && *psz_filter )
{
if( strstr ( psz_filter, "deinterlace" ) )
{
vlc_value_t val;
vout_thread_t *p_vout;
p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout &&
var_Get( p_vout, "deinterlace-mode", &val ) == VLC_SUCCESS )
{
if( val.psz_string && *val.psz_string )
{
free( psz_deinterlace_option );
psz_deinterlace_option = val.psz_string;
}
else if( val.psz_string ) free( val.psz_string );
}
if( p_vout ) vlc_object_release( p_vout );
}
}
if( psz_filter )
free( psz_filter );
p_item_active = NULL;
i_item = 0;
/* create a set of deinteralce buttons and append them to the container */
for( i = 0; ppsz_deinterlace_mode[i] != NULL; i++ )
{
i_item++;
p_item = gtk_radio_menu_item_new_with_label( p_group, ppsz_deinterlace_mode[i] );
p_group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( p_item ) );
gtk_widget_show( p_item );
if( !strcmp( ppsz_deinterlace_mode[i], psz_deinterlace_option ) )
{
p_item_active = p_item;
}
/* setup signal hanling */
gtk_signal_connect( GTK_OBJECT( p_item ), "toggled",
GTK_SIGNAL_FUNC( pf_toggle ),
NULL );
gtk_menu_append( GTK_MENU( p_menu ), p_item );
}
/* link the new menu to the menubar item */
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
* 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 ),
TRUE );
}
/* be sure that menu is sensitive if non empty */
if( i_item > 0 )
{
gtk_widget_set_sensitive( p_root, TRUE );
}
return TRUE;
}
/*****************************************************************************
* GtkSetupMenus: function that generates title/chapter/audio/subpic
* menus with help from preceding functions
*****************************************************************************
* Function called with the lock on stream
*****************************************************************************/
gint GtkSetupMenus( intf_thread_t * p_intf )
{
es_descriptor_t * p_audio_es;
es_descriptor_t * p_spu_es;
GtkWidget * p_menubar_menu;
GtkWidget * p_popup_menu;
guint i;
p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_title_update |
p_intf->p_sys->b_program_update;
p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_title_update |
p_intf->p_sys->b_program_update;
if( 1 )
{
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_deinterlace" ) );
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_deinterlace" ) );
p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
GtkDeinterlaceMenus( p_intf, p_menubar_menu, GtkMenubarDeinterlaceToggle );
p_intf->p_sys->b_deinterlace_update = VLC_TRUE;
GtkDeinterlaceMenus( p_intf, p_popup_menu, GtkPopupDeinterlaceToggle );
p_intf->p_sys->b_deinterlace_update = VLC_FALSE;
}
if( p_intf->p_sys->b_program_update )
{
pgrm_descriptor_t * p_pgrm;
if( p_intf->p_sys->p_input->stream.p_new_program )
{
p_pgrm = p_intf->p_sys->p_input->stream.p_new_program;
}
else
{
p_pgrm = p_intf->p_sys->p_input->stream.p_selected_program;
}
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_program" ) );
GtkProgramMenu( p_intf, p_menubar_menu, p_pgrm,
GtkMenubarProgramToggle );
p_intf->p_sys->b_program_update = VLC_TRUE;
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_program" ) );
GtkProgramMenu( p_intf, p_popup_menu, p_pgrm,
GtkPopupProgramToggle );
p_intf->p_sys->b_program_update = VLC_FALSE;
}
if( p_intf->p_sys->b_title_update )
{
char psz_title[5];
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"), 1,
p_intf->p_sys->p_input->stream.i_area_nb - 1,
p_intf->p_sys->p_input->stream.p_selected_area->i_id,
GtkMenubarTitleToggle );
snprintf( psz_title, 4, "%d",
p_intf->p_sys->p_input->stream.p_selected_area->i_id );
psz_title[ 4 ] = '\0';
gtk_label_set_text( p_intf->p_sys->p_label_title, psz_title );
p_intf->p_sys->b_title_update = VLC_FALSE;
}
if( p_intf->p_sys->b_chapter_update )
{
char psz_chapter[5];
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_navigation" ) );
GtkTitleMenu( p_intf, p_popup_menu, GtkPopupNavigationToggle );
#if 0
GtkRadioMenu( p_intf, p_menubar_menu, NULL, _("Title"), 1,
p_intf->p_sys->p_input->stream.i_area_nb - 1,
p_intf->p_sys->p_input->stream.p_selected_area->i_id,
on_menubar_chapter_toggle );
#endif
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_chapter" ) );
GtkRadioMenu( p_intf, p_menubar_menu, NULL, _("Chapter"), 1,
p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb - 1,
p_intf->p_sys->p_input->stream.p_selected_area->i_part,
GtkMenubarChapterToggle );
snprintf( psz_chapter, 4, "%d",
p_intf->p_sys->p_input->stream.p_selected_area->i_part );
psz_chapter[ 4 ] = '\0';
gtk_label_set_text( p_intf->p_sys->p_label_chapter, psz_chapter );
p_intf->p_sys->i_part =
p_intf->p_sys->p_input->stream.p_selected_area->i_part;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
}
/* look for selected ES */
p_audio_es = NULL;
p_spu_es = NULL;
for( i = 0 ; i < p_intf->p_sys->p_input->stream.i_selected_es_number ; i++ )
{
if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
{
p_audio_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
}
if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
{
p_spu_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
}
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
/* audio menus */
if( p_intf->p_sys->b_audio_update )
{
/* find audio root menu */
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_audio" ) );
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_language" ) );
p_intf->p_sys->b_audio_update = VLC_TRUE;
GtkLanguageMenus( p_intf, p_menubar_menu, p_audio_es, AUDIO_ES,
GtkMenubarAudioToggle );
p_intf->p_sys->b_audio_update = VLC_TRUE;
GtkLanguageMenus( p_intf, p_popup_menu, p_audio_es, AUDIO_ES,
GtkPopupAudioToggle );
p_intf->p_sys->b_audio_update = VLC_FALSE;
}
/* sub picture menus */
if( p_intf->p_sys->b_spu_update )
{
/* find spu root menu */
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_subpictures" ) );
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 = VLC_TRUE;
GtkLanguageMenus( p_intf, p_menubar_menu, p_spu_es, SPU_ES,
GtkMenubarSubtitleToggle );
p_intf->p_sys->b_spu_update = VLC_TRUE;
GtkLanguageMenus( p_intf, p_popup_menu, p_spu_es, SPU_ES,
GtkPopupSubtitleToggle );
p_intf->p_sys->b_spu_update = VLC_FALSE;
}
/* create audio channels and device menu (in menubar _and_ popup */
if( p_intf->p_sys->b_aout_update )
{
aout_instance_t *p_aout;
p_aout = (aout_instance_t*)vlc_object_find( p_intf, VLC_OBJECT_AOUT, FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
val.b_bool = VLC_FALSE;
var_Set( (vlc_object_t *)p_aout, "intf-change", val );
/* audio-channels */
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_audio_channels" ) );
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_audio_channels" ) );
GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_popup_menu,
"audio-channels", GtkPopupAoutChannelsToggle );
GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_menubar_menu,
"audio-channels", GtkPopupAoutChannelsToggle );
/* audio-device */
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_audio_device" ) );
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_audio_device" ) );
GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_popup_menu,
"audio-device", GtkPopupAoutDeviceToggle );
GtkSetupVarMenu( p_intf, (vlc_object_t *)p_aout, p_menubar_menu,
"audio-device", GtkPopupAoutDeviceToggle );
vlc_object_release( (vlc_object_t *)p_aout );
}
p_intf->p_sys->b_aout_update = VLC_FALSE;
}
if( p_intf->p_sys->b_vout_update )
{
vout_thread_t *p_vout;
p_vout = (vout_thread_t*)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
val.b_bool = VLC_FALSE;
var_Set( (vlc_object_t *)p_vout, "intf-change", val );
/* video-device */
p_menubar_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ), "menubar_video_device" ) );
p_popup_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_popup ), "popup_video_device" ) );
GtkSetupVarMenu( p_intf, (vlc_object_t *)p_vout, p_popup_menu,
"video-device", GtkPopupVoutDeviceToggle );
GtkSetupVarMenu( p_intf, (vlc_object_t *)p_vout, p_menubar_menu,
"video-device", GtkPopupVoutDeviceToggle );
vlc_object_release( (vlc_object_t *)p_vout );
}
p_intf->p_sys->b_vout_update = VLC_FALSE;
}
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
return TRUE;
}
/*****************************************************************************
* gtk_menu.h: prototypes for menu functions
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stéphane Borel <stef@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.
*****************************************************************************/
gint GtkSetupMenus( intf_thread_t * );
/*****************************************************************************
* String sizes
*****************************************************************************/
#define GTK_MENU_LABEL_SIZE 64
/*****************************************************************************
* Convert user_data structures to title and chapter information
*****************************************************************************/
#define DATA2TITLE( user_data ) ( (gint)((long)(user_data)) >> 16 )
#define DATA2CHAPTER( user_data ) ( (gint)((long)(user_data)) & 0xffff )
#define POS2DATA( title, chapter ) ( 0 + ( ((title) << 16) \
| ((chapter) & 0xffff)) )
/*****************************************************************************
* gtk_modules.c : functions to build modules configuration boxes.
*****************************************************************************
* Copyright (C) 2000, 2001 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@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/intf.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"
gboolean GtkModulesShow( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( widget );
if( !GTK_IS_WIDGET( p_intf->p_sys->p_modules ) )
{
/* p_intf->p_sys->p_modules = create_intf_modules(); */
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_modules ),
"p_intf", p_intf );
}
gtk_widget_show( p_intf->p_sys->p_modules );
gdk_window_raise( p_intf->p_sys->p_modules->window );
return FALSE;
}
void GtkModulesCancel( GtkButton * button, gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( button );
gtk_widget_hide( p_intf->p_sys->p_modules );
}
/*****************************************************************************
* gtk_modules.h: prototypes for modules functions
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stéphane Borel <stef@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.
*****************************************************************************/
gboolean GtkModulesShow ( GtkWidget *, gpointer );
void GtkModulesCancel ( GtkButton * button, gpointer );
/*****************************************************************************
* gtk_open.c : functions to handle file/disc/network open widgets.
*****************************************************************************
* Copyright (C) 2000, 2001, 2003 the VideoLAN team
* $Id$
*
* Authors: Sam Hocevar <sam@zoy.org>
* Stphane Borel <stef@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/intf.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"
#ifdef HAVE_CDDAX
#define CDDA_MRL "cddax://"
#else
#define CDDA_MRL "cdda://"
#endif
#ifdef HAVE_VCDX
#define VCD_MRL "vcdx://"
#else
#define VCD_MRL "vcdx://"
#endif
static void GtkOpenShow( intf_thread_t *, int );
static void GtkFileOpenChanged ( GtkWidget *, gpointer );
static void GtkDiscOpenChanged ( GtkWidget *, gpointer );
static void GtkNetworkOpenChanged ( GtkWidget *, gpointer );
static void GtkSatOpenChanged ( GtkWidget *, gpointer );
/*****************************************************************************
* File requester callbacks
*****************************************************************************
* The following callbacks are related to the file requester.
*****************************************************************************/
void GtkFileShow( GtkButton * button, gpointer user_data )
{
GtkWidget * p_file = create_intf_file();
gtk_object_set_data( GTK_OBJECT(p_file), "p_intf",
GtkGetIntf( button ) );
/* entry <- entry_file or entry_subtitle */
gtk_object_set_data( GTK_OBJECT(p_file), "entry",
user_data );
gtk_widget_show( p_file );
gdk_window_raise( p_file->window );
}
void GtkFileOk( GtkButton * button, gpointer user_data )
{
GtkWidget * p_file = gtk_widget_get_toplevel( GTK_WIDGET (button) );
char *psz_entry;
char *psz_filename;
intf_thread_t * p_intf = GtkGetIntf( button );
/* add the new file to the dialog box */
psz_entry = gtk_object_get_data( GTK_OBJECT( p_file ), "entry" );
psz_filename =
gtk_file_selection_get_filename( GTK_FILE_SELECTION( p_file ) );
gtk_entry_set_text( GTK_ENTRY( lookup_widget( p_intf->p_sys->p_open,
psz_entry ) ),
psz_filename );
gtk_widget_destroy( p_file );
}
void GtkFileCancel( GtkButton * button, gpointer user_data )
{
gtk_widget_destroy( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
/*****************************************************************************
* Open file callbacks
*****************************************************************************
* The following callbacks are related to the file tab.
*****************************************************************************/
gboolean GtkFileOpenShow( GtkWidget *widget,
gpointer user_data )
{
GtkOpenShow( GtkGetIntf( widget ), 0 );
return TRUE;
}
static void GtkFileOpenChanged( GtkWidget * button, gpointer user_data )
{
GString * p_target;
p_target = g_string_new( "file://" );
g_string_append( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "entry_file" ) ) ) );
gtk_entry_set_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "entry_open" ) ),
p_target->str );
g_string_free( p_target, TRUE );
}
/*****************************************************************************
* Open disc callbacks
*****************************************************************************
* The following callbacks are related to the disc manager.
*****************************************************************************/
gboolean GtkDiscOpenShow( GtkWidget *widget,
gpointer user_data)
{
GtkOpenShow( GtkGetIntf( widget ), 1 );
return TRUE;
}
void GtkDiscOpenDvd( GtkToggleButton * togglebutton, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( togglebutton );
char *psz_device;
if( togglebutton->active )
{
if ( (psz_device = config_GetPsz( p_intf, "dvd" )) )
{
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "disc_dvd_use_menu" ) ) , TRUE);
gtk_entry_set_text(
GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
"disc_name" ) ), psz_device );
free( psz_device );
}
else
{
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "disc_dvd_use_menu" ) ), FALSE );
}
GtkDiscOpenChanged( (GtkWidget *) togglebutton, user_data );
}
else
{
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "disc_dvd_use_menu" ) ), FALSE );
}
}
void GtkDiscOpenVcd( GtkToggleButton * togglebutton, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( togglebutton );
char *psz_device;
if( togglebutton->active )
{
if ( (psz_device = config_GetPsz( p_intf, "vcd" )) )
{
gtk_entry_set_text(
GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
"disc_name" ) ), psz_device );
free( psz_device );
} else {
gtk_entry_set_text(
GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
"disc_name" ) ), "" );
}
GtkDiscOpenChanged( (GtkWidget *) togglebutton, user_data );
}
}
void GtkDiscOpenCDDA( GtkToggleButton * togglebutton, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( togglebutton );
char *psz_device;
if( togglebutton->active )
{
if ( (psz_device = config_GetPsz( p_intf, "cd-audio" )) )
{
gtk_entry_set_text(
GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
"disc_name" ) ), psz_device );
free( psz_device );
} else {
gtk_entry_set_text(
GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
"disc_name" ) ), "" );
}
GtkDiscOpenChanged( (GtkWidget *) togglebutton, user_data );
}
}
static void GtkDiscOpenChanged( GtkWidget * button, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
GString * p_target = g_string_new( "" );
GtkWidget * p_open = gtk_widget_get_toplevel( GTK_WIDGET (button) );
vlc_bool_t b_menus = VLC_FALSE;
vlc_bool_t b_chapter_menu = VLC_TRUE;
GtkWidget *p_label = gtk_object_get_data( GTK_OBJECT( p_open ),
"disc_title_label" );
if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
"disc_dvd" ) )->active )
{
gtk_label_set_text( GTK_LABEL( p_label ), _("Title") );
b_menus = GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
"disc_dvd_use_menu" ) )->active;
if( b_menus )
{
g_string_append( p_target, "dvd://" );
}
else
{
g_string_append( p_target, "dvdsimple://" );
}
g_string_append( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "disc_name" ) ) ) );
if( !b_menus )
{
g_string_sprintfa( p_target, "@%i:%i",
gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "disc_title" ) ) ),
gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "disc_chapter" ) ) ) );
}
}
else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
"disc_vcd" ) )->active )
{
int i = gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "disc_title" ) ) );
#ifdef HAVE_VCDX
int i_pbc = config_GetInt( p_intf, "vcdx-PBC" );
gtk_label_set_text( GTK_LABEL( p_label ),
i_pbc ? _("PBC LID") : _("Entry") );
g_string_append( p_target, VCD_MRL );
g_string_append( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "disc_name" ) ) ) );
if ( i )
g_string_sprintfa( p_target, "@%c%d", i_pbc ? 'P' : 'E', i );
#else
gtk_label_set_text( GTK_LABEL( p_label ), _("Track") );
g_string_append( p_target, VCD_MRL );
g_string_sprintfa( p_target, "@%d", i );
#endif /* HAVE_VCDX */
b_chapter_menu = VLC_FALSE;
}
else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
"disc_cdda" ) )->active )
{
int i = gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "disc_title" ) ) );
gtk_label_set_text( GTK_LABEL( p_label ), _("Track") );
b_chapter_menu = VLC_FALSE;
g_string_append( p_target, CDDA_MRL );
g_string_append( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "disc_name" ) ) ) );
#ifdef HAVE_CDDAX
if ( i )
g_string_sprintfa( p_target, "@T%i", i );
#else
g_string_sprintfa( p_target, "@%i", i );
#endif
}
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"disc_title_label" ), !b_menus );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"disc_title" ), !b_menus );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"disc_chapter_label" ), b_chapter_menu && !b_menus );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"disc_chapter" ), b_chapter_menu && !b_menus );
gtk_entry_set_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "entry_open" ) ),
p_target->str );
g_string_free( p_target, TRUE );
}
/*****************************************************************************
* Network stream callbacks
*****************************************************************************
* The following callbacks are related to the network stream manager.
*****************************************************************************/
gboolean GtkNetworkOpenShow( GtkWidget *widget,
gpointer user_data )
{
GtkOpenShow( GtkGetIntf( widget ), 2 );
return TRUE;
}
static void GtkNetworkOpenChanged( GtkWidget *button, gpointer user_data )
{
GString * p_target = g_string_new( "" );
unsigned int i_port;
#define SELECTED( s ) GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button), \
(s) ) )->active
/* Check which option was chosen */
if( SELECTED( "network_udp" ) )
{
g_string_append( p_target, "udp://" );
i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
lookup_widget( GTK_WIDGET(button),
"network_udp_port" ) ) );
if( i_port != 1234 )
{
g_string_sprintfa( p_target, "@:%i", i_port );
}
}
else if( SELECTED( "network_multicast" ) )
{
g_string_sprintfa( p_target, "udp://@%s",
gtk_entry_get_text( GTK_ENTRY(
lookup_widget( GTK_WIDGET(button),
"network_multicast_address" ) ) ) );
i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
lookup_widget( GTK_WIDGET(button),
"network_multicast_port" ) ) );
if( i_port != 1234 )
{
g_string_sprintfa( p_target, ":%i", i_port );
}
}
else if( SELECTED( "network_http" ) )
{
g_string_assign( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "network_http_url" ) ) ) );
}
gtk_entry_set_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "entry_open" ) ),
p_target->str );
g_string_free( p_target, TRUE );
}
void GtkNetworkOpenUDP( GtkToggleButton *togglebutton,
gpointer user_data )
{
GtkWidget * p_open;
p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_udp_port_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_udp_port" ),
gtk_toggle_button_get_active( togglebutton ) );
GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
}
void GtkNetworkOpenMulticast( GtkToggleButton *togglebutton,
gpointer user_data )
{
GtkWidget * p_open;
p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_multicast_address_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_multicast_address_combo" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_multicast_port_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_multicast_port" ),
gtk_toggle_button_get_active( togglebutton ) );
GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
}
void GtkNetworkOpenHTTP( GtkToggleButton *togglebutton,
gpointer user_data )
{
GtkWidget * p_open;
p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_http_url_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
"network_http_url" ),
gtk_toggle_button_get_active( togglebutton ) );
GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
}
/*****************************************************************************
* Open satellite callbacks
*****************************************************************************
* The following callbacks are related to the satellite card manager.
*****************************************************************************/
gboolean GtkSatOpenShow( GtkWidget *widget,
gpointer user_data)
{
GtkOpenShow( GtkGetIntf( widget ), 3 );
return TRUE;
}
static void GtkSatOpenChanged( GtkWidget * button, gpointer user_data )
{
GString * p_target = g_string_new( "" );
g_string_sprintfa( p_target, "%s://%d,%d,%ld,%d", "satellite",
gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "sat_freq" ) ) ),
!GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET( button ),
"sat_pol_vert" ) )->active,
strtol( gtk_entry_get_text( GTK_ENTRY( GTK_COMBO(
lookup_widget( GTK_WIDGET( button ), "sat_fec" )
)->entry ) ), NULL, 10 ),
gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "sat_srate" ) ) ) );
gtk_entry_set_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "entry_open" ) ),
p_target->str );
g_string_free( p_target, TRUE );
}
void
GtkSatOpenToggle (GtkToggleButton *togglebutton,
gpointer user_data)
{
if( togglebutton->active )
{
GtkSatOpenChanged( GTK_WIDGET( togglebutton ), user_data );
}
}
/*****************************************************************************
* Open subtitle callbacks
*****************************************************************************
* The following callbacks are related to the subtitle
*****************************************************************************/
void
GtkOpenSubtitleShow (GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
if( GTK_TOGGLE_BUTTON( button )->active )
{
/* show hbox_subtitle */
gtk_widget_show_all( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "hbox_subtitle" ) ) );
}
else
{
/* hide hbox_subtitle */
gtk_widget_hide_all( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "hbox_subtitle" ) ) );
}
}
/*****************************************************************************
* Open sout callbacks
*****************************************************************************
* The following callbacks are related to the sout
*****************************************************************************/
void GtkOpenSoutShow ( GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
if( GTK_TOGGLE_BUTTON( button )->active )
{
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "sout_settings" ) ), TRUE );
}
else
{
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "sout_settings" ) ), FALSE );
}
}
/******************************
******************************/
static void GtkOpenShow( intf_thread_t *p_intf, int i_page )
{
char *psz_var;
GtkWidget *p_notebook;
/* If we have already created this window, do nothing */
if( GTK_IS_WIDGET( p_intf->p_sys->p_open ) )
{
goto setpage;
}
p_intf->p_sys->p_open = create_intf_open();
gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_open ),
"p_intf", p_intf );
/* FileOpen stuff */
psz_var = config_GetPsz( p_intf, MODULE_STRING"-search-path" );
if( psz_var )
{
gtk_file_selection_set_filename( GTK_FILE_SELECTION(
p_intf->p_sys->p_open ), psz_var );
free( psz_var );
}
/* Disc stuff */
psz_var = config_GetPsz( p_intf, "dvd" );
if( psz_var )
{
gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_open ), "disc_name" ) ),
psz_var );
free( psz_var );
}
/* Network stuff */
gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_open ), "network_udp_port" ) ),
config_GetInt( p_intf, "server-port" ) );
gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_open ), "network_http_url" ) ),
"http://" );
#ifdef HAVE_SATELLITE
/* Satellite stuff */
psz_var = config_GetPsz( p_intf, "frequency" );
if( psz_var )
{
gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_open ), "sat_freq" ) ),
psz_var );
free( psz_var );
}
psz_var = config_GetPsz( p_intf, "symbol-rate" );
if( psz_var )
{
gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_open ), "sat_srate" ) ),
psz_var );
free( psz_var );
}
#endif /*HAVE_SATELITE*/
/* subtitle stuff */
/* hide hbox_subtitle */
gtk_widget_hide_all( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "hbox_subtitle" ) ) );
/* sout */
psz_var = config_GetPsz( p_intf, "sout" );
if( psz_var && *psz_var )
{
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "show_sout_settings" ), TRUE );
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "sout_settings" ) ), TRUE );
}
else
{
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "show_sout_settings" ), FALSE );
gtk_widget_set_sensitive( GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_open ), "sout_settings" ) ), FALSE );
}
if( psz_var ) free( psz_var );
/* Set the right page */
setpage:
p_notebook = lookup_widget( GTK_WIDGET( p_intf->p_sys->p_open ),
"open_notebook" );
gtk_notebook_set_page( GTK_NOTEBOOK( p_notebook ), i_page );
gtk_widget_show( p_intf->p_sys->p_open );
gdk_window_raise( p_intf->p_sys->p_open->window );
}
void GtkOpenOk( GtkButton * button, gpointer user_data )
{
/* Check what was pressed */
intf_thread_t * p_intf = GtkGetIntf( button );
playlist_t * p_playlist;
GtkCList * p_playlist_clist;
gchar * psz_target;
/* Hide the dialog box */
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
/* Update the playlist */
p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
psz_target = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "entry_open" ) ) );
playlist_Add( p_playlist, (char*)psz_target, (char*)psz_target,
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
/* catch the GTK CList */
p_playlist_clist = GTK_CLIST( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_playwin ), "playlist_clist" ) );
/* update the plugin display */
GtkRebuildCList( p_playlist_clist, p_playlist );
vlc_object_release( p_playlist );
/* export subtitle */
if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
"show_subtitle" ) )->active )
{
/* yeah subtitle */
char *psz_subtitle;
gfloat delay;
gfloat fps;
psz_subtitle = gtk_entry_get_text( GTK_ENTRY( lookup_widget( GTK_WIDGET(button), "entry_subtitle" ) ) );
delay = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON( lookup_widget( GTK_WIDGET(button), "subtitle_delay" ) ) );
fps = gtk_spin_button_get_value_as_float( GTK_SPIN_BUTTON( lookup_widget( GTK_WIDGET(button), "subtitle_fps" ) ) );
config_PutPsz( p_intf, "sub-file", psz_subtitle );
config_PutInt( p_intf, "sub-delay", (int)( delay * 10 ) );
config_PutFloat( p_intf, "sub-fps", fps );
}
else
{
config_PutPsz( p_intf, "sub-file", "" );
}
/* export sout */
if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
"show_sout_settings" ) )->active )
{
char *psz_sout;
psz_sout = gtk_entry_get_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( p_intf->p_sys->p_sout ), "sout_entry_target" ) ) );
config_PutPsz( p_intf, "sout", psz_sout );
}
else
{
config_PutPsz( p_intf, "sout", "" );
}
}
void GtkOpenCancel( GtkButton * button, gpointer user_data )
{
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
void GtkOpenChanged( GtkWidget * button, gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
GtkWidget *p_notebook;
int i_page;
p_notebook = lookup_widget( GTK_WIDGET( p_intf->p_sys->p_open ),
"open_notebook" );
i_page = gtk_notebook_get_current_page( GTK_NOTEBOOK( p_notebook ) );
switch( i_page )
{
case 0:
GtkFileOpenChanged( button, NULL );
break;
case 1:
GtkDiscOpenChanged( button, NULL );
break;
case 2:
GtkNetworkOpenChanged( button, NULL );
break;
case 3:
GtkSatOpenChanged( button, NULL );
break;
}
}
/*****************************************************************************
* gtk_open.h: prototypes for open functions
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@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.
*****************************************************************************/
gboolean GtkFileOpenShow ( GtkWidget *, gpointer );
void GtkFileOpenCancel ( GtkButton *, gpointer );
void GtkFileOpenOk ( GtkButton *, gpointer );
gboolean GtkDiscOpenShow ( GtkWidget *, gpointer );
void GtkDiscOpenDvd ( GtkToggleButton *, gpointer );
void GtkDiscOpenVcd ( GtkToggleButton *, gpointer );
void GtkDiscOpenCDDA ( GtkToggleButton *, gpointer );
void GtkDiscOpenOk ( GtkButton *, gpointer );
void GtkDiscOpenCancel ( GtkButton *, gpointer );
gboolean GtkNetworkOpenShow ( GtkWidget *, gpointer );
void GtkNetworkOpenOk ( GtkButton *, gpointer );
void GtkNetworkOpenCancel ( GtkButton *, gpointer );
void GtkNetworkOpenBroadcast( GtkToggleButton *, gpointer );
void GtkNetworkOpenChannel ( GtkToggleButton *, gpointer );
/*****************************************************************************
* gtk_playlist.c : Interface for the playlist dialog
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Pierre Baillet <oct@zoy.org>
* Stphane Borel <stef@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 <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <sys/types.h> /* for readdir and stat stuff */
#if (!defined( WIN32 ) || defined(__MINGW32__))
/* Mingw has its own version of dirent */
# include <dirent.h>
#endif
#include <sys/stat.h>
#include <unistd.h>
#ifdef MODULE_NAME_IS_gnome
# include <gnome.h>
#else
# include <gtk/gtk.h>
#endif
#include "gtk_callbacks.h"
#include "gtk_interface.h"
#include "gtk_support.h"
#include "playlist.h"
#include "common.h"
/****************************************************************************
* Local prototypes
****************************************************************************/
static void UrlDecode ( char * );
static GList * GtkReadFiles ( intf_thread_t *, gchar * );
/****************************************************************************
* Playlist window management
****************************************************************************/
gboolean GtkPlaylistShow( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
if( GTK_WIDGET_VISIBLE( p_intf->p_sys->p_playwin ) )
{
gtk_widget_hide( p_intf->p_sys->p_playwin );
}
else
{
GtkCList * p_clist;
p_clist = GTK_CLIST( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_playwin ), "playlist_clist" ) );
GtkRebuildCList( p_clist , p_playlist );
gtk_widget_show( p_intf->p_sys->p_playwin );
gdk_window_raise( p_intf->p_sys->p_playwin->window );
}
vlc_object_release( p_playlist );
return TRUE;
}
void GtkPlaylistOk( GtkButton * button, gpointer user_data )
{
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
void GtkPlaylistCancel( GtkButton * button, gpointer user_data )
{
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
gboolean GtkPlaylistPrev( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
playlist_Prev( p_playlist );
vlc_object_release( p_playlist );
return TRUE;
}
gboolean GtkPlaylistNext( GtkWidget *widget,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
playlist_Next( p_playlist );
vlc_object_release( p_playlist );
return TRUE;
}
/****************************************************************************
* Playlist core functions
****************************************************************************/
void GtkPlaylistAddUrl( GtkMenuItem * menuitem, gpointer user_data )
{
}
void GtkPlaylistDeleteAll( GtkMenuItem * menuitem, gpointer user_data )
{
}
void GtkPlaylistDeleteSelected( GtkMenuItem * menuitem, gpointer user_data )
{
/* user wants to delete a file in the queue */
GList * p_selection;
GtkCList * p_clist;
intf_thread_t * p_intf = GtkGetIntf( menuitem);
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
/* lock the struct */
vlc_mutex_lock( &p_intf->change_lock );
p_clist = GTK_CLIST( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist" ) );
p_selection = p_clist->selection;
if( g_list_length( p_selection ) )
{
/* reverse-sort so that we can delete from the furthest
* to the closest item to delete...
*/
p_selection = g_list_sort( p_selection, GtkCompareItems );
g_list_foreach( p_selection, GtkDeleteGListItem, p_playlist );
/* rebuild the CList */
GtkRebuildCList( p_clist, p_playlist );
}
vlc_mutex_unlock( &p_intf->change_lock );
vlc_object_release( p_playlist );
}
void GtkPlaylistCrop( GtkMenuItem * menuitem, gpointer user_data )
{
/* Ok, this is a really small thing, but, hey, it works and
might be useful, who knows ? */
GtkPlaylistInvert( menuitem, user_data );
GtkPlaylistDeleteSelected( menuitem, user_data );
}
void GtkPlaylistInvert( GtkMenuItem * menuitem, gpointer user_data )
{
GtkCList * p_clist;
int * pi_selected;
int i_length;
int i_dummy;
/* catch the thread back */
intf_thread_t *p_intf = GtkGetIntf( menuitem );
/* lock the struct */
vlc_mutex_lock( &p_intf->change_lock );
p_clist = GTK_CLIST( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist" ) );
gtk_clist_freeze( p_clist );
/* have to copy the selection to an int *
I wasn't able to copy the g_list to another g_list
glib only does pointer copies, not real copies :( */
i_length = g_list_length( p_clist->selection );
pi_selected = malloc( sizeof(int) * i_length );
for( i_dummy = 0 ; i_dummy < i_length ; i_dummy++ )
{
pi_selected[i_dummy] =
GPOINTER_TO_UINT( g_list_nth_data( p_clist->selection, i_dummy ) );
}
gtk_clist_select_all( p_clist );
for( i_dummy = 0; i_dummy < i_length; i_dummy++ )
{
gtk_clist_unselect_row( p_clist, pi_selected[i_dummy], 0 );
}
gtk_clist_thaw( p_clist );
vlc_mutex_unlock( &p_intf->change_lock );
free( pi_selected );
}
void GtkPlaylistSelect( GtkMenuItem * menuitem, gpointer user_data)
{
}
gboolean GtkPlaylistEvent( GtkWidget * widget,
GdkEvent * event,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
if( ( event->button ).type == GDK_2BUTTON_PRESS )
{
GtkCList * p_clist;
gint i_row;
gint i_col;
p_clist = GTK_CLIST( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist" ) );
if( gtk_clist_get_selection_info( p_clist, (event->button).x,
(event->button).y, &i_row, &i_col ) == 1 )
{
playlist_Goto( p_playlist, i_row );
}
vlc_object_release( p_playlist );
return TRUE;
}
vlc_object_release( p_playlist );
return FALSE;
}
void GtkPlaylistDragData( GtkWidget *widget,
GdkDragContext *drag_context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( widget );
GtkCList * p_clist;
gint i_row;
gint i_col;
p_clist = GTK_CLIST( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist" ) );
if( gtk_clist_get_selection_info( p_clist, x, y, &i_row, &i_col ) == 1 )
{
/* we are dropping somewhere into the clist items */
GtkDropDataReceived( p_intf, data, info, i_row - 1 );
}
else
{
/* otherwise, put that at the end of the playlist */
GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
}
}
gboolean GtkPlaylistDragMotion( GtkWidget *widget,
GdkDragContext *drag_context,
gint x,
gint y,
guint time,
gpointer user_data )
{
GtkCList * p_clist;
gint i_row;
gint i_col;
int i_dummy;
GdkColor color;
intf_thread_t * p_intf = GtkGetIntf( widget );
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return FALSE;
}
p_clist = GTK_CLIST( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist" ) );
if( !GTK_WIDGET_TOPLEVEL(widget) )
{
gdk_window_raise( p_intf->p_sys->p_playwin->window );
}
color.red = 0xffff;
color.blue = 0xffff;
color.green = 0xffff;
gtk_clist_freeze( p_clist );
for( i_dummy = 0; i_dummy < p_clist->rows; i_dummy++)
{
gtk_clist_set_background( p_clist, i_dummy , &color );
}
color.red = 0;
color.blue = 0xf000;
color.green = 0x9000;
if( gtk_clist_get_selection_info( p_clist, x, y, &i_row, &i_col ) == 1 )
{
gtk_clist_set_background ( p_clist, i_row - 1, &color );
gtk_clist_set_background ( p_clist, i_row, &color );
}
else
{
gtk_clist_set_background ( p_clist, p_clist->rows - 1, &color );
}
color.red = 0xffff;
color.blue = 0;
color.green = 0;
vlc_mutex_lock( &p_playlist->object_lock );
gtk_clist_set_background( p_clist, p_playlist->i_index, &color );
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
gtk_clist_thaw( p_clist );
return TRUE;
}
void GtkDropDataReceived( intf_thread_t * p_intf,
GtkSelectionData * p_data, guint i_info, int i_position)
{
/* first we'll have to split against all the '\n' we have */
gchar * p_protocol;
gchar * p_temp;
gchar * p_next;
gchar * p_string = (gchar *)p_data->data;
GList * p_files = NULL;
GtkCList * p_clist;
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
/* if this has been URLencoded, decode it
*
* Is it a good thing to do it in place ?
* probably not...
*/
if( i_info == DROP_ACCEPT_TEXT_URI_LIST )
{
UrlDecode( p_string );
}
/* this cuts string into single file drops */
/* this code was borrowed from xmms, thx guys :) */
while( *p_string)
{
p_next = strchr( p_string, '\n' );
if( p_next )
{
if( *( p_next - 1 ) == '\r' )
{
*( p_next - 1) = '\0';
}
*p_next = '\0';
}
/* do we have a protocol or something ? */
p_temp = strstr( p_string, ":" );
if( p_temp != NULL && p_temp[0] != '\0' )
{
char i_save;
i_save = p_temp[0];
p_temp[0] = '\0';
p_protocol = strdup( p_string );
p_temp[0] = i_save;
p_temp++;
/* Allowed things are proto: or proto:// */
if( p_temp[0] == '/' && p_temp[1] == '/')
{
/* eat two '/'s */
p_temp += 2;
}
msg_Dbg( p_intf, "playlist protocol '%s', target '%s'",
p_protocol, p_temp );
}
else
{
p_protocol = strdup( "" );
}
/* if it uses the file protocol we can do something, else, sorry :(
* I think this is a good choice for now, as we don't have any
* ability to read http:// or ftp:// files
* what about adding dvd:// to the list of authorized proto ? */
if( strcmp( p_protocol, "file:" ) == 0 )
{
p_files = g_list_concat( p_files,
GtkReadFiles( p_intf, p_string ) );
}
else
{
p_files = g_list_concat( p_files,
g_list_append( NULL, g_strdup( p_string ) ) );
}
/* free the malloc and go on... */
free( p_protocol );
if( p_next == NULL )
{
break;
}
p_string = p_next + 1;
}
/* At this point, we have a nice big list maybe NULL */
if( p_files != NULL )
{
/* lock the interface */
vlc_mutex_lock( &p_intf->change_lock );
msg_Dbg( p_intf, "adding %d elements", g_list_length( p_files ) );
GtkAppendList( p_playlist, i_position, p_files );
/* get the CList and rebuild it. */
p_clist = GTK_CLIST( lookup_widget( p_intf->p_sys->p_playwin,
"playlist_clist" ) );
GtkRebuildCList( p_clist , p_playlist );
/* unlock the interface */
vlc_mutex_unlock( &p_intf->change_lock );
}
vlc_object_release( p_playlist );
}
void GtkDeleteGListItem( gpointer data, gpointer param )
{
int i_cur_row = (long)data;
playlist_t * p_playlist = param;
playlist_LockDelete( p_playlist, i_cur_row );
}
gint GtkCompareItems( gconstpointer a, gconstpointer b )
{
return (ptrdiff_t) ( (int *)b - (int *)a );
}
/* check a file (string) against supposed valid extension */
int GtkHasValidExtension( gchar * psz_filename )
{
char * ppsz_ext[6] = { "mpg", "mpeg", "vob", "mp2", "ts", "ps" };
int i_ext = 6;
int i_dummy;
gchar * psz_ext = strrchr( psz_filename, '.' ) + sizeof( char );
for( i_dummy = 0 ; i_dummy < i_ext ; i_dummy++ )
{
if( strcmp( psz_ext, ppsz_ext[i_dummy] ) == 0 )
{
return 1;
}
}
return 0;
}
/* recursive function: descend into folders and build a list of
* valid filenames */
static GList * GtkReadFiles( intf_thread_t * p_intf, gchar * psz_fsname )
{
struct stat statbuf;
GList * p_current = NULL;
/* get the attributes of this file */
stat( psz_fsname, &statbuf );
/* is it a regular file ? */
if( S_ISREG( statbuf.st_mode ) )
{
if( GtkHasValidExtension( psz_fsname ) )
{
msg_Dbg( p_intf, "%s is a valid file, stacking on the playlist",
psz_fsname );
return g_list_append( NULL, g_strdup( psz_fsname ) );
}
else
{
return NULL;
}
}
/* is it a directory (should we check for symlinks ?) */
else if( S_ISDIR( statbuf.st_mode ) )
{
/* have to cd into this dir */
DIR * p_current_dir = opendir( psz_fsname );
struct dirent * p_dir_content;
msg_Dbg( p_intf, "%s is a folder", psz_fsname );
if( p_current_dir == NULL )
{
/* something went bad, get out of here ! */
return p_current;
}
p_dir_content = readdir( p_current_dir );
/* while we still have entries in the directory */
while( p_dir_content != NULL )
{
/* if it is "." or "..", forget it */
if( ( strcmp( p_dir_content->d_name, "." ) != 0 ) &&
( strcmp( p_dir_content->d_name, ".." ) != 0 ) )
{
/* else build the new directory by adding
fsname "/" and the current entry name
(kludgy :()
*/
char * psz_newfs = malloc ( 2 + strlen( psz_fsname ) +
strlen( p_dir_content->d_name ) * sizeof(char) );
strcpy( psz_newfs, psz_fsname );
strcpy( psz_newfs + strlen( psz_fsname ) + 1,
p_dir_content->d_name );
psz_newfs[strlen( psz_fsname )] = '/';
p_current = g_list_concat( p_current,
GtkReadFiles( p_intf, psz_newfs ) );
g_free( psz_newfs );
}
p_dir_content = readdir( p_current_dir );
}
return p_current;
}
return NULL;
}
/* add items in a playlist
* when i_pos==-1 add to the end of the list...
*/
int GtkAppendList( playlist_t * p_playlist, int i_pos, GList * p_list )
{
int i_dummy;
int i_length;
i_length = g_list_length( p_list );
for( i_dummy = 0; i_dummy < i_length ; i_dummy++ )
{
playlist_Add( p_playlist,
/* ok; this is a really nasty trick to insert
the item where they are suppose to go but, hey
this works :P (btw, you are really nasty too) */
g_list_nth_data( p_list, i_dummy ),
g_list_nth_data( p_list, i_dummy ),
i_dummy == 0 ? PLAYLIST_INSERT | PLAYLIST_GO : PLAYLIST_INSERT,
i_pos == PLAYLIST_END ? PLAYLIST_END : ( i_pos + i_dummy ) );
}
return 0;
}
/* statis timeouted function */
void GtkPlayListManage( intf_thread_t * p_intf )
{
playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
GtkCList * p_clist;
if( p_playlist == NULL )
{
return;
}
/* this thing really sucks for now :( */
/* TODO speak more with src/playlist/playlist.c */
if( GTK_IS_WIDGET( p_intf->p_sys->p_playwin ) )
{
p_clist = GTK_CLIST( gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_playwin ), "playlist_clist" ) );
vlc_mutex_lock( &p_playlist->object_lock );
if( p_intf->p_sys->i_playing != p_playlist->i_index )
{
GdkColor color;
color.red = 0xffff;
color.blue = 0;
color.green = 0;
gtk_clist_set_background( p_clist, p_playlist->i_index, &color );
if( p_intf->p_sys->i_playing != -1 )
{
color.red = 0xffff;
color.blue = 0xffff;
color.green = 0xffff;
gtk_clist_set_background( p_clist, p_intf->p_sys->i_playing,
&color);
}
p_intf->p_sys->i_playing = p_playlist->i_index;
}
vlc_mutex_unlock( &p_playlist->object_lock );
}
vlc_object_release( p_playlist );
}
void GtkRebuildCList( GtkCList * p_clist, playlist_t * p_playlist )
{
int i_dummy;
gchar * ppsz_text[2];
GdkColor red;
red.red = 65535;
red.blue = 0;
red.green = 0;
gtk_clist_freeze( p_clist );
gtk_clist_clear( p_clist );
vlc_mutex_lock( &p_playlist->object_lock );
for( i_dummy = p_playlist->i_size ; i_dummy-- ; )
{
char psz_duration[MSTRTIME_MAX_SIZE];
mtime_t dur = p_playlist->pp_items[i_dummy]->input.i_duration;
if ( dur != -1 )
{
secstotimestr( psz_duration, dur/1000000 );
}
else
{
memcpy( psz_duration ,"no info",sizeof("no info" ));
}
ppsz_text[0] = p_playlist->pp_items[i_dummy]->input.psz_name;
ppsz_text[1] = strdup( psz_duration );
gtk_clist_insert( p_clist, 0, ppsz_text );
}
vlc_mutex_unlock( &p_playlist->object_lock );
gtk_clist_set_background( p_clist, p_playlist->i_index, &red);
gtk_clist_thaw( p_clist );
}
/* URL-decode a file: URL path, return NULL if it's not what we expect */
static void UrlDecode( char *encoded_path )
{
char *tmp = NULL, *cur = NULL, *ext = NULL;
int realchar;
if( !encoded_path || *encoded_path == '\0' )
{
return;
}
cur = encoded_path ;
tmp = calloc(strlen(encoded_path) + 1, sizeof(char) );
while ( ( ext = strchr(cur, '%') ) != NULL)
{
strncat(tmp, cur, (ext - cur) / sizeof(char));
ext++;
if (!sscanf(ext, "%2x", &realchar))
{
free(tmp);
return;
}
tmp[strlen(tmp)] = (char)realchar;
cur = ext + 2;
}
strcat(tmp, cur);
strcpy(encoded_path,tmp);
}
/*****************************************************************************
* gtk_playlist.h : Playlist functions for the Gtk plugin.
*****************************************************************************
* Copyright (C) 2000, 2001 the VideoLAN team
* $Id$
*
* Authors: Pierre Baillet <oct@zoy.org>
* Stphane Borel <stef@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.
*****************************************************************************/
void GtkPlaylistDeleteAll ( GtkMenuItem *, gpointer );
void GtkPlaylistDeleteSelected( GtkMenuItem *, gpointer );
void GtkPlaylistCrop ( GtkMenuItem *, gpointer );
void GtkPlaylistInvert ( GtkMenuItem *, gpointer );
void GtkPlaylistSelect ( GtkMenuItem *, gpointer );
void GtkPlaylistOk ( GtkButton *, gpointer );
void GtkPlaylistCancel ( GtkButton *, gpointer );
void GtkPlaylistAddUrl ( GtkMenuItem *, gpointer );
gint GtkCompareItems ( gconstpointer, gconstpointer );
int GtkHasValidExtension ( gchar * );
gboolean GtkPlaylistShow ( GtkWidget *, gpointer );
gboolean GtkPlaylistPrev ( GtkWidget *, gpointer );
gboolean GtkPlaylistNext ( GtkWidget *, gpointer );
gboolean GtkPlaylistDragMotion( GtkWidget *, GdkDragContext *,
gint, gint, guint, gpointer );
gboolean GtkPlaylistEvent ( GtkWidget *, GdkEvent *, gpointer );
void GtkPlaylistDragData ( GtkWidget *, GdkDragContext *,
gint, gint, GtkSelectionData *,
guint, guint, gpointer );
void GtkDeleteGListItem ( gpointer, gpointer );
void GtkDropDataReceived ( intf_thread_t *, GtkSelectionData *, guint, int );
int GtkAppendList ( playlist_t *, int, GList * );
void GtkRebuildCList ( GtkCList *, playlist_t * );
void GtkPlayListManage ( intf_thread_t * );
/*****************************************************************************
* gtk_preferences.c: functions to handle the preferences dialog box.
*****************************************************************************
* Copyright (C) 2001-2004 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Loc Minier <lool@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: Our main job is to build a nice interface from the modules config
* structure. Once this is done, we need to track each change made by the
* user to the data contained in this interface so that when/if he decides to
* apply his changes we can quickly commit them into the modules config
* structure. (for this last task we use a GHashTable to accumulate the
* changes. To commit them, we then just have to circle through it )
*
*****************************************************************************/
#include <sys/types.h> /* off_t */
#include <stdlib.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#ifdef MODULE_NAME_IS_gnome
# include <gnome.h>
#else
# include <gtk/gtk.h>
#endif
#include <string.h>
#include "gtk_support.h"
#include "common.h"
#include "preferences.h"
/* local functions */
static void GtkCreateConfigDialog( char *, intf_thread_t * );
static void GtkConfigOk ( GtkButton *, gpointer );
static void GtkConfigApply ( GtkButton *, gpointer );
static void GtkConfigCancel ( GtkButton *, gpointer );
static void GtkConfigSave ( GtkButton *, gpointer );
static void GtkConfigDialogDestroyed ( GtkObject *, gpointer );
static void GtkStringChanged ( GtkEditable *, gpointer );
static void GtkIntChanged ( GtkEditable *, gpointer );
static void GtkIntRangedChanged ( GtkEditable *, gpointer );
static void GtkFloatChanged ( GtkEditable *, gpointer );
static void GtkFloatRangedChanged ( GtkEditable *, gpointer );
static void GtkBoolChanged ( GtkToggleButton *, gpointer );
static void GtkFreeHashTable ( GtkObject *object );
static void GtkFreeHashValue ( gpointer, gpointer, gpointer );
static gboolean GtkSaveHashValue ( gpointer, gpointer, gpointer );
static void GtkModuleConfigure ( GtkButton *, gpointer );
static void GtkModuleSelected ( GtkButton *, gpointer );
static void GtkModuleHighlighted ( GtkCList *, int, int, GdkEventButton *,
gpointer );
/****************************************************************************
* Callback for menuitems: display configuration interface window
****************************************************************************/
void GtkPreferencesShow( GtkMenuItem * menuitem, gpointer user_data )
{
intf_thread_t * p_intf;
p_intf = GtkGetIntf( menuitem );
GtkCreateConfigDialog( "main", p_intf );
}
/****************************************************************************
* GtkCreateConfigDialog: dynamically creates the configuration dialog
* box from all the configuration data provided by the selected module.
****************************************************************************/
/* create a new tooltipped area */
#define TOOLTIP( text ) \
/* create an event box to catch some events */ \
item_event_box = gtk_event_box_new(); \
/* add a tooltip on mouseover */ \
gtk_tooltips_set_tip( p_intf->p_sys->p_tooltips, \
item_event_box, text, "" ); \
gtk_container_set_border_width( GTK_CONTAINER(item_event_box), 4 );
/* draws a right aligned label in side of a widget */
#define LABEL_AND_WIDGET( label_text, widget, tooltip ) \
gtk_table_resize( GTK_TABLE(category_table), ++rows, 2 ); \
item_align = gtk_alignment_new( 1, .5, 0, 0 ); \
item_label = gtk_label_new( label_text ); \
gtk_container_add( GTK_CONTAINER(item_align), item_label ); \
gtk_table_attach_defaults( GTK_TABLE(category_table), item_align, \
0, 1, rows - 1, rows ); \
item_align = gtk_alignment_new( 0, .5, .5, 0 ); \
gtk_container_add( GTK_CONTAINER(item_align), widget ); \
TOOLTIP(tooltip) \
gtk_container_add( GTK_CONTAINER(item_event_box), item_align ); \
gtk_table_attach_defaults( GTK_TABLE(category_table), item_event_box, \
1, 2, rows - 1, rows );
static void GtkCreateConfigDialog( char *psz_module_name,
intf_thread_t *p_intf )
{
module_t *p_parser = NULL;
vlc_list_t *p_list;
module_config_t *p_item;
vlc_bool_t b_advanced = config_GetInt( p_intf, "advanced" );
int i_index;
guint rows = 0;
GHashTable *config_hash_table;
GtkWidget *item_event_box;
GtkWidget *config_dialog;
GtkWidget *config_dialog_vbox;
GtkWidget *config_notebook;
GtkWidget *category_table = NULL;
GtkWidget *category_label = NULL;
#ifndef MODULE_NAME_IS_gnome
GtkWidget *dialog_action_area;
#endif
GtkWidget *ok_button;
GtkWidget *apply_button;
GtkWidget *save_button;
GtkWidget *cancel_button;
GtkWidget *item_align;
GtkWidget *item_frame;
GtkWidget *item_hbox;
GtkWidget *item_label;
GtkWidget *item_vbox;
GtkWidget *item_combo;
GtkWidget *string_entry;
GtkWidget *integer_spinbutton;
GtkWidget *integer_slider;
GtkWidget *float_spinbutton;
GtkWidget *float_slider;
GtkObject *item_adj;
GtkWidget *bool_checkbutton;
GtkWidget *module_clist;
GtkWidget *module_config_button;
GtkWidget *module_select_button;
gint category_max_height;
/* Check if the dialog box is already opened because we don't want to
* duplicate identical dialog windows. */
config_dialog = (GtkWidget *)gtk_object_get_data(
GTK_OBJECT(p_intf->p_sys->p_window), psz_module_name );
if( config_dialog )
{
/* Yeah it was open */
gtk_widget_grab_focus( config_dialog );
return;
}
/* Look for the selected module */
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( psz_module_name
&& !strcmp( psz_module_name, p_parser->psz_object_name ) )
{
break;
}
}
if( !p_parser || i_index == p_list->i_count )
{
vlc_list_release( p_list );
return;
}
/* We found it, now we can start building its configuration interface */
/* Create the configuration dialog box */
#ifdef MODULE_NAME_IS_gnome
config_dialog = gnome_dialog_new( p_parser->psz_longname, NULL );
config_dialog_vbox = GNOME_DIALOG(config_dialog)->vbox;
#else
config_dialog = gtk_dialog_new();
gtk_window_set_title( GTK_WINDOW(config_dialog),
p_parser->psz_longname );
config_dialog_vbox = GTK_DIALOG(config_dialog)->vbox;
#endif
gtk_object_set_data( GTK_OBJECT(config_dialog), "p_intf", p_intf );
category_max_height = config_GetInt( p_intf, MODULE_STRING "-prefs-maxh" );
gtk_window_set_policy( GTK_WINDOW(config_dialog), TRUE, TRUE, FALSE );
gtk_container_set_border_width( GTK_CONTAINER(config_dialog_vbox), 0 );
/* Create our config hash table and associate it with the dialog box */
config_hash_table = g_hash_table_new( NULL, NULL );
gtk_object_set_data( GTK_OBJECT(config_dialog),
"config_hash_table", config_hash_table );
/* Create notebook */
config_notebook = gtk_notebook_new();
gtk_notebook_set_scrollable( GTK_NOTEBOOK(config_notebook), TRUE );
gtk_container_add( GTK_CONTAINER(config_dialog_vbox), config_notebook );
/* Enumerate config options and add corresponding config boxes */
p_item = p_parser->p_config;
if( p_item ) do
{
if( p_item->b_advanced && !b_advanced ) continue;
if( p_item->i_type == CONFIG_HINT_CATEGORY ||
p_item->i_type == CONFIG_HINT_END ||
!category_table )
{
/*
* Before we start building the interface for the new category, we
* must close/finish the previous one we were generating.
*/
if( category_table )
{
GtkWidget *_scrolled_window;
GtkWidget *_viewport;
GtkWidget *_vbox;
GtkRequisition _requisition;
/* create a vbox to deal with EXPAND/FILL issues in the
* notebook page, and pack it with the previously generated
* category_table */
_vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_set_border_width( GTK_CONTAINER(_vbox), 4 );
gtk_box_pack_start( GTK_BOX(_vbox), category_table,
FALSE, FALSE, 0 );
/* create a new scrolled window that will contain all of the
* above. */
_scrolled_window = gtk_scrolled_window_new( NULL, NULL );
gtk_scrolled_window_set_policy(
GTK_SCROLLED_WINDOW(_scrolled_window), GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC );
/* add scrolled window as a notebook page */
gtk_notebook_append_page( GTK_NOTEBOOK(config_notebook),
_scrolled_window, category_label );
/* pack the vbox into the scrolled window */
_viewport = gtk_viewport_new( NULL, NULL );
gtk_viewport_set_shadow_type( GTK_VIEWPORT(_viewport),
GTK_SHADOW_NONE );
gtk_container_add( GTK_CONTAINER(_viewport), _vbox );
gtk_container_add( GTK_CONTAINER(_scrolled_window),
_viewport );
/* set the size of the scrolled window to the size of the
* child widget */
gtk_widget_show_all( _vbox );
gtk_widget_size_request( _vbox, &_requisition );
if( _requisition.height > category_max_height )
gtk_widget_set_usize( _scrolled_window, -1,
category_max_height );
else
gtk_widget_set_usize( _scrolled_window, -1,
_requisition.height );
}
/*
* Now we can start taking care of the new category
*/
if( p_item->i_type != CONFIG_HINT_END )
{
/* create a new table for right-left alignment of children */
category_table = gtk_table_new( 0, 0, FALSE );
gtk_table_set_col_spacings( GTK_TABLE(category_table), 4 );
rows = 0;
/* create a new category label */
if( p_item->i_type == CONFIG_HINT_CATEGORY )
category_label = gtk_label_new( p_item->psz_text );
else
category_label = gtk_label_new( p_parser->psz_longname );
}
}
switch( p_item->i_type )
{
case CONFIG_ITEM_MODULE:
item_frame = gtk_frame_new( p_item->psz_text );
gtk_table_resize( GTK_TABLE(category_table), ++rows, 2 );
gtk_table_attach_defaults( GTK_TABLE(category_table), item_frame,
0, 2, rows - 1, rows );
item_vbox = gtk_vbox_new( FALSE, 4 );
gtk_container_add( GTK_CONTAINER(item_frame), item_vbox );
/* create a new clist widget */
{
gchar * titles[] = { N_("Name"), N_("Description") };
titles[0] = _(titles[0]);
titles[1] = _(titles[1]);
module_clist = gtk_clist_new_with_titles( 2, titles );
}
gtk_object_set_data( GTK_OBJECT(module_clist), "p_intf", p_intf );
gtk_clist_column_titles_passive( GTK_CLIST(module_clist) );
gtk_clist_set_selection_mode( GTK_CLIST(module_clist),
GTK_SELECTION_SINGLE);
gtk_container_add( GTK_CONTAINER(item_vbox), module_clist );
/* build a list of available modules */
{
gchar * entry[2];
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !strcmp( p_parser->psz_capability,
p_item->psz_type ) )
{
entry[0] = p_parser->psz_object_name;
entry[1] = p_parser->psz_longname;
gtk_clist_append( GTK_CLIST(module_clist), entry );
}
}
}
gtk_clist_set_column_auto_resize( GTK_CLIST(module_clist),
0, TRUE );
gtk_clist_set_column_auto_resize( GTK_CLIST(module_clist),
1, TRUE );
/* connect signals to the modules list */
gtk_signal_connect( GTK_OBJECT(module_clist), "select_row",
GTK_SIGNAL_FUNC(GtkModuleHighlighted),
NULL );
/* hbox holding the "select" and "configure" buttons */
item_hbox = gtk_hbox_new( FALSE, 4 );
gtk_container_add( GTK_CONTAINER(item_vbox), item_hbox);
/* add configure button */
module_config_button =
gtk_button_new_with_label( _("Configure") );
gtk_widget_set_sensitive( module_config_button, FALSE );
gtk_container_add( GTK_CONTAINER(item_hbox),
module_config_button );
gtk_object_set_data( GTK_OBJECT(module_config_button),
"p_intf", p_intf );
gtk_object_set_data( GTK_OBJECT(module_clist),
"config_button", module_config_button );
/* add select button */
module_select_button =
gtk_button_new_with_label( _("Select") );
gtk_container_add( GTK_CONTAINER(item_hbox),
module_select_button );
/* add a tooltip on mouseover */
gtk_tooltips_set_tip( p_intf->p_sys->p_tooltips,
module_select_button,
p_item->psz_longtext, "" );
/* hbox holding the "selected" label and text input */
item_hbox = gtk_hbox_new( FALSE, 4 );
gtk_container_add( GTK_CONTAINER(item_vbox), item_hbox);
/* add new label */
item_label = gtk_label_new( _("Selected:") );
gtk_container_add( GTK_CONTAINER(item_hbox), item_label );
/* add input box with default value */
string_entry = gtk_entry_new();
gtk_object_set_data( GTK_OBJECT(module_clist),
"module_entry", string_entry );
gtk_container_add( GTK_CONTAINER(item_hbox), string_entry );
vlc_mutex_lock( p_item->p_lock );
gtk_entry_set_text( GTK_ENTRY(string_entry),
p_item->psz_value ? p_item->psz_value : "" );
vlc_mutex_unlock( p_item->p_lock );
/* add a tooltip on mouseover */
gtk_tooltips_set_tip( p_intf->p_sys->p_tooltips,
string_entry, p_item->psz_longtext, "" );
/* connect signals to the buttons */
gtk_signal_connect( GTK_OBJECT(module_config_button), "clicked",
GTK_SIGNAL_FUNC(GtkModuleConfigure),
(gpointer)module_clist );
gtk_signal_connect( GTK_OBJECT(module_select_button), "clicked",
GTK_SIGNAL_FUNC(GtkModuleSelected),
(gpointer)module_clist );
/* connect signal to track changes in the text box */
gtk_object_set_data( GTK_OBJECT(string_entry), "config_option",
p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(string_entry), "changed",
GTK_SIGNAL_FUNC(GtkStringChanged),
(gpointer)config_dialog );
break;
case CONFIG_ITEM_STRING:
case CONFIG_ITEM_FILE:
case CONFIG_ITEM_DIRECTORY:
if( !p_item->ppsz_list )
{
/* add input box with default value */
item_combo = string_entry = gtk_entry_new();
}
else
{
/* add combo box with default value */
GList *items = NULL;
int i;
for( i=0; p_item->ppsz_list[i]; i++ )
items = g_list_append( items, p_item->ppsz_list[i] );
item_combo = gtk_combo_new();
string_entry = GTK_COMBO(item_combo)->entry;
gtk_combo_set_popdown_strings( GTK_COMBO(item_combo),
items );
}
vlc_mutex_lock( p_item->p_lock );
gtk_entry_set_text( GTK_ENTRY(string_entry),
p_item->psz_value ? p_item->psz_value : "" );
vlc_mutex_unlock( p_item->p_lock );
/* connect signal to track changes in the text box */
gtk_object_set_data( GTK_OBJECT(string_entry), "config_option",
p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(string_entry), "changed",
GTK_SIGNAL_FUNC(GtkStringChanged),
(gpointer)config_dialog );
LABEL_AND_WIDGET( p_item->psz_text,
item_combo, p_item->psz_longtext );
break;
case CONFIG_ITEM_INTEGER:
if (( p_item->i_max == 0) && ( p_item->i_min == 0))
{
/* add input box with default value */
item_adj = gtk_adjustment_new( p_item->i_value,
-1, 99999, 1, 10, 10 );
integer_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj), 1, 0 );
/* connect signal to track changes in the spinbutton value */
gtk_object_set_data( GTK_OBJECT(integer_spinbutton),
"config_option", p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(integer_spinbutton), "changed",
GTK_SIGNAL_FUNC(GtkIntChanged),
(gpointer)config_dialog );
LABEL_AND_WIDGET( p_item->psz_text,
integer_spinbutton, p_item->psz_longtext );
}
else /* use i_min and i_max */
{
item_adj = gtk_adjustment_new( p_item->i_value, p_item->i_min,
p_item->i_max, 1, 1, 0 );
integer_slider = gtk_hscale_new( GTK_ADJUSTMENT(item_adj));
gtk_scale_set_digits (GTK_SCALE(integer_slider), 0);
/* connect signal to track changes in the spinbutton value */
gtk_object_set_data( GTK_OBJECT(item_adj),
"config_option", p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(item_adj), "value-changed",
GTK_SIGNAL_FUNC(GtkIntRangedChanged),
(gpointer)config_dialog );
LABEL_AND_WIDGET( p_item->psz_text,
integer_slider, p_item->psz_longtext );
}
break;
case CONFIG_ITEM_FLOAT:
if (( p_item->f_max == 0.0) && ( p_item->f_min == 0.0))
{
/* add input box with default value */
item_adj = gtk_adjustment_new( p_item->f_value,
0, 99999, 0.01, 10, 10 );
float_spinbutton = gtk_spin_button_new( GTK_ADJUSTMENT(item_adj),
0.01, 2 );
/* connect signal to track changes in the spinbutton value */
gtk_object_set_data( GTK_OBJECT(float_spinbutton),
"config_option", p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(float_spinbutton), "changed",
GTK_SIGNAL_FUNC(GtkFloatChanged),
(gpointer)config_dialog );
LABEL_AND_WIDGET( p_item->psz_text,
float_spinbutton, p_item->psz_longtext );
}
else /* use f_min and f_max */
{
item_adj = gtk_adjustment_new( p_item->f_value, p_item->f_min,
p_item->f_max, 0.01, 0.01, 0 );
float_slider = gtk_hscale_new( GTK_ADJUSTMENT(item_adj));
gtk_scale_set_digits (GTK_SCALE(float_slider), 2);
/* connect signal to track changes in the spinbutton value */
gtk_object_set_data( GTK_OBJECT(item_adj),
"config_option", p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(item_adj), "value-changed",
GTK_SIGNAL_FUNC(GtkFloatRangedChanged),
(gpointer)config_dialog );
LABEL_AND_WIDGET( p_item->psz_text,
float_slider, p_item->psz_longtext );
}
break;
case CONFIG_ITEM_BOOL:
/* add check button */
bool_checkbutton = gtk_check_button_new();
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(bool_checkbutton),
p_item->i_value );
/* connect signal to track changes in the button state */
gtk_object_set_data( GTK_OBJECT(bool_checkbutton), "config_option",
p_item->psz_name );
gtk_signal_connect( GTK_OBJECT(bool_checkbutton), "toggled",
GTK_SIGNAL_FUNC(GtkBoolChanged),
(gpointer)config_dialog );
LABEL_AND_WIDGET( p_item->psz_text,
bool_checkbutton, p_item->psz_longtext );
break;
}
}
while( p_item->i_type != CONFIG_HINT_END && p_item++ );
vlc_list_release( p_list );
#ifndef MODULE_NAME_IS_gnome
/* Now let's add the action buttons at the bottom of the page */
dialog_action_area = GTK_DIALOG(config_dialog)->action_area;
gtk_container_set_border_width( GTK_CONTAINER(dialog_action_area), 4 );
/* add a new table for the config option */
item_hbox = gtk_hbox_new( FALSE, 0 );
gtk_box_pack_end( GTK_BOX(dialog_action_area), item_hbox,
TRUE, FALSE, 0 );
item_hbox = gtk_hbox_new( FALSE, 0 );
gtk_box_pack_end( GTK_BOX(dialog_action_area), item_hbox,
TRUE, FALSE, 0 );
#endif
/* Create the OK button */
#ifdef MODULE_NAME_IS_gnome
gnome_dialog_append_button( GNOME_DIALOG(config_dialog),
GNOME_STOCK_BUTTON_OK );
ok_button =
GTK_WIDGET(g_list_last(GNOME_DIALOG(config_dialog)->buttons)->data);
gnome_dialog_append_button( GNOME_DIALOG(config_dialog),
GNOME_STOCK_BUTTON_APPLY );
apply_button =
GTK_WIDGET(g_list_last(GNOME_DIALOG(config_dialog)->buttons)->data);
gnome_dialog_append_button_with_pixmap(
GNOME_DIALOG(config_dialog), _("Save"), GNOME_STOCK_PIXMAP_SAVE );
save_button =
GTK_WIDGET(g_list_last(GNOME_DIALOG(config_dialog)->buttons)->data);
gnome_dialog_append_button( GNOME_DIALOG(config_dialog),
GNOME_STOCK_BUTTON_CANCEL );
cancel_button =
GTK_WIDGET(g_list_last(GNOME_DIALOG(config_dialog)->buttons)->data);
#else
ok_button = gtk_button_new_with_label( _("OK") );
gtk_box_pack_start( GTK_BOX(dialog_action_area), ok_button,
TRUE, TRUE, 0 );
apply_button = gtk_button_new_with_label( _("Apply") );
gtk_box_pack_start( GTK_BOX(dialog_action_area), apply_button,
TRUE, TRUE, 0 );
save_button = gtk_button_new_with_label( _("Save") );
gtk_box_pack_start( GTK_BOX(dialog_action_area), save_button,
TRUE, TRUE, 0 );
cancel_button = gtk_button_new_with_label( _("Cancel") );
gtk_box_pack_start( GTK_BOX(dialog_action_area), cancel_button,
TRUE, TRUE, 0 );
#endif
gtk_signal_connect( GTK_OBJECT(ok_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigOk),
config_dialog );
gtk_widget_set_sensitive( apply_button, FALSE );
gtk_object_set_data( GTK_OBJECT(config_dialog), "apply_button",
apply_button );
gtk_signal_connect( GTK_OBJECT(apply_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigApply),
config_dialog );
gtk_signal_connect( GTK_OBJECT(save_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigSave),
config_dialog );
gtk_signal_connect( GTK_OBJECT(cancel_button), "clicked",
GTK_SIGNAL_FUNC(GtkConfigCancel),
config_dialog );
/* Ok, job done successfully. Let's keep a reference to the dialog box */
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
psz_module_name, config_dialog );
gtk_object_set_data( GTK_OBJECT(config_dialog), "psz_module_name",
psz_module_name );
/* we want this ref to be destroyed if the object is destroyed */
gtk_signal_connect( GTK_OBJECT(config_dialog), "destroy",
GTK_SIGNAL_FUNC(GtkConfigDialogDestroyed),
(gpointer)p_intf );
gtk_widget_show_all( config_dialog );
}
#undef LABEL_AND_WIDGET
#undef TOOLTIP
/****************************************************************************
* GtkConfigApply: store the changes to the config inside the modules
* configuration structure and clear the hash table.
****************************************************************************/
static void GtkConfigApply( GtkButton * button, gpointer user_data )
{
intf_thread_t *p_intf;
GHashTable *hash_table;
GtkWidget *apply_button;
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(user_data),
"p_intf" );
g_hash_table_foreach_remove( hash_table, GtkSaveHashValue, (void*)p_intf );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, FALSE );
}
static void GtkConfigOk( GtkButton * button, gpointer user_data )
{
GtkConfigApply( button, user_data );
gtk_widget_destroy( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
static void GtkConfigCancel( GtkButton * button, gpointer user_data )
{
gtk_widget_destroy( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
static void GtkConfigSave( GtkButton * button, gpointer user_data )
{
intf_thread_t *p_intf;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(user_data),
"p_intf" );
GtkConfigApply( button, user_data );
config_SaveConfigFile( p_intf, NULL );
}
/****************************************************************************
* GtkModuleHighlighted: display module description when an entry is selected
* in the clist, and activate the configure button if necessary.
****************************************************************************/
static void GtkModuleHighlighted( GtkCList *module_clist, int row, int column,
GdkEventButton *event, gpointer user_data )
{
intf_thread_t *p_intf;
GtkWidget *config_button;
module_t *p_parser;
vlc_list_t *p_list;
char *psz_name;
int i_index;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(module_clist),
"p_intf" );
if( !gtk_clist_get_text( GTK_CLIST(module_clist), row, 0, &psz_name ) )
{
return;
}
/* look for module 'psz_name' */
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !strcmp( p_parser->psz_object_name, psz_name ) )
{
gtk_object_set_data( GTK_OBJECT(module_clist),
"module_highlighted", p_parser );
config_button = gtk_object_get_data( GTK_OBJECT(module_clist),
"config_button" );
if( p_parser->i_config_items )
gtk_widget_set_sensitive( config_button, TRUE );
else
gtk_widget_set_sensitive( config_button, FALSE );
break;
}
}
vlc_list_release( p_list );
}
/****************************************************************************
* GtkModuleConfigure: display module configuration dialog box.
****************************************************************************/
static void GtkModuleConfigure( GtkButton *button, gpointer user_data )
{
module_t *p_module;
intf_thread_t *p_intf;
p_module = (module_t *)gtk_object_get_data( GTK_OBJECT(user_data),
"module_highlighted" );
if( !p_module ) return;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(button),
"p_intf" );
GtkCreateConfigDialog( p_module->psz_object_name, (gpointer)p_intf );
}
/****************************************************************************
* GtkModuleSelected: select module.
****************************************************************************/
static void GtkModuleSelected( GtkButton *button, gpointer user_data )
{
module_t *p_module;
GtkWidget *widget;
p_module = (module_t *)gtk_object_get_data( GTK_OBJECT(user_data),
"module_highlighted" );
widget = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"module_entry" );
if( !p_module ) return;
gtk_entry_set_text( GTK_ENTRY(widget), p_module->psz_object_name );
}
/****************************************************************************
* GtkStringChanged: signal called when the user changes a string value.
****************************************************************************/
static void GtkStringChanged( GtkEditable *editable, gpointer user_data )
{
intf_thread_t *p_intf;
module_config_t *p_config;
GHashTable *hash_table;
GtkWidget *apply_button;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
"p_intf" );
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
/* free old p_config */
p_config = (module_config_t *)g_hash_table_lookup( hash_table,
(gpointer)editable );
if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = CONFIG_ITEM_STRING;
p_config->psz_value = gtk_editable_get_chars( editable, 0, -1 );
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
"config_option" );
g_hash_table_insert( hash_table, (gpointer)editable,
(gpointer)p_config );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, TRUE );
}
/****************************************************************************
* GtkIntChanged: signal called when the user changes an integer value.
****************************************************************************/
static void GtkIntChanged( GtkEditable *editable, gpointer user_data )
{
intf_thread_t *p_intf;
module_config_t *p_config;
GHashTable *hash_table;
GtkWidget *apply_button;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
"p_intf" );
gtk_spin_button_update( GTK_SPIN_BUTTON(editable) );
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
/* free old p_config */
p_config = (module_config_t *)g_hash_table_lookup( hash_table,
(gpointer)editable );
if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = CONFIG_ITEM_INTEGER;
p_config->i_value = gtk_spin_button_get_value_as_int(
GTK_SPIN_BUTTON(editable) );
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
"config_option" );
g_hash_table_insert( hash_table, (gpointer)editable,
(gpointer)p_config );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, TRUE );
}
/***************************************************************************************
* GtkIntRangedChanged: signal called when the user changes an integer with range value.
**************************************************************************************/
static void GtkIntRangedChanged( GtkEditable *editable, gpointer user_data )
{
intf_thread_t *p_intf;
module_config_t *p_config;
GHashTable *hash_table;
GtkWidget *apply_button;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
"p_intf" );
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
/* free old p_config */
p_config = (module_config_t *)g_hash_table_lookup( hash_table,
(gpointer)editable );
if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = CONFIG_ITEM_INTEGER;
p_config->i_value = ((GTK_ADJUSTMENT(editable))->value);
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
"config_option" );
g_hash_table_insert( hash_table, (gpointer)editable,
(gpointer)p_config );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, TRUE );
}
/****************************************************************************
* GtkFloatChanged: signal called when the user changes a float value.
****************************************************************************/
static void GtkFloatChanged( GtkEditable *editable, gpointer user_data )
{
intf_thread_t *p_intf;
module_config_t *p_config;
GHashTable *hash_table;
GtkWidget *apply_button;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
"p_intf" );
gtk_spin_button_update( GTK_SPIN_BUTTON(editable) );
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
/* free old p_config */
p_config = (module_config_t *)g_hash_table_lookup( hash_table,
(gpointer)editable );
if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = CONFIG_ITEM_FLOAT;
p_config->f_value = gtk_spin_button_get_value_as_float(
GTK_SPIN_BUTTON(editable) );
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
"config_option" );
g_hash_table_insert( hash_table, (gpointer)editable,
(gpointer)p_config );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, TRUE );
}
/***************************************************************************************
* GtkIntRangedChanged: signal called when the user changes an integer with range value.
**************************************************************************************/
static void GtkFloatRangedChanged( GtkEditable *editable, gpointer user_data )
{
intf_thread_t *p_intf;
module_config_t *p_config;
GHashTable *hash_table;
GtkWidget *apply_button;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(editable),
"p_intf" );
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
/* free old p_config */
p_config = (module_config_t *)g_hash_table_lookup( hash_table,
(gpointer)editable );
if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = CONFIG_ITEM_FLOAT;
p_config->f_value = ((GTK_ADJUSTMENT(editable))->value);
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(editable),
"config_option" );
g_hash_table_insert( hash_table, (gpointer)editable,
(gpointer)p_config );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, TRUE );
}
/****************************************************************************
* GtkBoolChanged: signal called when the user changes a bool value.
****************************************************************************/
static void GtkBoolChanged( GtkToggleButton *button, gpointer user_data )
{
intf_thread_t *p_intf;
module_config_t *p_config;
GHashTable *hash_table;
GtkWidget *apply_button;
p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT(button),
"p_intf" );
hash_table = (GHashTable *)gtk_object_get_data( GTK_OBJECT(user_data),
"config_hash_table" );
/* free old p_config */
p_config = (module_config_t *)g_hash_table_lookup( hash_table,
(gpointer)button );
if( p_config ) GtkFreeHashValue( NULL, (gpointer)p_config, (void *)p_intf );
p_config = malloc( sizeof(module_config_t) );
p_config->i_type = CONFIG_ITEM_BOOL;
p_config->i_value = gtk_toggle_button_get_active( button );
p_config->psz_name = (char *)gtk_object_get_data( GTK_OBJECT(button),
"config_option" );
g_hash_table_insert( hash_table, (gpointer)button,
(gpointer)p_config );
/* change the highlight status of the Apply button */
apply_button = (GtkWidget *)gtk_object_get_data( GTK_OBJECT(user_data),
"apply_button" );
gtk_widget_set_sensitive( apply_button, TRUE );
}
/****************************************************************************
* GtkFreeHashTable: signal called when the config hash table is destroyed.
****************************************************************************/
static void GtkFreeHashTable( GtkObject *object )
{
GHashTable *hash_table = (GHashTable *)gtk_object_get_data( object,
"config_hash_table" );
intf_thread_t *p_intf = (intf_thread_t *)gtk_object_get_data( object,
"p_intf" );
g_hash_table_foreach( hash_table, GtkFreeHashValue, (void *)p_intf );
g_hash_table_destroy( hash_table );
}
/****************************************************************************
* GtkFreeHashValue: signal called when an element of the config hash table
* is destroyed.
****************************************************************************/
static void GtkFreeHashValue( gpointer key, gpointer value, gpointer user_data)
{
module_config_t * p_config = (module_config_t *)value;
if( p_config->i_type == CONFIG_ITEM_STRING )
if( p_config->psz_value ) g_free( p_config->psz_value );
free( p_config );
}
/****************************************************************************
* GtkSaveHashValue: callback used when enumerating the hash table in
* GtkConfigApply().
****************************************************************************/
static gboolean GtkSaveHashValue( gpointer key, gpointer value,
gpointer user_data )
{
intf_thread_t * p_intf = (intf_thread_t *)user_data;
module_config_t * p_config = (module_config_t *)value;
switch( p_config->i_type )
{
case CONFIG_ITEM_STRING:
case CONFIG_ITEM_FILE:
case CONFIG_ITEM_DIRECTORY:
case CONFIG_ITEM_MODULE:
config_PutPsz( p_intf, p_config->psz_name,
*p_config->psz_value ? p_config->psz_value : NULL );
break;
case CONFIG_ITEM_INTEGER:
case CONFIG_ITEM_BOOL:
config_PutInt( p_intf, p_config->psz_name, p_config->i_value );
break;
case CONFIG_ITEM_FLOAT:
config_PutFloat( p_intf, p_config->psz_name, p_config->f_value );
break;
}
/* free the hash value we allocated */
if( p_config->i_type == CONFIG_ITEM_STRING )
g_free( p_config->psz_value );
free( p_config );
/* return TRUE so glib will free the hash entry */
return TRUE;
}
/****************************************************************************
* GtkConfigDialogDestroyed: callback triggered when the config dialog box is
* destroyed.
****************************************************************************/
static void GtkConfigDialogDestroyed( GtkObject *object, gpointer user_data )
{
intf_thread_t *p_intf = (intf_thread_t *)user_data;
char *psz_module_name;
psz_module_name = gtk_object_get_data( object, "psz_module_name" );
/* remove the ref to the dialog box */
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
psz_module_name, NULL );
GtkFreeHashTable( object );
}
/*****************************************************************************
* gtk_control.h: prototypes for control functions
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stéphane Borel <stef@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.
*****************************************************************************/
void GtkPreferencesShow( GtkMenuItem *, gpointer );
/*****************************************************************************
* sout.c :
*****************************************************************************
* Copyright (C) 2000, 2001 the VideoLAN team
* $Id$
*
* Authors: 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/intf.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"
void GtkSoutSettings ( GtkButton *button,
gpointer user_data );
void GtkSoutSettingsChanged ( GtkWidget *button, gpointer user_data);
void GtkSoutSettingsAccessFile (GtkToggleButton *togglebutton,
gpointer user_data)
{
GtkWidget * p_sout;
p_sout = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_file_path_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_file_path" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_ts" ), TRUE );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_ps" ), TRUE );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_avi" ), TRUE );
GtkSoutSettingsChanged( GTK_WIDGET( togglebutton ), user_data );
}
void GtkSoutSettingsAccessUdp (GtkToggleButton *togglebutton,
gpointer user_data)
{
GtkWidget * p_sout;
p_sout = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_udp_address_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_udp_address_combo" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_udp_port_label" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_udp_port" ),
gtk_toggle_button_get_active( togglebutton ) );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_ts" ), TRUE );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_ps" ), FALSE );
gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_avi" ), FALSE );
gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT( p_sout ),
"sout_mux_ts" ), TRUE );
GtkSoutSettingsChanged( GTK_WIDGET( togglebutton ), user_data );
}
void GtkSoutSettingsChanged ( GtkWidget *button,
gpointer user_data)
{
#define SELECTED( s ) GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button), \
(s) ) )->active
//intf_thread_t * p_intf = GtkGetIntf( button );
GString * p_target;
p_target = g_string_new( "" );
/* first set access */
if( SELECTED( "sout_access_file" ) )
{
g_string_append( p_target, "file/" );
}
else if( SELECTED( "sout_access_udp" ) )
{
g_string_append( p_target, "udp/" );
}
else if( SELECTED( "sout_access_rtp" ) )
{
g_string_append( p_target, "rtp/" );
}
/* then set muxer */
if( SELECTED( "sout_mux_ts" ) )
{
g_string_append( p_target, "ts://" );
}
else if( SELECTED( "sout_mux_ps" ) )
{
g_string_append( p_target, "ps://" );
}
else if( SELECTED( "sout_mux_avi" ) )
{
g_string_append( p_target, "avi://" );
}
/* last part of the url */
if( SELECTED( "sout_access_file" ) )
{
g_string_append( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "sout_file_path" ) ) ) );
}
else if( SELECTED( "sout_access_udp" ) || SELECTED( "sout_access_rtp" ) )
{
g_string_append( p_target,
gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "sout_udp_address" ) ) ) );
g_string_append( p_target, ":" );
g_string_sprintfa( p_target, "%i",
gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( lookup_widget(
GTK_WIDGET(button), "sout_udp_port" ) ) ) );
}
gtk_entry_set_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "sout_entry_target" ) ),
p_target->str );
g_string_free( p_target, TRUE );
}
/****************************************************************************/
void GtkSoutSettingsOk ( GtkButton *button,
gpointer user_data)
{
/* Hide the dialog box */
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
/* set sout */
#if 0
psz_target = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
GTK_WIDGET(button), "sout_entry_target" ) ) );
config_PutPsz( p_intf, "sout", psz_target );
#endif
}
void GtkSoutSettingsCancel ( GtkButton *button,
gpointer user_data)
{
/* Hide the dialog box */
gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
}
void GtkSoutSettings ( GtkButton *button,
gpointer user_data )
{
intf_thread_t * p_intf = GtkGetIntf( button );
gtk_widget_show( p_intf->p_sys->p_sout );
gdk_window_raise( p_intf->p_sys->p_sout->window );
}
COMMON_gtk2 = \
$(NULL)
SOURCES_gtk2 = \
gtk2.c \
gtk2_callbacks.c \
gtk2_callbacks.h \
gtk2_interface.c \
gtk2_interface.h \
gtk2_support.c \
gtk2_support.h \
$(COMMON_gtk2)
SOURCES_gnome2 = \
gnome2.c \
gnome2_callbacks.c \
gnome2_callbacks.h \
gnome2_interface.c \
gnome2_interface.h \
gnome2_support.c \
gnome2_support.h \
$(COMMON_gtk2)
EXTRA_DIST += \
gtk2.glade \
gnome2.glade \
$(NULL)
/*****************************************************************************
* gnome2.c : GNOME 2 plugin for vlc
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <gnome.h>
#include "gnome2_interface.h"
#include "gnome2_support.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
static int Manage ( intf_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
int i = getenv( "DISPLAY" ) == NULL ? 15 : 95;
set_description( _("Gtk2 interface") );
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_GENERAL );
set_capability( "interface", i );
set_callbacks( Open, Close );
set_program( "gvlc" );
vlc_module_end();
/*****************************************************************************
* intf_sys_t
*****************************************************************************/
struct intf_sys_t
{
module_t *p_gui_helper;
GtkWidget *p_app;
};
/*****************************************************************************
* Open: initialize and create window
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return VLC_ENOMEM;
}
#ifdef NEED_GTK2_MAIN
p_intf->p_sys->p_gui_helper =
module_Need( p_this, "gui-helper", "gnome2", VLC_TRUE );
if( p_intf->p_sys->p_gui_helper == NULL )
{
free( p_intf->p_sys );
return VLC_ENOMOD;
}
#endif
p_intf->pf_run = Run;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: destroy interface window
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
#ifdef NEED_GTK2_MAIN
module_Unneed( p_intf, p_intf->p_sys->p_gui_helper );
#endif
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: Gtk+ thread
*****************************************************************************
* this part of the interface is in a separate thread so that we can call
* gtk_main() from within it without annoying the rest of the program.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
#ifdef NEED_GTK2_MAIN
gdk_threads_enter();
#else
/* gnome_program_init needs to know the command line. We don't care, so
* we give it an empty one */
char *p_args[] = { "", NULL };
int i_args = 1;
int i_dummy;
gtk_set_locale();
gnome_program_init( PACKAGE, VERSION, LIBGNOMEUI_MODULE,
i_args, p_args,
GNOME_PARAM_APP_DATADIR, "",//PACKAGE_DATA_DIR,
NULL );
#endif
/* Create some useful widgets that will certainly be used */
p_intf->p_sys->p_app = create_app1();
/* Set the title of the main window */
//gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_app),
// VOUT_TITLE " (Gtk+ interface)" );
/* Show the control window */
gtk_widget_show( p_intf->p_sys->p_app );
#ifdef NEED_GTK2_MAIN
while( !p_intf->b_die )
{
Manage( p_intf );
/* Sleep to avoid using all CPU - since some interfaces need to
* access keyboard events, a 100ms delay is a good compromise */
gdk_threads_leave();
msleep( INTF_IDLE_SLEEP );
gdk_threads_enter();
}
#else
/* Sleep to avoid using all CPU - since some interfaces needs to access
* keyboard events, a 100ms delay is a good compromise */
i_dummy = gtk_timeout_add( INTF_IDLE_SLEEP / 1000, (GtkFunction)Manage,
p_intf );
/* Enter Gtk mode */
gtk_main();
/* Remove the timeout */
gtk_timeout_remove( i_dummy );
#endif
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_app) );
#ifdef NEED_GTK2_MAIN
gdk_threads_leave();
#endif
}
/* following functions are local */
/*****************************************************************************
* Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
static int Manage( intf_thread_t *p_intf )
{
#ifndef NEED_GTK2_MAIN
if( p_intf->b_die )
{
gtk_main_quit();
return FALSE;
}
#endif
return TRUE;
}
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<requires lib="gnome"/>
<requires lib="bonobo"/>
<widget class="GnomeApp" id="app1">
<property name="visible">True</property>
<property name="title" translatable="yes">gnome2</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="enable_layout_config">True</property>
<child internal-child="dock">
<widget class="BonoboDock" id="bonobodock1">
<property name="visible">True</property>
<property name="allow_floating">True</property>
<child>
<widget class="BonoboDockItem" id="bonobodockitem1">
<property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<child>
<widget class="GtkImageMenuItem" id="file1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_FILE_TREE</property>
<child>
<widget class="GtkMenu" id="file1_menu">
<child>
<widget class="GtkImageMenuItem" id="new1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_NEW_ITEM</property>
<property name="label" translatable="yes">_New</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_new1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="open1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_OPEN_ITEM</property>
<signal name="activate" handler="on_open1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_SAVE_ITEM</property>
<signal name="activate" handler="on_save1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save_as1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_SAVE_AS_ITEM</property>
<signal name="activate" handler="on_save_as1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="quit1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_EXIT_ITEM</property>
<signal name="activate" handler="on_quit1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="edit1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_EDIT_TREE</property>
<child>
<widget class="GtkMenu" id="edit1_menu">
<child>
<widget class="GtkImageMenuItem" id="cut1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_CUT_ITEM</property>
<signal name="activate" handler="on_cut1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="copy1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_COPY_ITEM</property>
<signal name="activate" handler="on_copy1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="paste1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_PASTE_ITEM</property>
<signal name="activate" handler="on_paste1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="clear1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_CLEAR_ITEM</property>
<signal name="activate" handler="on_clear1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator2">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="properties1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_PROPERTIES_ITEM</property>
<signal name="activate" handler="on_properties1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator3">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="preferences1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_PREFERENCES_ITEM</property>
<signal name="activate" handler="on_preferences1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="view1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_VIEW_TREE</property>
<child>
<widget class="GtkMenu" id="view1_menu">
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="help1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_HELP_TREE</property>
<child>
<widget class="GtkMenu" id="help1_menu">
<child>
<widget class="GtkImageMenuItem" id="about1">
<property name="visible">True</property>
<property name="stock_item">GNOMEUIINFO_MENU_ABOUT_ITEM</property>
<signal name="activate" handler="on_about1_activate" last_modification_time="Thu, 13 Mar 2003 20:03:27 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="placement">BONOBO_DOCK_TOP</property>
<property name="band">0</property>
<property name="position">0</property>
<property name="offset">0</property>
<property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL|BONOBO_DOCK_ITEM_BEH_LOCKED</property>
</packing>
</child>
<child>
<widget class="BonoboDockItem" id="bonobodockitem2">
<property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_OUT</property>
<child>
<widget class="GtkToolbar" id="toolbar1">
<property name="border_width">1</property>
<property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
<property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
<property name="tooltips">True</property>
<child>
<widget class="button" id="button2">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Open File</property>
<property name="label">gtk-open</property>
<property name="use_stock">True</property>
</widget>
</child>
<child>
<widget class="button" id="button4">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Open File</property>
<property name="label">button4</property>
<property name="use_underline">True</property>
<property name="stock_pixmap">gtk-cdrom</property>
</widget>
</child>
<child>
<widget class="button" id="button3">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Save File</property>
<property name="label">button3</property>
<property name="use_underline">True</property>
<property name="stock_pixmap">gtk-refresh</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="placement">BONOBO_DOCK_TOP</property>
<property name="band">1</property>
<property name="position">0</property>
<property name="offset">0</property>
<property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHScale" id="hscale1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="draw_value">True</property>
<property name="value_pos">GTK_POS_TOP</property>
<property name="digits">1</property>
<property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
<property name="inverted">False</property>
<property name="adjustment">0 0 0 0 0 0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child internal-child="appbar">
<widget class="GnomeAppBar" id="appbar1">
<property name="visible">True</property>
<property name="has_progress">True</property>
<property name="has_status">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</glade-interface>
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
<glade-project>
<name>gnome2</name>
<program_name>gnome2</program_name>
<source_directory></source_directory>
<pixmaps_directory></pixmaps_directory>
<output_build_files>FALSE</output_build_files>
<main_source_file>gnome2_interface.c</main_source_file>
<main_header_file>gnome2_interface.h</main_header_file>
<handler_source_file>gnome2_callbacks.c</handler_source_file>
<handler_header_file>gnome2_callbacks.h</handler_header_file>
<support_source_file>gnome2_support.c</support_source_file>
<support_header_file>gnome2_support.h</support_header_file>
</glade-project>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gnome.h>
#include "gnome2_callbacks.h"
#include "gnome2_interface.h"
#include "gnome2_support.h"
void
on_new1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_open1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_save1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_save_as1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_quit1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_cut1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_copy1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_paste1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_clear1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_properties1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_preferences1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_about1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
#include <gnome.h>
void
on_new1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_open1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_save1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_save_as1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_quit1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_cut1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_copy1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_paste1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_clear1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_properties1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_preferences1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_about1_activate (GtkMenuItem *menuitem,
gpointer user_data);
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "gnome2_callbacks.h"
#include "gnome2_interface.h"
#include "gnome2_support.h"
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
g_object_set_data (G_OBJECT (component), name, widget)
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include "gnome2_support.h"
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (!parent)
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
static GList *pixmaps_directories = NULL;
/* Use this function to set the directory containing installed pixmaps. */
void
add_pixmap_directory (const gchar *directory)
{
pixmaps_directories = g_list_prepend (pixmaps_directories,
g_strdup (directory));
}
/* This is an internally used function to find pixmap files. */
static gchar*
find_pixmap_file (const gchar *filename)
{
GList *elem;
/* We step through each of the pixmaps directory to find it. */
elem = pixmaps_directories;
while (elem)
{
gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
G_DIR_SEPARATOR_S, filename);
if (g_file_test (pathname, G_FILE_TEST_EXISTS))
return pathname;
g_free (pathname);
elem = elem->next;
}
return NULL;
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename)
{
gchar *pathname = NULL;
GtkWidget *pixmap;
if (!filename || !filename[0])
return gtk_image_new ();
pathname = find_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return gtk_image_new ();
}
pixmap = gtk_image_new_from_file (pathname);
g_free (pathname);
return pixmap;
}
/* This is an internally used function to create pixmaps. */
GdkPixbuf*
create_pixbuf (const gchar *filename)
{
gchar *pathname = NULL;
GdkPixbuf *pixbuf;
GError *error = NULL;
if (!filename || !filename[0])
return NULL;
pathname = find_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return NULL;
}
pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
if (!pixbuf)
{
fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
pathname, error->message);
g_error_free (error);
}
g_free (pathname);
return pixbuf;
}
/* This is used to set ATK action descriptions. */
void
glade_set_atk_action_description (AtkAction *action,
const gchar *action_name,
const gchar *description)
{
gint n_actions, i;
n_actions = atk_action_get_n_actions (action);
for (i = 0; i < n_actions; i++)
{
if (!strcmp (atk_action_get_name (action, i), action_name))
atk_action_set_description (action, i, description);
}
}
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
/*
* Standard gettext macros.
*/
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif
/*
* Public Functions.
*/
/*
* This function returns a widget in a component created by Glade.
* Call it with the toplevel widget in the component (i.e. a window/dialog),
* or alternatively any widget in the component, and the name of the widget
* you want returned.
*/
GtkWidget* lookup_widget (GtkWidget *widget,
const gchar *widget_name);
/* Use this function to set the directory containing installed pixmaps. */
void add_pixmap_directory (const gchar *directory);
/*
* Private Functions.
*/
/* This is used to create the pixmaps used in the interface. */
GtkWidget* create_pixmap (GtkWidget *widget,
const gchar *filename);
/* This is used to create the pixbufs used in the interface. */
GdkPixbuf* create_pixbuf (const gchar *filename);
/* This is used to set ATK action descriptions. */
void glade_set_atk_action_description (AtkAction *action,
const gchar *action_name,
const gchar *description);
/*****************************************************************************
* gtk2.c : Gtk2 plugin for vlc
*****************************************************************************
* Copyright (C) 2003 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <gtk/gtk.h>
#include "gtk2_callbacks.h"
#include "gtk2_interface.h"
#include "gtk2_support.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
static int Manage ( intf_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
int i = getenv( "DISPLAY" ) == NULL ? 15 : 95;
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_GENERAL );
set_description( _("Gtk2 interface") );
set_capability( "interface", i );
set_callbacks( Open, Close );
set_program( "gvlc" );
vlc_module_end();
/*****************************************************************************
* intf_sys_t
*****************************************************************************/
struct intf_sys_t
{
module_t *p_gui_helper;
GtkWidget *p_window;
};
/*****************************************************************************
* Open: initialize and create window
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return VLC_ENOMEM;
}
#ifdef NEED_GTK2_MAIN
p_intf->p_sys->p_gui_helper =
module_Need( p_this, "gui-helper", "gtk2", VLC_TRUE );
if( p_intf->p_sys->p_gui_helper == NULL )
{
free( p_intf->p_sys );
return VLC_ENOMOD;
}
#endif
p_intf->pf_run = Run;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: destroy interface window
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
#ifdef NEED_GTK2_MAIN
module_Unneed( p_intf, p_intf->p_sys->p_gui_helper );
#endif
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: Gtk2 thread
*****************************************************************************
* this part of the interface is in a separate thread so that we can call
* gtk_main() from within it without annoying the rest of the program.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
#ifdef NEED_GTK2_MAIN
gdk_threads_enter();
#else
/* gtk_init needs to know the command line. We don't care, so we
* give it an empty one */
char *p_args[] = { "", NULL };
char **pp_args = p_args;
int i_args = 1;
int i_dummy;
gtk_set_locale();
gtk_init( &i_args, &pp_args );
#endif
/* Create some useful widgets that will certainly be used */
p_intf->p_sys->p_window = create_window1();
/* Set the title of the main window */
gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
VOUT_TITLE " (Gtk2 interface)");
/* Show the control window */
gtk_widget_show( p_intf->p_sys->p_window );
#ifdef NEED_GTK2_MAIN
while( !p_intf->b_die )
{
Manage( p_intf );
/* Sleep to avoid using all CPU - since some interfaces need to
* access keyboard events, a 100ms delay is a good compromise */
gdk_threads_leave();
msleep( INTF_IDLE_SLEEP );
gdk_threads_enter();
}
#else
/* Sleep to avoid using all CPU - since some interfaces needs to access
* keyboard events, a 100ms delay is a good compromise */
i_dummy = gtk_timeout_add( INTF_IDLE_SLEEP / 1000, (GtkFunction)Manage,
p_intf );
/* Enter Gtk mode */
gtk_main();
/* Remove the timeout */
gtk_timeout_remove( i_dummy );
#endif
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_window) );
#ifdef NEED_GTK2_MAIN
gdk_threads_leave();
#endif
}
/* following functions are local */
/*****************************************************************************
* Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
static int Manage( intf_thread_t *p_intf )
{
#ifndef NEED_GTK2_MAIN
if( p_intf->b_die )
{
gtk_main_quit();
return FALSE;
}
#endif
return TRUE;
}
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
<property name="title" translatable="yes">window1</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu1">
<child>
<widget class="GtkImageMenuItem" id="new1">
<property name="visible">True</property>
<property name="label">gtk-new</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_new1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="open1">
<property name="visible">True</property>
<property name="label">gtk-open</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_open1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save1">
<property name="visible">True</property>
<property name="label">gtk-save</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_save1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save_as1">
<property name="visible">True</property>
<property name="label">gtk-save-as</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_save_as1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="quit1">
<property name="visible">True</property>
<property name="label">gtk-quit</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_quit1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu2">
<child>
<widget class="GtkImageMenuItem" id="cut1">
<property name="visible">True</property>
<property name="label">gtk-cut</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_cut1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="copy1">
<property name="visible">True</property>
<property name="label">gtk-copy</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_copy1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="paste1">
<property name="visible">True</property>
<property name="label">gtk-paste</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_paste1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="delete1">
<property name="visible">True</property>
<property name="label">gtk-delete</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_delete1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu3">
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem4">
<property name="visible">True</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu4">
<child>
<widget class="GtkMenuItem" id="about1">
<property name="visible">True</property>
<property name="label" translatable="yes">_About</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_about1_activate" last_modification_time="Thu, 13 Mar 2003 19:52:16 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHandleBox" id="handlebox1">
<property name="visible">True</property>
<property name="shadow_type">GTK_SHADOW_OUT</property>
<property name="handle_position">GTK_POS_LEFT</property>
<property name="snap_edge">GTK_POS_TOP</property>
<child>
<widget class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
<property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
<property name="tooltips">True</property>
<child>
<widget class="button" id="button1">
<property name="visible">True</property>
<property name="label">button1</property>
<property name="use_underline">True</property>
<property name="stock_pixmap">gtk-open</property>
</widget>
</child>
<child>
<widget class="button" id="button2">
<property name="visible">True</property>
<property name="label">button2</property>
<property name="use_underline">True</property>
<property name="stock_pixmap">gtk-cdrom</property>
</widget>
</child>
<child>
<widget class="button" id="button3">
<property name="visible">True</property>
<property name="label">button3</property>
<property name="use_underline">True</property>
<property name="stock_pixmap">gtk-refresh</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHScale" id="hscale1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="draw_value">True</property>
<property name="value_pos">GTK_POS_TOP</property>
<property name="digits">1</property>
<property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
<property name="inverted">False</property>
<property name="adjustment">0 0 0 0 0 0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusbar1">
<property name="visible">True</property>
<property name="has_resize_grip">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
<glade-project>
<name>gtk2</name>
<program_name>gtk2</program_name>
<source_directory></source_directory>
<pixmaps_directory></pixmaps_directory>
<gnome_support>FALSE</gnome_support>
<output_build_files>FALSE</output_build_files>
<main_source_file>gtk2_interface.c</main_source_file>
<main_header_file>gtk2_interface.h</main_header_file>
<handler_source_file>gtk2_callbacks.c</handler_source_file>
<handler_header_file>gtk2_callbacks.h</handler_header_file>
<support_source_file>gtk2_support.c</support_source_file>
<support_header_file>gtk2_support.h</support_header_file>
</glade-project>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include "gtk2_callbacks.h"
#include "gtk2_interface.h"
#include "gtk2_support.h"
void
on_new1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_open1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_save1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_save_as1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_quit1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_cut1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_copy1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_paste1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_delete1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_about1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
#include <gtk/gtk.h>
void
on_new1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_open1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_save1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_save_as1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_quit1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_cut1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_copy1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_paste1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_delete1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_about1_activate (GtkMenuItem *menuitem,
gpointer user_data);
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "gtk2_callbacks.h"
#include "gtk2_interface.h"
#include "gtk2_support.h"
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
g_object_set_data (G_OBJECT (component), name, widget)
GtkWidget*
create_window1 (void)
{
GtkWidget *window1;
GtkWidget *vbox1;
GtkWidget *menubar1;
GtkWidget *menuitem1;
GtkWidget *menu1;
GtkWidget *new1;
GtkWidget *open1;
GtkWidget *save1;
GtkWidget *save_as1;
GtkWidget *separatormenuitem1;
GtkWidget *quit1;
GtkWidget *menuitem2;
GtkWidget *menu2;
GtkWidget *cut1;
GtkWidget *copy1;
GtkWidget *paste1;
GtkWidget *delete1;
GtkWidget *menuitem3;
GtkWidget *menu3;
GtkWidget *menuitem4;
GtkWidget *menu4;
GtkWidget *about1;
GtkWidget *handlebox1;
GtkWidget *toolbar1;
GtkWidget *tmp_toolbar_icon;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *button3;
GtkWidget *hscale1;
GtkWidget *statusbar1;
GtkAccelGroup *accel_group;
accel_group = gtk_accel_group_new ();
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window1), _("window1"));
vbox1 = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox1);
gtk_container_add (GTK_CONTAINER (window1), vbox1);
menubar1 = gtk_menu_bar_new ();
gtk_widget_show (menubar1);
gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
menuitem1 = gtk_menu_item_new_with_mnemonic (_("_File"));
gtk_widget_show (menuitem1);
gtk_container_add (GTK_CONTAINER (menubar1), menuitem1);
menu1 = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menu1);
new1 = gtk_image_menu_item_new_from_stock ("gtk-new", accel_group);
gtk_widget_show (new1);
gtk_container_add (GTK_CONTAINER (menu1), new1);
open1 = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
gtk_widget_show (open1);
gtk_container_add (GTK_CONTAINER (menu1), open1);
save1 = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group);
gtk_widget_show (save1);
gtk_container_add (GTK_CONTAINER (menu1), save1);
save_as1 = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
gtk_widget_show (save_as1);
gtk_container_add (GTK_CONTAINER (menu1), save_as1);
separatormenuitem1 = gtk_separator_menu_item_new ();
gtk_widget_show (separatormenuitem1);
gtk_container_add (GTK_CONTAINER (menu1), separatormenuitem1);
gtk_widget_set_sensitive (separatormenuitem1, FALSE);
quit1 = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
gtk_widget_show (quit1);
gtk_container_add (GTK_CONTAINER (menu1), quit1);
menuitem2 = gtk_menu_item_new_with_mnemonic (_("_Edit"));
gtk_widget_show (menuitem2);
gtk_container_add (GTK_CONTAINER (menubar1), menuitem2);
menu2 = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem2), menu2);
cut1 = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group);
gtk_widget_show (cut1);
gtk_container_add (GTK_CONTAINER (menu2), cut1);
copy1 = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group);
gtk_widget_show (copy1);
gtk_container_add (GTK_CONTAINER (menu2), copy1);
paste1 = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group);
gtk_widget_show (paste1);
gtk_container_add (GTK_CONTAINER (menu2), paste1);
delete1 = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
gtk_widget_show (delete1);
gtk_container_add (GTK_CONTAINER (menu2), delete1);
menuitem3 = gtk_menu_item_new_with_mnemonic (_("_View"));
gtk_widget_show (menuitem3);
gtk_container_add (GTK_CONTAINER (menubar1), menuitem3);
menu3 = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem3), menu3);
menuitem4 = gtk_menu_item_new_with_mnemonic (_("_Help"));
gtk_widget_show (menuitem4);
gtk_container_add (GTK_CONTAINER (menubar1), menuitem4);
menu4 = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menu4);
about1 = gtk_menu_item_new_with_mnemonic (_("_About"));
gtk_widget_show (about1);
gtk_container_add (GTK_CONTAINER (menu4), about1);
handlebox1 = gtk_handle_box_new ();
gtk_widget_show (handlebox1);
gtk_box_pack_start (GTK_BOX (vbox1), handlebox1, FALSE, TRUE, 0);
toolbar1 = gtk_toolbar_new ();
gtk_widget_show (toolbar1);
gtk_container_add (GTK_CONTAINER (handlebox1), toolbar1);
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar1), GTK_TOOLBAR_BOTH);
tmp_toolbar_icon = gtk_image_new_from_stock ("gtk-open", gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar1)));
button1 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar1),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("button1"),
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (toolbar1)->children)->data))->label), TRUE);
gtk_widget_show (button1);
tmp_toolbar_icon = gtk_image_new_from_stock ("gtk-cdrom", gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar1)));
button2 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar1),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("button2"),
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (toolbar1)->children)->data))->label), TRUE);
gtk_widget_show (button2);
tmp_toolbar_icon = gtk_image_new_from_stock ("gtk-refresh", gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar1)));
button3 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar1),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("button3"),
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (toolbar1)->children)->data))->label), TRUE);
gtk_widget_show (button3);
hscale1 = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0)));
gtk_widget_show (hscale1);
gtk_box_pack_start (GTK_BOX (vbox1), hscale1, TRUE, TRUE, 0);
statusbar1 = gtk_statusbar_new ();
gtk_widget_show (statusbar1);
gtk_box_pack_start (GTK_BOX (vbox1), statusbar1, FALSE, FALSE, 0);
g_signal_connect ((gpointer) new1, "activate",
G_CALLBACK (on_new1_activate),
NULL);
g_signal_connect ((gpointer) open1, "activate",
G_CALLBACK (on_open1_activate),
NULL);
g_signal_connect ((gpointer) save1, "activate",
G_CALLBACK (on_save1_activate),
NULL);
g_signal_connect ((gpointer) save_as1, "activate",
G_CALLBACK (on_save_as1_activate),
NULL);
g_signal_connect ((gpointer) quit1, "activate",
G_CALLBACK (on_quit1_activate),
NULL);
g_signal_connect ((gpointer) cut1, "activate",
G_CALLBACK (on_cut1_activate),
NULL);
g_signal_connect ((gpointer) copy1, "activate",
G_CALLBACK (on_copy1_activate),
NULL);
g_signal_connect ((gpointer) paste1, "activate",
G_CALLBACK (on_paste1_activate),
NULL);
g_signal_connect ((gpointer) delete1, "activate",
G_CALLBACK (on_delete1_activate),
NULL);
g_signal_connect ((gpointer) about1, "activate",
G_CALLBACK (on_about1_activate),
NULL);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF (window1, window1, "window1");
GLADE_HOOKUP_OBJECT (window1, vbox1, "vbox1");
GLADE_HOOKUP_OBJECT (window1, menubar1, "menubar1");
GLADE_HOOKUP_OBJECT (window1, menuitem1, "menuitem1");
GLADE_HOOKUP_OBJECT (window1, menu1, "menu1");
GLADE_HOOKUP_OBJECT (window1, new1, "new1");
GLADE_HOOKUP_OBJECT (window1, open1, "open1");
GLADE_HOOKUP_OBJECT (window1, save1, "save1");
GLADE_HOOKUP_OBJECT (window1, save_as1, "save_as1");
GLADE_HOOKUP_OBJECT (window1, separatormenuitem1, "separatormenuitem1");
GLADE_HOOKUP_OBJECT (window1, quit1, "quit1");
GLADE_HOOKUP_OBJECT (window1, menuitem2, "menuitem2");
GLADE_HOOKUP_OBJECT (window1, menu2, "menu2");
GLADE_HOOKUP_OBJECT (window1, cut1, "cut1");
GLADE_HOOKUP_OBJECT (window1, copy1, "copy1");
GLADE_HOOKUP_OBJECT (window1, paste1, "paste1");
GLADE_HOOKUP_OBJECT (window1, delete1, "delete1");
GLADE_HOOKUP_OBJECT (window1, menuitem3, "menuitem3");
GLADE_HOOKUP_OBJECT (window1, menu3, "menu3");
GLADE_HOOKUP_OBJECT (window1, menuitem4, "menuitem4");
GLADE_HOOKUP_OBJECT (window1, menu4, "menu4");
GLADE_HOOKUP_OBJECT (window1, about1, "about1");
GLADE_HOOKUP_OBJECT (window1, handlebox1, "handlebox1");
GLADE_HOOKUP_OBJECT (window1, toolbar1, "toolbar1");
GLADE_HOOKUP_OBJECT (window1, button1, "button1");
GLADE_HOOKUP_OBJECT (window1, button2, "button2");
GLADE_HOOKUP_OBJECT (window1, button3, "button3");
GLADE_HOOKUP_OBJECT (window1, hscale1, "hscale1");
GLADE_HOOKUP_OBJECT (window1, statusbar1, "statusbar1");
gtk_window_add_accel_group (GTK_WINDOW (window1), accel_group);
return window1;
}
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
GtkWidget* create_window1 (void);
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include "gtk2_support.h"
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (!parent)
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
static GList *pixmaps_directories = NULL;
/* Use this function to set the directory containing installed pixmaps. */
void
add_pixmap_directory (const gchar *directory)
{
pixmaps_directories = g_list_prepend (pixmaps_directories,
g_strdup (directory));
}
/* This is an internally used function to find pixmap files. */
static gchar*
find_pixmap_file (const gchar *filename)
{
GList *elem;
/* We step through each of the pixmaps directory to find it. */
elem = pixmaps_directories;
while (elem)
{
gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
G_DIR_SEPARATOR_S, filename);
if (g_file_test (pathname, G_FILE_TEST_EXISTS))
return pathname;
g_free (pathname);
elem = elem->next;
}
return NULL;
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename)
{
gchar *pathname = NULL;
GtkWidget *pixmap;
if (!filename || !filename[0])
return gtk_image_new ();
pathname = find_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return gtk_image_new ();
}
pixmap = gtk_image_new_from_file (pathname);
g_free (pathname);
return pixmap;
}
/* This is an internally used function to create pixmaps. */
GdkPixbuf*
create_pixbuf (const gchar *filename)
{
gchar *pathname = NULL;
GdkPixbuf *pixbuf;
GError *error = NULL;
if (!filename || !filename[0])
return NULL;
pathname = find_pixmap_file (filename);
if (!pathname)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return NULL;
}
pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
if (!pixbuf)
{
fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
pathname, error->message);
g_error_free (error);
}
g_free (pathname);
return pixbuf;
}
/* This is used to set ATK action descriptions. */
void
glade_set_atk_action_description (AtkAction *action,
const gchar *action_name,
const gchar *description)
{
gint n_actions, i;
n_actions = atk_action_get_n_actions (action);
for (i = 0; i < n_actions; i++)
{
if (!strcmp (atk_action_get_name (action, i), action_name))
atk_action_set_description (action, i, description);
}
}
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
/*
* Standard gettext macros.
*/
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif
/*
* Public Functions.
*/
/*
* This function returns a widget in a component created by Glade.
* Call it with the toplevel widget in the component (i.e. a window/dialog),
* or alternatively any widget in the component, and the name of the widget
* you want returned.
*/
GtkWidget* lookup_widget (GtkWidget *widget,
const gchar *widget_name);
/* Use this function to set the directory containing installed pixmaps. */
void add_pixmap_directory (const gchar *directory);
/*
* Private Functions.
*/
/* This is used to create the pixmaps used in the interface. */
GtkWidget* create_pixmap (GtkWidget *widget,
const gchar *filename);
/* This is used to create the pixbufs used in the interface. */
GdkPixbuf* create_pixbuf (const gchar *filename);
/* This is used to set ATK action descriptions. */
void glade_set_atk_action_description (AtkAction *action,
const gchar *action_name,
const gchar *description);
SOURCES_kde = \
kde.cpp \
interface.cpp \
slider.cpp \
disc.cpp \
net.cpp \
menu.cpp \
preferences.cpp \
pluginsbox.cpp \
QConfigItem.cpp \
messages.cpp \
info.cpp \
languagemenu.cpp \
$(NULL)
nodist_SOURCES_kde = \
interface.moc.cpp \
slider.moc.cpp \
disc.moc.cpp \
net.moc.cpp \
menu.moc.cpp \
preferences.moc.cpp \
pluginsbox.moc.cpp \
QConfigItem.moc.cpp \
messages.moc.cpp \
info.moc.cpp \
languagemenu.moc.cpp \
$(NULL)
noinst_HEADERS += \
common.h \
disc.h \
QConfigItem.h \
interface.h \
menu.h \
net.h \
pluginsbox.h \
preferences.h \
slider.h \
messages.h \
info.h \
languagemenu.h \
$(NULL)
interface.moc.cpp: interface.h
$(MOC) $< -o $@
slider.moc.cpp: slider.h
$(MOC) $< -o $@
disc.moc.cpp: disc.h
$(MOC) $< -o $@
net.moc.cpp: net.h
$(MOC) $< -o $@
menu.moc.cpp: menu.h
$(MOC) $< -o $@
preferences.moc.cpp: preferences.h
$(MOC) $< -o $@
pluginsbox.moc.cpp: pluginsbox.h
$(MOC) $< -o $@
QConfigItem.moc.cpp: QConfigItem.h
$(MOC) $< -o $@
messages.moc.cpp: messages.h
$(MOC) $< -o $@
info.moc.cpp: info.h
$(MOC) $< -o $@
languagemenu.moc.cpp: languagemenu.h
$(MOC) $< -o $@
kdedatadir = $(datadir)/vlc
dist_kdedata_DATA = ui.rc
/*****************************************************************************
* QConfigItem.cpp: The QConfigItem class
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon 12.08.2002
*
* 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.
*****************************************************************************/
#include "QConfigItem.h"
#include <vlc/vlc.h>
QConfigItem::QConfigItem(QObject *parent, QString name, int iType, int i_val) :
QObject(parent, name)
{
type = iType;
iVal = i_val;
bChanged = false;
}
QConfigItem::QConfigItem(QObject *parent, QString name, int iType, float f_val) :
QObject(parent, name)
{
type = iType;
fVal = f_val;
bChanged = false;
}
QConfigItem::QConfigItem(QObject *parent, QString name, int iType, QString s_val) :
QObject(parent, name)
{
type = iType;
sVal = s_val;
bChanged = false;
}
QConfigItem::~QConfigItem()
{
;
}
int QConfigItem::getType()
{
return type;
}
int QConfigItem::iValue()
{
return iVal;
}
float QConfigItem::fValue()
{
return fVal;
}
QString QConfigItem::sValue()
{
return sVal;
}
void QConfigItem::setValue(int val)
{
iVal = val;
bChanged = true;
}
void QConfigItem::setValue(float val)
{
fVal = val;
bChanged = true;
}
void QConfigItem::setValue(double val)
{
fVal = (float)val;
bChanged = true;
}
void QConfigItem::setValue(const QString &val)
{
sVal = val;
bChanged = true;
}
bool QConfigItem::changed()
{
return bChanged;
}
void QConfigItem::resetChanged()
{
bChanged = false;
}
/*****************************************************************************
* QConfigItem.h : includes for the QConfigItem class
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Andres Krapf <dae@chez.com> Sun Mar 25 2001
*
* 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.
*****************************************************************************/
#ifndef _KCONFIGITEM_H_
#define _KCONFIGITEM_H_
#include <qobject.h>
#include <qstring.h>
/*
A class to handle the information for one configuration item.
*/
class QConfigItem : public QObject
{
Q_OBJECT
public:
QConfigItem(QObject *parent, QString name, int iType, int i_val);
QConfigItem(QObject *parent, QString name, int iType, float f_val);
QConfigItem(QObject *parent, QString name, int iType, QString s_val);
~QConfigItem();
int getType();
float fValue();
int iValue();
QString sValue();
bool changed();
public slots:
void setValue(int val);
void setValue(float val);
void setValue(double val);
void setValue(const QString &val);
void resetChanged();
private:
int iVal, type;
float fVal;
QString sVal;
bool bChanged;
};
#endif
/***************************************************************************
common.h - description
-------------------
begin : Mon Apr 9 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#ifndef _INTF_PLUGIN_H_
#define _INTF_PLUGIN_H_
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#endif /* _INTF_PLUGIN_H_ */
/***************************************************************************
disc.cpp - description
-------------------
begin : Sat Apr 7 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#include "disc.h"
#include <qhbox.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qspinbox.h>
#include <qstring.h>
#include <qvbox.h>
#include <qvbuttongroup.h>
#include <qvgroupbox.h>
#include <qwidget.h>
#include <kdialogbase.h>
#include <klineedit.h>
KDiskDialog::KDiskDialog( QWidget *parent, const char *name )
:KDialogBase( parent, name, true, QString::null,
Ok|Cancel, Ok, true )
{
QVBox *pageVBox = makeVBoxMainWidget();
QHBox *deviceSelectHBox = new QHBox( pageVBox );
deviceSelectHBox->setSpacing( 5 );
fButtonGroup = new QVButtonGroup( _("Disk type"), deviceSelectHBox );
fDVDButton = new QRadioButton( "DVD", fButtonGroup);
fDVDButton->setChecked( true );
fVCDButton = new QRadioButton( "VCD", fButtonGroup);
fVCDButton->setEnabled( false );
QVGroupBox *startVBox = new QVGroupBox( _("Starting position"), deviceSelectHBox );
QHBox *titleHBox = new QHBox( startVBox );
new QLabel( _("Title "), titleHBox );
fTitle = new QSpinBox( titleHBox );
QHBox *chapterHBox = new QHBox( startVBox );
new QLabel( _("Chapter "), chapterHBox );
fChapter = new QSpinBox( chapterHBox );
QHBox *deviceNameHBox = new QHBox( pageVBox );
new QLabel( _("Device name "), deviceNameHBox );
fLineEdit = new KLineEdit( "/dev/dvd", deviceNameHBox );
}
KDiskDialog::~KDiskDialog()
{
}
QString KDiskDialog::type() const
{
if ( fDVDButton->isChecked() )
{
return ( QString("dvd") );
}
else
{
return ( QString("vcd") );
}
}
QString KDiskDialog::device() const
{
return ( fLineEdit->text() );
}
int KDiskDialog::title() const
{
return ( fTitle->value() );
}
int KDiskDialog::chapter() const
{
return ( fChapter->value() );
}
/***************************************************************************
disc.h - description
-------------------
begin : Sat Apr 7 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#ifndef KDE_DISC_H
#define KDE_DISC_H
#include "common.h"
#include <kdialogbase.h>
#include <qstring.h>
class QVButtonGroup;
class QRadioButton;
class QSpinBox;
class KLineEdit;
/**
*@author andres
*/
class KDiskDialog : public KDialogBase
{
Q_OBJECT
public:
KDiskDialog( QWidget *parent=0, const char *name=0 );
~KDiskDialog();
QString type() const;
QString device() const;
int title() const;
int chapter() const;
private:
QVButtonGroup *fButtonGroup;
QRadioButton *fDVDButton;
QRadioButton *fVCDButton;
QSpinBox *fTitle;
QSpinBox *fChapter;
KLineEdit *fLineEdit;
};
#endif
/*****************************************************************************
* info.cpp: the KInfoWindow class
*****************************************************************************
* Copyright (C) 2001-2003 the VideoLAN team
* $Id$
*
* Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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.
*****************************************************************************/
#include "info.h"
#include "common.h"
#include <qtextview.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qvbox.h>
KInfoWindow::KInfoWindow( intf_thread_t * p_intf, input_thread_t *p_input ) :
KDialogBase( Tabbed, _( "Messages" ), Ok, Ok, 0, 0, false)
{
// clearWFlags(~0);
// setWFlags(WType_TopLevel);
setSizeGripEnabled(true);
int i, j;
vlc_mutex_lock( &p_input->p_item->lock );
for ( i = 0; i < p_input->p_item->i_categories; i++ )
{
info_category_t *p_category =
p_input->p_item->pp_categories[i];
QFrame *page = addPage( QString(p_category->psz_name) );
QVBoxLayout *toplayout = new QVBoxLayout( page);
QVBox *category_table = new QVBox(page);
toplayout->addWidget(category_table);
toplayout->setResizeMode(QLayout::FreeResize);
toplayout->addStretch(10);
category_table->setSpacing(spacingHint());
for ( j = 0; j < p_category->i_infos; j++ )
{
info_t *p_info = p_category->pp_infos[j];
QHBox *hb = new QHBox( category_table );
new QLabel( QString(p_info->psz_name) + ":", hb );
new QLabel( p_info->psz_value, hb );
}
}
vlc_mutex_unlock( &p_input->p_item->lock );
resize(300,400);
show();
}
KInfoWindow::~KInfoWindow()
{
;
}
/*****************************************************************************
* info.h: the KInfoWindow class
*****************************************************************************
* Copyright (C) 2001-2003 the VideoLAN team
* $Id$
*
* Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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.
*****************************************************************************/
#include <kdialogbase.h>
#include "common.h"
class KInfoWindow : public KDialogBase
{
Q_OBJECT
public:
KInfoWindow( intf_thread_t*, input_thread_t * );
~KInfoWindow();
};
/***************************************************************************
interface.cpp - description
-------------------
begin : Sun Mar 25 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#include "disc.h"
#include "info.h"
#include "interface.h"
#include "net.h"
#include "menu.h"
#include "slider.h"
#include "preferences.h"
#include "languagemenu.h"
#include <iostream>
#include <kaction.h>
#include <kfiledialog.h>
#include <klocale.h>
#include <kstdaction.h>
#include <kurl.h>
#include <kurldrag.h>
#include <qcursor.h>
#include <qdragobject.h>
#include <qtimer.h>
#include <kdialog.h>
#include <kstatusbar.h>
#define ID_STATUS_MSG 1
#define ID_DATE 2
#define ID_STREAM_SOURCE 3
KInterface::KInterface( intf_thread_t *p_intf, QWidget *parent,
const char *name ) : KMainWindow(parent,name)
{
setAcceptDrops(true);
this->p_intf = p_intf;
p_messagesWindow = new KMessagesWindow( p_intf, p_intf->p_sys->p_msg );
fDiskDialog = new KDiskDialog( this );
fNetDialog = new KNetDialog( this );
fTitleMenu = new KTitleMenu( p_intf, this );
fSlider = new KVLCSlider( QSlider::Horizontal, this );
fSlider->setMaxValue(10000);
connect( fSlider, SIGNAL( userChanged( int ) ), this,
SLOT( slotSliderMoved( int ) ) );
connect( fSlider, SIGNAL( valueChanged( int ) ), this,
SLOT( slotSliderChanged( int ) ) );
connect( fSlider, SIGNAL( sliderMoved( int ) ), this,
SLOT( slotSliderChanged( int ) ) );
setCentralWidget(fSlider);
fTimer = new QTimer( this );
connect( fTimer, SIGNAL( timeout() ), this, SLOT( slotManage() ) );
resize( 400, 30 );
///////////////////////////////////////////////////////////////////
// call inits to invoke all other construction parts
// XXX could we move this up ?
initStatusBar();
initActions();
// add certain calls to the popup menu
fileOpen->plug( fTitleMenu );
fileOpenRecent->plug( fTitleMenu );
diskOpen->plug( fTitleMenu );
streamOpen->plug( fTitleMenu );
play->plug( fTitleMenu );
pause->plug( fTitleMenu );
slow->plug( fTitleMenu );
fast->plug( fTitleMenu );
fileQuit->plug( fTitleMenu );
fTimer->start( 0, FALSE );
}
KInterface::~KInterface()
{
;
}
void KInterface::initActions()
{
languages = new KActionMenu( _( "Languages" ), actionCollection(),
_("language") );
languages->setEnabled( false );
languageCollection = new KActionCollection( this );
subtitleCollection = new KActionCollection( this );
subtitles = new KActionMenu( _( "Subtitles" ), actionCollection(),
"subtitles" );
subtitles->setEnabled( false );
fileOpen =
KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
fileOpenRecent =
KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)),
actionCollection());
preferences = KStdAction::preferences(this, SLOT(slotShowPreferences()),
actionCollection());
fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()),
actionCollection());
viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()),
actionCollection());
viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()),
actionCollection());
diskOpen = new KAction( i18n( _("Open &Disk") ), 0, 0, this,
SLOT( slotOpenDisk() ), actionCollection(),
"open_disk" );
streamOpen = new KAction( i18n( _("Open &Stream") ), 0, 0, this,
SLOT( slotOpenStream() ), actionCollection(),
"open_stream" );
backward = new KAction( i18n( _("&Backward") ), 0, 0, this,
SLOT( slotBackward() ), actionCollection(),
"backward" );
stop = new KAction( i18n( _("&Stop") ), 0, 0, this,
SLOT( slotStop() ), actionCollection(), "stop" );
play = new KAction( i18n( _("&Play") ), 0, 0, this,
SLOT( slotPlay() ), actionCollection(), "play" );
pause = new KAction( i18n( _("P&ause") ), 0, 0, this,
SLOT( slotPause() ), actionCollection(), "pause" );
slow = new KAction( i18n( _("&Slow") ), 0, 0, this,
SLOT( slotSlow() ), actionCollection(), "slow" );
fast = new KAction( i18n( _("Fas&t") ), 0, 0, this,
SLOT( slotFast() ), actionCollection(), "fast" );
prev = new KAction( i18n( _("Prev") ), 0, 0, this,
SLOT( slotPrev() ), actionCollection(), "prev" );
next = new KAction( i18n( _("Next") ), 0, 0, this,
SLOT( slotNext() ), actionCollection(), "next" );
messages = new KAction( _( "Messages..." ), 0, 0, this,
SLOT( slotShowMessages() ), actionCollection(),
"view_messages");
info = new KAction( _( "Stream info..." ), 0, 0, this,
SLOT( slotShowInfo() ), actionCollection(),
"view_stream_info");
info->setEnabled( false );
program = new KActionMenu( _( "Program" ), actionCollection(), "program" );
program->setEnabled( false );
title = new KActionMenu( _( "Title" ), actionCollection(), "title" );
title->setEnabled( false );
chapter = new KActionMenu( _( "Chapter" ), actionCollection(), "chapter" );
chapter->setEnabled( false );
fileOpen->setStatusText(i18n(_("Opens an existing document")));
fileOpenRecent->setStatusText(i18n(_("Opens a recently used file")));
fileQuit->setStatusText(i18n(_("Quits the application")));
viewToolBar->setStatusText(i18n(_("Enables/disables the toolbar")));
viewStatusBar->setStatusText(i18n(_("Enables/disables the status bar")));
diskOpen->setStatusText( i18n( _("Opens a disk") ) );
streamOpen->setStatusText( i18n( _("Opens a network stream") ) );
backward->setStatusText( i18n( _("Backward") ) );
stop->setStatusText( i18n( _("Stops playback") ) );
play->setStatusText( i18n( _("Starts playback") ) );
pause->setStatusText( i18n( _("Pauses playback") ) );
slow->setStatusText( i18n( _("Slow") ) );
fast->setStatusText( i18n( _("Fast") ) );
prev->setStatusText( i18n( _("Prev") ) );
next->setStatusText( i18n( _("Next") ) );
// use the absolute path to your ktestui.rc file for testing purpose in createGUI();
char *psz_uifile = config_GetPsz( p_intf, "kde-uirc" );
createGUI( psz_uifile );
// createGUI( "./modules/gui/kde/ui.rc" );
}
void KInterface::initStatusBar()
{
///////////////////////////////////////////////////////////////////
// STATUSBAR
// TODO: add your own items you need for displaying current application status.
statusBar()->insertItem(i18n(_("Ready.")), ID_STATUS_MSG, 1, false);
statusBar()->setItemAlignment( ID_STATUS_MSG, AlignLeft | AlignVCenter );
statusBar()->insertItem( "0:00:00", ID_DATE, 0, true );
}
/////////////////////////////////////////////////////////////////////
// SLOT IMPLEMENTATION
/////////////////////////////////////////////////////////////////////
void KInterface::slotShowMessages()
{
p_messagesWindow->show();
}
void KInterface::slotShowInfo()
{
if ( p_intf->p_sys->p_input )
{
new KInfoWindow(p_intf, p_intf->p_sys->p_input);
}
}
void KInterface::slotFileOpen()
{
playlist_t *p_playlist;
slotStatusMsg( i18n( _("Opening file...") ) );
KURL url=KFileDialog::getOpenURL( QString::null,
i18n( "*|All files" ), this, i18n( _("Open File...") ) );
if( !url.isEmpty() )
{
p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
fileOpenRecent->addURL( url );
playlist_Add( p_playlist, url.path(), url.path(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
vlc_object_release( p_playlist );
}
}
slotStatusMsg( i18n( _("Ready.") ) );
}
void KInterface::slotFileOpenRecent(const KURL& url)
{
slotStatusMsg(i18n(_("Opening file...")));
slotStatusMsg(i18n(_("Ready.")));
}
void KInterface::slotFileQuit()
{
slotStatusMsg(i18n(_("Exiting...")));
p_intf->p_vlc->b_die = VLC_TRUE;
slotStatusMsg(i18n(_("Ready.")));
}
void KInterface::slotViewToolBar()
{
slotStatusMsg(i18n(_("Toggling toolbar...")));
///////////////////////////////////////////////////////////////////
// turn Toolbar on or off
if(!viewToolBar->isChecked())
{
toolBar("mainToolBar")->hide();
}
else
{
toolBar("mainToolBar")->show();
}
slotStatusMsg(i18n(_("Ready.")));
}
void KInterface::slotViewStatusBar()
{
slotStatusMsg(i18n(_("Toggle the status bar...")));
///////////////////////////////////////////////////////////////////
//turn Statusbar on or off
if(!viewStatusBar->isChecked())
{
statusBar()->hide();
}
else
{
statusBar()->show();
}
slotStatusMsg(i18n(_("Ready.")));
}
void KInterface::slotShowPreferences()
{
// Do something
KPreferences(this->p_intf, "main", this, "preferences");
}
void KInterface::slotStatusMsg(const QString &text)
{
///////////////////////////////////////////////////////////////////
// change status message permanently
statusBar()->clear();
statusBar()->changeItem(text, ID_STATUS_MSG);
}
void KInterface::slotManage()
{
p_messagesWindow->update();
// p_intf->p_sys->p_app->processEvents();
vlc_mutex_lock( &p_intf->change_lock );
/* Update the input */
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input = (input_thread_t *)
vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
if ( p_intf->p_sys->p_input )
{
languages->setEnabled( true );
subtitles->setEnabled( true );
info->setEnabled( true );
}
}
else if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
languages->setEnabled( false );
subtitles->setEnabled( false );
info->setEnabled( false );
}
/* If the "display popup" flag has changed */
if( p_intf->b_menu_change )
{
fTitleMenu->popup( ( QCursor::pos() ) );
p_intf->b_menu_change = 0;
}
if( p_intf->p_sys->p_input )
{
input_thread_t *p_input = p_intf->p_sys->p_input;
vlc_mutex_lock( &p_input->stream.stream_lock );
if( !p_input->b_die )
{
/* New input or stream map change */
if( p_input->stream.b_changed )
{
// E_(GtkModeManage)( p_intf );
//GtkSetupMenus( p_intf );
slotUpdateLanguages();
p_intf->p_sys->b_playing = 1;
p_input->stream.b_changed = 0;
}
/* Manage the slider. fSlider->setValue triggers
* slotSliderChanged which needs to grab the stream lock*/
#define p_area p_input->stream.p_selected_area
if( p_area->i_size ) {
vlc_mutex_unlock( &p_input->stream.stream_lock );
fSlider->setValue( ( 10000 * p_area->i_tell )
/ p_area->i_size );
vlc_mutex_lock( &p_input->stream.stream_lock );
}
#undef p_area
// if( p_intf->p_sys->i_part !=
// p_input->stream.p_selected_area->i_part )
//{
// p_intf->p_sys->b_chapter_update = 1;
//GtkSetupMenus( p_intf );
//}
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
//E_(GtkModeManage)( p_intf );
p_intf->p_sys->b_playing = 0;
}
if( p_intf->b_die )
{
p_intf->p_sys->p_app->quit();
}
vlc_mutex_unlock( &p_intf->change_lock );
msleep( 100 );
}
void KInterface::slotSliderMoved( int position )
{
if( p_intf->p_sys->p_input )
{
// XXX is this locking really useful ?
vlc_mutex_lock( &p_intf->change_lock );
var_SetFloat( p_intf->p_sys->p_input, "position",
(double)position / 10000.0 );
vlc_mutex_unlock( &p_intf->change_lock );
}
}
void KInterface::slotUpdateLanguages()
{
es_descriptor_t * p_spu_es;
es_descriptor_t * p_audio_es;
/* look for selected ES */
p_audio_es = NULL;
p_spu_es = NULL;
for( unsigned int i = 0 ;
i < p_intf->p_sys->p_input->stream.i_selected_es_number ;
i++
)
{
if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat
== AUDIO_ES )
{
p_audio_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
}
if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
{
p_spu_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
}
}
languages->setEnabled( false );
subtitles->setEnabled( false );
languageCollection->clear();
subtitleCollection->clear();
languages->popupMenu()->clear();
subtitles->popupMenu()->clear();
/* audio menus */
/* find audio root menu */
languageMenus( languages, p_audio_es, AUDIO_ES );
/* sub picture menus */
/* find spu root menu */
languageMenus( subtitles, p_spu_es, SPU_ES );
}
/*
* called with stream lock
*/
void KInterface::languageMenus(KActionMenu *root, es_descriptor_t *p_es,
int i_cat)
{
int i_item = 0;
if ( i_cat != AUDIO_ES )
{
KLanguageMenuAction *p_item =
new KLanguageMenuAction( p_intf, _( "Off" ), 0, this );
subtitleCollection->insert( p_item );
root->insert( p_item );
root->insert( new KActionSeparator( this ) );
p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
p_item->setChecked( p_es == 0 );
}
#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( unsigned int i = 0 ;
i < p_intf->p_sys->p_input->stream.i_es_number ;
i++ )
{
if( ( ES->i_cat == i_cat ) &&
( !ES->p_pgrm ||
ES->p_pgrm ==
p_intf->p_sys->p_input->stream.p_selected_program ) )
{
i_item++;
QString name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
if( name.isEmpty() )
{
name.sprintf( "Language %d", i_item );
}
KLanguageMenuAction *p_item;
if ( i_cat == AUDIO_ES )
{
p_item = new KLanguageMenuAction( p_intf, name, ES,
this );
languageCollection->insert(p_item);
}
else
{
p_item = new KLanguageMenuAction( p_intf, name, ES,
this );
subtitleCollection->insert(p_item);
}
p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
root->insert( p_item );
if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
{
/* don't lose p_item when we append into menu */
//p_item_active = p_item;
p_item->setChecked( true );
}
connect( p_item, SIGNAL( toggled( bool, es_descriptor_t * ) ),
this, SLOT( slotSetLanguage( bool, es_descriptor_t * ) ));
}
}
root->setEnabled( true );
}
void KInterface::slotSetLanguage( bool on, es_descriptor_t *p_es )
{
if( p_es )
var_SetInteger( p_intf->p_sys->p_input, "audio-es", p_es->i_id );
else
var_SetInteger( p_intf->p_sys->p_input, "audio-es", -1 );
}
void KInterface::slotSliderChanged( int position )
{
if( p_intf->p_sys->p_input != NULL )
{
char psz_time[ MSTRTIME_MAX_SIZE ];
int64_t i_seconds;
i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
secstotimestr( psz_time, i_seconds );
statusBar()->changeItem( psz_time, ID_DATE );
}
}
void KInterface::slotOpenDisk()
{
playlist_t *p_playlist;
int r = fDiskDialog->exec();
if ( r )
{
// Build source name
QString source;
source += fDiskDialog->type();
source += ':';
source += fDiskDialog->device();
source += '@';
source += fDiskDialog->title();
source += ',';
source += fDiskDialog->chapter();
p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
// add it to playlist
playlist_Add( p_playlist, source.latin1(), source.latin1(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
vlc_object_release( p_playlist );
}
}
}
void KInterface::slotOpenStream()
{
playlist_t *p_playlist;
int r = fNetDialog->exec();
if ( r )
{
// Build source name
QString source;
source += fNetDialog->protocol();
source += "://";
source += fNetDialog->server();
source += ":";
source += QString().setNum( fNetDialog->port() );
p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
// add it to playlist
playlist_Add( p_playlist, source.latin1(), source.latin1(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
vlc_object_release( p_playlist );
}
}
}
void KInterface::slotPlay()
{
if( p_intf->p_sys->p_input )
{
var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
}
}
void KInterface::slotPause()
{
if ( p_intf->p_sys->p_input )
{
var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
}
}
void KInterface::slotStop()
{
playlist_t *p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
playlist_Stop( p_playlist );
vlc_object_release( p_playlist );
}
}
void KInterface::slotBackward()
{
msg_Err( p_intf, "KInterface::slotBackward() - Unimplemented" );
}
void KInterface::slotPrev()
{
playlist_t *p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
playlist_Prev( p_playlist );
vlc_object_release( p_playlist );
}
}
void KInterface::slotNext()
{
playlist_t *p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist )
{
playlist_Next( p_playlist );
vlc_object_release( p_playlist );
}
}
void KInterface::slotSlow()
{
if( p_intf->p_sys->p_input != NULL )
{
var_SetVoid( p_intf->p_sys->p_input, "rate-slower" );
}
}
void KInterface::slotFast()
{
if( p_intf->p_sys->p_input != NULL )
{
var_SetVoid( p_intf->p_sys->p_input, "rate-faster" );
}
}
void KInterface::dragEnterEvent( QDragEnterEvent *event )
{
event->accept( QUriDrag::canDecode( event ) );
}
void KInterface::dropEvent( QDropEvent *event )
{
KURL::List urlList;
playlist_t *p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
if ( KURLDrag::decode( event, urlList ) )
{
for ( KURL::List::ConstIterator i = urlList.begin(); i != urlList.end(); i++ )
{
// XXX add a private function to add a KURL with checking
// actually a whole class for core abstraction would be neat
if( !(*i).isEmpty() )
{
fileOpenRecent->addURL( *i );
playlist_Add( p_playlist, (*i).path(), (*i).path(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
}
}
}
vlc_object_release( p_playlist );
}
/***************************************************************************
interface.h - description
-------------------
begin : Sun Mar 25 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#ifndef _KDE_INTERFACE_H_
#define _KDE_INTERFACE_H_
#include "common.h"
#include <kaction.h>
#include <kmainwindow.h>
#include <kapplication.h>
#include <kurl.h>
#include <qdragobject.h>
#include <qstring.h>
#include <qwidget.h>
#include "messages.h"
class KThread;
class KDiskDialog;
class KNetDialog;
class KRecentFilesAction;
class KTitleMenu;
class KToggleAction;
class KVLCSlider;
/**Main Window for the KDE vlc interface
*@author andres
*/
class KInterface : public KMainWindow
{
Q_OBJECT
public:
KInterface(intf_thread_t *p_intf, QWidget *parent=0,
const char *name="VLC");
~KInterface();
public slots:
/** open a file and load it into the document*/
void slotFileOpen();
/** opens a file from the recent files menu */
void slotFileOpenRecent(const KURL& url);
/** closes all open windows by calling close() on each
* memberList item until the list is empty, then quits the
* application. If queryClose() returns false because the
* user canceled the saveModified() dialog, the closing
* breaks.
*/
void slotFileQuit();
void slotShowPreferences();
/** toggles the toolbar
*/
void slotViewToolBar();
/** toggles the statusbar
*/
void slotViewStatusBar();
/** changes the statusbar contents for the standard label
* permanently, used to indicate current actions.
* @param text the text that is displayed in the statusbar
*/
void slotStatusMsg( const QString &text );
void slotShowMessages();
void slotShowInfo();
void slotSetLanguage( bool, es_descriptor_t * );
protected:
/** initializes the KActions of the application */
void initActions();
/** sets up the statusbar for the main window by initialzing a statuslabel.
*/
void initStatusBar();
virtual void dragEnterEvent( QDragEnterEvent *event );
virtual void dropEvent( QDropEvent *event );
private slots:
/** we use this to manage the communication with the vlc core */
void slotManage();
/** this slot is called when we drag the position seek bar */
void slotSliderMoved( int );
/** called every time the slider changes values */
void slotSliderChanged( int position );
void slotUpdateLanguages();
void slotOpenDisk();
void slotOpenStream();
void slotBackward();
void slotStop();
void slotPlay();
void slotPause();
void slotSlow();
void slotFast();
void slotPrev();
void slotNext();
private:
void languageMenus( KActionMenu *, es_descriptor_t *, int );
intf_thread_t *p_intf;
KMessagesWindow *p_messagesWindow;
/** to call p_intf->pf_manage every now and then */
QTimer *fTimer;
/** slider which works well with user movement */
KVLCSlider *fSlider;
/** open dvd/vcd */
KDiskDialog *fDiskDialog;
/** open net stream */
KNetDialog *fNetDialog;
KTitleMenu *fTitleMenu;
// KAction pointers to enable/disable actions
KAction *fileOpen;
KAction *diskOpen;
KAction *streamOpen;
KRecentFilesAction *fileOpenRecent;
KAction *fileQuit;
KToggleAction *viewToolBar;
KToggleAction *viewStatusBar;
KAction *backward;
KAction *stop;
KAction *play;
KAction *pause;
KAction *slow;
KAction *fast;
KAction *prev;
KAction *next;
KAction *messages;
KAction *preferences;
KAction *info;
KActionMenu *languages;
KActionMenu *subtitles;
KActionCollection *languageCollection;
KActionCollection *subtitleCollection;
KActionMenu *program;
KActionMenu *title;
KActionMenu *chapter;
};
/*****************************************************************************
* intf_sys_t: description and status of KDE interface
*****************************************************************************/
struct intf_sys_t
{
KApplication *p_app;
KInterface *p_window;
KAboutData *p_about;
int b_playing;
input_thread_t *p_input;
msg_subscription_t *p_msg;
};
#endif /* _KDE_INTERFACE_H_ */
/*****************************************************************************
* kde.cpp : KDE plugin for vlc
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Andres Krapf <dae@chez.com> Sun Mar 25 2001
*
* 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.
*****************************************************************************/
#include "common.h"
#include "interface.h"
#include <iostream>
#include <kaction.h>
#include <kapp.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kmainwindow.h>
#include <kstdaction.h>
#include <qwidget.h>
/*****************************************************************************
* The local class and prototypes
*****************************************************************************/
class KInterface;
class KAboutData;
static int open( vlc_object_t * p_this );
static void close( vlc_object_t * p_this );
static void run(intf_thread_t *p_intf);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
/* int i = getenv( "DISPLAY" ) == NULL ? 8 : 85; */
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_GENERAL );
set_description( _("KDE interface") );
add_file( "kde-uirc", DATA_PATH "/ui.rc", NULL, N_( "path to ui.rc file" ), NULL, VLC_TRUE );
set_capability( "interface", 0 ); /* 0 used to be i, disabled because kvlc not maintained */
set_program( "kvlc" );
set_callbacks( open, close );
vlc_module_end();
/*****************************************************************************
* KThread::open: initialize and create window
*****************************************************************************/
static int open(vlc_object_t *p_this)
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return( 1 );
}
p_intf->pf_run = run;
return ( 0 );
}
/*****************************************************************************
* KThread::close: destroy interface window
*****************************************************************************/
static void close(vlc_object_t *p_this)
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
delete p_intf->p_sys->p_app;
delete p_intf->p_sys->p_about;
msg_Unsubscribe(p_intf, p_intf->p_sys->p_msg);
free( p_intf->p_sys );
}
/*****************************************************************************
* KThread::run: KDE thread
*****************************************************************************
* This part of the interface is in a separate thread so that we can call
* exec() from within it without annoying the rest of the program.
*****************************************************************************/
void run(intf_thread_t *p_intf)
{
p_intf->p_sys->p_about =
new KAboutData( "kvlc", I18N_NOOP("Kvlc"), VERSION,
_("This is the VLC media player, a DVD, MPEG and DivX player. It can "
"play MPEG and MPEG2 files from a file or from a network source."),
KAboutData::License_GPL,
_("(c) 1996-2004 the VideoLAN team"),
0, 0, "");
p_intf->p_sys->p_about->addAuthor( "the VideoLAN team", 0,
"<videolan@videolan.org>" );
int argc = 5;
char *argv[] = { "vlc", "--icon", DATA_PATH "/kvlc32x32.png", "--miniicon", DATA_PATH "/kvlc16x16.png" };
KCmdLineArgs::init( argc, argv, p_intf->p_sys->p_about );
/* Subscribe to message queue */
p_intf->p_sys->p_msg = msg_Subscribe( p_intf );
p_intf->p_sys->p_app = new KApplication();
p_intf->p_sys->p_window = new KInterface(p_intf);
p_intf->p_sys->p_window->setCaption( VOUT_TITLE " (KDE interface)" );
p_intf->p_sys->p_input = NULL;
p_intf->p_sys->p_window->show();
p_intf->p_sys->p_app->exec();
}
/*****************************************************************************
* languagemenu.cpp: the KLanguageMenuAction class
*****************************************************************************
* Copyright (C) 2001-2003 the VideoLAN team
* $Id$
*
* Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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.
*****************************************************************************/
#include "languagemenu.h"
KLanguageMenuAction::KLanguageMenuAction( intf_thread_t *p_intf, const QString &text, es_descriptor_t * p_es, QObject *parent) : KRadioAction( text,0,parent), p_es(p_es), p_intf(p_intf)
{
;
}
void KLanguageMenuAction::setChecked( bool on )
{
if ( on != isChecked() )
{
emit toggled( on, p_es );
KRadioAction::setChecked( on );
}
}
KLanguageMenuAction::~KLanguageMenuAction()
{
}
/*****************************************************************************
* languagemenu.h: the KLanguageMenuAction class
*****************************************************************************
* Copyright (C) 2001-2003 the VideoLAN team
* $Id$
*
* Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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.
*****************************************************************************/
#include <kaction.h>
#include "common.h"
class KLanguageMenuAction : public KRadioAction
{
Q_OBJECT
public:
KLanguageMenuAction(intf_thread_t*, const QString&, es_descriptor_t *, QObject *);
~KLanguageMenuAction();
signals:
void toggled( bool, es_descriptor_t *);
public slots:
void setChecked( bool );
private:
es_descriptor_t *p_es;
intf_thread_t *p_intf;
};
/***************************************************************************
menu.cpp - description
-------------------
begin : Thu Apr 12 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#include "interface.h"
#include "menu.h"
#include <kaction.h>
#include <klocale.h>
KTitleMenu::KTitleMenu( intf_thread_t *p_intf, QWidget *parent, const char *name ) : KPopupMenu( parent, name )
{
fInterfaceThread = p_intf;
connect( this, SIGNAL( aboutToShow() ), this, SLOT( regenerateSlot() ) );
fLanguageList = new KActionMenu( "Language", 0, this );
}
KTitleMenu::~KTitleMenu()
{
}
void KTitleMenu::regenerateSlot()
{
// removal of elements and disconnection of signal/slots happen transparently on delete
delete fLanguageList;
fLanguageList = new KActionMenu( "Language", 0, this );
int i_item = 0;
vlc_mutex_lock( &fInterfaceThread->p_sys->p_input->stream.stream_lock );
for( unsigned int i = 0 ;
i < fInterfaceThread->p_sys->p_input->stream.i_es_number ;
i++ )
{
if( fInterfaceThread->p_sys->p_input->stream.pp_es[i]->i_cat /* == i_cat */ )
{
i_item++;
QString language( fInterfaceThread->p_sys->p_input->stream.pp_es[i]->psz_desc );
if ( QString::null == language )
{
language += i18n( "Language" );
language += " " + i_item;
}
KRadioAction *action = new KRadioAction( language, 0, this, "language_action" );
fLanguageList->insert( action );
if( /* p_es == */ fInterfaceThread->p_sys->p_input->stream.pp_es[i] )
{
/* don't lose p_item when we append into menu */
//p_item_active = p_item;
}
}
}
vlc_mutex_unlock( &fInterfaceThread->p_sys->p_input->stream.stream_lock );
#if 0
/* link the new menu to the menubar item */
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 */
if( p_item_active != NULL )
{
gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( p_item_active ),
TRUE );
}
#endif
/* be sure that menu is sensitive if non empty */
if ( i_item > 0 )
{
fLanguageList->setEnabled( true );
}
}
/** this method is called when the user selects a language */
void KTitleMenu::languageSelectedSlot()
{
}
/***************************************************************************
menu.h - description
-------------------
begin : Thu Apr 12 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#ifndef _KDE_MENU_H_
#define _KDE_MENU_H_
#include "common.h"
#include <qwidget.h>
#include <kpopupmenu.h>
class KActionMenu;
/**
*@author andres
*/
class KTitleMenu : public KPopupMenu
{
Q_OBJECT
public:
KTitleMenu( intf_thread_t *p_intf, QWidget *parent=0,
const char *name=0 );
~KTitleMenu();
private:
intf_thread_t *fInterfaceThread;
KActionMenu *fLanguageList;
private slots: // Private slots
/** this method regenerates the popup menu */
void regenerateSlot();
/** this method is called when the user selects a language */
void languageSelectedSlot();
};
#endif /* _KDE_MENU_H_ */
/*****************************************************************************
* messages.cpp: the KMessagesWindow class
*****************************************************************************
* Copyright (C) 2001-2003 the VideoLAN team
* $Id$
*
* Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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.
*****************************************************************************/
#include "messages.h"
#include <qtextview.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qvbox.h>
KMessagesWindow::KMessagesWindow( intf_thread_t * p_intf, msg_subscription_t *p_msg ) :
KDialogBase( Plain, _( "Messages" ), Ok, Ok, 0, 0, false)
{
// clearWFlags(~0);
// setWFlags(WType_TopLevel);
setSizeGripEnabled(true);
this->p_intf = p_intf;
this->p_msg = p_msg;
QFrame *page = plainPage();
QVBoxLayout *toplayout = new QVBoxLayout( page);
// QScrollView *sv = new QScrollView(page);
// sv->setResizePolicy(QScrollView::AutoOneFit);
// sv->setFrameStyle(QScrollView::NoFrame);
// toplayout->addWidget(sv);
// QVBox *category_table = new QVBox(sv->viewport());
// sv->addChild(category_table);
// toplayout->addStretch(10);
QVBox *category_table = new QVBox(page);
toplayout->addWidget(category_table);
toplayout->setResizeMode(QLayout::FreeResize);
category_table->setSpacing(spacingHint());
resize(300,400);
new QLabel( _("Messages:"), category_table );
text = new QTextView( category_table );
text->setPaper( QBrush( black ) );
// clearWFlags(WStyle_DialogBorder|WStyle_NoBorder);
// setWFlags(WStyle_NormalBorder|WStyle_Customize);
// connect(this, SIGNAL(okClicked()), this, SLOT(accept()));
}
KMessagesWindow::~KMessagesWindow()
{
;
}
void KMessagesWindow::update()
{
int i_stop, i_start;
/* Update the log window */
vlc_mutex_lock( p_msg->p_lock );
i_stop = *p_msg->pi_stop;
vlc_mutex_unlock( p_msg->p_lock );
if( p_msg->i_start != i_stop )
{
static const char * ppsz_type[4] = { ": ", " error: ", " warning: ",
" debug: " };
static const char * ppsz_color[4] = {
"<font color=white>",
"<font color=red>",
"<font color=yellow>",
"<font color=gray>"
};
for( i_start = p_msg->i_start;
i_start != i_stop;
i_start = (i_start+1) % VLC_MSG_QSIZE )
{
text->append( QString("<font color=white>") +
p_msg->p_msg[i_start].psz_module +
ppsz_type[p_msg->p_msg[i_start].i_type] +
"</font>" +
ppsz_color[p_msg->p_msg[i_start].i_type] +
p_msg->p_msg[i_start].psz_msg + "</font>" );
}
vlc_mutex_lock( p_msg->p_lock );
p_msg->i_start = i_start;
vlc_mutex_unlock( p_msg->p_lock );
}
}
/*****************************************************************************
* messages.h: the KMessagesWindow class
*****************************************************************************
* Copyright (C) 2001-2003 the VideoLAN team
* $Id$
*
* Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
* 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.
*****************************************************************************/
#include <kdialogbase.h>
#include <qtextview.h>
#include "common.h"
class KMessagesWindow : public KDialogBase
{
Q_OBJECT
public:
KMessagesWindow( intf_thread_t*, msg_subscription_t * );
~KMessagesWindow();
public slots:
void update();
private:
intf_thread_t* p_intf;
QTextView* text;
msg_subscription_t *p_msg;
};
/***************************************************************************
net.cpp - description
-------------------
begin : Mon Apr 9 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#include "net.h"
#include <kdialogbase.h>
#include <klineedit.h>
#include <qhbox.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qspinbox.h>
#include <qstring.h>
#include <qvbox.h>
#include <qvbuttongroup.h>
#include <qvgroupbox.h>
#include <qwidget.h>
KNetDialog::KNetDialog( QWidget *parent, const char *name )
:KDialogBase( parent, name, true,
QString::null, Ok|Cancel, Ok, true )
{
QVBox *pageVBox = makeVBoxMainWidget();
QHBox *layout = new QHBox( pageVBox );
layout->setSpacing( 5 );
fButtonGroup = new QVButtonGroup( _("Protocol"), layout );
fTSButton = new QRadioButton( "TS", fButtonGroup);
fTSButton->setChecked( true );
fRTPButton = new QRadioButton( "RTP", fButtonGroup);
fRTPButton->setEnabled( false );
fHTTPButton = new QRadioButton( "HTTP", fButtonGroup);
fHTTPButton->setEnabled( false );
QVGroupBox *serverVBox = new QVGroupBox( _("Starting position"), layout );
QHBox *titleHBox = new QHBox( serverVBox );
new QLabel( _("Address "), titleHBox );
fAddress = new KLineEdit( "vls", titleHBox );
QHBox *portHBox = new QHBox( serverVBox );
new QLabel( _("Port "), portHBox );
fPort = new QSpinBox( 0, 65535, 1, portHBox );
}
KNetDialog::~KNetDialog()
{
}
QString KNetDialog::protocol() const
{
if ( fTSButton->isChecked() )
{
return ( QString( "ts" ) );
}
else if ( fRTPButton->isChecked() )
{
return ( QString( "rtp" ) );
}
else
{
return ( QString( "http" ) );
}
}
QString KNetDialog::server() const
{
return ( fAddress->text() );
}
int KNetDialog::port() const
{
return ( fPort->value() );
}
/***************************************************************************
net.h - description
-------------------
begin : Mon Apr 9 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
#ifndef _KDE_NET_H_
#define _KDE_NET_H_
#include "common.h"
#include <qwidget.h>
#include <kdialogbase.h>
class QVButtonGroup;
class QRadioButton;
class QSpinBox;
class KLineEdit;
/**
*@author andres
*/
class KNetDialog : public KDialogBase
{
Q_OBJECT
public:
KNetDialog(QWidget *parent=0, const char *name=0);
~KNetDialog();
QString protocol() const;
QString server() const;
int port() const;
private:
QVButtonGroup *fButtonGroup;
QRadioButton *fTSButton;
QRadioButton *fRTPButton;
QRadioButton *fHTTPButton;
KLineEdit *fAddress;
QSpinBox *fPort;
};
#endif /* _KDE_NET_H_ */
/*****************************************************************************
* pluginbox.cpp: the pluginbox class
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon Aug 12 2002
*
* 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.
*****************************************************************************/
#include "pluginsbox.h"
#include "preferences.h"
#include <qgroupbox.h>
#include <qhbox.h>
#include <qlabel.h>
#include <qvbox.h>
#include <klistview.h>
#include <kbuttonbox.h>
KPluginsBox::KPluginsBox(intf_thread_t *p_intf,
QString text, QString value, QWidget *parent,
int spacing, KPreferences *pref) :
QGroupBox( 1, Vertical, text, parent )
{
owner = pref;
this->p_intf = p_intf;
QVBox *item_vbox = new QVBox( this );
item_vbox->setSpacing(spacing);
listView = new KListView(item_vbox);
listView->setAllColumnsShowFocus(true);
listView->addColumn(_("Name"));
listView->addColumn(_("Description"));
KButtonBox *item_bbox = new KButtonBox(item_vbox);
selectButton = item_bbox->addButton( _("Select") );
QHBox *item_hbox = new QHBox(item_vbox);
item_hbox->setSpacing(spacing);
new QLabel( _("Selected:"), item_hbox );
line = new KLineEdit( value, item_hbox );
connect(selectButton, SIGNAL(clicked()), this, SLOT(selectClicked()));
connect(listView, SIGNAL(selectionChanged( QListViewItem *)),
this, SLOT( selectionChanged( QListViewItem *)));
}
KPluginsBox::~KPluginsBox()
{
;
}
QListView* KPluginsBox::getListView()
{
return listView;
}
void KPluginsBox::selectClicked()
{
if (listView->selectedItem()) {
line->setText(listView->selectedItem()->text(0));
emit selectionChanged(listView->selectedItem()->text(0));
}
}
void KPluginsBox::selectionChanged( QListViewItem *item )
{
selectButton->setEnabled(true);
}
/*****************************************************************************
* pluginbox.h: includes for the pluginbox class
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon Aug 12 2002
*
* 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.
*****************************************************************************/
#ifndef _KDE_PLUGINBOX_H_
#define _KDE_PLUGINBOX_H_
#include <qgroupbox.h>
#include <klistview.h>
#include <qpushbutton.h>
#include <klineedit.h>
#include "preferences.h"
class KPluginsBox : public QGroupBox
{
Q_OBJECT
public:
KPluginsBox(intf_thread_t *p_intf, QString title, QString value,
QWidget *parent, int spacing, KPreferences *pref);
~KPluginsBox();
QListView *getListView(void);
private slots:
void selectClicked(void);
void selectionChanged( QListViewItem * );
signals:
void selectionChanged(const QString &text);
private:
intf_thread_t *p_intf;
KListView *listView;
QPushButton *selectButton;
KLineEdit *line;
KPreferences *owner;
};
#endif
/*****************************************************************************
* preferences.cpp: preferences window for the kde gui
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon Aug 12 2002
*
* 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.
*****************************************************************************/
#include <kdialogbase.h>
#include <qmap.h>
#include <qcheckbox.h>
#include <qframe.h>
#include <qgroupbox.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qlistview.h>
#include <qnamespace.h>
#include <qobjectlist.h>
#include <qslider.h>
#include <qspinbox.h>
#include <qtooltip.h>
#include <qvbox.h>
#include <kbuttonbox.h>
#include <klineedit.h>
#include <klocale.h>
#include <knuminput.h>
#include <kurlrequester.h>
#include <kfiledialog.h>
#include <kcombobox.h>
#include "QConfigItem.h"
#include "pluginsbox.h"
#include "preferences.h"
/*
construct a new configuration window for the given module
*/
KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
QWidget *parent, const QString &caption) :
KDialogBase ( TreeList, caption, Ok| Apply|Cancel|User1, Ok, parent,
_("VLC preferences"), true, false, i18n(_("&Save")) )
{
module_t *p_parser = NULL;
vlc_list_t *p_list;
module_config_t *p_item;
int i_index;
QVBox *category_table = NULL;
QString *category_label;
this->p_intf = p_intf;
/* List all modules */
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
p_item = p_parser->p_config;
while( p_item && p_item->i_type != CONFIG_HINT_END )
{
switch( p_item->i_type )
{
case CONFIG_HINT_CATEGORY:
/* force the content to the top of the page */
if ( category_table )
{
QWidget *space = new QWidget( category_table );
category_table->setStretchFactor( space, 10 );
category_table = NULL;
}
/*
* Now we can start taking care of the new category
*/
if( p_item->i_type == CONFIG_HINT_CATEGORY )
{
category_label = new QString( p_item->psz_text );
QStringList path;
if ( strcmp( p_parser->psz_object_name, "main" ) )
{
path += _( "Plugins" );
path += p_parser->psz_capability;
path += p_parser->psz_object_name;
}
path += *category_label;
QFrame *page = addPage( path );
QVBoxLayout *toplayout = new QVBoxLayout( page);
QScrollView *sv = new QScrollView(page);
sv->setResizePolicy(QScrollView::AutoOneFit);
sv->setFrameStyle(QScrollView::NoFrame);
toplayout->addWidget(sv);
category_table = new QVBox(sv->viewport());
sv->addChild(category_table);
category_table->setSpacing(spacingHint());
}
break;
case CONFIG_ITEM_MODULE:
{
vlc_mutex_lock( p_item->p_lock );
KPluginsBox *item_frame =
new KPluginsBox( p_intf, p_item->psz_text,
p_item->psz_value ? p_item->psz_value :"",
category_table,
spacingHint(),
this );
QConfigItem *ci = new QConfigItem(this,
p_item->psz_name,
p_item->i_type,
p_item->psz_value);
connect(item_frame, SIGNAL(selectionChanged(const QString &)),
ci, SLOT(setValue(const QString &)));
/* build a list of available plugins */
for( int i_index = 0; i_index < p_list->i_count; i_index++ )
{
module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !strcmp( p_parser->psz_capability,
p_item->psz_type ) )
{
new QListViewItem(item_frame->getListView(),
p_parser->psz_object_name,
p_parser->psz_longname);
}
}
vlc_mutex_unlock( p_item->p_lock );
}
break;
case CONFIG_ITEM_STRING:
{
QHBox *hb = new QHBox(category_table);
hb->setSpacing(spacingHint());
new QLabel(p_item->psz_text, hb);
/* add input box with default value */
vlc_mutex_lock( p_item->p_lock );
QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
p_item->i_type,
p_item->psz_value ?
p_item->psz_value : "");
if ( p_item->ppsz_list )
{
char **ppsz_list = p_item->ppsz_list;
KComboBox *p_combobox = new KComboBox( true, hb );
QToolTip::add(p_combobox, p_item->psz_longtext);
connect(p_combobox, SIGNAL(activated ( const QString & )),
ci, SLOT(setValue( const QString &)));
while ( *ppsz_list )
{
p_combobox->insertItem( *ppsz_list );
if ( !strcmp( *ppsz_list, p_item->psz_value ?
p_item->psz_value : "" ) )
{
#if KDE_VERSION_MAJOR >= 3
p_combobox->setCurrentText( *ppsz_list );
#else
p_combobox->setCurrentItem( p_combobox->count() );
#endif
}
ppsz_list++;
}
}
else
{
KLineEdit *kl = new KLineEdit( p_item->psz_value ?
p_item->psz_value : "", hb);
connect(kl, SIGNAL(textChanged ( const QString & )),
ci, SLOT(setValue( const QString &)));
QToolTip::add(kl, p_item->psz_longtext);
kl->setMaxLength(40);
}
vlc_mutex_unlock( p_item->p_lock );
}
break;
case CONFIG_ITEM_FILE:
case CONFIG_ITEM_DIRECTORY:
{
QHBox *hb = new QHBox(category_table);
hb->setSpacing(spacingHint());
new QLabel(p_item->psz_text, hb);
/* add input box with default value */
vlc_mutex_lock( p_item->p_lock );
// KLineEdit *kl = new KLineEdit( p_item->psz_value ?
// p_item->psz_value : "", hb);
QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
p_item->i_type,
p_item->psz_value ?
p_item->psz_value : "");
// QPushButton *bbrowse = new QPushButton( _("Browse"), hb );
KURLRequester *kfile = new KURLRequester( p_item->psz_value ?
p_item->psz_value : "",
hb );
if ( p_item->i_type == CONFIG_ITEM_DIRECTORY )
{
kfile->fileDialog()->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
}
connect(kfile, SIGNAL(textChanged ( const QString & )),
ci, SLOT(setValue( const QString &)));
QToolTip::add(kfile, p_item->psz_longtext);
vlc_mutex_unlock( p_item->p_lock );
}
break;
case CONFIG_ITEM_INTEGER:
/* add input box with default value */
{
QHBox *hb = new QHBox(category_table);
hb->setSpacing(spacingHint());
new QLabel(p_item->psz_text, hb);
QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
p_item->i_type,
p_item->i_value);
if ( p_item->i_min == 0 && p_item->i_max == 0 )
{
QSpinBox *item_adj = new QSpinBox(-1, 99999, 1, hb);
item_adj->setValue( p_item->i_value );
connect(item_adj, SIGNAL(valueChanged( int)),
ci, SLOT(setValue(int)));
QToolTip::add(item_adj, p_item->psz_longtext);
}
else
{
KIntNumInput *p_ii = new KIntNumInput( p_item->i_value, hb );
p_ii->setRange( p_item->i_min, p_item->i_max, 1, true );
connect( p_ii, SIGNAL( valueChanged( int ) ),
ci, SLOT( setValue( int ) ) );
QToolTip::add( p_ii, p_item->psz_longtext );
}
}
break;
case CONFIG_ITEM_FLOAT:
{
QHBox *hb = new QHBox(category_table);
hb->setSpacing(spacingHint());
new QLabel(p_item->psz_text, hb);
KDoubleNumInput *kdi= new KDoubleNumInput(p_item->f_value, hb);
if ( p_item->f_min == 0 && p_item->f_max == 0 )
{
kdi->setRange(-1, 99999, 0.01, false);
}
else
{
kdi->setRange( p_item->f_min, p_item->f_max, 0.01, true );
}
QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
p_item->i_type,
p_item->f_value);
connect(kdi, SIGNAL(valueChanged(double)),
ci, SLOT(setValue(double)));
QToolTip::add(kdi, p_item->psz_longtext);
}
break;
case CONFIG_ITEM_BOOL:
/* add check button */
{
QCheckBox *bool_checkbutton =
new QCheckBox(QString(p_item->psz_text), category_table);
QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
p_item->i_type,
p_item->i_value);
bool_checkbutton->setChecked(p_item->i_value);
connect(bool_checkbutton, SIGNAL(stateChanged( int)),
ci, SLOT(setValue(int)));
QToolTip::add(bool_checkbutton, p_item->psz_longtext);
}
break;
}
p_item++;
}
}
/* force the content to the top of the page, even on the last page */
if ( category_table )
{
QWidget *space = new QWidget( category_table );
category_table->setStretchFactor( space, 10 );
category_table = NULL;
}
vlc_list_release( p_list );
exec();
}
/*
empty destructor, qt takes care of this (I think)
*/
KPreferences::~KPreferences()
{
}
/*
return true if the give module is configureable
*/
bool KPreferences::isConfigureable(QString module)
{
module_t *p_parser;
vlc_list_t *p_list;
int i_index;
p_list = vlc_list_find( this->p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !module.compare( p_parser->psz_object_name ) )
{
bool ret = p_parser->i_config_items != 0;
vlc_list_release( p_list );
return ret;
}
}
vlc_list_release( p_list );
return false;
}
/*
run when the Apply button is pressed, and by the methods for the ok
and save buttons
*/
void KPreferences::slotApply()
{
QObjectList * l = queryList( "QConfigItem" );
QObjectListIt it( *l ); // iterate over the config items
QObject * obj;
while ( (obj=it.current()) != 0 ) {
++it;
QConfigItem *p_config = (QConfigItem *)obj;
if ( p_config->changed() )
{
msg_Dbg( p_intf, const_cast<char *>(p_config->name()));
msg_Dbg( p_intf, "%d", p_config->getType());
switch( p_config->getType() ) {
case CONFIG_ITEM_DIRECTORY:
case CONFIG_ITEM_STRING:
case CONFIG_ITEM_FILE:
case CONFIG_ITEM_MODULE:
if (p_config->sValue()) {
config_PutPsz( p_intf, p_config->name(),
strdup(p_config->sValue().latin1()));
}
else {
config_PutPsz( p_intf, p_config->name(), NULL );
}
break;
case CONFIG_ITEM_INTEGER:
case CONFIG_ITEM_BOOL:
config_PutInt( p_intf, p_config->name(), p_config->iValue() );
break;
case CONFIG_ITEM_FLOAT:
config_PutFloat( p_intf, p_config->name(), p_config->fValue() );
break;
}
p_config->resetChanged();
}
}
delete l;
}
/*
run when the Ok button is pressed
*/
void KPreferences::slotOk()
{
slotApply();
accept();
}
/*
run when the save button is pressed
*/
void KPreferences::slotUser1()
{
slotApply();
config_SaveConfigFile( p_intf, NULL );
}
/*****************************************************************************
* preferences.h: includes for the preferences window
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon Aug 12 2002
*
* 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.
*****************************************************************************/
#ifndef _KDE_PREFERENCES_H_
#define _KDE_PREFERENCES_H_
#include "common.h"
#include <kdialogbase.h>
#include "QConfigItem.h"
class KPreferences : KDialogBase
{
Q_OBJECT
public:
KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
QWidget *parent, const QString &caption=QString::null);
~KPreferences();
bool isConfigureable(QString module);
public slots:
void slotApply();
void slotOk();
void slotUser1();
private:
intf_thread_t *p_intf;
};
#endif
/***************************************************************************
slider.cpp - description
-------------------
begin : Sun Mar 25 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
/***************************************************************************
shamelessly copied from noatun's excellent interface
****************************************************************************/
#include "slider.h"
KVLCSlider::KVLCSlider(QWidget * parent, const char * name) :
QSlider(parent,name), pressed(false)
{
}
KVLCSlider::KVLCSlider(Orientation o, QWidget * parent, const char * name) :
QSlider(o,parent,name), pressed(false)
{
}
KVLCSlider::KVLCSlider(int minValue, int maxValue, int pageStep, int value,
Orientation o, QWidget * parent, const char * name) :
QSlider(minValue, maxValue, pageStep, value, o, parent,name), pressed(false)
{
}
void KVLCSlider::setValue(int i)
{
if ( !pressed )
{
QSlider::setValue( i );
}
}
void KVLCSlider::mousePressEvent( QMouseEvent *e )
{
if ( e->button() != RightButton )
{
pressed=true;
QSlider::mousePressEvent( e );
}
}
void KVLCSlider::mouseReleaseEvent( QMouseEvent *e )
{
pressed=false;
QSlider::mouseReleaseEvent( e );
emit userChanged( value() );
}
/***************************************************************************
slider.h - description
-------------------
begin : Sun Apr 03 2001
copyright : (C) 2001 by andres
email : dae@chez.com
***************************************************************************/
/***************************************************************************
shamelessly copied from noatun's excellent interface
****************************************************************************/
#ifndef _KDE_SLIDER_H_
#define _KDE_SLIDER_H_
#include <qslider.h>
/**
* This slider can be changed by the vlc while not dragged by the user
*/
class KVLCSlider : public QSlider
{
Q_OBJECT
public:
KVLCSlider(QWidget * parent, const char * name=0);
KVLCSlider(Orientation, QWidget * parent, const char * name=0);
KVLCSlider(int minValue, int maxValue, int pageStep, int value,
Orientation, QWidget * parent, const char * name=0);
signals:
/**
* emmited only when the user changes the value by hand
*/
void userChanged( int value );
public slots:
virtual void setValue( int );
protected:
virtual void mousePressEvent( QMouseEvent * e );
virtual void mouseReleaseEvent( QMouseEvent * e );
private:
bool pressed; // set this to true when the user drags the slider
};
#endif /* _KDE_SLIDER_H_ */
<!DOCTYPE kpartgui>
<kpartgui name="kvlc" version="0.1">
<ActionProperties>
<Action name="open_disk" icon="cdrom_unmount"/>
<Action name="open_stream" icon="network"/>
<Action name="backward" icon="back"/>
<Action name="stop" icon="stop"/>
<Action name="play" icon="forward"/>
<Action name="pause" icon = "bottom"/>
<Action name="slow" icon="undo"/>
<Action name="fast" icon="redo"/>
<Action name="prev" icon="start"/>
<Action name="next" icon="finish"/>
</ActionProperties>
<MenuBar>
<Menu name="file">
<text>&amp;File</text>
<Action name="open_disk"/>
<Action name="open_stream"/>
</Menu>
<Menu name="view">
<text>&amp;View</text>
<Action name="program"/>
<Action name="title"/>
<Action name="chapter"/>
<Separator lineSeparator="true"/>
<Action name="view_messages"/>
<Action name="view_stream_info"/>
</Menu>
<Menu name="settings">
<text>&amp;Settings</text>
<Action name="language"/>
<Action name="subtitles"/>
</Menu>
</MenuBar>
<ToolBar name="mainToolBar" iconText="icononly" iconSize="16" noMerge="1">
<Action name="file_open"/>
<Action name="open_disk"/>
<Action name="open_stream"/>
<Separator lineSeparator="true"/>
<Action name="backward"/>
<Action name="stop"/>
<Action name="play"/>
<Action name="pause"/>
<Action name="slow"/>
<Action name="fast"/>
<Separator lineSeparator="true"/>
<Action name="prev"/>
<Action name="next"/>
</ToolBar>
</kpartgui>
SOURCES_qt = \
qt.cpp \
intf.cpp
nodist_SOURCES_qt = \
intf.moc.cpp
noinst_HEADERS += \
intf.h
intf.moc.cpp: intf.h
$(MOC) $< -o $@
/*****************************************************************************
* intf.cpp: Qt interface
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <stdio.h>
#include "intf.h"
#define SLIDER_MIN 0x00000
#define SLIDER_MAX 0x10000
#define SLIDER_STEP (SLIDER_MAX >> 4)
/*****************************************************************************
* intf_sys_t: description and status of Qt interface
*****************************************************************************/
struct intf_sys_t
{
QApplication *p_app;
IntfWindow *p_window;
input_thread_t *p_input;
};
/*****************************************************************************
* Local prototype
*****************************************************************************/
static void Run ( intf_thread_t *p_intf );
/*****************************************************************************
* Open: initialize and create window
*****************************************************************************/
int E_(Open) ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*) p_this;
char *pp_argv[] = { "" };
int i_argc = 1;
/* Allocate instance and initialize some members */
p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return 1;
}
p_intf->pf_run = Run;
/* Create the C++ objects */
p_intf->p_sys->p_app = new QApplication( i_argc, pp_argv );
p_intf->p_sys->p_window = new IntfWindow( p_intf );
/* Tell the world we are here */
p_intf->p_sys->p_window->setCaption( VOUT_TITLE " (Qt interface)" );
p_intf->p_sys->p_input = NULL;
return 0;
}
/*****************************************************************************
* Close: destroy interface window
*****************************************************************************/
void E_(Close) ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*) p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
/* Get rid of the C++ objects */
delete p_intf->p_sys->p_window;
delete p_intf->p_sys->p_app;
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: Qt thread
*****************************************************************************
* This part of the interface is in a separate thread so that we can call
* exec() from within it without annoying the rest of the program.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
p_intf->p_sys->p_window->show();
p_intf->p_sys->p_app->exec();
}
/* following functions are local */
/*****************************************************************************
* IntfWindow: interface window creator
*****************************************************************************
* This function creates the interface window, and populates it with a
* menu bar, a toolbar and a slider.
*****************************************************************************/
IntfWindow::IntfWindow( intf_thread_t *p_intf )
:QMainWindow( 0 )
{
setUsesTextLabel( TRUE );
this->p_intf = p_intf;
/*
* Create the toolbar
*/
p_toolbar = new QToolBar( this, "toolbar" );
p_toolbar->setHorizontalStretchable( TRUE );
QIconSet * set = new QIconSet();
QPixmap pixmap = set->pixmap( QIconSet::Automatic, QIconSet::Normal );
#define addbut( l, t, s ) new QToolButton( pixmap, l, t, this, s, p_toolbar );
addbut( "Open", "Open a File", SLOT(FileOpen()) );
addbut( "Disc", "Open a DVD or VCD", SLOT(Unimplemented()) );
addbut( "Net", "Select a Network Stream", SLOT(Unimplemented()) );
p_toolbar->addSeparator();
addbut( "Back", "Rewind Stream", SLOT(Unimplemented()) );
addbut( "Stop", "Stop Stream", SLOT(Unimplemented()) );
addbut( "Play", "Play Stream", SLOT(PlaybackPlay()) );
addbut( "Pause", "Pause Stream", SLOT(PlaybackPause()) );
addbut( "Slow", "Play Slower", SLOT(PlaybackSlow()) );
addbut( "Fast", "Play Faster", SLOT(PlaybackFast()) );
p_toolbar->addSeparator();
addbut( "Playlist", "Open Playlist", SLOT(Unimplemented()) );
addbut( "Prev", "Previous File", SLOT(PlaylistPrev()) );
addbut( "Next", "Next File", SLOT(PlaylistNext()) );
#undef addbut
/*
* Create the menubar
*/
QPopupMenu * p_tmpmenu = new QPopupMenu( this );
#define instmp0( x, y ) p_tmpmenu->insertItem( x, this, y )
#define instmp1( x, y, a ) p_tmpmenu->insertItem( x, this, y, a )
menuBar()->insertItem( "&File", p_tmpmenu );
instmp1( "&Open File...", SLOT(FileOpen()), Key_F3 );
instmp1( "Open &Disc...", SLOT(Unimplemented()), Key_F4 );
instmp1( "&Network Stream...", SLOT(Unimplemented()), Key_F5 );
p_tmpmenu->insertSeparator();
instmp1( "&Exit", SLOT(FileQuit()), CTRL+Key_Q );
p_tmpmenu = new QPopupMenu( this );
menuBar()->insertItem( "&View", p_tmpmenu );
instmp0( "&Playlist...", SLOT(Unimplemented()) );
instmp0( "&Modules...", SLOT(Unimplemented()) );
p_tmpmenu = new QPopupMenu( this );
menuBar()->insertItem( "&Settings", p_tmpmenu );
instmp0( "&Preferences...", SLOT(Unimplemented()) );
p_tmpmenu = new QPopupMenu( this );
menuBar()->insertItem( "&Help", p_tmpmenu );
instmp0( "&About...", SLOT(About()) );
/*
* Create the popup menu
*/
p_popup = new QPopupMenu( /* floating menu */ );
#define inspop0( x, y ) p_popup->insertItem( x, this, y )
#define inspop1( x, y, a ) p_popup->insertItem( x, this, y, a )
inspop0( "&Play", SLOT(PlaybackPlay()) );
inspop0( "Pause", SLOT(PlaybackPause()) );
inspop0( "&Slow", SLOT(PlaybackSlow()) );
inspop0( "&Fast", SLOT(PlaybackFast()) );
p_popup->insertSeparator();
inspop1( "&Open File...", SLOT(FileOpen()), Key_F3 );
inspop1( "Open &Disc...", SLOT(Unimplemented()), Key_F4 );
inspop1( "&Network Stream...", SLOT(Unimplemented()), Key_F5 );
p_popup->insertSeparator();
inspop0( "&About...", SLOT(About()) );
inspop0( "&Exit", SLOT(FileQuit()) );
/* Activate the statusbar */
statusBar();
/* Add the vertical box */
QVBox * p_vbox = new QVBox( this );
setCentralWidget( p_vbox );
/* The horizontal box */
QHBox * p_hbox = new QHBox( p_vbox );
/* The date label */
p_date = new QLabel( p_hbox );
p_date->setAlignment( AlignHCenter | AlignVCenter );
p_date->setText( "-:--:--" );
/* The status label */
QLabel *p_label = new QLabel( p_hbox );
p_label->setAlignment( AlignHCenter | AlignVCenter );
p_label->setText( "Status: foo" );
/* The bar label */
p_label = new QLabel( p_hbox );
p_label->setAlignment( AlignHCenter | AlignVCenter );
p_label->setText( "Bar: baz quux" );
/* Create the slider and connect it to the date label */
p_slider = new IntfSlider( p_intf, p_vbox );
connect( p_slider, SIGNAL(valueChanged(int)),
this, SLOT(DateDisplay(int)) );
/* The timer */
QTimer *p_timer = new QTimer( this );
connect( p_timer, SIGNAL(timeout()), this, SLOT(Manage()) );
p_timer->start( INTF_IDLE_SLEEP / 1000 );
/* Everything worked fine */
resize( 620, 30 );
}
/*****************************************************************************
* ~IntfWindow: interface window destructor
*****************************************************************************
* This function is called when the interface window is destroyed.
*****************************************************************************/
IntfWindow::~IntfWindow( void )
{
/* FIXME: remove everything cleanly */
}
/*****************************************************************************
* DateDisplay: display date
*****************************************************************************
* This function displays the current date in the date label.
*****************************************************************************/
void IntfWindow::DateDisplay( int i_range )
{
if( p_intf->p_sys->p_input )
{
char psz_time[ MSTRTIME_MAX_SIZE ];
int64_t i_seconds;
i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
secstotimestr( psz_time, i_seconds );
p_date->setText( psz_time );
}
}
/*****************************************************************************
* FileOpen: open a file
*****************************************************************************
* This function opens a file requester and adds the selected file to
* the playlist.
*****************************************************************************/
void IntfWindow::FileOpen( void )
{
playlist_t *p_playlist;
QString file = QFileDialog::getOpenFileName( QString::null,
QString::null, this );
if( file.isEmpty() )
{
statusBar()->message( "No file loaded", 2000 );
}
else
{
p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
playlist_Add( p_playlist, file.latin1(), file.latin1(),
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
vlc_object_release( p_playlist );
}
}
/*****************************************************************************
* FileQuit: terminate vlc
*****************************************************************************/
void IntfWindow::FileQuit( void )
{
p_intf->p_vlc->b_die = VLC_TRUE;
}
/*****************************************************************************
* About: display the "about" box
*****************************************************************************
* This function displays a simple "about" box with copyright information.
*****************************************************************************/
void IntfWindow::About( void )
{
QMessageBox::about( this, "About",
"VLC media player\n"
"(C) 1996 - 2004 - the VideoLAN Team\n"
"\n"
"This is the VLC media player, a DVD and MPEG player.\n"
"It can play MPEG and MPEG 2 files from a file "
"or from a network source.\n"
"\n"
"More information: http://www.videolan.org/" );
}
/*****************************************************************************
* Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
void IntfWindow::Manage( void )
{
/* Update the input */
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input = (input_thread_t *)
vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
}
else if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
/* Manage the slider */
if( p_intf->p_sys->p_input && p_intf->p_sys->p_input->stream.b_seekable )
{
int i_value = p_slider->value();
#define p_area p_intf->p_sys->p_input->stream.p_selected_area
/* If the user hasn't touched the slider since the last time,
* then the input can safely change it */
if( i_value == p_slider->oldvalue() )
{
i_value = ( SLIDER_MAX * p_area->i_tell ) / p_area->i_size;
p_slider->setValue( i_value );
p_slider->setOldValue( i_value );
}
/* Otherwise, send message to the input if the user has
* finished dragging the slider */
else if( p_slider->b_free )
{
double f_pos = (double)i_value / (double)SLIDER_MAX;
var_SetFloat( p_intf->p_sys->p_input, "position", f_pos );
/* Update the old value */
p_slider->setOldValue( i_value );
}
#undef p_area
}
/* If the "display popup" flag has changed, popup the context menu */
if( p_intf->b_menu_change )
{
p_popup->popup( QCursor::pos() );
p_intf->b_menu_change = 0;
}
if( p_intf->b_die )
{
qApp->quit();
}
}
/*****************************************************************************
* PlaybackPlay: play
*****************************************************************************/
void IntfWindow::PlaybackPlay( void )
{
if( p_intf->p_sys->p_input != NULL )
{
var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
}
}
/*****************************************************************************
* PlaybackPause: pause
*****************************************************************************/
void IntfWindow::PlaybackPause( void )
{
if( p_intf->p_sys->p_input != NULL )
{
var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
}
}
/*****************************************************************************
* PlaybackSlow: slow
*****************************************************************************/
void IntfWindow::PlaybackSlow( void )
{
if( p_intf->p_sys->p_input != NULL )
{
var_SetVoid( p_intf->p_sys->p_input, "rate-slower" );
}
}
/*****************************************************************************
* PlaybackFast: fast
*****************************************************************************/
void IntfWindow::PlaybackFast( void )
{
if( p_intf->p_sys->p_input != NULL )
{
var_SetVoid( p_intf->p_sys->p_input, "rate-faster" );
}
}
/*****************************************************************************
* PlaylistPrev: previous playlist entry
*****************************************************************************/
void IntfWindow::PlaylistPrev( void )
{
playlist_t *p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
playlist_Prev( p_playlist );
vlc_object_release( p_playlist );
}
/*****************************************************************************
* PlaylistNext: next playlist entry
*****************************************************************************/
void IntfWindow::PlaylistNext( void )
{
playlist_t *p_playlist = (playlist_t *)
vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
playlist_Next( p_playlist );
vlc_object_release( p_playlist );
}
/*****************************************************************************
* IntfSlider: slider creator
*****************************************************************************
* This function creates the slider, sets its default values, and connects
* the interesting signals.
*****************************************************************************/
IntfSlider::IntfSlider( intf_thread_t *p_intf, QWidget *p_parent )
:QSlider( Horizontal, p_parent )
{
this->p_intf = p_intf;
setRange( SLIDER_MIN, SLIDER_MAX );
setPageStep( SLIDER_STEP );
setValue( SLIDER_MIN );
setOldValue( SLIDER_MIN );
setTracking( TRUE );
b_free = TRUE;
connect( this, SIGNAL(sliderMoved(int)), this, SLOT(SlideStart()) );
connect( this, SIGNAL(sliderPressed()), this, SLOT(SlideStart()) );
connect( this, SIGNAL(sliderReleased()), this, SLOT(SlideStop()) );
}
/*****************************************************************************
* ~IntfSlider: slider destructor
*****************************************************************************
* This function is called when the interface slider is destroyed.
*****************************************************************************/
IntfSlider::~IntfSlider( void )
{
/* We don't need to remove anything */
}
/*****************************************************************************
* intf.h: Qt interface
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <vlc/vlc.h>
#include <vlc/intf.h>
#include <qapplication.h>
#include <qmainwindow.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qwhatsthis.h>
#include <qpushbutton.h>
#include <qfiledialog.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qmenubar.h>
#include <qstatusbar.h>
#include <qmessagebox.h>
#include <qlabel.h>
#include <qtimer.h>
#include <qiconset.h>
#include <qvbox.h>
#include <qhbox.h>
/*****************************************************************************
* Local Qt slider class
*****************************************************************************/
class IntfSlider : public QSlider
{
Q_OBJECT
public:
IntfSlider( intf_thread_t *, QWidget * ); /* Constructor and destructor */
~IntfSlider();
bool b_free; /* Is the slider free ? */
int oldvalue ( void ) { return i_oldvalue; };
void setOldValue( int i_value ) { i_oldvalue = i_value; };
private slots:
void SlideStart ( void ) { b_free = FALSE; };
void SlideStop ( void ) { b_free = TRUE; };
private:
intf_thread_t *p_intf;
int i_oldvalue;
};
/*****************************************************************************
* Local Qt interface window class
*****************************************************************************/
class IntfWindow : public QMainWindow
{
Q_OBJECT
public:
IntfWindow( intf_thread_t * );
~IntfWindow();
private slots:
void Manage ( void );
void FileOpen ( void );
void FileQuit ( void );
void PlaybackPlay ( void );
void PlaybackPause ( void );
void PlaybackSlow ( void );
void PlaybackFast ( void );
void PlaylistPrev ( void );
void PlaylistNext ( void );
void DateDisplay ( int );
void About ( void );
void Unimplemented( void ) { msg_Warn( p_intf, "unimplemented" ); };
private:
intf_thread_t *p_intf;
IntfSlider *p_slider;
QToolBar *p_toolbar;
QPopupMenu *p_popup;
QLabel *p_date;
};
/*****************************************************************************
* qt.cpp : Qt plugin for vlc
*****************************************************************************
* Copyright (C) 2001 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <vlc/vlc.h>
/*****************************************************************************
* External prototypes
*****************************************************************************/
int E_(Open) ( vlc_object_t * );
void E_(Close) ( vlc_object_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
#ifdef WIN32
int i = 80;
#else
int i = getenv( "DISPLAY" ) == NULL ? 7 : 80;
#endif
set_description( _("Qt interface") );
set_capability( "interface", i );
set_program( "qvlc" );
set_category( CAT_INTERFACE );
set_subcategory( SUBCAT_INTERFACE_GENERAL );
set_callbacks( E_(Open), E_(Close) );
vlc_module_end();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment