1 /*****************************************************************************
2 * gnome_callbacks.c : Callbacks for the Gnome plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: gnome_callbacks.c,v 1.18 2001/03/21 13:42:34 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 #define MODULE_NAME gnome
25 #include "modules_inner.h"
27 /*****************************************************************************
29 *****************************************************************************/
39 #include "stream_control.h"
40 #include "input_ext-intf.h"
42 #include "interface.h"
43 #include "intf_playlist.h"
46 #include "gnome_callbacks.h"
47 #include "gnome_interface.h"
48 #include "gnome_support.h"
49 #include "intf_gnome.h"
53 /*****************************************************************************
54 * Inline function to retrieve the interface structure
55 *****************************************************************************/
56 static __inline__ intf_thread_t * GetIntf( GtkWidget *item, char * psz_parent )
58 return( gtk_object_get_data( GTK_OBJECT( lookup_widget(item, psz_parent) ),
63 /*****************************************************************************
65 *****************************************************************************
66 * The following callbacks are related to the main interface window.
67 *****************************************************************************/
69 on_intf_window_destroy (GtkObject *object,
72 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(object), "intf_window" );
74 vlc_mutex_lock( &p_intf->change_lock );
76 vlc_mutex_unlock( &p_intf->change_lock );
81 on_slider_button_press_event (GtkWidget *widget,
82 GdkEventButton *event,
85 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
87 vlc_mutex_lock( &p_intf->change_lock );
88 p_intf->p_sys->b_slider_free = 0;
89 vlc_mutex_unlock( &p_intf->change_lock );
96 on_slider_button_release_event (GtkWidget *widget,
97 GdkEventButton *event,
100 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
102 vlc_mutex_lock( &p_intf->change_lock );
103 p_intf->p_sys->b_slider_free = 1;
104 vlc_mutex_unlock( &p_intf->change_lock );
111 on_intf_window_drag_data_received (GtkWidget *widget,
112 GdkDragContext *drag_context,
115 GtkSelectionData *data,
120 char *psz_text = data->data;
121 int i_len = strlen( psz_text );
125 case DROP_ACCEPT_TEXT_PLAIN: /* FIXME: handle multiple files */
132 /* get rid of ' ' at the end */
133 *( psz_text + i_len - 1 ) = 0;
135 intf_WarnMsg( 1, "intf: dropped text/uri-list data `%s'", psz_text );
136 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_text );
140 case DROP_ACCEPT_TEXT_URI_LIST: /* FIXME: handle multiple files */
147 /* get rid of \r\n at the end */
148 *( psz_text + i_len - 2 ) = 0;
150 intf_WarnMsg( 1, "intf: dropped text/uri-list data `%s'", psz_text );
151 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_text );
156 intf_ErrMsg( "intf error: unknown dropped type");
162 /*****************************************************************************
164 *****************************************************************************
165 * The following callbacks are related to the menubar of the main
167 *****************************************************************************/
169 on_menubar_open_activate (GtkMenuItem *menuitem,
172 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
174 /* If we have never used the file selector, open it */
175 if( p_intf->p_sys->p_fileopen == NULL)
177 p_intf->p_sys->p_fileopen = create_intf_fileopen();
178 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
182 gtk_widget_show( p_intf->p_sys->p_fileopen );
183 gdk_window_raise( p_intf->p_sys->p_fileopen->window );
188 on_menubar_disc_activate (GtkMenuItem *menuitem,
191 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
193 gtk_widget_show( p_intf->p_sys->p_disc );
194 gdk_window_raise( p_intf->p_sys->p_disc->window );
199 on_menubar_network_activate (GtkMenuItem *menuitem,
202 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
204 gtk_widget_show( p_intf->p_sys->p_network );
205 gdk_window_raise( p_intf->p_sys->p_network->window );
210 on_menubar_exit_activate (GtkMenuItem *menuitem,
213 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
215 vlc_mutex_lock( &p_intf->change_lock );
217 vlc_mutex_unlock( &p_intf->change_lock );
222 on_menubar_playlist_activate (GtkMenuItem *menuitem,
225 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
227 if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) )
229 p_intf->p_sys->p_playlist = create_intf_playlist();
230 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_playlist ),
233 gtk_widget_show( p_intf->p_sys->p_playlist );
234 gdk_window_raise( p_intf->p_sys->p_playlist->window );
239 on_menubar_audio_toggle (GtkCheckMenuItem *menuitem,
242 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
243 es_descriptor_t * p_es;
245 p_es = (es_descriptor_t*)user_data;
247 input_ChangeES( p_intf->p_input, p_es, 1 );
252 on_menubar_subtitle_toggle (GtkCheckMenuItem *menuitem,
255 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
256 es_descriptor_t * p_es;
258 p_es = (es_descriptor_t*)user_data;
260 input_ChangeES( p_intf->p_input, p_es, 2 );
265 on_menubar_title_toggle (GtkCheckMenuItem *menuitem,
268 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
270 p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)user_data );
271 p_intf->p_sys->b_menus_update = 1;
272 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
277 on_menubar_chapter_toggle (GtkCheckMenuItem *menuitem,
280 intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
281 input_area_t * p_area = p_intf->p_input->stream.p_selected_area;
282 gint i_chapter = (gint)user_data;
284 p_area->i_part = i_chapter;
286 p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
287 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
291 on_menubar_modules_activate (GtkMenuItem *menuitem,
294 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
296 if( !GTK_IS_WIDGET( p_intf->p_sys->p_modules ) )
298 p_intf->p_sys->p_modules = create_intf_modules();
299 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_modules ),
302 gtk_widget_show( p_intf->p_sys->p_modules );
303 gdk_window_raise( p_intf->p_sys->p_modules->window );
308 on_menubar_preferences_activate (GtkMenuItem *menuitem,
316 on_menubar_about_activate (GtkMenuItem *menuitem,
319 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
321 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
323 p_intf->p_sys->p_about = create_intf_about();
324 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
327 gtk_widget_show( p_intf->p_sys->p_about );
328 gdk_window_raise( p_intf->p_sys->p_about->window );
332 /*****************************************************************************
334 *****************************************************************************
335 * The following callbacks are related to the toolbar of the main
337 *****************************************************************************/
339 on_toolbar_open_clicked (GtkButton *button,
342 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
344 /* If we have never used the file selector, open it */
345 if( p_intf->p_sys->p_fileopen == NULL)
347 p_intf->p_sys->p_fileopen = create_intf_fileopen();
348 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
352 gtk_widget_show( p_intf->p_sys->p_fileopen );
353 gdk_window_raise( p_intf->p_sys->p_fileopen->window );
358 on_toolbar_disc_clicked (GtkButton *button,
361 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
363 gtk_widget_show( p_intf->p_sys->p_disc );
364 gdk_window_raise( p_intf->p_sys->p_disc->window );
369 on_toolbar_network_clicked (GtkButton *button,
372 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
374 gtk_widget_show( p_intf->p_sys->p_network );
375 gdk_window_raise( p_intf->p_sys->p_network->window );
380 on_toolbar_back_clicked (GtkButton *button,
388 on_toolbar_stop_clicked (GtkButton *button,
396 on_toolbar_play_clicked (GtkButton *button,
399 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
401 if( p_intf->p_input != NULL )
403 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
409 on_toolbar_pause_clicked (GtkButton *button,
412 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
414 if( p_intf->p_input != NULL )
416 input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
422 on_toolbar_slow_clicked (GtkButton *button,
425 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
427 if( p_intf->p_input != NULL )
429 input_SetStatus( p_intf->p_input, INPUT_STATUS_SLOWER );
435 on_toolbar_fast_clicked (GtkButton *button,
438 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
440 if( p_intf->p_input != NULL )
442 input_SetStatus( p_intf->p_input, INPUT_STATUS_FASTER );
448 on_toolbar_playlist_clicked (GtkButton *button,
451 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
453 if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) )
455 p_intf->p_sys->p_playlist = create_intf_playlist();
456 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_playlist ),
459 gtk_widget_show( p_intf->p_sys->p_playlist );
460 gdk_window_raise( p_intf->p_sys->p_playlist->window );
465 on_toolbar_prev_clicked (GtkButton *button,
468 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
470 if( p_intf->p_input != NULL )
472 /* FIXME: temporary hack */
473 intf_PlaylistPrev( p_main->p_playlist );
474 intf_PlaylistPrev( p_main->p_playlist );
475 p_intf->p_input->b_eof = 1;
481 on_toolbar_next_clicked (GtkButton *button,
484 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
486 if( p_intf->p_input != NULL )
488 /* FIXME: temporary hack */
489 p_intf->p_input->b_eof = 1;
494 /*****************************************************************************
496 *****************************************************************************
497 * The following callbacks are related to the popup menu. The popup
498 * menu is activated when right-clicking on the video output window.
499 *****************************************************************************/
501 on_popup_play_activate (GtkMenuItem *menuitem,
504 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
506 if( p_intf->p_input != NULL )
508 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
514 on_popup_pause_activate (GtkMenuItem *menuitem,
517 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
519 if( p_intf->p_input != NULL )
521 input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
527 on_popup_slow_activate (GtkMenuItem *menuitem,
530 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
532 if( p_intf->p_input != NULL )
534 input_SetStatus( p_intf->p_input, INPUT_STATUS_SLOWER );
540 on_popup_fast_activate (GtkMenuItem *menuitem,
543 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
545 if( p_intf->p_input != NULL )
547 input_SetStatus( p_intf->p_input, INPUT_STATUS_FASTER );
553 on_popup_audio_toggle (GtkCheckMenuItem *menuitem,
556 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
557 es_descriptor_t * p_es;
559 p_es = (es_descriptor_t*)user_data;
561 input_ChangeES( p_intf->p_input, p_es, 1 );
566 on_popup_subtitle_toggle (GtkCheckMenuItem *menuitem,
569 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
570 es_descriptor_t * p_es;
572 p_es = (es_descriptor_t*)user_data;
574 input_ChangeES( p_intf->p_input, p_es, 2 );
579 on_popup_navigation_toggle (GtkCheckMenuItem *menuitem,
582 if( menuitem->active )
584 intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
585 input_area_t * p_area;
589 i_title = (gint)(user_data) / 100 ;
590 i_chapter = (gint)(user_data) - ( 100 * i_title );
592 if( i_title != p_intf->p_input->stream.p_selected_area->i_id )
594 p_intf->p_sys->b_menus_update = 1;
597 p_area = p_intf->p_input->stream.pp_areas[i_title];
598 p_area->i_part = i_chapter;
600 p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
601 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
607 on_popup_open_activate (GtkMenuItem *menuitem,
610 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
612 /* If we have never used the file selector, open it */
613 if( p_intf->p_sys->p_fileopen == NULL)
615 p_intf->p_sys->p_fileopen = create_intf_fileopen();
616 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
620 gtk_widget_show( p_intf->p_sys->p_fileopen );
621 gdk_window_raise( p_intf->p_sys->p_fileopen->window );
626 on_popup_disc_activate (GtkMenuItem *menuitem,
629 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
631 gtk_widget_show( p_intf->p_sys->p_disc );
632 gdk_window_raise( p_intf->p_sys->p_disc->window );
637 on_popup_network_activate (GtkMenuItem *menuitem,
640 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
642 gtk_widget_show( p_intf->p_sys->p_network );
643 gdk_window_raise( p_intf->p_sys->p_network->window );
648 on_popup_about_activate (GtkMenuItem *menuitem,
651 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
653 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
655 p_intf->p_sys->p_about = create_intf_about();
656 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
659 gtk_widget_show( p_intf->p_sys->p_about );
660 gdk_window_raise( p_intf->p_sys->p_about->window );
665 on_popup_exit_activate (GtkMenuItem *menuitem,
668 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
670 vlc_mutex_lock( &p_intf->change_lock );
672 vlc_mutex_unlock( &p_intf->change_lock );
676 /*****************************************************************************
678 *****************************************************************************
679 * The following callbacks are related to the file requester.
680 *****************************************************************************/
682 on_intf_fileopen_destroy (GtkObject *object,
685 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(object), "intf_fileopen" );
687 p_intf->p_sys->p_fileopen = NULL;
692 on_fileopen_ok_clicked (GtkButton *button,
698 filesel = gtk_widget_get_toplevel (GTK_WIDGET (button));
699 gtk_widget_hide (filesel);
700 filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel));
702 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)filename );
707 on_fileopen_cancel_clicked (GtkButton *button,
710 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
714 /*****************************************************************************
716 *****************************************************************************
717 * The following callbacks are related to the playlist.
718 *****************************************************************************/
720 on_intf_playlist_destroy (GtkObject *object,
723 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(object), "intf_playlist" );
725 p_intf->p_sys->p_playlist = NULL;
730 on_playlist_ok_clicked (GtkButton *button,
733 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_playlist" );
735 gtk_widget_hide( p_intf->p_sys->p_playlist );
740 on_playlist_close_clicked (GtkButton *button,
743 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
748 /*****************************************************************************
749 * Module manager callbacks
750 *****************************************************************************
751 * The following callbacks are related to the module manager.
752 *****************************************************************************/
754 on_intf_modules_destroy (GtkObject *object,
762 on_modules_ok_clicked (GtkButton *button,
765 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_modules" );
767 gtk_widget_hide( p_intf->p_sys->p_modules );
772 on_modules_apply_clicked (GtkButton *button,
780 on_modules_cancel_clicked (GtkButton *button,
783 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
787 /*****************************************************************************
788 * Open disc callbacks
789 *****************************************************************************
790 * The following callbacks are related to the disc manager.
791 *****************************************************************************/
793 on_disc_dvd_toggled (GtkToggleButton *togglebutton,
796 if( togglebutton->active )
798 gtk_entry_set_text( GTK_ENTRY( lookup_widget(
799 GTK_WIDGET(togglebutton), "disc_name" ) ), "/dev/dvd" );
805 on_disc_vcd_toggled (GtkToggleButton *togglebutton,
808 if( togglebutton->active )
810 gtk_entry_set_text( GTK_ENTRY( lookup_widget(
811 GTK_WIDGET(togglebutton), "disc_name" ) ), "/dev/cdrom" );
817 on_disc_ok_clicked (GtkButton *button,
820 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_disc" );
821 char *psz_device, *psz_source, *psz_method;
823 psz_device = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
824 GTK_WIDGET(button), "disc_name" ) ) );
826 /* "dvd:foo" has size 5 + strlen(foo) */
827 psz_source = malloc( 5 + strlen( psz_device ) );
828 if( psz_source == NULL )
833 /* Check which method was activated */
834 if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
835 "disc_dvd" ) )->active )
839 else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
840 "disc_vcd" ) )->active )
846 intf_ErrMsg( "intf error: unknown disc type toggle button position" );
851 /* Select title and chapter */
852 main_PutIntVariable( INPUT_TITLE_VAR, gtk_spin_button_get_value_as_int(
853 GTK_SPIN_BUTTON( lookup_widget(
854 GTK_WIDGET(button), "disc_title" ) ) ) );
856 main_PutIntVariable( INPUT_CHAPTER_VAR, gtk_spin_button_get_value_as_int(
857 GTK_SPIN_BUTTON( lookup_widget(
858 GTK_WIDGET(button), "disc_chapter" ) ) ) );
860 /* Build source name and add it to playlist */
861 sprintf( psz_source, "%s:%s", psz_method, psz_device );
862 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
865 gtk_widget_hide( p_intf->p_sys->p_disc );
870 on_disc_cancel_clicked (GtkButton *button,
873 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
877 /*****************************************************************************
878 * Network stream callbacks
879 *****************************************************************************
880 * The following callbacks are related to the network stream manager.
881 *****************************************************************************/
883 on_network_ok_clicked (GtkButton *button,
886 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_network" );
887 char *psz_source, *psz_server, *psz_protocol;
890 psz_server = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
891 GTK_WIDGET(button), "network_server" ) ) );
893 /* Check which protocol was activated */
894 if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
895 "network_ts" ) )->active )
899 else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
900 "network_rtp" ) )->active )
902 psz_protocol = "rtp";
906 intf_ErrMsg( "intf error: unknown protocol toggle button position" );
910 /* Get the port number and make sure it will not overflow 5 characters */
911 i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
912 lookup_widget( GTK_WIDGET(button), "network_port" ) ) );
915 intf_ErrMsg( "intf error: invalid port %i", i_port );
918 /* Allocate room for "protocol://server:port" */
919 psz_source = malloc( strlen( psz_protocol ) + strlen( psz_server ) + 10 );
920 if( psz_source == NULL )
925 /* Build source name and add it to playlist */
926 sprintf( psz_source, "%s://%s:%i", psz_protocol, psz_server, i_port );
927 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
930 gtk_widget_hide( p_intf->p_sys->p_network );
935 on_network_cancel_clicked (GtkButton *button,
938 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );