1 /*****************************************************************************
2 * gnome_callbacks.c : Callbacks for the Gnome plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
6 * Authors: Samuel Hocevar <sam@zoy.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 #define MODULE_NAME gnome
24 #include "modules_inner.h"
26 /*****************************************************************************
28 *****************************************************************************/
38 #include "stream_control.h"
39 #include "input_ext-intf.h"
41 #include "interface.h"
42 #include "intf_playlist.h"
45 #include "gnome_callbacks.h"
46 #include "gnome_interface.h"
47 #include "gnome_support.h"
48 #include "intf_gnome.h"
52 /*****************************************************************************
53 * Inline function to retrieve the interface structure
54 *****************************************************************************/
55 static __inline__ intf_thread_t * GetIntf( GtkWidget *item, char * psz_parent )
57 return( gtk_object_get_data( GTK_OBJECT( lookup_widget(item, psz_parent) ),
62 /*****************************************************************************
64 *****************************************************************************
65 * The following callbacks are related to the main interface window.
66 *****************************************************************************/
68 on_intf_window_destroy (GtkObject *object,
71 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(object), "intf_window" );
73 vlc_mutex_lock( &p_intf->change_lock );
75 vlc_mutex_unlock( &p_intf->change_lock );
80 on_slider_button_press_event (GtkWidget *widget,
81 GdkEventButton *event,
84 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
86 vlc_mutex_lock( &p_intf->change_lock );
87 p_intf->p_sys->b_slider_free = 0;
88 vlc_mutex_unlock( &p_intf->change_lock );
95 on_slider_button_release_event (GtkWidget *widget,
96 GdkEventButton *event,
99 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
101 vlc_mutex_lock( &p_intf->change_lock );
102 p_intf->p_sys->b_slider_free = 1;
103 vlc_mutex_unlock( &p_intf->change_lock );
110 on_intf_window_drag_data_received (GtkWidget *widget,
111 GdkDragContext *drag_context,
114 GtkSelectionData *data,
119 char *psz_text = data->data;
120 int i_len = strlen( psz_text );
124 case DROP_ACCEPT_TEXT_PLAIN: /* FIXME: handle multiple files */
131 /* get rid of ' ' at the end */
132 *( psz_text + i_len - 1 ) = 0;
134 intf_WarnMsg( 1, "intf: dropped text/uri-list data `%s'", psz_text );
135 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_text );
139 case DROP_ACCEPT_TEXT_URI_LIST: /* FIXME: handle multiple files */
146 /* get rid of \r\n at the end */
147 *( psz_text + i_len - 2 ) = 0;
149 intf_WarnMsg( 1, "intf: dropped text/uri-list data `%s'", psz_text );
150 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_text );
155 intf_ErrMsg( "intf error: unknown dropped type");
161 /*****************************************************************************
163 *****************************************************************************
164 * The following callbacks are related to the menubar of the main
166 *****************************************************************************/
168 on_menubar_open_activate (GtkMenuItem *menuitem,
171 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
173 /* If we have never used the file selector, open it */
174 if( p_intf->p_sys->p_fileopen == NULL)
176 p_intf->p_sys->p_fileopen = create_intf_fileopen();
177 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
181 gtk_widget_show( p_intf->p_sys->p_fileopen );
182 gdk_window_raise( p_intf->p_sys->p_fileopen->window );
187 on_menubar_disc_activate (GtkMenuItem *menuitem,
190 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
192 gtk_widget_show( p_intf->p_sys->p_disc );
193 gdk_window_raise( p_intf->p_sys->p_disc->window );
198 on_menubar_network_activate (GtkMenuItem *menuitem,
201 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
203 gtk_widget_show( p_intf->p_sys->p_network );
204 gdk_window_raise( p_intf->p_sys->p_network->window );
209 on_menubar_exit_activate (GtkMenuItem *menuitem,
212 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
214 vlc_mutex_lock( &p_intf->change_lock );
216 vlc_mutex_unlock( &p_intf->change_lock );
221 on_menubar_playlist_activate (GtkMenuItem *menuitem,
224 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
226 if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) )
228 p_intf->p_sys->p_playlist = create_intf_playlist();
229 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_playlist ),
232 gtk_widget_show( p_intf->p_sys->p_playlist );
233 gdk_window_raise( p_intf->p_sys->p_playlist->window );
238 on_menubar_audio_toggle (GtkCheckMenuItem *menuitem,
241 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
242 es_descriptor_t * p_es;
244 p_es = (es_descriptor_t*)user_data;
246 input_ChangeES( p_intf->p_input, p_es, 1 );
251 on_menubar_subtitle_toggle (GtkCheckMenuItem *menuitem,
254 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
255 es_descriptor_t * p_es;
257 p_es = (es_descriptor_t*)user_data;
259 input_ChangeES( p_intf->p_input, p_es, 2 );
264 on_menubar_title_toggle (GtkCheckMenuItem *menuitem,
267 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
269 p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)user_data );
270 p_intf->p_sys->b_menus_update = 1;
271 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
276 on_menubar_chapter_toggle (GtkCheckMenuItem *menuitem,
279 intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
280 input_area_t * p_area = p_intf->p_input->stream.p_selected_area;
281 gint i_chapter = (gint)user_data;
283 p_area->i_part = i_chapter;
285 p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
286 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
290 on_menubar_modules_activate (GtkMenuItem *menuitem,
293 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
295 if( !GTK_IS_WIDGET( p_intf->p_sys->p_modules ) )
297 p_intf->p_sys->p_modules = create_intf_modules();
298 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_modules ),
301 gtk_widget_show( p_intf->p_sys->p_modules );
302 gdk_window_raise( p_intf->p_sys->p_modules->window );
307 on_menubar_preferences_activate (GtkMenuItem *menuitem,
315 on_menubar_about_activate (GtkMenuItem *menuitem,
318 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_window" );
320 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
322 p_intf->p_sys->p_about = create_intf_about();
323 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
326 gtk_widget_show( p_intf->p_sys->p_about );
327 gdk_window_raise( p_intf->p_sys->p_about->window );
331 /*****************************************************************************
333 *****************************************************************************
334 * The following callbacks are related to the toolbar of the main
336 *****************************************************************************/
338 on_toolbar_open_clicked (GtkButton *button,
341 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
343 /* If we have never used the file selector, open it */
344 if( p_intf->p_sys->p_fileopen == NULL)
346 p_intf->p_sys->p_fileopen = create_intf_fileopen();
347 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
351 gtk_widget_show( p_intf->p_sys->p_fileopen );
352 gdk_window_raise( p_intf->p_sys->p_fileopen->window );
357 on_toolbar_disc_clicked (GtkButton *button,
360 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
362 gtk_widget_show( p_intf->p_sys->p_disc );
363 gdk_window_raise( p_intf->p_sys->p_disc->window );
368 on_toolbar_network_clicked (GtkButton *button,
371 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
373 gtk_widget_show( p_intf->p_sys->p_network );
374 gdk_window_raise( p_intf->p_sys->p_network->window );
379 on_toolbar_back_clicked (GtkButton *button,
387 on_toolbar_stop_clicked (GtkButton *button,
395 on_toolbar_play_clicked (GtkButton *button,
398 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
400 if( p_intf->p_input != NULL )
402 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
408 on_toolbar_pause_clicked (GtkButton *button,
411 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
413 if( p_intf->p_input != NULL )
415 input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
421 on_toolbar_slow_clicked (GtkButton *button,
424 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
426 if( p_intf->p_input != NULL )
428 input_SetStatus( p_intf->p_input, INPUT_STATUS_SLOWER );
434 on_toolbar_fast_clicked (GtkButton *button,
437 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
439 if( p_intf->p_input != NULL )
441 input_SetStatus( p_intf->p_input, INPUT_STATUS_FASTER );
447 on_toolbar_playlist_clicked (GtkButton *button,
450 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
452 if( !GTK_IS_WIDGET( p_intf->p_sys->p_playlist ) )
454 p_intf->p_sys->p_playlist = create_intf_playlist();
455 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_playlist ),
458 gtk_widget_show( p_intf->p_sys->p_playlist );
459 gdk_window_raise( p_intf->p_sys->p_playlist->window );
464 on_toolbar_prev_clicked (GtkButton *button,
467 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
469 if( p_intf->p_input != NULL )
471 /* FIXME: temporary hack */
472 intf_PlaylistPrev( p_main->p_playlist );
473 intf_PlaylistPrev( p_main->p_playlist );
474 p_intf->p_input->b_eof = 1;
480 on_toolbar_next_clicked (GtkButton *button,
483 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_window" );
485 if( p_intf->p_input != NULL )
487 /* FIXME: temporary hack */
488 p_intf->p_input->b_eof = 1;
493 /*****************************************************************************
495 *****************************************************************************
496 * The following callbacks are related to the popup menu. The popup
497 * menu is activated when right-clicking on the video output window.
498 *****************************************************************************/
500 on_popup_play_activate (GtkMenuItem *menuitem,
503 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
505 if( p_intf->p_input != NULL )
507 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
513 on_popup_pause_activate (GtkMenuItem *menuitem,
516 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
518 if( p_intf->p_input != NULL )
520 input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
526 on_popup_slow_activate (GtkMenuItem *menuitem,
529 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
531 if( p_intf->p_input != NULL )
533 input_SetStatus( p_intf->p_input, INPUT_STATUS_SLOWER );
539 on_popup_fast_activate (GtkMenuItem *menuitem,
542 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
544 if( p_intf->p_input != NULL )
546 input_SetStatus( p_intf->p_input, INPUT_STATUS_FASTER );
552 on_popup_audio_toggle (GtkCheckMenuItem *menuitem,
555 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
556 es_descriptor_t * p_es;
558 p_es = (es_descriptor_t*)user_data;
560 input_ChangeES( p_intf->p_input, p_es, 1 );
565 on_popup_subtitle_toggle (GtkCheckMenuItem *menuitem,
568 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
569 es_descriptor_t * p_es;
571 p_es = (es_descriptor_t*)user_data;
573 input_ChangeES( p_intf->p_input, p_es, 2 );
578 on_popup_navigation_toggle (GtkCheckMenuItem *menuitem,
581 if( menuitem->active )
583 intf_thread_t * p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
584 input_area_t * p_area;
588 i_title = (gint)(user_data) / 100 ;
589 i_chapter = (gint)(user_data) - ( 100 * i_title );
591 if( i_title != p_intf->p_input->stream.p_selected_area->i_id )
593 p_intf->p_sys->b_menus_update = 1;
596 p_area = p_intf->p_input->stream.pp_areas[i_title];
597 p_area->i_part = i_chapter;
599 p_intf->p_input->pf_set_area( p_intf->p_input, (input_area_t*)p_area );
600 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
606 on_popup_open_activate (GtkMenuItem *menuitem,
609 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
611 /* If we have never used the file selector, open it */
612 if( p_intf->p_sys->p_fileopen == NULL)
614 p_intf->p_sys->p_fileopen = create_intf_fileopen();
615 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
619 gtk_widget_show( p_intf->p_sys->p_fileopen );
620 gdk_window_raise( p_intf->p_sys->p_fileopen->window );
625 on_popup_disc_activate (GtkMenuItem *menuitem,
628 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
630 gtk_widget_show( p_intf->p_sys->p_disc );
631 gdk_window_raise( p_intf->p_sys->p_disc->window );
636 on_popup_network_activate (GtkMenuItem *menuitem,
639 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
641 gtk_widget_show( p_intf->p_sys->p_network );
642 gdk_window_raise( p_intf->p_sys->p_network->window );
647 on_popup_about_activate (GtkMenuItem *menuitem,
650 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
652 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
654 p_intf->p_sys->p_about = create_intf_about();
655 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
658 gtk_widget_show( p_intf->p_sys->p_about );
659 gdk_window_raise( p_intf->p_sys->p_about->window );
664 on_popup_exit_activate (GtkMenuItem *menuitem,
667 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(menuitem), "intf_popup" );
669 vlc_mutex_lock( &p_intf->change_lock );
671 vlc_mutex_unlock( &p_intf->change_lock );
675 /*****************************************************************************
677 *****************************************************************************
678 * The following callbacks are related to the file requester.
679 *****************************************************************************/
681 on_intf_fileopen_destroy (GtkObject *object,
684 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(object), "intf_fileopen" );
686 p_intf->p_sys->p_fileopen = NULL;
691 on_fileopen_ok_clicked (GtkButton *button,
697 filesel = gtk_widget_get_toplevel (GTK_WIDGET (button));
698 gtk_widget_hide (filesel);
699 filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel));
701 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)filename );
706 on_fileopen_cancel_clicked (GtkButton *button,
709 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
713 /*****************************************************************************
715 *****************************************************************************
716 * The following callbacks are related to the playlist.
717 *****************************************************************************/
719 on_intf_playlist_destroy (GtkObject *object,
722 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(object), "intf_playlist" );
724 p_intf->p_sys->p_playlist = NULL;
729 on_playlist_ok_clicked (GtkButton *button,
732 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_playlist" );
734 gtk_widget_hide( p_intf->p_sys->p_playlist );
739 on_playlist_close_clicked (GtkButton *button,
742 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
747 /*****************************************************************************
748 * Module manager callbacks
749 *****************************************************************************
750 * The following callbacks are related to the module manager.
751 *****************************************************************************/
753 on_intf_modules_destroy (GtkObject *object,
761 on_modules_ok_clicked (GtkButton *button,
764 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_modules" );
766 gtk_widget_hide( p_intf->p_sys->p_modules );
771 on_modules_apply_clicked (GtkButton *button,
779 on_modules_cancel_clicked (GtkButton *button,
782 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
786 /*****************************************************************************
787 * Open disc callbacks
788 *****************************************************************************
789 * The following callbacks are related to the disc manager.
790 *****************************************************************************/
792 on_disc_dvd_toggled (GtkToggleButton *togglebutton,
795 if( togglebutton->active )
797 gtk_entry_set_text( GTK_ENTRY( lookup_widget(
798 GTK_WIDGET(togglebutton), "disc_name" ) ), "/dev/dvd" );
804 on_disc_vcd_toggled (GtkToggleButton *togglebutton,
807 if( togglebutton->active )
809 gtk_entry_set_text( GTK_ENTRY( lookup_widget(
810 GTK_WIDGET(togglebutton), "disc_name" ) ), "/dev/cdrom" );
816 on_disc_ok_clicked (GtkButton *button,
819 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_disc" );
820 char *psz_device, *psz_source, *psz_method;
822 psz_device = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
823 GTK_WIDGET(button), "disc_name" ) ) );
825 /* "dvd:foo" has size 5 + strlen(foo) */
826 psz_source = malloc( 5 + strlen( psz_device ) );
827 if( psz_source == NULL )
832 /* Check which method was activated */
833 if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
834 "disc_dvd" ) )->active )
838 else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
839 "disc_vcd" ) )->active )
845 intf_ErrMsg( "intf error: unknown disc type toggle button position" );
850 /* Select title and chapter */
851 main_PutIntVariable( INPUT_TITLE_VAR, gtk_spin_button_get_value_as_int(
852 GTK_SPIN_BUTTON( lookup_widget(
853 GTK_WIDGET(button), "disc_title" ) ) ) );
855 main_PutIntVariable( INPUT_CHAPTER_VAR, gtk_spin_button_get_value_as_int(
856 GTK_SPIN_BUTTON( lookup_widget(
857 GTK_WIDGET(button), "disc_chapter" ) ) ) );
859 /* Build source name and add it to playlist */
860 sprintf( psz_source, "%s:%s", psz_method, psz_device );
861 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
864 gtk_widget_hide( p_intf->p_sys->p_disc );
869 on_disc_cancel_clicked (GtkButton *button,
872 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
876 /*****************************************************************************
877 * Network stream callbacks
878 *****************************************************************************
879 * The following callbacks are related to the network stream manager.
880 *****************************************************************************/
882 on_network_ok_clicked (GtkButton *button,
885 intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), "intf_network" );
886 char *psz_source, *psz_server, *psz_protocol;
889 psz_server = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
890 GTK_WIDGET(button), "network_server" ) ) );
892 /* Check which protocol was activated */
893 if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
894 "network_ts" ) )->active )
898 else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
899 "network_rtp" ) )->active )
901 psz_protocol = "rtp";
905 intf_ErrMsg( "intf error: unknown protocol toggle button position" );
909 /* Get the port number and make sure it will not overflow 5 characters */
910 i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
911 lookup_widget( GTK_WIDGET(button), "network_port" ) ) );
914 intf_ErrMsg( "intf error: invalid port %i", i_port );
917 /* Allocate room for "protocol://server:port" */
918 psz_source = malloc( strlen( psz_protocol ) + strlen( psz_server ) + 10 );
919 if( psz_source == NULL )
924 /* Build source name and add it to playlist */
925 sprintf( psz_source, "%s://%s:%i", psz_protocol, psz_server, i_port );
926 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
929 gtk_widget_hide( p_intf->p_sys->p_network );
934 on_network_cancel_clicked (GtkButton *button,
937 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );