]> git.sesse.net Git - vlc/blob - plugins/gtk/gtk_callbacks.c
* Automatic handling of the Channel Server's response in network mode.
[vlc] / plugins / gtk / gtk_callbacks.c
1 /*****************************************************************************
2  * gtk_callbacks.c : Callbacks for the Gtk+ plugin.
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: gtk_callbacks.c,v 1.25 2001/11/12 04:12:37 sam Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *          Stéphane Borel <stef@via.ecp.fr>
9  *      
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29 #include <sys/types.h>                                              /* off_t */
30 #include <stdlib.h>
31
32 #include <gtk/gtk.h>
33
34 #include <string.h>
35
36 #include "config.h"
37 #include "common.h"
38 #include "threads.h"
39 #include "mtime.h"
40
41 #include "stream_control.h"
42 #include "input_ext-intf.h"
43
44 #include "interface.h"
45 #include "intf_playlist.h"
46 #include "intf_msg.h"
47
48 #include "video.h"
49 #include "video_output.h"
50
51 #include "gtk_callbacks.h"
52 #include "gtk_interface.h"
53 #include "gtk_support.h"
54 #include "intf_gtk.h"
55
56 #include "main.h"
57 #include "netutils.h"
58
59 #include "modules_export.h"
60
61 /*****************************************************************************
62  * Callbacks
63  *****************************************************************************/
64
65 /*
66  * Main interface callbacks
67  */
68
69 gboolean GtkExit( GtkWidget       *widget,
70                   GdkEventButton  *event,
71                   gpointer         user_data )
72 {
73     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
74
75     vlc_mutex_lock( &p_intf->change_lock );
76     p_intf->b_die = 1;
77     vlc_mutex_unlock( &p_intf->change_lock );
78
79     return TRUE;
80 }
81
82 gboolean GtkWindowDelete( GtkWidget       *widget,
83                           GdkEvent        *event,
84                           gpointer         user_data )
85 {
86     GtkExit( GTK_WIDGET( widget ), NULL, user_data );
87
88     return TRUE;
89 }
90
91
92 gboolean GtkWindowToggle( GtkWidget       *widget,
93                           GdkEventButton  *event,
94                           gpointer         user_data )
95 {
96     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
97     
98     if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
99     {
100         gtk_widget_hide( p_intf->p_sys->p_window);
101
102     } 
103     else 
104     {
105         gtk_widget_show( p_intf->p_sys->p_window );
106     }
107
108     return TRUE;
109 }
110
111 gboolean GtkFullscreen( GtkWidget       *widget,
112                         GdkEventButton  *event,
113                         gpointer         user_data)
114 {
115     if( p_vout_bank->i_count )
116     {
117         vlc_mutex_lock( &p_vout_bank->pp_vout[0]->change_lock );
118
119         p_vout_bank->pp_vout[0]->i_changes |= VOUT_FULLSCREEN_CHANGE;
120
121         vlc_mutex_unlock( &p_vout_bank->pp_vout[0]->change_lock );
122
123         return TRUE;
124     }
125     else
126     {
127         return FALSE;
128     }
129 }
130
131 void GtkWindowDrag( GtkWidget       *widget,
132                     GdkDragContext  *drag_context,
133                     gint             x,
134                     gint             y,
135                     GtkSelectionData *data,
136                     guint            info,
137                     guint            time,
138                     gpointer         user_data)
139 {
140     intf_thread_t * p_intf =  GetIntf( GTK_WIDGET(widget), "intf_window" );
141     int end = p_main->p_playlist->i_size;
142     GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
143
144     if( p_intf->p_input != NULL )
145     {
146        /* FIXME: temporary hack */
147        p_intf->p_input->b_eof = 1;
148     }
149      
150     intf_PlaylistJumpto( p_main->p_playlist, end-1 );
151 }
152
153
154 /****************************************************************************
155  * Slider management
156  ****************************************************************************/
157
158 gboolean GtkSliderRelease( GtkWidget       *widget,
159                            GdkEventButton  *event,
160                            gpointer         user_data )
161 {
162     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
163
164     vlc_mutex_lock( &p_intf->change_lock );
165     p_intf->p_sys->b_slider_free = 1;
166     vlc_mutex_unlock( &p_intf->change_lock );
167
168     return FALSE;
169 }
170
171
172 gboolean GtkSliderPress( GtkWidget       *widget,
173                          GdkEventButton  *event,
174                          gpointer         user_data)
175 {
176     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
177
178     vlc_mutex_lock( &p_intf->change_lock );
179     p_intf->p_sys->b_slider_free = 0;
180     vlc_mutex_unlock( &p_intf->change_lock );
181
182     return FALSE;
183 }
184
185
186 /****************************************************************************
187  * DVD specific items
188  ****************************************************************************/
189
190 void GtkTitlePrev( GtkButton * button, gpointer user_data )
191 {
192     intf_thread_t * p_intf;
193     input_area_t *  p_area;
194     int             i_id;
195
196     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
197     i_id = p_intf->p_input->stream.p_selected_area->i_id - 1;
198
199     /* Disallow area 0 since it is used for video_ts.vob */
200     if( i_id > 0 )
201     {
202         p_area = p_intf->p_input->stream.pp_areas[i_id];
203         input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
204
205         input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
206
207         p_intf->p_sys->b_title_update = 1;
208         vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
209         GtkSetupMenus( p_intf );
210         vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
211     }
212 }
213
214
215 void GtkTitleNext( GtkButton * button, gpointer user_data )
216 {
217     intf_thread_t * p_intf;
218     input_area_t *  p_area;
219     int             i_id;
220
221     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
222     i_id = p_intf->p_input->stream.p_selected_area->i_id + 1;
223
224     if( i_id < p_intf->p_input->stream.i_area_nb )
225     {
226         p_area = p_intf->p_input->stream.pp_areas[i_id];   
227         input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
228
229         input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
230
231         p_intf->p_sys->b_title_update = 1;
232         vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
233         GtkSetupMenus( p_intf );
234         vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
235     }
236
237 }
238
239
240 void GtkChapterPrev( GtkButton * button, gpointer user_data )
241 {
242     intf_thread_t * p_intf;
243     input_area_t *  p_area;
244
245     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
246     p_area = p_intf->p_input->stream.p_selected_area;
247
248     if( p_area->i_part > 0 )
249     {
250         p_area->i_part--;
251         input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
252
253         input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
254
255         p_intf->p_sys->b_chapter_update = 1;
256         vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
257         GtkSetupMenus( p_intf );
258         vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
259     }
260 }
261
262
263 void GtkChapterNext( GtkButton * button, gpointer user_data )
264 {
265     intf_thread_t * p_intf;
266     input_area_t *  p_area;
267
268     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
269     p_area = p_intf->p_input->stream.p_selected_area;
270
271     if( p_area->i_part < p_area->i_part_nb )
272     {
273         p_area->i_part++;
274         input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
275
276         input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
277
278         p_intf->p_sys->b_chapter_update = 1;
279         vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
280         GtkSetupMenus( p_intf );
281         vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
282     }
283 }
284
285 /****************************************************************************
286  * Network specific items
287  ****************************************************************************/
288 void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
289 {
290     int     i_channel;
291
292     i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
293 //    intf_WarnMsg( 3, "intf info: joining channel %d", i_channel );
294
295 //    network_ChannelJoin( i_channel );
296 }
297
298 void GtkChannelGo( GtkButton * button, gpointer user_data )
299 {
300     GtkWidget *     window;
301     GtkWidget *     spin;
302     int             i_channel;
303
304     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
305
306     window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
307     spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
308                        "network_channel_spinbutton" ) );
309
310     i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
311     intf_WarnMsg( 3, "intf info: joining channel %d", i_channel );
312
313     vlc_mutex_lock( &p_intf->change_lock );
314     if( p_intf->p_input != NULL )
315     {
316         /* end playing item */
317         p_intf->p_input->b_eof = 1;
318
319         /* update playlist */
320         vlc_mutex_lock( &p_main->p_playlist->change_lock );
321
322         p_main->p_playlist->i_index--;
323         p_main->p_playlist->b_stopped = 1;
324
325         vlc_mutex_unlock( &p_main->p_playlist->change_lock );
326
327         /* FIXME: ugly hack to close input and outputs */
328         p_intf->pf_manage( p_intf );
329     }
330
331     network_ChannelJoin( i_channel );
332
333     /* FIXME 2 */
334     p_main->p_playlist->b_stopped = 0;
335     p_intf->pf_manage( p_intf );
336
337     vlc_mutex_unlock( &p_intf->change_lock );
338
339     input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
340 }
341
342
343 /****************************************************************************
344  * About box
345  ****************************************************************************/
346
347 gboolean GtkAboutShow( GtkWidget       *widget,
348                        GdkEventButton  *event,
349                        gpointer         user_data)
350 {
351     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
352
353     if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
354     {
355         p_intf->p_sys->p_about = create_intf_about();
356         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
357                              "p_intf", p_intf );
358     }
359     gtk_widget_show( p_intf->p_sys->p_about );
360     gdk_window_raise( p_intf->p_sys->p_about->window );
361
362     return TRUE;
363 }
364
365 void GtkAboutOk( GtkButton * button, gpointer user_data)
366 {
367     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
368
369     gtk_widget_hide( p_intf->p_sys->p_about );
370 }
371
372
373 /****************************************************************************
374  * Jump box
375  ****************************************************************************/
376
377 gboolean GtkJumpShow( GtkWidget       *widget,
378                       GdkEventButton  *event,
379                       gpointer         user_data)
380 {
381     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
382
383     if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
384     {
385         p_intf->p_sys->p_jump = create_intf_jump();
386         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
387                              "p_intf", p_intf );
388     }
389
390     gtk_widget_show( p_intf->p_sys->p_jump );
391     gdk_window_raise( p_intf->p_sys->p_jump->window );
392
393     return FALSE;
394 }
395
396
397 void GtkJumpOk( GtkButton       *button,
398                 gpointer         user_data)
399 {
400     intf_thread_t * p_intf;
401     off_t           i_seek;
402     off_t           i_size;
403     int             i_hours;
404     int             i_minutes;
405     int             i_seconds;
406
407     p_intf = GetIntf( GTK_WIDGET( button ), (char*)user_data );
408
409 #define GET_VALUE( name )                                                   \
410     gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
411         GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
412
413     i_hours   = GET_VALUE( "jump_hour_spinbutton" );
414     i_minutes = GET_VALUE( "jump_minute_spinbutton" );
415     i_seconds = GET_VALUE( "jump_second_spinbutton" );
416
417 #undef GET_VALUE
418
419     i_seconds += 60 *i_minutes + 3600* i_hours;
420
421     vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
422     i_seek = i_seconds * 50 * p_intf->p_input->stream.i_mux_rate;
423     i_size = p_intf->p_input->stream.p_selected_area->i_size;
424     vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
425
426     if( i_seek < i_size )
427     {
428         input_Seek( p_intf->p_input, i_seek );
429     }
430     p_main->p_playlist->b_stopped = 0;
431     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
432 }
433
434
435 void GtkJumpCancel( GtkButton       *button,
436                     gpointer         user_data)
437 {
438     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
439 }
440
441
442 /****************************************************************************
443  * Callbacks for menuitems
444  ****************************************************************************/
445 void GtkExitActivate( GtkMenuItem * menuitem, gpointer user_data )
446 {
447     GtkExit( GTK_WIDGET( menuitem ), NULL, user_data );
448 }
449
450
451 void GtkFullscreenActivate( GtkMenuItem * menuitem, gpointer user_data )
452 {
453     GtkFullscreen( GTK_WIDGET( menuitem ), NULL, user_data );
454 }
455
456
457 void GtkWindowToggleActivate( GtkMenuItem * menuitem, gpointer user_data )
458 {
459     GtkWindowToggle( GTK_WIDGET( menuitem ), NULL, user_data );
460 }
461
462
463 void GtkAboutActivate( GtkMenuItem * menuitem, gpointer user_data )
464 {
465     GtkAboutShow( GTK_WIDGET( menuitem ), NULL, user_data );
466 }
467
468
469 void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data )
470 {
471     GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data );
472 }
473