Commit fc39d649 authored by Jean-Paul Saman's avatar Jean-Paul Saman

Familiar Linux interface (non functional yet).

parent 91cf1f1b
familiar_SOURCES = familiar.c familiar_interface.c familiar_support.c familiar_callbacks.c
\ No newline at end of file
/*****************************************************************************
* familiar.c : familiar plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: familiar.c,v 1.1 2002/07/22 13:49:42 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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 "familiar_callbacks.h"
#include "familiar_interface.h"
#include "familiar_support.h"
#include "familiar.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static void intf_getfunctions ( function_list_t * p_function_list );
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;
/*****************************************************************************
* 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 )
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 )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
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
* we don't pollute the namespace too much.
*****************************************************************************/
static void intf_getfunctions( function_list_t * p_function_list )
{
p_function_list->functions.intf.pf_open = intf_Open;
p_function_list->functions.intf.pf_close = intf_Close;
p_function_list->functions.intf.pf_run = intf_Run;
}
/*****************************************************************************
* intf_Open: initialize and create window
*****************************************************************************/
static int intf_Open( intf_thread_t *p_intf )
{
/* 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( 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 );
}
/*****************************************************************************
* intf_Close: destroy interface window
*****************************************************************************/
static void intf_Close( intf_thread_t *p_intf )
{
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 );
/* Destroy structure */
if (p_intf->p_sys) free( p_intf->p_sys );
}
/*****************************************************************************
* intf_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.
* XXX: the approach may look kludgy, and probably is, but I could not find
* a better way to dynamically load a Gtk+ interface at runtime.
*****************************************************************************/
static void intf_Run( intf_thread_t *p_intf )
{
/* gtk_init needs to know the command line. We don't care, so we
* give it an empty one */
char *p_args[] = { "" };
char **pp_args = p_args;
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_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 */
vlc_mutex_lock( p_intf->p_vlc->p_global_lock );
*p_intf->p_vlc->pp_global_data = p_intf;
gtk_init( &i_args, &pp_args );
vlc_mutex_unlock( p_intf->p_vlc->p_global_lock );
/* Create some useful widgets that will certainly be used */
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();
/* 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 );
}
/* 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
}
<?xml version="1.0"?>
<GTK-Interface>
<project>
<name>Familiar</name>
<program_name>familiar</program_name>
<directory></directory>
<source_directory>src</source_directory>
<pixmaps_directory>share</pixmaps_directory>
<language>C</language>
<gnome_support>False</gnome_support>
<gettext_support>True</gettext_support>
<main_source_file>familiar_interface.c</main_source_file>
<main_header_file>familiar_interface.h</main_header_file>
<handler_source_file>familiar_callbacks.c</handler_source_file>
<handler_header_file>familiar_callbacks.h</handler_header_file>
<support_source_file>familiar_support.c</support_source_file>
<support_header_file>familiar_support.h</support_header_file>
</project>
<widget>
<class>GtkWindow</class>
<name>familiar</name>
<width>240</width>
<height>320</height>
<title>vlc (familiar)</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>False</allow_grow>
<auto_shrink>False</auto_shrink>
<widget>
<class>GtkVBox</class>
<name>vbox</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkToolbar</class>
<name>toolbar</name>
<width>112</width>
<height>16</height>
<orientation>GTK_ORIENTATION_HORIZONTAL</orientation>
<type>GTK_TOOLBAR_ICONS</type>
<space_size>5</space_size>
<space_style>GTK_TOOLBAR_SPACE_EMPTY</space_style>
<relief>GTK_RELIEF_NORMAL</relief>
<tooltips>True</tooltips>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkPixmap</class>
<name>xpm_open</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_open_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:18:11 GMT</last_modification_time>
</signal>
<filename>familiar-openb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
<widget>
<class>GtkPixmap</class>
<name>xpm_preferences</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_preferences_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:17:55 GMT</last_modification_time>
</signal>
<filename>familiar-preferencesb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
<widget>
<class>GtkPixmap</class>
<name>xpm_rewind</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_rewind_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:18:17 GMT</last_modification_time>
</signal>
<filename>familiar-rewindb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
<child>
<new_group>True</new_group>
</child>
</widget>
<widget>
<class>GtkPixmap</class>
<name>xpm_pause</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_pause_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:18:29 GMT</last_modification_time>
</signal>
<filename>familiar-pauseb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
<widget>
<class>GtkPixmap</class>
<name>xpm_play</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_play_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:18:36 GMT</last_modification_time>
</signal>
<filename>familiar-playb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
<widget>
<class>GtkPixmap</class>
<name>xpm_stop</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_stop_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:18:43 GMT</last_modification_time>
</signal>
<filename>familiar-stopb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
<widget>
<class>GtkPixmap</class>
<name>xpm_forward</name>
<can_focus>True</can_focus>
<signal>
<name>button_press_event</name>
<handler>on_xpm_forward_button_press_event</handler>
<last_modification_time>Mon, 22 Jul 2002 13:18:55 GMT</last_modification_time>
</signal>
<filename>familiar-forwardb16x16.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
</widget>
<widget>
<class>GtkProgressBar</class>
<name>progress</name>
<value>0</value>
<lower>0</lower>
<upper>100</upper>
<bar_style>GTK_PROGRESS_CONTINUOUS</bar_style>
<orientation>GTK_PROGRESS_LEFT_TO_RIGHT</orientation>
<activity_mode>True</activity_mode>
<show_text>False</show_text>
<format>%P %%</format>
<text_xalign>0.5</text_xalign>
<text_yalign>0.5</text_yalign>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkNotebook</class>
<name>notebook</name>
<can_focus>True</can_focus>
<show_tabs>True</show_tabs>
<show_border>True</show_border>
<tab_pos>GTK_POS_TOP</tab_pos>
<scrollable>False</scrollable>
<tab_hborder>2</tab_hborder>
<tab_vborder>2</tab_vborder>
<popup_enable>False</popup_enable>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>Placeholder</class>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>media</name>
<label>Media</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>Placeholder</class>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>preference</name>
<label>Preference</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>Placeholder</class>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>help</name>
<label>Help</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>Placeholder</class>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>about</name>
<label>About</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</widget>
</GTK-Interface>
/*****************************************************************************
* 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 $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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 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 * );
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include "familiar_callbacks.h"
#include "familiar_interface.h"
#include "familiar_support.h"
gboolean
on_xpm_open_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
gboolean
on_xpm_preferences_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
gboolean
on_xpm_rewind_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
gboolean
on_xpm_pause_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
gboolean
on_xpm_play_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
gboolean
on_xpm_stop_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
gboolean
on_xpm_forward_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
#include <gtk/gtk.h>
gboolean
on_xpm_open_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
gboolean
on_xpm_preferences_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
gboolean
on_xpm_rewind_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
gboolean
on_xpm_pause_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
gboolean
on_xpm_play_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
gboolean
on_xpm_stop_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
gboolean
on_xpm_forward_button_press_event (GtkWidget *widget,
GdkEventButton *event,
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 <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "familiar_callbacks.h"
#include "familiar_interface.h"
#include "familiar_support.h"
GtkWidget*
create_familiar (void)
{
GtkWidget *familiar;
GtkWidget *vbox;
GtkWidget *toolbar;
GtkWidget *xpm_open;
GtkWidget *xpm_preferences;
GtkWidget *xpm_rewind;
GtkWidget *xpm_pause;
GtkWidget *xpm_play;
GtkWidget *xpm_stop;
GtkWidget *xpm_forward;
GtkWidget *progress;
GtkWidget *notebook;
GtkWidget *empty_notebook_page;
GtkWidget *media;
GtkWidget *preference;
GtkWidget *help;
GtkWidget *about;
familiar = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_object_set_data (GTK_OBJECT (familiar), "familiar", familiar);
gtk_widget_set_usize (familiar, 240, 320);
gtk_window_set_title (GTK_WINDOW (familiar), _("vlc (familiar)"));
gtk_window_set_policy (GTK_WINDOW (familiar), FALSE, FALSE, FALSE);
vbox = gtk_vbox_new (FALSE, 0);
gtk_widget_ref (vbox);
gtk_object_set_data_full (GTK_OBJECT (familiar), "vbox", vbox,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (familiar), vbox);
toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
gtk_widget_ref (toolbar);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar", toolbar,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar);
gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, TRUE, 0);
gtk_widget_set_usize (toolbar, 112, 16);
xpm_open = create_pixmap (familiar, "familiar-openb16x16.xpm");
gtk_widget_ref (xpm_open);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_open", xpm_open,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_open);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_open, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_open, GTK_CAN_FOCUS);
xpm_preferences = create_pixmap (familiar, "familiar-preferencesb16x16.xpm");
gtk_widget_ref (xpm_preferences);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_preferences", xpm_preferences,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_preferences);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_preferences, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_preferences, GTK_CAN_FOCUS);
xpm_rewind = create_pixmap (familiar, "familiar-rewindb16x16.xpm");
gtk_widget_ref (xpm_rewind);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_rewind", xpm_rewind,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_rewind);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_rewind, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_rewind, GTK_CAN_FOCUS);
xpm_pause = create_pixmap (familiar, "familiar-pauseb16x16.xpm");
gtk_widget_ref (xpm_pause);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_pause", xpm_pause,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_pause);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_pause, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_pause, GTK_CAN_FOCUS);
xpm_play = create_pixmap (familiar, "familiar-playb16x16.xpm");
gtk_widget_ref (xpm_play);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_play", xpm_play,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_play);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_play, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_play, GTK_CAN_FOCUS);
xpm_stop = create_pixmap (familiar, "familiar-stopb16x16.xpm");
gtk_widget_ref (xpm_stop);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_stop", xpm_stop,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_stop);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_stop, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_stop, GTK_CAN_FOCUS);
xpm_forward = create_pixmap (familiar, "familiar-forwardb16x16.xpm");
gtk_widget_ref (xpm_forward);
gtk_object_set_data_full (GTK_OBJECT (familiar), "xpm_forward", xpm_forward,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (xpm_forward);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), xpm_forward, NULL, NULL);
GTK_WIDGET_SET_FLAGS (xpm_forward, GTK_CAN_FOCUS);
progress = gtk_progress_bar_new ();
gtk_widget_ref (progress);
gtk_object_set_data_full (GTK_OBJECT (familiar), "progress", progress,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (progress);
gtk_box_pack_start (GTK_BOX (vbox), progress, FALSE, FALSE, 0);
gtk_progress_set_activity_mode (GTK_PROGRESS (progress), TRUE);
notebook = gtk_notebook_new ();
gtk_widget_ref (notebook);
gtk_object_set_data_full (GTK_OBJECT (familiar), "notebook", notebook,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (notebook);
gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (empty_notebook_page);
gtk_container_add (GTK_CONTAINER (notebook), empty_notebook_page);
media = gtk_label_new (_("Media"));
gtk_widget_ref (media);
gtk_object_set_data_full (GTK_OBJECT (familiar), "media", media,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (media);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0), media);
empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (empty_notebook_page);
gtk_container_add (GTK_CONTAINER (notebook), empty_notebook_page);
preference = gtk_label_new (_("Preference"));
gtk_widget_ref (preference);
gtk_object_set_data_full (GTK_OBJECT (familiar), "preference", preference,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (preference);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), preference);
empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (empty_notebook_page);
gtk_container_add (GTK_CONTAINER (notebook), empty_notebook_page);
help = gtk_label_new (_("Help"));
gtk_widget_ref (help);
gtk_object_set_data_full (GTK_OBJECT (familiar), "help", help,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (help);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 2), help);
empty_notebook_page = gtk_vbox_new (FALSE, 0);
gtk_widget_show (empty_notebook_page);
gtk_container_add (GTK_CONTAINER (notebook), empty_notebook_page);
about = gtk_label_new (_("About"));
gtk_widget_ref (about);
gtk_object_set_data_full (GTK_OBJECT (familiar), "about", about,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (about);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 3), about);
gtk_signal_connect (GTK_OBJECT (xpm_open), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_open_button_press_event),
NULL);
gtk_signal_connect (GTK_OBJECT (xpm_preferences), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_preferences_button_press_event),
NULL);
gtk_signal_connect (GTK_OBJECT (xpm_rewind), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_rewind_button_press_event),
NULL);
gtk_signal_connect (GTK_OBJECT (xpm_pause), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_pause_button_press_event),
NULL);
gtk_signal_connect (GTK_OBJECT (xpm_play), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_play_button_press_event),
NULL);
gtk_signal_connect (GTK_OBJECT (xpm_stop), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_stop_button_press_event),
NULL);
gtk_signal_connect (GTK_OBJECT (xpm_forward), "button_press_event",
GTK_SIGNAL_FUNC (on_xpm_forward_button_press_event),
NULL);
return familiar;
}
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
GtkWidget* create_familiar (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 "familiar_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 ("../share", 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;
}
/*
* 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);
/* 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);
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