1 /*****************************************************************************
2 * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: gtk_callbacks.c,v 1.13 2003/02/09 01:56:21 massiot Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Stéphane Borel <stef@via.ecp.fr>
9 * Julien BLACHE <jb@technologeek.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
29 #include <sys/types.h> /* off_t */
43 #include "gtk_callbacks.h"
44 #include "gtk_interface.h"
45 #include "gtk_support.h"
51 /*****************************************************************************
52 * Useful function to retrieve p_intf
53 ****************************************************************************/
54 void * E_(__GtkGetIntf)( GtkWidget * widget )
58 if( GTK_IS_MENU_ITEM( widget ) )
60 /* Look for a GTK_MENU */
61 while( widget->parent && !GTK_IS_MENU( widget ) )
63 widget = widget->parent;
66 /* Maybe this one has the data */
67 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
73 /* Otherwise, the parent widget has it */
74 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
75 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
82 /* We look for the top widget */
83 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
84 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
89 /*****************************************************************************
91 *****************************************************************************/
94 * Main interface callbacks
97 #ifdef MODULE_NAME_IS_gtk
98 # define GTKEXIT GtkExit
100 # define GTKEXIT GnomeExit
103 gboolean GTKEXIT( GtkWidget *widget,
106 intf_thread_t *p_intf = GtkGetIntf( widget );
108 vlc_mutex_lock( &p_intf->change_lock );
109 p_intf->p_vlc->b_die = VLC_TRUE;
110 vlc_mutex_unlock( &p_intf->change_lock );
115 void GtkClose( GtkMenuItem *menuitem,
118 intf_thread_t *p_intf = GtkGetIntf( menuitem );
119 p_intf->b_die = VLC_TRUE;
122 gboolean GtkWindowDelete( GtkWidget *widget,
126 GTKEXIT( GTK_WIDGET( widget ), user_data );
132 gboolean GtkWindowToggle( GtkWidget *widget,
135 intf_thread_t *p_intf = GtkGetIntf( widget );
137 if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
139 gtk_widget_hide( p_intf->p_sys->p_window);
143 gtk_widget_show( p_intf->p_sys->p_window );
149 gboolean GtkFullscreen( GtkWidget *widget,
152 intf_thread_t *p_intf = GtkGetIntf( widget );
153 vout_thread_t *p_vout;
155 if( p_intf->p_sys->p_input == NULL )
160 p_vout = vlc_object_find( p_intf->p_sys->p_input,
161 VLC_OBJECT_VOUT, FIND_CHILD );
167 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
168 vlc_object_release( p_vout );
172 void GtkWindowDrag( GtkWidget *widget,
173 GdkDragContext *drag_context,
176 GtkSelectionData *data,
181 intf_thread_t * p_intf = GtkGetIntf( widget );
182 GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
186 /****************************************************************************
188 ****************************************************************************/
190 gboolean GtkSliderRelease( GtkWidget *widget,
191 GdkEventButton *event,
194 intf_thread_t *p_intf = GtkGetIntf( widget );
196 vlc_mutex_lock( &p_intf->change_lock );
197 p_intf->p_sys->b_slider_free = VLC_TRUE;
198 vlc_mutex_unlock( &p_intf->change_lock );
204 gboolean GtkSliderPress( GtkWidget *widget,
205 GdkEventButton *event,
208 intf_thread_t *p_intf = GtkGetIntf( widget );
210 vlc_mutex_lock( &p_intf->change_lock );
211 p_intf->p_sys->b_slider_free = VLC_FALSE;
212 vlc_mutex_unlock( &p_intf->change_lock );
218 /****************************************************************************
220 ****************************************************************************/
222 void GtkTitlePrev( GtkButton * button, gpointer user_data )
224 intf_thread_t * p_intf;
225 input_area_t * p_area;
228 p_intf = GtkGetIntf( button );
229 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
230 i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
234 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
235 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
237 input_ChangeArea( p_intf->p_sys->p_input, p_area );
238 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
240 p_intf->p_sys->b_title_update = VLC_TRUE;
241 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
242 GtkSetupMenus( p_intf );
245 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
249 void GtkTitleNext( GtkButton * button, gpointer user_data )
251 intf_thread_t * p_intf;
252 input_area_t * p_area;
255 p_intf = GtkGetIntf( button );
256 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
257 i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
259 if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
261 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
262 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
264 input_ChangeArea( p_intf->p_sys->p_input, p_area );
265 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
267 p_intf->p_sys->b_title_update = VLC_TRUE;
268 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
269 GtkSetupMenus( p_intf );
272 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
276 void GtkChapterPrev( GtkButton * button, gpointer user_data )
278 intf_thread_t * p_intf;
279 input_area_t * p_area;
281 p_intf = GtkGetIntf( button );
282 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
283 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
285 if( p_area->i_part - 1 > 0 )
288 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
290 input_ChangeArea( p_intf->p_sys->p_input, p_area );
291 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
293 p_intf->p_sys->b_chapter_update = VLC_TRUE;
294 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
295 GtkSetupMenus( p_intf );
298 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
302 void GtkChapterNext( GtkButton * button, gpointer user_data )
304 intf_thread_t * p_intf;
305 input_area_t * p_area;
307 p_intf = GtkGetIntf( button );
308 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
309 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
311 if( p_area->i_part + 1 < p_area->i_part_nb )
314 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
316 input_ChangeArea( p_intf->p_sys->p_input, p_area );
317 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
319 p_intf->p_sys->b_chapter_update = VLC_TRUE;
320 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
321 GtkSetupMenus( p_intf );
324 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
327 /****************************************************************************
328 * Network specific items
329 ****************************************************************************/
330 void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
334 i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
336 msg_Dbg( "intf info: joining channel %d", i_channel );
338 network_ChannelJoin( i_channel );
342 void GtkChannelGo( GtkButton * button, gpointer user_data )
348 intf_thread_t *p_intf = GtkGetIntf( button );
350 window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
351 spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
352 "network_channel_spinbutton" ) );
354 i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
355 msg_Dbg( p_intf, "joining channel %d", i_channel );
357 vlc_mutex_lock( &p_intf->change_lock );
358 network_ChannelJoin( p_intf, i_channel );
359 vlc_mutex_unlock( &p_intf->change_lock );
361 /* input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); */
365 /****************************************************************************
367 ****************************************************************************/
369 gboolean GtkAboutShow( GtkWidget *widget,
372 intf_thread_t *p_intf = GtkGetIntf( widget );
374 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
376 p_intf->p_sys->p_about = create_intf_about();
377 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
380 gtk_widget_show( p_intf->p_sys->p_about );
381 gdk_window_raise( p_intf->p_sys->p_about->window );
386 void GtkAboutOk( GtkButton * button, gpointer user_data)
388 intf_thread_t *p_intf = GtkGetIntf( button );
390 gtk_widget_hide( p_intf->p_sys->p_about );
394 /****************************************************************************
396 ****************************************************************************/
398 gboolean GtkJumpShow( GtkWidget *widget,
401 intf_thread_t *p_intf = GtkGetIntf( widget );
403 if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
405 p_intf->p_sys->p_jump = create_intf_jump();
406 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
410 gtk_widget_show( p_intf->p_sys->p_jump );
411 gdk_window_raise( p_intf->p_sys->p_jump->window );
417 void GtkJumpOk( GtkButton *button,
420 intf_thread_t * p_intf = GtkGetIntf( button );
421 int i_hours, i_minutes, i_seconds;
423 if( p_intf->p_sys->p_input == NULL )
428 #define GET_VALUE( name ) \
429 gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
430 GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
431 i_hours = GET_VALUE( "jump_hour_spinbutton" );
432 i_minutes = GET_VALUE( "jump_minute_spinbutton" );
433 i_seconds = GET_VALUE( "jump_second_spinbutton" );
436 input_Seek( p_intf->p_sys->p_input,
437 i_seconds + 60 * i_minutes + 3600 * i_hours,
438 INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
440 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
444 void GtkJumpCancel( GtkButton *button,
447 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
450 /****************************************************************************
451 * Callbacks for disc ejection
452 ****************************************************************************/
453 gboolean GtkDiscEject ( GtkWidget *widget, gpointer user_data )
455 char *psz_device = NULL;
459 intf_thread_t *p_intf = GtkGetIntf( widget );
460 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
462 if( p_playlist == NULL )
467 vlc_mutex_lock( &p_playlist->object_lock );
469 if( p_playlist->i_index < 0 )
471 vlc_mutex_unlock( &p_playlist->object_lock );
472 vlc_object_release( p_playlist );
476 psz_current = p_playlist->pp_items[ p_playlist->i_index ]->psz_name;
479 * Get the active input
480 * Determine whether we can eject a media, ie it's a VCD or DVD
481 * If it's neither a VCD nor a DVD, then return
485 * Don't really know if I must lock the stuff here, we're using it read-only
488 if( psz_current != NULL )
490 if( !strncmp(psz_current, "dvd:", 4) )
492 switch( psz_current[4] )
496 psz_device = config_GetPsz( p_intf, "dvd" );
499 /* Omit the first 4 characters */
500 psz_device = strdup( psz_current + 4 );
504 else if( !strncmp(psz_current, "vcd:", 4) )
506 switch( psz_current[4] )
510 psz_device = config_GetPsz( p_intf, "vcd" );
513 /* Omit the first 4 characters */
514 psz_device = strdup( psz_current + 4 );
520 psz_device = strdup( psz_current );
524 vlc_mutex_unlock( &p_playlist->object_lock );
525 vlc_object_release( p_playlist );
527 if( psz_device == NULL )
532 /* Remove what we have after @ */
533 psz_parser = psz_device;
534 for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
536 if( *psz_parser == '@' )
543 /* If there's a stream playing, we aren't allowed to eject ! */
544 if( p_intf->p_sys->p_input == NULL )
546 msg_Dbg( p_intf, "ejecting %s", psz_device );
548 intf_Eject( p_intf, psz_device );
556 /****************************************************************************
558 ****************************************************************************/
560 gboolean GtkMessagesShow( GtkWidget *widget,
563 static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
564 static GdkColormap *colormap;
565 intf_thread_t *p_intf = GtkGetIntf( widget );
567 gtk_widget_show( p_intf->p_sys->p_messages );
568 colormap = gdk_colormap_get_system ();
569 gdk_color_alloc( colormap, &black );
570 gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
573 gdk_window_raise( p_intf->p_sys->p_messages->window );
575 gtk_text_set_point( p_intf->p_sys->p_messages_text,
576 gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
582 GtkMessagesOk (GtkButton *button,
585 intf_thread_t *p_intf = GtkGetIntf( button );
586 gtk_widget_hide( p_intf->p_sys->p_messages );
591 GtkMessagesDelete (GtkWidget *widget,
595 intf_thread_t *p_intf = GtkGetIntf( widget );
596 gtk_widget_hide( p_intf->p_sys->p_messages );
602 GtkOpenNotebookChanged (GtkNotebook *notebook,
603 GtkNotebookPage *page,
607 GtkOpenChanged( GTK_WIDGET( notebook ), user_data );
610 /****************************************************************************
612 ****************************************************************************/
613 void GtkVolumeUp ( GtkMenuItem *menuitem,
616 intf_thread_t *p_intf = GtkGetIntf( menuitem );
617 audio_volume_t i_volume;
619 aout_VolumeUp( p_intf, 1, &i_volume );
620 p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
624 void GtkVolumeDown ( GtkMenuItem *menuitem,
627 intf_thread_t *p_intf = GtkGetIntf( menuitem );
628 audio_volume_t i_volume;
630 aout_VolumeDown( p_intf, 1, &i_volume );
631 p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
635 void GtkVolumeMute ( GtkMenuItem *menuitem,
638 intf_thread_t *p_intf = GtkGetIntf( menuitem );
639 audio_volume_t i_volume;
641 aout_VolumeMute( p_intf, &i_volume );
642 p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
646 GtkMenubarDeinterlace ( GtkMenuItem *menuitem,
649 intf_thread_t *p_intf = GtkGetIntf( menuitem );
652 msg_Dbg( p_intf, "GtkMenubarDeinterlace" );
659 GtkPopupDeinterlace (GtkRadioMenuItem *radiomenuitem,
662 intf_thread_t *p_intf = GtkGetIntf( radiomenuitem );
665 msg_Dbg( p_intf, "GtkPopupDeinterlace" );