1 /*****************************************************************************
2 * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001, 2003 VideoLAN
7 * Authors: Sam 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"
50 #define CDDA_MRL "cddax://"
52 #define CDDA_MRL "cdda://"
56 #define VCD_MRL "vcdx://"
58 #define VCD_MRL "vcdx://"
61 /*****************************************************************************
62 * Useful function to retrieve p_intf
63 ****************************************************************************/
64 void * E_(__GtkGetIntf)( GtkWidget * widget )
68 if( GTK_IS_MENU_ITEM( widget ) )
70 /* Look for a GTK_MENU */
71 while( widget->parent && !GTK_IS_MENU( widget ) )
73 widget = widget->parent;
76 /* Maybe this one has the data */
77 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
83 /* Otherwise, the parent widget has it */
84 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
85 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
92 /* We look for the top widget */
93 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
94 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
99 /*****************************************************************************
101 *****************************************************************************/
104 * Main interface callbacks
107 #ifdef MODULE_NAME_IS_gtk
108 # define GTKEXIT GtkExit
110 # define GTKEXIT GnomeExit
113 gboolean GTKEXIT( GtkWidget *widget,
116 intf_thread_t *p_intf = GtkGetIntf( widget );
118 vlc_mutex_lock( &p_intf->change_lock );
119 p_intf->p_vlc->b_die = VLC_TRUE;
120 vlc_mutex_unlock( &p_intf->change_lock );
125 void GtkClose( GtkMenuItem *menuitem,
128 intf_thread_t *p_intf = GtkGetIntf( menuitem );
129 p_intf->b_die = VLC_TRUE;
132 gboolean GtkWindowDelete( GtkWidget *widget,
136 GTKEXIT( GTK_WIDGET( widget ), user_data );
142 gboolean GtkWindowToggle( GtkWidget *widget,
145 intf_thread_t *p_intf = GtkGetIntf( widget );
147 if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
149 gtk_widget_hide( p_intf->p_sys->p_window);
153 gtk_widget_show( p_intf->p_sys->p_window );
159 gboolean GtkFullscreen( GtkWidget *widget,
162 intf_thread_t *p_intf = GtkGetIntf( widget );
163 vout_thread_t *p_vout;
165 if( p_intf->p_sys->p_input == NULL )
170 p_vout = vlc_object_find( p_intf->p_sys->p_input,
171 VLC_OBJECT_VOUT, FIND_CHILD );
177 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
178 vlc_object_release( p_vout );
182 void GtkWindowDrag( GtkWidget *widget,
183 GdkDragContext *drag_context,
186 GtkSelectionData *data,
191 intf_thread_t * p_intf = GtkGetIntf( widget );
192 GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
196 /****************************************************************************
198 ****************************************************************************/
200 gboolean GtkSliderRelease( GtkWidget *widget,
201 GdkEventButton *event,
204 intf_thread_t *p_intf = GtkGetIntf( widget );
206 vlc_mutex_lock( &p_intf->change_lock );
207 p_intf->p_sys->b_slider_free = VLC_TRUE;
208 vlc_mutex_unlock( &p_intf->change_lock );
214 gboolean GtkSliderPress( GtkWidget *widget,
215 GdkEventButton *event,
218 intf_thread_t *p_intf = GtkGetIntf( widget );
220 vlc_mutex_lock( &p_intf->change_lock );
221 p_intf->p_sys->b_slider_free = VLC_FALSE;
222 vlc_mutex_unlock( &p_intf->change_lock );
228 /****************************************************************************
230 ****************************************************************************/
232 void GtkTitlePrev( GtkButton * button, gpointer user_data )
234 intf_thread_t * p_intf = GtkGetIntf( button );
236 var_SetVoid( p_intf->p_sys->p_input, "prev-title" );
238 p_intf->p_sys->b_title_update = VLC_TRUE;
239 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
240 GtkSetupMenus( p_intf );
241 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
245 void GtkTitleNext( GtkButton * button, gpointer user_data )
247 intf_thread_t * p_intf = GtkGetIntf( button );
249 var_SetVoid( p_intf->p_sys->p_input, "next-title" );
251 p_intf->p_sys->b_title_update = VLC_TRUE;
252 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
253 GtkSetupMenus( p_intf );
254 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
258 void GtkChapterPrev( GtkButton * button, gpointer user_data )
260 intf_thread_t * p_intf = GtkGetIntf( button );
262 var_SetVoid( p_intf->p_sys->p_input, "prev-chapter" );
264 p_intf->p_sys->b_chapter_update = VLC_TRUE;
265 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
266 GtkSetupMenus( p_intf );
267 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
271 void GtkChapterNext( GtkButton * button, gpointer user_data )
273 intf_thread_t * p_intf = GtkGetIntf( button );
275 var_SetVoid( p_intf->p_sys->p_input, "next-chapter" );
277 p_intf->p_sys->b_chapter_update = VLC_TRUE;
278 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
279 GtkSetupMenus( p_intf );
280 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
283 /****************************************************************************
285 ****************************************************************************/
287 gboolean GtkAboutShow( GtkWidget *widget,
290 intf_thread_t *p_intf = GtkGetIntf( widget );
292 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
294 p_intf->p_sys->p_about = create_intf_about();
295 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
298 gtk_widget_show( p_intf->p_sys->p_about );
299 gdk_window_raise( p_intf->p_sys->p_about->window );
304 void GtkAboutOk( GtkButton * button, gpointer user_data)
306 intf_thread_t *p_intf = GtkGetIntf( button );
308 gtk_widget_hide( p_intf->p_sys->p_about );
312 /****************************************************************************
314 ****************************************************************************/
316 gboolean GtkJumpShow( GtkWidget *widget,
319 intf_thread_t *p_intf = GtkGetIntf( widget );
321 if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
323 p_intf->p_sys->p_jump = create_intf_jump();
324 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
328 gtk_widget_show( p_intf->p_sys->p_jump );
329 gdk_window_raise( p_intf->p_sys->p_jump->window );
335 void GtkJumpOk( GtkButton *button,
338 intf_thread_t * p_intf = GtkGetIntf( button );
339 int i_hours, i_minutes, i_seconds;
341 if( p_intf->p_sys->p_input == NULL )
346 #define GET_VALUE( name ) \
347 gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
348 GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
349 i_hours = GET_VALUE( "jump_hour_spinbutton" );
350 i_minutes = GET_VALUE( "jump_minute_spinbutton" );
351 i_seconds = GET_VALUE( "jump_second_spinbutton" );
354 var_SetTime( p_intf->p_sys->p_input, "time",
355 (int64_t)(i_seconds+60*i_minutes+3600*i_hours)*I64C(1000000));
357 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
361 void GtkJumpCancel( GtkButton *button,
364 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
367 /****************************************************************************
368 * Callbacks for disc ejection
369 ****************************************************************************/
370 gboolean GtkDiscEject ( GtkWidget *widget, gpointer user_data )
372 char *psz_device = NULL;
376 intf_thread_t *p_intf = GtkGetIntf( widget );
377 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
379 if( p_playlist == NULL )
384 vlc_mutex_lock( &p_playlist->object_lock );
386 if( p_playlist->i_index < 0 )
388 vlc_mutex_unlock( &p_playlist->object_lock );
389 vlc_object_release( p_playlist );
393 psz_current = p_playlist->pp_items[ p_playlist->i_index ]->input.psz_name;
396 * Get the active input
397 * Determine whether we can eject a media, ie it's a VCD or DVD
398 * If it's neither a VCD nor a DVD, then return
402 * Don't really know if I must lock the stuff here, we're using it read-only
405 if( psz_current != NULL )
407 if( !strncmp(psz_current, "dvd://", 4) )
409 switch( psz_current[strlen("dvd://")] )
413 psz_device = config_GetPsz( p_intf, "dvd" );
416 /* Omit the first MRL-selector characters */
417 psz_device = strdup( psz_current + strlen("dvd://" ) );
421 else if( !strncmp(psz_current, "vcd:", strlen("vcd:")) )
423 switch( psz_current[strlen("vcd:")] )
427 psz_device = config_GetPsz( p_intf, VCD_MRL );
430 /* Omit the beginning MRL-selector characters */
431 psz_device = strdup( psz_current + strlen(VCD_MRL) );
435 else if( !strncmp(psz_current, CDDA_MRL, strlen(CDDA_MRL) ) )
437 switch( psz_current[strlen(CDDA_MRL)] )
441 psz_device = config_GetPsz( p_intf, "cd-audio" );
444 /* Omit the beginning MRL-selector characters */
445 psz_device = strdup( psz_current + strlen(CDDA_MRL) );
451 psz_device = strdup( psz_current );
455 vlc_mutex_unlock( &p_playlist->object_lock );
456 vlc_object_release( p_playlist );
458 if( psz_device == NULL )
463 /* Remove what we have after @ */
464 psz_parser = psz_device;
465 for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
467 if( *psz_parser == '@' )
474 /* If there's a stream playing, we aren't allowed to eject ! */
475 if( p_intf->p_sys->p_input == NULL )
477 msg_Dbg( p_intf, "ejecting %s", psz_device );
479 intf_Eject( p_intf, psz_device );
487 /****************************************************************************
489 ****************************************************************************/
491 gboolean GtkMessagesShow( GtkWidget *widget,
494 static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
495 static GdkColormap *colormap;
496 intf_thread_t *p_intf = GtkGetIntf( widget );
498 gtk_widget_show( p_intf->p_sys->p_messages );
499 colormap = gdk_colormap_get_system ();
500 gdk_color_alloc( colormap, &black );
501 gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
504 gdk_window_raise( p_intf->p_sys->p_messages->window );
506 gtk_text_set_point( p_intf->p_sys->p_messages_text,
507 gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
513 GtkMessagesOk (GtkButton *button,
516 intf_thread_t *p_intf = GtkGetIntf( button );
517 gtk_widget_hide( p_intf->p_sys->p_messages );
522 GtkMessagesDelete (GtkWidget *widget,
526 intf_thread_t *p_intf = GtkGetIntf( widget );
527 gtk_widget_hide( p_intf->p_sys->p_messages );
533 GtkOpenNotebookChanged (GtkNotebook *notebook,
534 GtkNotebookPage *page,
538 GtkOpenChanged( GTK_WIDGET( notebook ), user_data );
541 /****************************************************************************
543 ****************************************************************************/
544 void GtkVolumeUp ( GtkMenuItem *menuitem,
547 intf_thread_t *p_intf = GtkGetIntf( menuitem );
548 audio_volume_t i_volume;
550 aout_VolumeUp( p_intf, 1, &i_volume );
551 p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
555 void GtkVolumeDown ( GtkMenuItem *menuitem,
558 intf_thread_t *p_intf = GtkGetIntf( menuitem );
559 audio_volume_t i_volume;
561 aout_VolumeDown( p_intf, 1, &i_volume );
562 p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
566 void GtkVolumeMute ( GtkMenuItem *menuitem,
569 intf_thread_t *p_intf = GtkGetIntf( menuitem );
570 audio_volume_t i_volume;
572 aout_VolumeMute( p_intf, &i_volume );
573 p_intf->p_sys->b_mute = ( i_volume == 0 ) ? 1 : 0;
577 GtkMenubarDeinterlace ( GtkMenuItem *menuitem,
580 intf_thread_t *p_intf = GtkGetIntf( menuitem );
583 msg_Dbg( p_intf, "GtkMenubarDeinterlace" );
588 GtkPopupDeinterlace (GtkRadioMenuItem *radiomenuitem,
591 intf_thread_t *p_intf = GtkGetIntf( radiomenuitem );
594 msg_Dbg( p_intf, "GtkPopupDeinterlace" );