]> git.sesse.net Git - vlc/blob - plugins/gtk/gtk_callbacks.c
* ./include/modules_inner.h: replaced _X with __VLC_SYMBOL because _X was
[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.31 2002/01/09 02:01:14 sam Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *          Stéphane Borel <stef@via.ecp.fr>
9  *          Julien BLACHE <jb@technologeek.org>
10  *      
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.
15  * 
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.
20  *
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  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <sys/types.h>                                              /* off_t */
30 #include <stdlib.h>
31
32 #include <videolan/vlc.h>
33
34 #include <unistd.h>
35
36 #include <gtk/gtk.h>
37
38 #include <string.h>
39
40 #include "stream_control.h"
41 #include "input_ext-intf.h"
42
43 #include "interface.h"
44 #include "intf_playlist.h"
45 #include "intf_eject.h"
46
47 #include "video.h"
48 #include "video_output.h"
49
50 #include "gtk_callbacks.h"
51 #include "gtk_interface.h"
52 #include "gtk_support.h"
53 #include "gtk_common.h"
54
55 #include "netutils.h"
56
57 /*****************************************************************************
58  * Callbacks
59  *****************************************************************************/
60
61 /*
62  * Main interface callbacks
63  */
64
65 gboolean GtkExit( GtkWidget       *widget,
66                   GdkEventButton  *event,
67                   gpointer         user_data )
68 {
69     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
70
71     vlc_mutex_lock( &p_intf->change_lock );
72     p_intf->b_die = 1;
73     vlc_mutex_unlock( &p_intf->change_lock );
74
75     return TRUE;
76 }
77
78 gboolean GtkWindowDelete( GtkWidget       *widget,
79                           GdkEvent        *event,
80                           gpointer         user_data )
81 {
82     GtkExit( GTK_WIDGET( widget ), NULL, user_data );
83
84     return TRUE;
85 }
86
87
88 gboolean GtkWindowToggle( GtkWidget       *widget,
89                           GdkEventButton  *event,
90                           gpointer         user_data )
91 {
92     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
93     
94     if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
95     {
96         gtk_widget_hide( p_intf->p_sys->p_window);
97
98     } 
99     else 
100     {
101         gtk_widget_show( p_intf->p_sys->p_window );
102     }
103
104     return TRUE;
105 }
106
107 gboolean GtkFullscreen( GtkWidget       *widget,
108                         GdkEventButton  *event,
109                         gpointer         user_data)
110 {
111     if( p_vout_bank->i_count )
112     {
113         vlc_mutex_lock( &p_vout_bank->pp_vout[0]->change_lock );
114
115         p_vout_bank->pp_vout[0]->i_changes |= VOUT_FULLSCREEN_CHANGE;
116
117         vlc_mutex_unlock( &p_vout_bank->pp_vout[0]->change_lock );
118
119         return TRUE;
120     }
121     else
122     {
123         return FALSE;
124     }
125 }
126
127 void GtkWindowDrag( GtkWidget       *widget,
128                     GdkDragContext  *drag_context,
129                     gint             x,
130                     gint             y,
131                     GtkSelectionData *data,
132                     guint            info,
133                     guint            time,
134                     gpointer         user_data)
135 {
136     intf_thread_t * p_intf =  GetIntf( GTK_WIDGET(widget), "intf_window" );
137     int end = p_main->p_playlist->i_size;
138     GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
139
140     if( p_input_bank->pp_input[0] != NULL )
141     {
142        /* FIXME: temporary hack */
143        p_input_bank->pp_input[0]->b_eof = 1;
144     }
145      
146     intf_PlaylistJumpto( p_main->p_playlist, end-1 );
147 }
148
149
150 /****************************************************************************
151  * Slider management
152  ****************************************************************************/
153
154 gboolean GtkSliderRelease( GtkWidget       *widget,
155                            GdkEventButton  *event,
156                            gpointer         user_data )
157 {
158     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
159
160     vlc_mutex_lock( &p_intf->change_lock );
161     p_intf->p_sys->b_slider_free = 1;
162     vlc_mutex_unlock( &p_intf->change_lock );
163
164     return FALSE;
165 }
166
167
168 gboolean GtkSliderPress( GtkWidget       *widget,
169                          GdkEventButton  *event,
170                          gpointer         user_data)
171 {
172     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
173
174     vlc_mutex_lock( &p_intf->change_lock );
175     p_intf->p_sys->b_slider_free = 0;
176     vlc_mutex_unlock( &p_intf->change_lock );
177
178     return FALSE;
179 }
180
181
182 /****************************************************************************
183  * DVD specific items
184  ****************************************************************************/
185
186 void GtkTitlePrev( GtkButton * button, gpointer user_data )
187 {
188     intf_thread_t * p_intf;
189     input_area_t *  p_area;
190     int             i_id;
191
192     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
193     i_id = p_input_bank->pp_input[0]->stream.p_selected_area->i_id - 1;
194
195     /* Disallow area 0 since it is used for video_ts.vob */
196     if( i_id > 0 )
197     {
198         p_area = p_input_bank->pp_input[0]->stream.pp_areas[i_id];
199         input_ChangeArea( p_input_bank->pp_input[0], (input_area_t*)p_area );
200
201         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
202
203         p_intf->p_sys->b_title_update = 1;
204         vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
205         GtkSetupMenus( p_intf );
206         vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
207     }
208 }
209
210
211 void GtkTitleNext( GtkButton * button, gpointer user_data )
212 {
213     intf_thread_t * p_intf;
214     input_area_t *  p_area;
215     int             i_id;
216
217     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
218     i_id = p_input_bank->pp_input[0]->stream.p_selected_area->i_id + 1;
219
220     if( i_id < p_input_bank->pp_input[0]->stream.i_area_nb )
221     {
222         p_area = p_input_bank->pp_input[0]->stream.pp_areas[i_id];   
223         input_ChangeArea( p_input_bank->pp_input[0], (input_area_t*)p_area );
224
225         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
226
227         p_intf->p_sys->b_title_update = 1;
228         vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
229         GtkSetupMenus( p_intf );
230         vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
231     }
232
233 }
234
235
236 void GtkChapterPrev( GtkButton * button, gpointer user_data )
237 {
238     intf_thread_t * p_intf;
239     input_area_t *  p_area;
240
241     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
242     p_area = p_input_bank->pp_input[0]->stream.p_selected_area;
243
244     if( p_area->i_part > 0 )
245     {
246         p_area->i_part--;
247         input_ChangeArea( p_input_bank->pp_input[0], (input_area_t*)p_area );
248
249         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
250
251         p_intf->p_sys->b_chapter_update = 1;
252         vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
253         GtkSetupMenus( p_intf );
254         vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
255     }
256 }
257
258
259 void GtkChapterNext( GtkButton * button, gpointer user_data )
260 {
261     intf_thread_t * p_intf;
262     input_area_t *  p_area;
263
264     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
265     p_area = p_input_bank->pp_input[0]->stream.p_selected_area;
266
267     if( p_area->i_part < p_area->i_part_nb )
268     {
269         p_area->i_part++;
270         input_ChangeArea( p_input_bank->pp_input[0], (input_area_t*)p_area );
271
272         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
273
274         p_intf->p_sys->b_chapter_update = 1;
275         vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
276         GtkSetupMenus( p_intf );
277         vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
278     }
279 }
280
281 /****************************************************************************
282  * Network specific items
283  ****************************************************************************/
284 void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
285 {
286     int     i_channel;
287
288     i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
289 //    intf_WarnMsg( 3, "intf info: joining channel %d", i_channel );
290
291 //    network_ChannelJoin( i_channel );
292 }
293
294 void GtkChannelGo( GtkButton * button, gpointer user_data )
295 {
296     GtkWidget *     window;
297     GtkWidget *     spin;
298     int             i_channel;
299
300     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
301
302     window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
303     spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
304                        "network_channel_spinbutton" ) );
305
306     i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
307     intf_WarnMsg( 3, "intf info: joining channel %d", i_channel );
308
309     vlc_mutex_lock( &p_intf->change_lock );
310     if( p_input_bank->pp_input[0] != NULL )
311     {
312         /* end playing item */
313         p_input_bank->pp_input[0]->b_eof = 1;
314
315         /* update playlist */
316         vlc_mutex_lock( &p_main->p_playlist->change_lock );
317
318         p_main->p_playlist->i_index--;
319         p_main->p_playlist->b_stopped = 1;
320
321         vlc_mutex_unlock( &p_main->p_playlist->change_lock );
322
323         /* FIXME: ugly hack to close input and outputs */
324         p_intf->pf_manage( p_intf );
325     }
326
327     network_ChannelJoin( i_channel );
328
329     /* FIXME 2 */
330     p_main->p_playlist->b_stopped = 0;
331     p_intf->pf_manage( p_intf );
332
333     vlc_mutex_unlock( &p_intf->change_lock );
334
335 //    input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
336 }
337
338
339 /****************************************************************************
340  * About box
341  ****************************************************************************/
342
343 gboolean GtkAboutShow( GtkWidget       *widget,
344                        GdkEventButton  *event,
345                        gpointer         user_data)
346 {
347     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
348
349     if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
350     {
351         p_intf->p_sys->p_about = create_intf_about();
352         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
353                              "p_intf", p_intf );
354     }
355     gtk_widget_show( p_intf->p_sys->p_about );
356     gdk_window_raise( p_intf->p_sys->p_about->window );
357
358     return TRUE;
359 }
360
361 void GtkAboutOk( GtkButton * button, gpointer user_data)
362 {
363     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
364
365     gtk_widget_hide( p_intf->p_sys->p_about );
366 }
367
368
369 /****************************************************************************
370  * Jump box
371  ****************************************************************************/
372
373 gboolean GtkJumpShow( GtkWidget       *widget,
374                       GdkEventButton  *event,
375                       gpointer         user_data)
376 {
377     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
378
379     if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
380     {
381         p_intf->p_sys->p_jump = create_intf_jump();
382         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
383                              "p_intf", p_intf );
384     }
385
386     gtk_widget_show( p_intf->p_sys->p_jump );
387     gdk_window_raise( p_intf->p_sys->p_jump->window );
388
389     return FALSE;
390 }
391
392
393 void GtkJumpOk( GtkButton       *button,
394                 gpointer         user_data)
395 {
396     intf_thread_t * p_intf;
397     off_t           i_seek;
398     off_t           i_size;
399     int             i_hours;
400     int             i_minutes;
401     int             i_seconds;
402
403     p_intf = GetIntf( GTK_WIDGET( button ), (char*)user_data );
404
405 #define GET_VALUE( name )                                                   \
406     gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
407         GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
408
409     i_hours   = GET_VALUE( "jump_hour_spinbutton" );
410     i_minutes = GET_VALUE( "jump_minute_spinbutton" );
411     i_seconds = GET_VALUE( "jump_second_spinbutton" );
412
413 #undef GET_VALUE
414
415     i_seconds += 60 *i_minutes + 3600* i_hours;
416
417     vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
418     i_seek = i_seconds * 50 * p_input_bank->pp_input[0]->stream.i_mux_rate;
419     i_size = p_input_bank->pp_input[0]->stream.p_selected_area->i_size;
420     vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
421
422     if( i_seek < i_size )
423     {
424         input_Seek( p_input_bank->pp_input[0], i_seek );
425     }
426     p_main->p_playlist->b_stopped = 0;
427     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
428 }
429
430
431 void GtkJumpCancel( GtkButton       *button,
432                     gpointer         user_data)
433 {
434     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
435 }
436
437
438 /****************************************************************************
439  * Callbacks for menuitems
440  ****************************************************************************/
441 void GtkExitActivate( GtkMenuItem * menuitem, gpointer user_data )
442 {
443     GtkExit( GTK_WIDGET( menuitem ), NULL, user_data );
444 }
445
446
447 void GtkFullscreenActivate( GtkMenuItem * menuitem, gpointer user_data )
448 {
449     GtkFullscreen( GTK_WIDGET( menuitem ), NULL, user_data );
450 }
451
452
453 void GtkWindowToggleActivate( GtkMenuItem * menuitem, gpointer user_data )
454 {
455     GtkWindowToggle( GTK_WIDGET( menuitem ), NULL, user_data );
456 }
457
458
459 void GtkAboutActivate( GtkMenuItem * menuitem, gpointer user_data )
460 {
461     GtkAboutShow( GTK_WIDGET( menuitem ), NULL, user_data );
462 }
463
464
465 void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data )
466 {
467     GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data );
468 }
469
470
471 /****************************************************************************
472  * Callbacks for disc ejection
473  ****************************************************************************/
474 gboolean GtkDiscEject ( GtkWidget *widget, GdkEventButton *event,
475                         gpointer user_data )
476 {
477   char *psz_device = NULL;
478
479   /*
480    * Get the active input
481    * Determine whether we can eject a media, ie it's a VCD or DVD
482    * If it's neither a VCD nor a DVD, then return
483    */
484
485   /*
486    * Don't really know if I must lock the stuff here, we're using it read-only
487    */
488
489   if (p_main->p_playlist->current.psz_name != NULL)
490   {
491       if (strncmp(p_main->p_playlist->current.psz_name, "dvd", 3)
492           || strncmp(p_main->p_playlist->current.psz_name, "vcd", 3))
493       {
494           /* Determine the device name by omitting the first 4 characters */
495           psz_device = strdup((p_main->p_playlist->current.psz_name + 4));
496       }
497   }
498
499   if( psz_device == NULL )
500   {
501       return TRUE;
502   }
503
504   /* If there's a stream playing, we aren't allowed to eject ! */
505   if( p_input_bank->pp_input[0] == NULL )
506   {
507       intf_WarnMsg( 4, "intf: ejecting %s", psz_device );
508
509       intf_Eject( psz_device );
510   }
511
512   free(psz_device);
513   return TRUE;
514 }
515
516 void GtkEjectDiscActivate ( GtkMenuItem *menuitem, gpointer user_data )
517 {
518   fprintf(stderr, "DEBUG: EJECT called from MENU !\n");
519
520   GtkDiscEject( GTK_WIDGET( menuitem ), NULL, user_data );
521 }