1 /*****************************************************************************
2 * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: gtk_callbacks.c,v 1.6 2002/12/06 16:34:07 sam 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 */
42 #include "gtk_callbacks.h"
43 #include "gtk_interface.h"
44 #include "gtk_support.h"
50 /*****************************************************************************
51 * Useful function to retrieve p_intf
52 ****************************************************************************/
53 void * E_(__GtkGetIntf)( GtkWidget * widget )
57 if( GTK_IS_MENU_ITEM( widget ) )
59 /* Look for a GTK_MENU */
60 while( widget->parent && !GTK_IS_MENU( widget ) )
62 widget = widget->parent;
65 /* Maybe this one has the data */
66 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
72 /* Otherwise, the parent widget has it */
73 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
76 /* We look for the top widget */
77 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
79 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
84 /*****************************************************************************
86 *****************************************************************************/
89 * Main interface callbacks
92 #ifdef MODULE_NAME_IS_gtk
93 # define GTKEXIT GtkExit
95 # define GTKEXIT GnomeExit
98 gboolean GTKEXIT( GtkWidget *widget,
101 intf_thread_t *p_intf = GtkGetIntf( widget );
103 vlc_mutex_lock( &p_intf->change_lock );
104 p_intf->p_vlc->b_die = VLC_TRUE;
105 vlc_mutex_unlock( &p_intf->change_lock );
110 void GtkClose( GtkMenuItem *menuitem,
113 intf_thread_t *p_intf = GtkGetIntf( menuitem );
114 p_intf->b_die = VLC_TRUE;
117 gboolean GtkWindowDelete( GtkWidget *widget,
121 GTKEXIT( GTK_WIDGET( widget ), user_data );
127 gboolean GtkWindowToggle( GtkWidget *widget,
130 intf_thread_t *p_intf = GtkGetIntf( widget );
132 if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
134 gtk_widget_hide( p_intf->p_sys->p_window);
138 gtk_widget_show( p_intf->p_sys->p_window );
144 gboolean GtkFullscreen( GtkWidget *widget,
147 intf_thread_t *p_intf = GtkGetIntf( widget );
148 vout_thread_t *p_vout;
150 p_vout = vlc_object_find( p_intf->p_sys->p_input,
151 VLC_OBJECT_VOUT, FIND_CHILD );
157 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
158 vlc_object_release( p_vout );
162 void GtkWindowDrag( GtkWidget *widget,
163 GdkDragContext *drag_context,
166 GtkSelectionData *data,
171 intf_thread_t * p_intf = GtkGetIntf( widget );
172 GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
176 /****************************************************************************
178 ****************************************************************************/
180 gboolean GtkSliderRelease( GtkWidget *widget,
181 GdkEventButton *event,
184 intf_thread_t *p_intf = GtkGetIntf( widget );
186 vlc_mutex_lock( &p_intf->change_lock );
187 p_intf->p_sys->b_slider_free = 1;
188 vlc_mutex_unlock( &p_intf->change_lock );
194 gboolean GtkSliderPress( GtkWidget *widget,
195 GdkEventButton *event,
198 intf_thread_t *p_intf = GtkGetIntf( widget );
200 vlc_mutex_lock( &p_intf->change_lock );
201 p_intf->p_sys->b_slider_free = 0;
202 vlc_mutex_unlock( &p_intf->change_lock );
208 /****************************************************************************
210 ****************************************************************************/
212 void GtkTitlePrev( GtkButton * button, gpointer user_data )
214 intf_thread_t * p_intf;
215 input_area_t * p_area;
218 p_intf = GtkGetIntf( button );
220 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
221 i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
225 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
226 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
227 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
229 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
231 p_intf->p_sys->b_title_update = 1;
232 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
233 GtkSetupMenus( p_intf );
235 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
239 void GtkTitleNext( GtkButton * button, gpointer user_data )
241 intf_thread_t * p_intf;
242 input_area_t * p_area;
245 p_intf = GtkGetIntf( button );
246 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
247 i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
249 if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
251 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
252 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
253 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
255 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
257 p_intf->p_sys->b_title_update = 1;
258 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
259 GtkSetupMenus( p_intf );
261 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
265 void GtkChapterPrev( GtkButton * button, gpointer user_data )
267 intf_thread_t * p_intf;
268 input_area_t * p_area;
270 p_intf = GtkGetIntf( button );
271 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
272 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
274 if( p_area->i_part > 0 )
277 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
278 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
280 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
282 p_intf->p_sys->b_chapter_update = 1;
283 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
284 GtkSetupMenus( p_intf );
286 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
290 void GtkChapterNext( GtkButton * button, gpointer user_data )
292 intf_thread_t * p_intf;
293 input_area_t * p_area;
295 p_intf = GtkGetIntf( button );
296 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
297 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
299 if( p_area->i_part < p_area->i_part_nb )
302 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
303 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
305 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
307 p_intf->p_sys->b_chapter_update = 1;
308 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
309 GtkSetupMenus( p_intf );
311 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
314 /****************************************************************************
315 * Network specific items
316 ****************************************************************************/
317 void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
321 i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
323 msg_Dbg( "intf info: joining channel %d", i_channel );
325 network_ChannelJoin( i_channel );
329 void GtkChannelGo( GtkButton * button, gpointer user_data )
335 intf_thread_t *p_intf = GtkGetIntf( button );
337 window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
338 spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
339 "network_channel_spinbutton" ) );
341 i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
342 msg_Dbg( p_intf, "joining channel %d", i_channel );
344 vlc_mutex_lock( &p_intf->change_lock );
345 network_ChannelJoin( p_intf, i_channel );
346 vlc_mutex_unlock( &p_intf->change_lock );
348 /* input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); */
352 /****************************************************************************
354 ****************************************************************************/
356 gboolean GtkAboutShow( GtkWidget *widget,
359 intf_thread_t *p_intf = GtkGetIntf( widget );
361 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
363 p_intf->p_sys->p_about = create_intf_about();
364 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
367 gtk_widget_show( p_intf->p_sys->p_about );
368 gdk_window_raise( p_intf->p_sys->p_about->window );
373 void GtkAboutOk( GtkButton * button, gpointer user_data)
375 intf_thread_t *p_intf = GtkGetIntf( button );
377 gtk_widget_hide( p_intf->p_sys->p_about );
381 /****************************************************************************
383 ****************************************************************************/
385 gboolean GtkJumpShow( GtkWidget *widget,
388 intf_thread_t *p_intf = GtkGetIntf( widget );
390 if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
392 p_intf->p_sys->p_jump = create_intf_jump();
393 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
397 gtk_widget_show( p_intf->p_sys->p_jump );
398 gdk_window_raise( p_intf->p_sys->p_jump->window );
404 void GtkJumpOk( GtkButton *button,
407 intf_thread_t * p_intf = GtkGetIntf( button );
408 int i_hours, i_minutes, i_seconds;
410 if( p_intf->p_sys->p_input == NULL )
415 #define GET_VALUE( name ) \
416 gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
417 GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
418 i_hours = GET_VALUE( "jump_hour_spinbutton" );
419 i_minutes = GET_VALUE( "jump_minute_spinbutton" );
420 i_seconds = GET_VALUE( "jump_second_spinbutton" );
423 input_Seek( p_intf->p_sys->p_input,
424 i_seconds + 60 * i_minutes + 3600 * i_hours,
425 INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
427 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
431 void GtkJumpCancel( GtkButton *button,
434 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
437 /****************************************************************************
438 * Callbacks for disc ejection
439 ****************************************************************************/
440 gboolean GtkDiscEject ( GtkWidget *widget, gpointer user_data )
442 char *psz_device = NULL;
446 intf_thread_t *p_intf = GtkGetIntf( widget );
447 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
449 if( p_playlist == NULL )
454 vlc_mutex_lock( &p_playlist->object_lock );
456 if( p_playlist->i_index < 0 )
458 vlc_mutex_unlock( &p_playlist->object_lock );
459 vlc_object_release( p_playlist );
463 psz_current = p_playlist->pp_items[ p_playlist->i_index ]->psz_name;
466 * Get the active input
467 * Determine whether we can eject a media, ie it's a VCD or DVD
468 * If it's neither a VCD nor a DVD, then return
472 * Don't really know if I must lock the stuff here, we're using it read-only
475 if( psz_current != NULL )
477 if( !strncmp(psz_current, "dvd:", 4) )
479 switch( psz_current[4] )
483 psz_device = config_GetPsz( p_intf, "dvd" );
486 /* Omit the first 4 characters */
487 psz_device = strdup( psz_current + 4 );
491 else if( !strncmp(psz_current, "vcd:", 4) )
493 switch( psz_current[4] )
497 psz_device = config_GetPsz( p_intf, "vcd" );
500 /* Omit the first 4 characters */
501 psz_device = strdup( psz_current + 4 );
507 psz_device = strdup( psz_current );
511 vlc_mutex_unlock( &p_playlist->object_lock );
512 vlc_object_release( p_playlist );
514 if( psz_device == NULL )
519 /* Remove what we have after @ */
520 psz_parser = psz_device;
521 for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
523 if( *psz_parser == '@' )
530 /* If there's a stream playing, we aren't allowed to eject ! */
531 if( p_intf->p_sys->p_input == NULL )
533 msg_Dbg( p_intf, "ejecting %s", psz_device );
535 intf_Eject( p_intf, psz_device );
543 /****************************************************************************
545 ****************************************************************************/
547 gboolean GtkMessagesShow( GtkWidget *widget,
550 static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
551 static GdkColormap *colormap;
552 intf_thread_t *p_intf = GtkGetIntf( widget );
554 gtk_widget_show( p_intf->p_sys->p_messages );
555 colormap = gdk_colormap_get_system ();
556 gdk_color_alloc( colormap, &black );
557 gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
560 gdk_window_raise( p_intf->p_sys->p_messages->window );
562 gtk_text_set_point( p_intf->p_sys->p_messages_text,
563 gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
570 GtkMessagesOk (GtkButton *button,
573 intf_thread_t *p_intf = GtkGetIntf( button );
574 gtk_widget_hide( p_intf->p_sys->p_messages );
579 GtkMessagesDelete (GtkWidget *widget,
583 intf_thread_t *p_intf = GtkGetIntf( widget );
584 gtk_widget_hide( p_intf->p_sys->p_messages );
590 GtkOpenNotebookChanged (GtkNotebook *notebook,
591 GtkNotebookPage *page,
595 GtkOpenChanged( GTK_WIDGET( notebook ), user_data );