Commit 10f8855d authored by Jean-Paul Saman's avatar Jean-Paul Saman

Now "vlc --intf familiar" spawns interface.

parent fc39d649
......@@ -2,7 +2,7 @@
* familiar.c : familiar plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: familiar.c,v 1.1 2002/07/22 13:49:42 jpsaman Exp $
* $Id: familiar.c,v 1.2 2002/07/22 19:49:40 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -47,85 +47,30 @@ static int intf_Open ( intf_thread_t *p_intf );
static void intf_Close ( intf_thread_t *p_intf );
static void intf_Run ( intf_thread_t *p_intf );
static gint GtkManage ( gpointer p_data );
/*****************************************************************************
* Local variables (mutex-protected).
*****************************************************************************/
static void ** pp_global_data = NULL;
//static void ** pp_global_data = NULL;
/*****************************************************************************
* Building configuration tree
*****************************************************************************/
#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.")
MODULE_CONFIG_START
ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL )
ADD_BOOL ( "familiar-tooltips", 1, NULL /*GtkHideTooltips*/, TOOLTIPS_TEXT,
TOOLTIPS_LONGTEXT )
ADD_BOOL ( "familiar-toolbartext", 1, NULL /*GtkHideToolbarText*/, TOOLBAR_TEXT,
TOOLBAR_LONGTEXT )
ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL )
MODULE_CONFIG_STOP
MODULE_INIT_START
pp_global_data = p_module->p_vlc->pp_global_data;
SET_DESCRIPTION( _("Familiar Linux Gtk+ interface module") )
ADD_CAPABILITY( INTF, 90 )
ADD_CAPABILITY( INTF, 590 )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
intf_getfunctions( &p_module->p_functions->intf );
_M( intf_getfunctions )( &p_module->p_functions->intf );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
/*****************************************************************************
* g_atexit: kludge to avoid the Gtk+ thread to segfault at exit
*****************************************************************************
* gtk_init() makes several calls to g_atexit() which calls atexit() to
* register tidying callbacks to be called at program exit. Since the Gtk+
* plugin is likely to be unloaded at program exit, we have to export this
* symbol to intercept the g_atexit() calls. Talk about crude hack.
*****************************************************************************/
void g_atexit( GVoidFunc func )
{
intf_thread_t *p_intf;
int i_dummy;
if( pp_global_data == NULL )
{
atexit( func );
return;
}
p_intf = (intf_thread_t *)*pp_global_data;
if( p_intf == NULL )
{
return;
}
for( i_dummy = 0;
i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL;
i_dummy++ )
{
;
}
if( i_dummy >= MAX_ATEXIT - 1 )
{
msg_Err( p_intf, "too many atexit() callbacks to register" );
return;
}
p_intf->p_sys->pf_callback[i_dummy] = func;
p_intf->p_sys->pf_callback[i_dummy + 1] = NULL;
}
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
......@@ -151,21 +96,8 @@ static int intf_Open( intf_thread_t *p_intf )
return( 1 );
}
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
/* Initialize Gtk+ thread */
p_intf->p_sys->b_playing = 0;
p_intf->p_sys->b_popup_changed = 0;
p_intf->p_sys->b_window_changed = 0;
p_intf->p_sys->b_playlist_changed = 0;
p_intf->p_sys->p_input = NULL;
p_intf->p_sys->i_playing = -1;
p_intf->p_sys->b_slider_free = 1;
p_intf->p_sys->pf_callback[0] = NULL;
p_intf->p_sys->i_part = 0;
return( 0 );
}
......@@ -180,8 +112,6 @@ static void intf_Close( intf_thread_t *p_intf )
vlc_object_release( p_intf->p_sys->p_input );
}
msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
/* Destroy structure */
if (p_intf->p_sys) free( p_intf->p_sys );
}
......@@ -203,15 +133,8 @@ static void intf_Run( intf_thread_t *p_intf )
int i_args = 1;
int i_dummy;
/* 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 }
};
/* Initialize Gtk+ */
gtk_set_locale ();
/* gtk_init will register stuff with g_atexit, so we need to take
* the global lock if we want to be able to intercept the calls */
......@@ -221,276 +144,28 @@ static void intf_Run( intf_thread_t *p_intf )
vlc_mutex_unlock( p_intf->p_vlc->p_global_lock );
/* Create some useful widgets that will certainly be used */
// FIXME: magic path
add_pixmap_directory("/home/jpsaman/vlc/share");
p_intf->p_sys->p_window = create_familiar();
// 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();
if (p_intf->p_sys->p_window == NULL)
{
msg_Err( p_intf, "unable to create familiar interface" );
}
/* Set the title of the main window */
gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
VOUT_TITLE " (Familiar 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,
1, 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,
1, 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 ), "progress" ) );
/* 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( 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 );
}
VOUT_TITLE " (Familiar Linux interface)");
/* 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( 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 );
/* Show the control window */
gtk_widget_show( p_intf->p_sys->p_window );
/* 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, GtkManage, p_intf );
/* Enter Gtk mode */
gtk_main();
/* Remove the timeout */
gtk_timeout_remove( i_dummy );
/* Destroy the Tooltips structure */
gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_tooltips) );
/* Launch stored callbacks */
for( i_dummy = 0;
i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL;
i_dummy++ )
{
p_intf->p_sys->pf_callback[i_dummy]();
}
}
/* following functions are local */
/*****************************************************************************
* GtkManage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
static gint GtkManage( gpointer p_data )
{
#define p_intf ((intf_thread_t *)p_data)
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 );
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_data );
/* 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;
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 )
{
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 */
else if( p_intf->p_sys->b_slider_free )
{
off_t i_seek = ( newvalue * p_area->i_size ) / 100;
/* release the lock to be able to seek */
vlc_mutex_unlock( &p_input->stream.stream_lock );
input_Seek( p_input, i_seek, INPUT_SEEK_SET );
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;
GtkSetupMenus( p_intf );
}
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
GtkModeManage( p_intf );
p_intf->p_sys->b_playing = 0;
}
if( p_intf->b_die )
{
vlc_mutex_unlock( &p_intf->change_lock );
/* Prepare to die, young Skywalker */
gtk_main_quit();
/* Just in case */
return( FALSE );
}
vlc_mutex_unlock( &p_intf->change_lock );
return( TRUE );
#undef p_intf
}
......@@ -2,7 +2,7 @@
* familiar.h: private Gtk+ interface description
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: familiar.h,v 1.1 2002/07/22 13:49:42 jpsaman Exp $
* $Id: familiar.h,v 1.2 2002/07/22 19:49:40 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -21,81 +21,15 @@
* 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 MAX_ATEXIT 10
/*****************************************************************************
* intf_sys_t: description and status of Gtk+ interface
*****************************************************************************/
struct intf_sys_t
{
/* 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 */
/* menus handlers */
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 */
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;
gint i_part; /* current chapter */
/* XXX: Ugly kludge, see gtk.c */
void ( *pf_callback[MAX_ATEXIT] ) ( void );
};
/*****************************************************************************
* Prototypes
*****************************************************************************/
gint GtkModeManage ( intf_thread_t * p_intf );
void GtkDisplayDate ( GtkAdjustment *p_adj );
/*****************************************************************************
* Useful macro
****************************************************************************/
#define GtkGetIntf( widget ) __GtkGetIntf( GTK_WIDGET( widget ) )
void * __GtkGetIntf( GtkWidget * );
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