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