1 /*****************************************************************************
2 * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: gtk_callbacks.c,v 1.50 2002/07/23 19:28:25 stef 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"
45 #include "gtk_common.h"
49 /*****************************************************************************
50 * Useful function to retrieve p_intf
51 ****************************************************************************/
52 void * __GtkGetIntf( GtkWidget * widget )
56 if( GTK_IS_MENU_ITEM( widget ) )
58 /* Look for a GTK_MENU */
59 while( widget->parent && !GTK_IS_MENU( widget ) )
61 widget = widget->parent;
64 /* Maybe this one has the data */
65 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
71 /* Otherwise, the parent widget has it */
72 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
75 /* We look for the top widget */
76 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
78 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
83 /*****************************************************************************
85 *****************************************************************************/
88 * Main interface callbacks
91 gboolean GtkExit( GtkWidget *widget,
94 intf_thread_t *p_intf = GtkGetIntf( widget );
96 vlc_mutex_lock( &p_intf->change_lock );
97 p_intf->p_vlc->b_die = VLC_TRUE;
98 vlc_mutex_unlock( &p_intf->change_lock );
103 void GtkClose( GtkMenuItem *menuitem,
106 intf_thread_t *p_intf = GtkGetIntf( menuitem );
107 p_intf->b_die = VLC_TRUE;
110 gboolean GtkWindowDelete( GtkWidget *widget,
114 GtkExit( GTK_WIDGET( widget ), user_data );
120 gboolean GtkWindowToggle( GtkWidget *widget,
123 intf_thread_t *p_intf = GtkGetIntf( widget );
125 if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
127 gtk_widget_hide( p_intf->p_sys->p_window);
131 gtk_widget_show( p_intf->p_sys->p_window );
137 gboolean GtkFullscreen( GtkWidget *widget,
140 intf_thread_t *p_intf = GtkGetIntf( widget );
141 vout_thread_t *p_vout;
143 p_vout = vlc_object_find( p_intf->p_sys->p_input,
144 VLC_OBJECT_VOUT, FIND_CHILD );
150 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
151 vlc_object_release( p_vout );
155 void GtkWindowDrag( GtkWidget *widget,
156 GdkDragContext *drag_context,
159 GtkSelectionData *data,
164 intf_thread_t * p_intf = GtkGetIntf( widget );
165 GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
169 /****************************************************************************
171 ****************************************************************************/
173 gboolean GtkSliderRelease( GtkWidget *widget,
174 GdkEventButton *event,
177 intf_thread_t *p_intf = GtkGetIntf( widget );
179 vlc_mutex_lock( &p_intf->change_lock );
180 p_intf->p_sys->b_slider_free = 1;
181 vlc_mutex_unlock( &p_intf->change_lock );
187 gboolean GtkSliderPress( GtkWidget *widget,
188 GdkEventButton *event,
191 intf_thread_t *p_intf = GtkGetIntf( widget );
193 vlc_mutex_lock( &p_intf->change_lock );
194 p_intf->p_sys->b_slider_free = 0;
195 vlc_mutex_unlock( &p_intf->change_lock );
201 /****************************************************************************
203 ****************************************************************************/
205 void GtkTitlePrev( GtkButton * button, gpointer user_data )
207 intf_thread_t * p_intf;
208 input_area_t * p_area;
211 p_intf = GtkGetIntf( button );
213 i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
217 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
218 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
220 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
222 p_intf->p_sys->b_title_update = 1;
223 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
224 GtkSetupMenus( p_intf );
225 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
230 void GtkTitleNext( GtkButton * button, gpointer user_data )
232 intf_thread_t * p_intf;
233 input_area_t * p_area;
236 p_intf = GtkGetIntf( button );
237 i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
239 if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
241 p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
242 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
244 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
246 p_intf->p_sys->b_title_update = 1;
247 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
248 GtkSetupMenus( p_intf );
249 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
254 void GtkChapterPrev( GtkButton * button, gpointer user_data )
256 intf_thread_t * p_intf;
257 input_area_t * p_area;
259 p_intf = GtkGetIntf( button );
260 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
262 if( p_area->i_part > 0 )
265 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
267 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
269 p_intf->p_sys->b_chapter_update = 1;
270 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
271 GtkSetupMenus( p_intf );
272 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
277 void GtkChapterNext( GtkButton * button, gpointer user_data )
279 intf_thread_t * p_intf;
280 input_area_t * p_area;
282 p_intf = GtkGetIntf( button );
283 p_area = p_intf->p_sys->p_input->stream.p_selected_area;
285 if( p_area->i_part < p_area->i_part_nb )
288 input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
290 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
292 p_intf->p_sys->b_chapter_update = 1;
293 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
294 GtkSetupMenus( p_intf );
295 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
299 /****************************************************************************
300 * Network specific items
301 ****************************************************************************/
302 void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
306 i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
307 // msg_Dbg( "intf info: joining channel %d", i_channel );
309 // network_ChannelJoin( i_channel );
312 void GtkChannelGo( GtkButton * button, gpointer user_data )
318 intf_thread_t *p_intf = GtkGetIntf( button );
320 window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
321 spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
322 "network_channel_spinbutton" ) );
324 i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
325 msg_Dbg( p_intf, "joining channel %d", i_channel );
327 vlc_mutex_lock( &p_intf->change_lock );
328 network_ChannelJoin( p_intf, i_channel );
329 vlc_mutex_unlock( &p_intf->change_lock );
331 // input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
335 /****************************************************************************
337 ****************************************************************************/
339 gboolean GtkAboutShow( GtkWidget *widget,
342 intf_thread_t *p_intf = GtkGetIntf( widget );
344 if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
346 p_intf->p_sys->p_about = create_intf_about();
347 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
350 gtk_widget_show( p_intf->p_sys->p_about );
351 gdk_window_raise( p_intf->p_sys->p_about->window );
356 void GtkAboutOk( GtkButton * button, gpointer user_data)
358 intf_thread_t *p_intf = GtkGetIntf( button );
360 gtk_widget_hide( p_intf->p_sys->p_about );
364 /****************************************************************************
366 ****************************************************************************/
368 gboolean GtkJumpShow( GtkWidget *widget,
371 intf_thread_t *p_intf = GtkGetIntf( widget );
373 if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
375 p_intf->p_sys->p_jump = create_intf_jump();
376 gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
380 gtk_widget_show( p_intf->p_sys->p_jump );
381 gdk_window_raise( p_intf->p_sys->p_jump->window );
387 void GtkJumpOk( GtkButton *button,
390 intf_thread_t * p_intf = GtkGetIntf( button );
391 int i_hours, i_minutes, i_seconds;
393 if( p_intf->p_sys->p_input == NULL )
398 #define GET_VALUE( name ) \
399 gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
400 GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
401 i_hours = GET_VALUE( "jump_hour_spinbutton" );
402 i_minutes = GET_VALUE( "jump_minute_spinbutton" );
403 i_seconds = GET_VALUE( "jump_second_spinbutton" );
406 input_Seek( p_intf->p_sys->p_input,
407 i_seconds + 60 * i_minutes + 3600 * i_hours,
408 INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
410 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
414 void GtkJumpCancel( GtkButton *button,
417 gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
420 /****************************************************************************
421 * Callbacks for disc ejection
422 ****************************************************************************/
423 gboolean GtkDiscEject ( GtkWidget *widget, gpointer user_data )
425 char *psz_device = NULL;
429 intf_thread_t *p_intf = GtkGetIntf( widget );
430 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
432 if( p_playlist == NULL )
437 vlc_mutex_lock( &p_playlist->object_lock );
439 if( p_playlist->i_index < 0 )
441 vlc_mutex_unlock( &p_playlist->object_lock );
442 vlc_object_release( p_playlist );
446 psz_current = p_playlist->pp_items[ p_playlist->i_index ]->psz_name;
449 * Get the active input
450 * Determine whether we can eject a media, ie it's a VCD or DVD
451 * If it's neither a VCD nor a DVD, then return
455 * Don't really know if I must lock the stuff here, we're using it read-only
458 if( psz_current != NULL )
460 if( !strncmp(psz_current, "dvd:", 4) )
462 switch( psz_current[4] )
466 psz_device = config_GetPsz( p_intf, "dvd" );
469 /* Omit the first 4 characters */
470 psz_device = strdup( psz_current + 4 );
474 else if( !strncmp(psz_current, "vcd:", 4) )
476 switch( psz_current[4] )
480 psz_device = config_GetPsz( p_intf, "vcd" );
483 /* Omit the first 4 characters */
484 psz_device = strdup( psz_current + 4 );
490 psz_device = strdup( psz_current );
494 vlc_mutex_unlock( &p_playlist->object_lock );
495 vlc_object_release( p_playlist );
497 if( psz_device == NULL )
502 /* Remove what we have after @ */
503 psz_parser = psz_device;
504 for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
506 if( *psz_parser == '@' )
513 /* If there's a stream playing, we aren't allowed to eject ! */
514 if( p_intf->p_sys->p_input == NULL )
516 msg_Dbg( p_intf, "ejecting %s", psz_device );
518 intf_Eject( p_intf, psz_device );
526 /****************************************************************************
528 ****************************************************************************/
530 gboolean GtkMessagesShow( GtkWidget *widget,
533 static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
534 static GdkColormap *colormap;
535 intf_thread_t *p_intf = GtkGetIntf( widget );
537 gtk_widget_show( p_intf->p_sys->p_messages );
538 colormap = gdk_colormap_get_system ();
539 gdk_color_alloc( colormap, &black );
540 gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
543 gdk_window_raise( p_intf->p_sys->p_messages->window );
545 gtk_text_set_point( p_intf->p_sys->p_messages_text,
546 gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
553 GtkMessagesOk (GtkButton *button,
556 intf_thread_t *p_intf = GtkGetIntf( button );
557 gtk_widget_hide( p_intf->p_sys->p_messages );
562 GtkMessagesDelete (GtkWidget *widget,
566 intf_thread_t *p_intf = GtkGetIntf( widget );
567 gtk_widget_hide( p_intf->p_sys->p_messages );
573 GtkOpenNotebookChanged (GtkNotebook *notebook,
574 GtkNotebookPage *page,
578 GtkOpenChanged( GTK_WIDGET( notebook ), user_data );