]> git.sesse.net Git - vlc/blob - plugins/gtk/gtk_callbacks.c
* ALL: the first libvlc commit.
[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.40 2002/06/01 12:31:59 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     if( p_intf->p_sys->p_input != NULL )
307     {
308         /* end playing item */
309         p_intf->p_sys->p_input->b_eof = 1;
310
311 #if 0 /* PLAYLIST TARASS */
312         /* update playlist */
313         vlc_mutex_lock( &p_intf->p_vlc->p_playlist->change_lock );
314
315         p_intf->p_vlc->p_playlist->i_index--;
316         p_intf->p_vlc->p_playlist->b_stopped = 1;
317
318         vlc_mutex_unlock( &p_intf->p_vlc->p_playlist->change_lock );
319 #endif
320     }
321
322     network_ChannelJoin( p_intf->p_this, i_channel );
323
324     /* FIXME 2 */
325 #if 0 /* PLAYLIST TARASS */
326     p_intf->p_vlc->p_playlist->b_stopped = 0;
327 #endif
328
329     vlc_mutex_unlock( &p_intf->change_lock );
330
331 //    input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
332 }
333
334
335 /****************************************************************************
336  * About box
337  ****************************************************************************/
338
339 gboolean GtkAboutShow( GtkWidget       *widget,
340                        GdkEventButton  *event,
341                        gpointer         user_data)
342 {
343     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
344
345     if( !GTK_IS_WIDGET( p_intf->p_sys->p_about ) )
346     {
347         p_intf->p_sys->p_about = create_intf_about();
348         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_about ),
349                              "p_intf", p_intf );
350     }
351     gtk_widget_show( p_intf->p_sys->p_about );
352     gdk_window_raise( p_intf->p_sys->p_about->window );
353
354     return TRUE;
355 }
356
357 void GtkAboutOk( GtkButton * button, gpointer user_data)
358 {
359     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
360
361     gtk_widget_hide( p_intf->p_sys->p_about );
362 }
363
364
365 /****************************************************************************
366  * Jump box
367  ****************************************************************************/
368
369 gboolean GtkJumpShow( GtkWidget       *widget,
370                       GdkEventButton  *event,
371                       gpointer         user_data)
372 {
373     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
374
375     if( !GTK_IS_WIDGET( p_intf->p_sys->p_jump ) )
376     {
377         p_intf->p_sys->p_jump = create_intf_jump();
378         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_jump ),
379                              "p_intf", p_intf );
380     }
381
382     gtk_widget_show( p_intf->p_sys->p_jump );
383     gdk_window_raise( p_intf->p_sys->p_jump->window );
384
385     return FALSE;
386 }
387
388
389 void GtkJumpOk( GtkButton       *button,
390                 gpointer         user_data)
391 {
392     intf_thread_t * p_intf = GetIntf( GTK_WIDGET( button ), (char*)user_data );
393     int i_hours, i_minutes, i_seconds;
394
395 #define GET_VALUE( name )                                                   \
396     gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( gtk_object_get_data( \
397         GTK_OBJECT( p_intf->p_sys->p_jump ), name ) ) )
398     i_hours   = GET_VALUE( "jump_hour_spinbutton" );
399     i_minutes = GET_VALUE( "jump_minute_spinbutton" );
400     i_seconds = GET_VALUE( "jump_second_spinbutton" );
401 #undef GET_VALUE
402
403     input_Seek( p_intf, i_seconds + 60 * i_minutes + 3600 * i_hours,
404                         INPUT_SEEK_SECONDS | INPUT_SEEK_SET );
405
406 #if 0 /* PLAYLIST TARASS */
407     p_intf->p_vlc->p_playlist->b_stopped = 0;
408 #endif
409     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
410 }
411
412
413 void GtkJumpCancel( GtkButton       *button,
414                     gpointer         user_data)
415 {
416     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
417 }
418
419
420 /****************************************************************************
421  * Callbacks for menuitems
422  ****************************************************************************/
423 void GtkExitActivate( GtkMenuItem * menuitem, gpointer user_data )
424 {
425     GtkExit( GTK_WIDGET( menuitem ), NULL, user_data );
426 }
427
428
429 void GtkFullscreenActivate( GtkMenuItem * menuitem, gpointer user_data )
430 {
431     GtkFullscreen( GTK_WIDGET( menuitem ), NULL, user_data );
432 }
433
434
435 void GtkWindowToggleActivate( GtkMenuItem * menuitem, gpointer user_data )
436 {
437     GtkWindowToggle( GTK_WIDGET( menuitem ), NULL, user_data );
438 }
439
440
441 void GtkAboutActivate( GtkMenuItem * menuitem, gpointer user_data )
442 {
443     GtkAboutShow( GTK_WIDGET( menuitem ), NULL, user_data );
444 }
445
446
447 void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data )
448 {
449     GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data );
450 }
451
452
453 void GtkMessagesActivate( GtkMenuItem * menuitem, gpointer user_data )
454 {
455     GtkMessagesShow( GTK_WIDGET( menuitem ), NULL, user_data );
456 }
457
458
459 /****************************************************************************
460  * Callbacks for disc ejection
461  ****************************************************************************/
462 gboolean GtkDiscEject ( GtkWidget *widget, GdkEventButton *event,
463                         gpointer user_data )
464 {
465 #if 0 /* PLAYLIST TARASS */
466     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
467
468     char *psz_device = NULL;
469     char *psz_parser;
470     char *psz_current = p_intf->p_vlc->p_playlist->current.psz_name;
471
472     /*
473      * Get the active input
474      * Determine whether we can eject a media, ie it's a VCD or DVD
475      * If it's neither a VCD nor a DVD, then return
476      */
477
478     /*
479      * Don't really know if I must lock the stuff here, we're using it read-only
480      */
481
482     if( psz_current != NULL )
483     {
484         if( !strncmp(psz_current, "dvd:", 4) )
485         {
486             switch( psz_current[4] )
487             {
488             case '\0':
489             case '@':
490                 psz_device = config_GetPsz( p_intf, "dvd" );
491                 break;
492             default:
493                 /* Omit the first 4 characters */
494                 psz_device = strdup( psz_current + 4 );
495                 break;
496             }
497         }
498         else if( !strncmp(psz_current, "vcd:", 4) )
499         {
500             switch( psz_current[4] )
501             {
502             case '\0':
503             case '@':
504                 psz_device = config_GetPsz( p_intf, "vcd" );
505                 break;
506             default:
507                 /* Omit the first 4 characters */
508                 psz_device = strdup( psz_current + 4 );
509                 break;
510             }
511         }
512         else
513         {
514             psz_device = strdup( psz_current );
515         }
516     }
517
518     if( psz_device == NULL )
519     {
520         return TRUE;
521     }
522
523     /* Remove what we have after @ */
524     psz_parser = psz_device;
525     for( psz_parser = psz_device ; *psz_parser ; psz_parser++ )
526     {
527         if( *psz_parser == '@' )
528         {
529             *psz_parser = '\0';
530             break;
531         }
532     }
533
534     /* If there's a stream playing, we aren't allowed to eject ! */
535     if( p_intf->p_sys->p_input == NULL )
536     {
537         msg_Dbg( p_intf, "ejecting %s", psz_device );
538
539         intf_Eject( p_intf->p_this, psz_device );
540     }
541
542     free(psz_device);
543 #endif
544     return TRUE;
545 }
546
547 void GtkEjectDiscActivate ( GtkMenuItem *menuitem, gpointer user_data )
548 {
549     GtkDiscEject( GTK_WIDGET( menuitem ), NULL, user_data );
550 }
551
552 /****************************************************************************
553  * Messages window
554  ****************************************************************************/
555
556 gboolean GtkMessagesShow( GtkWidget       *widget,
557                           GdkEventButton  *event,
558                           gpointer         user_data)
559 {
560     static GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
561     static GdkColormap *colormap;
562     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
563
564     gtk_widget_show( p_intf->p_sys->p_messages );
565     colormap = gdk_colormap_get_system ();
566     gdk_color_alloc( colormap, &black );
567     gdk_window_set_background( p_intf->p_sys->p_messages_text->text_area,
568                                &black );
569
570     gdk_window_raise( p_intf->p_sys->p_messages->window );
571
572     gtk_text_set_point( p_intf->p_sys->p_messages_text,
573                     gtk_text_get_length( p_intf->p_sys->p_messages_text ) );
574
575     return TRUE;
576 }
577
578
579 void
580 GtkMessagesOk                          (GtkButton       *button,
581                                         gpointer         user_data)
582 {
583     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(button), (char*)user_data );
584     gtk_widget_hide( p_intf->p_sys->p_messages );
585 }
586
587
588 gboolean
589 GtkMessagesDelete                      (GtkWidget       *widget,
590                                         GdkEvent        *event,
591                                         gpointer         user_data)
592 {
593     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
594     gtk_widget_hide( p_intf->p_sys->p_messages );
595     return TRUE;
596 }
597