]> git.sesse.net Git - vlc/blob - plugins/gtk/gtk_open.c
* Fixed a bug that made vlc segfault when choosing a program, change to
[vlc] / plugins / gtk / gtk_open.c
1 /*****************************************************************************
2  * gtk_open.c : functions to handle file/disc/network open widgets.
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: gtk_open.c,v 1.20 2002/03/25 02:06:24 jobi 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 <sys/types.h>                                              /* off_t */
29 #include <stdlib.h>
30
31 #include <videolan/vlc.h>
32
33 #ifdef MODULE_NAME_IS_gnome
34 #   include <gnome.h>
35 #else
36 #   include <gtk/gtk.h>
37 #endif
38
39 #include <string.h>
40
41 #include "stream_control.h"
42 #include "input_ext-intf.h"
43
44 #include "interface.h"
45 #include "intf_playlist.h"
46
47 #include "gtk_callbacks.h"
48 #include "gtk_interface.h"
49 #include "gtk_support.h"
50 #include "gtk_playlist.h"
51 #include "gtk_common.h"
52
53 #include "netutils.h"
54
55 /*****************************************************************************
56  * Fileopen callbacks
57  *****************************************************************************
58  * The following callbacks are related to the file requester.
59  *****************************************************************************/
60 gboolean GtkFileOpenShow( GtkWidget       *widget,
61                           GdkEventButton  *event,
62                           gpointer         user_data )
63 {
64     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
65
66     /* If we have never used the file selector, open it */
67     if( !GTK_IS_WIDGET( p_intf->p_sys->p_fileopen ) )
68     {
69         char *psz_path;
70
71         p_intf->p_sys->p_fileopen = create_intf_fileopen();
72         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
73                              "p_intf", p_intf );
74
75         if( (psz_path = config_GetPszVariable( "search_path" )) )
76             gtk_file_selection_set_filename( GTK_FILE_SELECTION(
77                 p_intf->p_sys->p_fileopen ), psz_path );
78         if( psz_path ) free( psz_path );
79     }
80
81     gtk_widget_show( p_intf->p_sys->p_fileopen );
82     gdk_window_raise( p_intf->p_sys->p_fileopen->window );
83
84     return TRUE;
85 }
86
87
88 void GtkFileOpenCancel( GtkButton * button, gpointer user_data )
89 {
90     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
91 }
92
93 void GtkFileOpenOk( GtkButton * button, gpointer user_data )
94 {
95     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_fileopen" );
96     GtkCList *      p_playlist_clist;
97     GtkWidget *     p_filesel;
98     gchar *         psz_filename;
99     int             i_end = p_main->p_playlist->i_size;
100
101     /* hide the file selector */
102     p_filesel = gtk_widget_get_toplevel( GTK_WIDGET(button) );
103     gtk_widget_hide( p_filesel );
104
105     /* add the new file to the interface playlist */
106     psz_filename =
107         gtk_file_selection_get_filename( GTK_FILE_SELECTION( p_filesel ) );
108     intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_filename );
109
110     /* catch the GTK CList */
111     p_playlist_clist = GTK_CLIST( gtk_object_get_data(
112         GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
113     /* update the plugin display */
114     GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
115
116     /* end current item, select added item  */
117     if( p_input_bank->pp_input[0] != NULL )
118     {
119         p_input_bank->pp_input[0]->b_eof = 1;
120     }
121
122     intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
123 }
124
125 /*****************************************************************************
126  * Open disc callbacks
127  *****************************************************************************
128  * The following callbacks are related to the disc manager.
129  *****************************************************************************/
130 gboolean GtkDiscOpenShow( GtkWidget       *widget,
131                           GdkEventButton  *event,
132                           gpointer         user_data)
133 {
134     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
135
136     if( !GTK_IS_WIDGET( p_intf->p_sys->p_disc ) )
137     {
138         p_intf->p_sys->p_disc = create_intf_disc();
139         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_disc ),
140                              "p_intf", p_intf );
141     }
142
143     gtk_widget_show( p_intf->p_sys->p_disc );
144     gdk_window_raise( p_intf->p_sys->p_disc->window );
145
146     return TRUE;
147 }
148
149
150 void GtkDiscOpenDvd( GtkToggleButton * togglebutton, gpointer user_data )
151 {
152     if( togglebutton->active )
153     {
154         char *psz_dvd_device;
155
156         if( (psz_dvd_device = config_GetPszVariable( "dvd_device" )) )
157             gtk_entry_set_text(
158                 GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
159                                           "disc_name" ) ), psz_dvd_device );
160         if( psz_dvd_device ) free( psz_dvd_device );
161     }
162 }
163
164 void GtkDiscOpenVcd( GtkToggleButton * togglebutton, gpointer user_data )
165 {
166     if( togglebutton->active )
167     {
168         char *psz_vcd_device;
169
170         if( (psz_vcd_device = config_GetPszVariable( "vcd_device" )) )
171             gtk_entry_set_text(
172                 GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
173                                           "disc_name" ) ), psz_vcd_device );
174         if( psz_vcd_device ) free( psz_vcd_device );
175     }
176 }
177
178 void GtkDiscOpenOk( GtkButton * button, gpointer user_data )
179 {
180     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_disc" );
181     GtkCList *      p_playlist_clist;
182     char *          psz_device, *psz_source, *psz_method;
183     int             i_end = p_main->p_playlist->i_size;
184     int             i_title, i_chapter;
185
186     gtk_widget_hide( p_intf->p_sys->p_disc );
187     psz_device = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
188                                          GTK_WIDGET(button), "disc_name" ) ) );
189
190     /* Check which method was activated */
191     if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
192                                           "disc_dvd" ) )->active )
193     {
194         psz_method = "dvd";
195     }
196     else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
197                                                "disc_vcd" ) )->active )
198     {
199         psz_method = "vcd";
200     }
201     else
202     {
203         intf_ErrMsg( "intf error: unknown disc type toggle button position" );
204         return;
205     }
206     
207     /* Select title and chapter */
208     i_title = gtk_spin_button_get_value_as_int(
209                               GTK_SPIN_BUTTON( lookup_widget(
210                                   GTK_WIDGET(button), "disc_title" ) ) );
211
212     i_chapter = gtk_spin_button_get_value_as_int(
213                               GTK_SPIN_BUTTON( lookup_widget(
214                                   GTK_WIDGET(button), "disc_chapter" ) ) );
215     
216     /* "dvd:foo" has size 5 + strlen(foo) */
217     psz_source = malloc( 3 /* "dvd" */ + 1 /* ":" */
218                            + strlen( psz_device ) + 2 /* @, */
219                            + 4 /* i_title & i_chapter < 100 */ + 1 /* "\0" */ );
220     if( psz_source == NULL )
221     {
222         return;
223     }
224
225     /* Build source name and add it to playlist */
226     sprintf( psz_source, "%s:%s@%d,%d",
227              psz_method, psz_device, i_title, i_chapter );
228     intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
229     free( psz_source );
230
231     /* catch the GTK CList */
232     p_playlist_clist = GTK_CLIST( gtk_object_get_data(
233         GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
234
235     /* update the display */
236     GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
237
238     /* stop current item, select added item */
239     if( p_input_bank->pp_input[0] != NULL )
240     {
241         p_input_bank->pp_input[0]->b_eof = 1;
242     }
243
244     intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
245 }
246
247
248 void GtkDiscOpenCancel( GtkButton * button, gpointer user_data )
249 {
250     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
251 }
252
253
254 /*****************************************************************************
255  * Network stream callbacks
256  *****************************************************************************
257  * The following callbacks are related to the network stream manager.
258  *****************************************************************************/
259 gboolean GtkNetworkOpenShow( GtkWidget       *widget,
260                              GdkEventButton  *event,
261                              gpointer         user_data )
262 {
263     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
264
265     if( !GTK_IS_WIDGET( p_intf->p_sys->p_network ) )
266     {
267         char *psz_channel_server;
268
269         p_intf->p_sys->p_network = create_intf_network();
270         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_network ),
271                              "p_intf", p_intf );
272
273         gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
274             GTK_OBJECT( p_intf->p_sys->p_network ), "network_port" ) ),
275             config_GetIntVariable( "server_port" ) );
276
277         psz_channel_server = config_GetPszVariable( "channel_server" );
278         if( psz_channel_server )
279             gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
280                 GTK_OBJECT( p_intf->p_sys->p_network ), "network_channel" ) ),
281                 psz_channel_server );
282         if( psz_channel_server ) free( psz_channel_server );
283
284         gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
285             GTK_OBJECT( p_intf->p_sys->p_network ), "network_channel_port" ) ),
286             config_GetIntVariable( "channel_port" ) );
287
288         gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT(
289             p_intf->p_sys->p_network ), "network_channel_check" ),
290             config_GetIntVariable( "network_channel" ) );
291     }
292
293     gtk_widget_show( p_intf->p_sys->p_network );
294     gdk_window_raise( p_intf->p_sys->p_network->window );
295
296     return TRUE;
297 }
298
299
300 void GtkNetworkOpenOk( GtkButton *button, gpointer user_data )
301 {
302     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_network" );
303     GtkCList *      p_playlist_clist;
304     char *          psz_source, *psz_server, *psz_protocol;
305     unsigned int    i_port;
306     boolean_t       b_broadcast;
307     boolean_t       b_channel;
308     int             i_end = p_main->p_playlist->i_size;
309
310     gtk_widget_hide( p_intf->p_sys->p_network );
311     psz_server = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
312                                  GTK_WIDGET(button), "network_server" ) ) );
313
314     /* select added item */
315     if( p_input_bank->pp_input[0] != NULL )
316     {
317         p_input_bank->pp_input[0]->b_eof = 1;
318     }
319
320     /* Check which protocol was activated */
321     if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
322                                           "network_ts" ) )->active )
323     {
324         psz_protocol = "udpstream";
325     }
326     else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
327                                                "network_rtp" ) )->active )
328     {
329         psz_protocol = "rtp";
330     }
331     else
332     {
333         intf_ErrMsg( "intf error: unknown protocol toggle button position" );
334         return;
335     }
336
337     /* Manage channel server */
338     b_channel = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
339         lookup_widget( GTK_WIDGET(button), "network_channel_check" ) ) );
340     config_PutIntVariable( "network_channel", b_channel );
341     if( b_channel )
342     {
343         char *          psz_channel;
344         unsigned int    i_channel_port;
345
346         if( p_main->p_channel == NULL )
347         {
348             network_ChannelCreate();
349         }
350
351         psz_channel = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
352                              GTK_WIDGET(button), "network_channel" ) ) );
353         i_channel_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
354             lookup_widget( GTK_WIDGET(button), "network_channel_port" ) ) );
355
356         config_PutPszVariable( "channel_server", psz_channel );
357         if( i_channel_port < 65536 )
358         {
359             config_PutIntVariable( "channel_port", i_channel_port );
360         }
361
362         p_intf->p_sys->b_playing = 1;
363
364     }
365     else
366     {
367         /* Get the port number and make sure it will not
368          * overflow 5 characters */
369         i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
370                      lookup_widget( GTK_WIDGET(button), "network_port" ) ) );
371         if( i_port > 65535 )
372         {
373             intf_ErrMsg( "intf error: invalid port %i", i_port );
374         }
375
376         /* do we have a broadcast address */
377         b_broadcast = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
378             lookup_widget( GTK_WIDGET(button), "network_broadcast_check" ) ) );
379         if( b_broadcast )
380         {
381             char *  psz_broadcast;
382             psz_broadcast = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
383                             GTK_WIDGET(button), "network_broadcast" ) ) );
384             /* Allocate room for "protocol://server:port" */
385             psz_source = malloc( strlen( psz_protocol ) + 3 /* "://" */
386                                    + strlen( psz_server ) + 2 /* "@:" */
387                                    + 5 /* 0-65535 */
388                                    + strlen( psz_broadcast ) + 2 /* "::" */ 
389                                    + 1 /* "\0" */ );
390             if( psz_source == NULL )
391             {
392                 return;
393             }
394
395             /* Build source name and add it to playlist */
396             sprintf( psz_source, "%s://%s@:%i/%s", psz_protocol,
397                                                   psz_server,
398                                                   i_port,
399                                                   psz_broadcast );
400         }
401         else
402         {
403             /* Allocate room for "protocol://server:port" */
404             psz_source = malloc( strlen( psz_protocol ) + 3 /* "://" */
405                                    + strlen( psz_server ) + 2 /* "@:" */
406                                    + 5 /* 0-65535 */ + 1 /* "\0" */ );
407             if( psz_source == NULL )
408             {
409                 return;
410             }
411            
412             /* Build source name and add it to playlist */
413             sprintf( psz_source, "%s://%s@:%i",
414                      psz_protocol, psz_server, i_port );
415         }
416
417         intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
418         free( psz_source );
419         
420         /* catch the GTK CList */
421         p_playlist_clist = GTK_CLIST( gtk_object_get_data(
422             GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
423         /* update the display */
424         GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
425
426         intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
427     }
428 }
429
430 void GtkNetworkOpenCancel( GtkButton * button, gpointer user_data)
431 {
432     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
433 }
434
435
436 void GtkNetworkOpenBroadcast( GtkToggleButton * togglebutton,
437                               gpointer user_data )
438 {
439     GtkWidget *     p_network;
440
441     p_network = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
442
443     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
444             "network_broadcast_combo" ),
445             gtk_toggle_button_get_active( togglebutton ) );
446
447     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
448             "network_broadcast" ),
449             gtk_toggle_button_get_active( togglebutton ) );
450 }
451
452
453 void GtkNetworkOpenChannel( GtkToggleButton * togglebutton,
454                             gpointer user_data )
455 {
456     GtkWidget *     p_network;
457     boolean_t       b_channel;
458     boolean_t       b_broadcast;
459
460     p_network = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
461     b_channel = gtk_toggle_button_get_active( togglebutton );
462     b_broadcast = gtk_toggle_button_get_active( gtk_object_get_data(
463                   GTK_OBJECT( p_network ), "network_broadcast_check" ) );
464         
465     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
466             "network_channel_combo" ), b_channel ) ;
467
468     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
469             "network_channel" ), b_channel );
470
471     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
472             "network_channel_port" ), b_channel );
473
474     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
475             "network_channel_port_label" ), b_channel );
476
477     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
478             "network_server_combo" ), ! b_channel );
479
480     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
481             "network_server_label" ), ! b_channel );
482
483     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
484             "network_server" ), ! b_channel );
485
486     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
487             "network_port_label" ), ! b_channel );
488
489     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
490             "network_port" ), ! b_channel );
491
492     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
493             "network_broadcast_check" ), ! b_channel );
494     
495     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
496             "network_broadcast_combo" ), b_broadcast && ! b_channel );
497
498     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
499             "network_broadcast" ), b_broadcast && ! b_channel );
500 }
501
502 /*****************************************************************************
503  * Open satellite callbacks
504  *****************************************************************************
505  * The following callbacks are related to the satellite card manager.
506  *****************************************************************************/
507 gboolean GtkSatOpenShow( GtkWidget       *widget,
508                           GdkEventButton  *event,
509                           gpointer         user_data)
510 {
511     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
512
513     if( !GTK_IS_WIDGET( p_intf->p_sys->p_sat ) )
514     {
515         p_intf->p_sys->p_sat = create_intf_sat();
516         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_sat ),
517                              "p_intf", p_intf );
518     }
519
520     gtk_widget_show( p_intf->p_sys->p_sat );
521     gdk_window_raise( p_intf->p_sys->p_sat->window );
522
523     return TRUE;
524 }
525
526 void GtkSatOpenOk( GtkButton * button, gpointer user_data )
527 {
528     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_sat" );
529     GtkCList *      p_playlist_clist;
530     char *          psz_source;
531     int             i_end = p_main->p_playlist->i_size;
532     int             i_freq, i_srate;
533     boolean_t       b_pol;
534
535     gtk_widget_hide( p_intf->p_sys->p_sat );
536
537     /* Check which polarization was activated */
538     if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
539                                           "sat_pol_vert" ) )->active )
540     {
541         b_pol = 0;
542     }
543     else
544     {
545         b_pol = 1;
546     }
547     
548     /* Select frequency and symbol rate */
549     i_freq = gtk_spin_button_get_value_as_int(
550                               GTK_SPIN_BUTTON( lookup_widget(
551                                   GTK_WIDGET(button), "sat_freq" ) ) );
552
553     i_srate = gtk_spin_button_get_value_as_int(
554                               GTK_SPIN_BUTTON( lookup_widget(
555                                   GTK_WIDGET(button), "sat_srate" ) ) );
556     
557     psz_source = malloc( 22 );
558     if( psz_source == NULL )
559     {
560         return;
561     }
562
563     /* Build source name and add it to playlist */
564     sprintf( psz_source, "%s:%d,%d,%d",
565              "satellite", i_freq, b_pol, i_srate );
566     intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
567     free( psz_source );
568
569     /* catch the GTK CList */
570     p_playlist_clist = GTK_CLIST( gtk_object_get_data(
571         GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
572
573     /* update the display */
574     GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
575
576     /* stop current item, select added item */
577     if( p_input_bank->pp_input[0] != NULL )
578     {
579         p_input_bank->pp_input[0]->b_eof = 1;
580     }
581
582     intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
583 }
584
585
586 void GtkSatOpenCancel( GtkButton * button, gpointer user_data )
587 {
588     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
589 }
590
591 /****************************************************************************
592  * Callbacks for menuitem
593  ****************************************************************************/
594 void GtkFileOpenActivate( GtkMenuItem * menuitem, gpointer user_data )
595 {
596     GtkFileOpenShow( GTK_WIDGET( menuitem ), NULL, user_data );
597 }
598
599
600 void GtkDiscOpenActivate( GtkMenuItem * menuitem, gpointer user_data )
601 {
602     GtkDiscOpenShow( GTK_WIDGET( menuitem ), NULL, user_data );
603 }
604
605
606 void GtkNetworkOpenActivate( GtkMenuItem * menuitem, gpointer user_data )
607 {
608     GtkNetworkOpenShow( GTK_WIDGET( menuitem ), NULL, user_data );
609 }
610