]> git.sesse.net Git - vlc/blob - plugins/gtk/gtk_callbacks.c
00359d459e4f6fdd86b8896c70c136b6e0e60f1a
[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.42 2002/06/04 00:11:12 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 <vlc/vlc.h>
33 #include <vlc/intf.h>
34 #include <vlc/vout.h>
35
36 #include <unistd.h>
37
38 #include <gtk/gtk.h>
39
40 #include <string.h>
41
42 #include "gtk_callbacks.h"
43 #include "gtk_interface.h"
44 #include "gtk_support.h"
45 #include "gtk_common.h"
46
47 #include "netutils.h"
48
49 /*****************************************************************************
50  * Callbacks
51  *****************************************************************************/
52
53 /*
54  * Main interface callbacks
55  */
56
57 gboolean GtkExit( GtkWidget       *widget,
58                   GdkEventButton  *event,
59                   gpointer         user_data )
60 {
61     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
62
63     vlc_mutex_lock( &p_intf->change_lock );
64     p_intf->p_vlc->b_die = 1;
65     vlc_mutex_unlock( &p_intf->change_lock );
66
67     return TRUE;
68 }
69
70 gboolean GtkWindowDelete( GtkWidget       *widget,
71                           GdkEvent        *event,
72                           gpointer         user_data )
73 {
74     GtkExit( GTK_WIDGET( widget ), NULL, user_data );
75
76     return TRUE;
77 }
78
79
80 gboolean GtkWindowToggle( GtkWidget       *widget,
81                           GdkEventButton  *event,
82                           gpointer         user_data )
83 {
84     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
85     
86     if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_window) )
87     {
88         gtk_widget_hide( p_intf->p_sys->p_window);
89
90     } 
91     else 
92     {
93         gtk_widget_show( p_intf->p_sys->p_window );
94     }
95
96     return TRUE;
97 }
98
99 gboolean GtkFullscreen( GtkWidget       *widget,
100                         GdkEventButton  *event,
101                         gpointer         user_data)
102 {
103     intf_thread_t * p_intf =  GetIntf( GTK_WIDGET(widget), "intf_window" );
104     vout_thread_t *p_vout;
105
106     p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_CHILD );
107
108     if( p_vout )
109     {
110         p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
111         vlc_object_release( p_vout );
112         return TRUE;
113     }
114
115     return FALSE;
116 }
117
118 void GtkWindowDrag( GtkWidget       *widget,
119                     GdkDragContext  *drag_context,
120                     gint             x,
121                     gint             y,
122                     GtkSelectionData *data,
123                     guint            info,
124                     guint            time,
125                     gpointer         user_data)
126 {
127 #if 0 /* PLAYLIST TARASS */
128     intf_thread_t * p_intf =  GetIntf( GTK_WIDGET(widget), "intf_window" );
129     int end = p_intf->p_vlc->p_playlist->i_size;
130     GtkDropDataReceived( p_intf, data, info, PLAYLIST_END );
131
132     if( p_intf->p_sys->p_input != NULL )
133     {
134         /* FIXME: temporary hack */
135         p_intf->p_sys->p_input->b_eof = 1;
136     }
137      
138     intf_PlaylistJumpto( p_intf->p_vlc->p_playlist, end-1 );
139 #endif
140 }
141
142
143 /****************************************************************************
144  * Slider management
145  ****************************************************************************/
146
147 gboolean GtkSliderRelease( GtkWidget       *widget,
148                            GdkEventButton  *event,
149                            gpointer         user_data )
150 {
151     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
152
153     vlc_mutex_lock( &p_intf->change_lock );
154     p_intf->p_sys->b_slider_free = 1;
155     vlc_mutex_unlock( &p_intf->change_lock );
156
157     return FALSE;
158 }
159
160
161 gboolean GtkSliderPress( GtkWidget       *widget,
162                          GdkEventButton  *event,
163                          gpointer         user_data)
164 {
165     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), "intf_window" );
166
167     vlc_mutex_lock( &p_intf->change_lock );
168     p_intf->p_sys->b_slider_free = 0;
169     vlc_mutex_unlock( &p_intf->change_lock );
170
171     return FALSE;
172 }
173
174
175 /****************************************************************************
176  * DVD specific items
177  ****************************************************************************/
178
179 void GtkTitlePrev( GtkButton * button, gpointer user_data )
180 {
181     intf_thread_t *  p_intf;
182     input_area_t *   p_area;
183     int              i_id;
184
185     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
186
187     i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
188
189     /* Disallow area 0 since it is used for video_ts.vob */
190     if( i_id > 0 )
191     {
192         p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
193         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
194
195         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
196
197         p_intf->p_sys->b_title_update = 1;
198         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
199         GtkSetupMenus( p_intf );
200         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
201     }
202
203     vlc_object_release( p_intf->p_sys->p_input );
204 }
205
206
207 void GtkTitleNext( GtkButton * button, gpointer user_data )
208 {
209     intf_thread_t * p_intf;
210     input_area_t *  p_area;
211     int             i_id;
212
213     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
214     i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
215
216     if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
217     {
218         p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];   
219         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
220
221         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
222
223         p_intf->p_sys->b_title_update = 1;
224         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
225         GtkSetupMenus( p_intf );
226         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
227     }
228
229 }
230
231
232 void GtkChapterPrev( GtkButton * button, gpointer user_data )
233 {
234     intf_thread_t * p_intf;
235     input_area_t *  p_area;
236
237     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
238     p_area = p_intf->p_sys->p_input->stream.p_selected_area;
239
240     if( p_area->i_part > 0 )
241     {
242         p_area->i_part--;
243         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
244
245         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
246
247         p_intf->p_sys->b_chapter_update = 1;
248         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
249         GtkSetupMenus( p_intf );
250         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
251     }
252 }
253
254
255 void GtkChapterNext( GtkButton * button, gpointer user_data )
256 {
257     intf_thread_t * p_intf;
258     input_area_t *  p_area;
259
260     p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
261     p_area = p_intf->p_sys->p_input->stream.p_selected_area;
262
263     if( p_area->i_part < p_area->i_part_nb )
264     {
265         p_area->i_part++;
266         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
267
268         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
269
270         p_intf->p_sys->b_chapter_update = 1;
271         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
272         GtkSetupMenus( p_intf );
273         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
274     }
275 }
276
277 /****************************************************************************
278  * Network specific items
279  ****************************************************************************/
280 void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
281 {
282     int     i_channel;
283
284     i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
285 //    msg_Dbg( "intf info: joining channel %d", i_channel );
286
287 //    network_ChannelJoin( i_channel );
288 }
289
290 void GtkChannelGo( GtkButton * button, gpointer user_data )
291 {
292     GtkWidget *     window;
293     GtkWidget *     spin;
294     int             i_channel;
295
296     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
297
298     window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
299     spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
300                        "network_channel_spinbutton" ) );
301
302     i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
303     msg_Dbg( p_intf, "joining channel %d", i_channel );
304
305     vlc_mutex_lock( &p_intf->change_lock );
306     network_ChannelJoin( p_intf, i_channel );
307     vlc_mutex_unlock( &p_intf->change_lock );
308
309 //    input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
310 }
311
312
313 /****************************************************************************
314  * About box
315  ****************************************************************************/
316
317 gboolean GtkAboutShow( GtkWidget       *widget,
318                        GdkEventButton  *event,
319                        gpointer         user_data)
320 {
321     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
322
323     if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
324     {
325         p_intf->p_sys->p_about = create_intf_about();
326         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
327                              "p_intf", p_intf );
328     }
329     gtk_widget_show( p_intf->p_sys->p_about );
330     gdk_window_raise( p_intf->p_sys->p_about->window );
331
332     return TRUE;
333 }
334
335 void GtkAboutOk( GtkButton * button, gpointer user_data)
336 {
337     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
338
339     gtk_widget_hide( p_intf->p_sys->p_about );
340 }
341
342
343 /****************************************************************************
344  * Jump box
345  ****************************************************************************/
346
347 gboolean GtkJumpShow( 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_jump ) )
354     {
355         p_intf->p_sys->p_jump = create_intf_jump();
356         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
357                              "p_intf", p_intf );
358     }
359
360     gtk_widget_show( p_intf->p_sys->p_jump );
361     gdk_window_raise( p_intf->p_sys->p_jump->window );
362
363     return FALSE;
364 }
365
366
367 void GtkJumpOk( GtkButton       *button,
368                 gpointer         user_data)
369 {
370     intf_thread_t * p_intf = GetIntf( GTK_WIDGET( button ), (char*)user_data );
371     int i_hours, i_minutes, i_seconds;
372
373 #define GET_VALUE( name )                                                   \
374     gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
375         GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
376     i_hours   = GET_VALUE( "jump_hour_spinbutton" );
377     i_minutes = GET_VALUE( "jump_minute_spinbutton" );
378     i_seconds = GET_VALUE( "jump_second_spinbutton" );
379 #undef GET_VALUE
380
381     input_Seek( p_intf, i_seconds + 60 * i_minutes + 3600 * i_hours,
382                         INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
383
384 #if 0 /* PLAYLIST TARASS */
385     p_intf->p_vlc->p_playlist->b_stopped = 0;
386 #endif
387     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
388 }
389
390
391 void GtkJumpCancel( GtkButton       *button,
392                     gpointer         user_data)
393 {
394     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
395 }
396
397
398 /****************************************************************************
399  * Callbacks for menuitems
400  ****************************************************************************/
401 void GtkExitActivate( GtkMenuItem * menuitem, gpointer user_data )
402 {
403     GtkExit( GTK_WIDGET( menuitem ), NULL, user_data );
404 }
405
406
407 void GtkFullscreenActivate( GtkMenuItem * menuitem, gpointer user_data )
408 {
409     GtkFullscreen( GTK_WIDGET( menuitem ), NULL, user_data );
410 }
411
412
413 void GtkWindowToggleActivate( GtkMenuItem * menuitem, gpointer user_data )
414 {
415     GtkWindowToggle( GTK_WIDGET( menuitem ), NULL, user_data );
416 }
417
418
419 void GtkAboutActivate( GtkMenuItem * menuitem, gpointer user_data )
420 {
421     GtkAboutShow( GTK_WIDGET( menuitem ), NULL, user_data );
422 }
423
424
425 void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data )
426 {
427     GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data );
428 }
429
430
431 void GtkMessagesActivate( GtkMenuItem * menuitem, gpointer user_data )
432 {
433     GtkMessagesShow( GTK_WIDGET( menuitem ), NULL, user_data );
434 }
435
436
437 /****************************************************************************
438  * Callbacks for disc ejection
439  ****************************************************************************/
440 gboolean GtkDiscEject ( GtkWidget *widget, GdkEventButton *event,
441                         gpointer user_data )
442 {
443 #if 0 /* PLAYLIST TARASS */
444     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
445
446     char *psz_device = NULL;
447     char *psz_parser;
448     char *psz_current = p_intf->p_vlc->p_playlist->current.psz_name;
449
450     /*
451      * Get the active input
452      * Determine whether we can eject a media, ie it's a VCD or DVD
453      * If it's neither a VCD nor a DVD, then return
454      */
455
456     /*
457      * Don't really know if I must lock the stuff here, we're using it read-only
458      */
459
460     if( psz_current != NULL )
461     {
462         if( !strncmp(psz_current, "dvd:", 4) )
463         {
464             switch( psz_current[4] )
465             {
466             case '\0':
467             case '@':
468                 psz_device = config_GetPsz( p_intf, "dvd" );
469                 break;
470             default:
471                 /* Omit the first 4 characters */
472                 psz_device = strdup( psz_current + 4 );
473                 break;
474             }
475         }
476         else if( !strncmp(psz_current, "vcd:", 4) )
477         {
478             switch( psz_current[4] )
479             {
480             case '\0':
481             case '@':
482                 psz_device = config_GetPsz( p_intf, "vcd" );
483                 break;
484             default:
485                 /* Omit the first 4 characters */
486                 psz_device = strdup( psz_current + 4 );
487                 break;
488             }
489         }
490         else
491         {
492             psz_device = strdup( psz_current );
493         }
494     }
495
496     if( psz_device == NULL )
497     {
498         return TRUE;
499     }
500
501     /* Remove what we have after @ */
502     psz_parser = psz_device;
503     for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
504     {
505         if( *psz_parser == '@' )
506         {
507             *psz_parser = '\0';
508             break;
509         }
510     }
511
512     /* If there's a stream playing, we aren't allowed to eject ! */
513     if( p_intf->p_sys->p_input == NULL )
514     {
515         msg_Dbg( p_intf, "ejecting %s", psz_device );
516
517         intf_Eject( p_intf, psz_device );
518     }
519
520     free(psz_device);
521 #endif
522     return TRUE;
523 }
524
525 void GtkEjectDiscActivate ( GtkMenuItem *menuitem, gpointer user_data )
526 {
527     GtkDiscEject( GTK_WIDGET( menuitem ), NULL, user_data );
528 }
529
530 /****************************************************************************
531  * Messages window
532  ****************************************************************************/
533
534 gboolean GtkMessagesShow( GtkWidget       *widget,
535                           GdkEventButton  *event,
536                           gpointer         user_data)
537 {
538     static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
539     static GdkColormap *colormap;
540     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
541
542     gtk_widget_show( p_intf->p_sys->p_messages );
543     colormap = gdk_colormap_get_system ();
544     gdk_color_alloc( colormap, &black );
545     gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
546                                &black );
547
548     gdk_window_raise( p_intf->p_sys->p_messages->window );
549
550     gtk_text_set_point( p_intf->p_sys->p_messages_text,
551                     gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
552
553     return TRUE;
554 }
555
556
557 void
558 GtkMessagesOk                          (GtkButton       *button,
559                                         gpointer         user_data)
560 {
561     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
562     gtk_widget_hide( p_intf->p_sys->p_messages );
563 }
564
565
566 gboolean
567 GtkMessagesDelete                      (GtkWidget       *widget,
568                                         GdkEvent        *event,
569                                         gpointer         user_data)
570 {
571     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
572     gtk_widget_hide( p_intf->p_sys->p_messages );
573     return TRUE;
574 }
575