2b63299290c56969664d6e4ee24f131b9c815b18
[vlc.git] / modules / gui / 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: open.c,v 1.4 2002/11/25 12:19:04 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
46 #include "playlist.h"
47 #include "common.h"
48
49 #include "netutils.h"
50
51 static void GtkOpenShow( intf_thread_t *, int );
52
53 static void GtkFileOpenChanged    ( GtkWidget *, gpointer );
54 static void GtkDiscOpenChanged    ( GtkWidget *, gpointer );
55 static void GtkNetworkOpenChanged ( GtkWidget *, gpointer );
56 static void GtkSatOpenChanged     ( GtkWidget *, gpointer );
57
58 /*****************************************************************************
59  * File requester callbacks
60  *****************************************************************************
61  * The following callbacks are related to the file requester.
62  *****************************************************************************/
63 void GtkFileShow( GtkButton * button, gpointer user_data )
64 {
65     GtkWidget * p_file = create_intf_file();
66
67     gtk_object_set_data( GTK_OBJECT(p_file), "p_intf",
68                          GtkGetIntf( button ) );
69
70     gtk_widget_show( p_file );
71     gdk_window_raise( p_file->window );
72 }
73
74 void GtkFileOk( GtkButton * button, gpointer user_data )
75 {
76     GtkWidget * p_file = gtk_widget_get_toplevel( GTK_WIDGET (button) );
77
78     char *psz_filename;
79     intf_thread_t * p_intf = GtkGetIntf( button );
80
81     /* add the new file to the dialog box */
82     psz_filename =
83             gtk_file_selection_get_filename( GTK_FILE_SELECTION( p_file ) );
84     gtk_entry_set_text( GTK_ENTRY( lookup_widget( p_intf->p_sys->p_open,
85                                                   "entry_file" ) ),
86                         psz_filename );
87     gtk_widget_destroy( p_file );
88 }
89
90 void GtkFileCancel( GtkButton * button, gpointer user_data )
91 {
92     gtk_widget_destroy( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
93 }
94
95 /*****************************************************************************
96  * Open file callbacks
97  *****************************************************************************
98  * The following callbacks are related to the file tab.
99  *****************************************************************************/
100 gboolean GtkFileOpenShow( GtkWidget       *widget,
101                           gpointer         user_data )
102 {
103     GtkOpenShow( GtkGetIntf( widget ), 0 );
104
105     return TRUE;
106 }
107
108 static void GtkFileOpenChanged( GtkWidget * button, gpointer user_data )
109 {
110     GString *       p_target;
111
112     p_target = g_string_new( "file://" );
113     g_string_append( p_target,
114                      gtk_entry_get_text( GTK_ENTRY( lookup_widget(
115                                      GTK_WIDGET(button), "entry_file" ) ) ) );
116     gtk_entry_set_text( GTK_ENTRY( lookup_widget(
117                                    GTK_WIDGET(button), "entry_open" ) ),
118                         p_target->str );
119     g_string_free( p_target, TRUE );
120 }
121
122 /*****************************************************************************
123  * Open disc callbacks
124  *****************************************************************************
125  * The following callbacks are related to the disc manager.
126  *****************************************************************************/
127 gboolean GtkDiscOpenShow( GtkWidget       *widget,
128                           gpointer         user_data)
129 {
130     GtkOpenShow( GtkGetIntf( widget ), 1 );
131
132     return TRUE;
133 }
134
135 void GtkDiscOpenDvd( GtkToggleButton * togglebutton, gpointer user_data )
136 {
137     intf_thread_t * p_intf = GtkGetIntf( togglebutton );
138     char *psz_device;
139
140     if( togglebutton->active
141          && (psz_device = config_GetPsz( p_intf, "dvd" )) )
142     {
143         gtk_entry_set_text(
144             GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
145                                       "disc_name" ) ), psz_device );
146         free( psz_device );
147     }
148 }
149
150 void GtkDiscOpenVcd( GtkToggleButton * togglebutton, gpointer user_data )
151 {
152     intf_thread_t * p_intf = GtkGetIntf( togglebutton );
153     char *psz_device;
154
155     if( togglebutton->active
156          && (psz_device = config_GetPsz( p_intf, "vcd" )) )
157     {
158         gtk_entry_set_text(
159             GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton),
160                                       "disc_name" ) ), psz_device );
161         free( psz_device );
162     }
163 }
164
165 static void GtkDiscOpenChanged( GtkWidget * button, gpointer user_data )
166 {
167     GString * p_target = g_string_new( "" );
168
169     if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button), 
170                                           "disc_dvd" ) )->active )
171     {
172         g_string_append( p_target, "dvd://" );
173     }
174     else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
175                                                "disc_vcd" ) )->active )
176     {
177         g_string_append( p_target, "vcd://" );
178     }       
179
180     g_string_append( p_target,
181                      gtk_entry_get_text( GTK_ENTRY( lookup_widget(
182                                      GTK_WIDGET(button), "disc_name" ) ) ) );
183     g_string_sprintfa( p_target, "@%i,%i",
184                        gtk_spin_button_get_value_as_int(
185                               GTK_SPIN_BUTTON( lookup_widget(
186                                   GTK_WIDGET(button), "disc_title" ) ) ),
187                        gtk_spin_button_get_value_as_int(
188                               GTK_SPIN_BUTTON( lookup_widget(
189                                   GTK_WIDGET(button), "disc_chapter" ) ) ) );
190
191     gtk_entry_set_text( GTK_ENTRY( lookup_widget(
192                                    GTK_WIDGET(button), "entry_open" ) ),
193                         p_target->str );
194     g_string_free( p_target, TRUE );
195 }
196
197 /*****************************************************************************
198  * Network stream callbacks
199  *****************************************************************************
200  * The following callbacks are related to the network stream manager.
201  *****************************************************************************/
202 gboolean GtkNetworkOpenShow( GtkWidget       *widget,
203                              gpointer         user_data )
204 {
205     GtkOpenShow( GtkGetIntf( widget ), 2 );
206
207     return TRUE;
208 }
209
210 static void GtkNetworkOpenChanged( GtkWidget *button, gpointer user_data )
211 {
212     intf_thread_t * p_intf = GtkGetIntf( button );
213     GString *       p_target = g_string_new( "" );
214
215     unsigned int    i_port;
216     vlc_bool_t      b_channel;
217
218     /* Manage channel server */
219     b_channel = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
220             lookup_widget( GTK_WIDGET(button), "network_channel" ) ) );
221     config_PutInt( p_intf, "network-channel", b_channel );
222
223 #define SELECTED( s ) GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button), \
224                        (s) ) )->active
225     /* Check which option was chosen */
226     if( SELECTED( "network_udp" ) )
227     {
228         g_string_append( p_target, "udp://" );
229         i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
230                                lookup_widget( GTK_WIDGET(button),
231                                               "network_udp_port" ) ) );
232         if( i_port != 1234 )
233         {
234             g_string_sprintfa( p_target, "@:%i", i_port );
235         }
236     }
237     else if( SELECTED( "network_multicast" ) )
238     {
239         g_string_sprintfa( p_target, "udp://@%s",
240                            gtk_entry_get_text( GTK_ENTRY(
241                             lookup_widget( GTK_WIDGET(button),
242                                            "network_multicast_address" ) ) ) );
243         i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
244                                lookup_widget( GTK_WIDGET(button),
245                                               "network_multicast_port" ) ) );
246         if( i_port != 1234 )
247         {
248             g_string_sprintfa( p_target, ":%i", i_port );
249         }
250     }
251     else if( SELECTED( "network_channel" ) )
252     {
253         char *          psz_channel;
254         unsigned int    i_channel_port;
255
256         if( p_intf->p_vlc->p_channel == NULL )
257         {
258             network_ChannelCreate( p_intf );
259         }
260
261         psz_channel = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
262                         GTK_WIDGET(button), "network_channel_address" ) ) );
263         i_channel_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
264             lookup_widget( GTK_WIDGET(button), "network_channel_port" ) ) );
265
266         config_PutPsz( p_intf, "channel-server", psz_channel );
267         if( i_channel_port < 65536 )
268         {
269             config_PutInt( p_intf, "channel-port", i_channel_port );
270         }
271
272         /* FIXME: we should use a playlist server instead */
273         g_string_append( p_target, "udp://" );
274     }
275     else if( SELECTED( "network_http" ) )
276     {
277         g_string_assign( p_target,
278                          gtk_entry_get_text( GTK_ENTRY( lookup_widget(
279                                GTK_WIDGET(button), "network_http_url" ) ) ) );
280     }
281
282     gtk_entry_set_text( GTK_ENTRY( lookup_widget(
283                                    GTK_WIDGET(button), "entry_open" ) ),
284                         p_target->str );
285     g_string_free( p_target, TRUE );
286 }
287
288 void GtkNetworkOpenUDP( GtkToggleButton *togglebutton,
289                                         gpointer user_data )
290 {
291     GtkWidget *     p_open;
292
293     p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
294
295     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
296                     "network_udp_port_label" ),
297                     gtk_toggle_button_get_active( togglebutton ) );
298     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
299                     "network_udp_port" ),
300                     gtk_toggle_button_get_active( togglebutton ) );
301
302     GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
303 }
304
305 void GtkNetworkOpenMulticast( GtkToggleButton *togglebutton,
306                                               gpointer user_data )
307 {
308     GtkWidget *     p_open;
309
310     p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
311     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
312                     "network_multicast_address_label" ),
313                     gtk_toggle_button_get_active( togglebutton ) );
314     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
315                     "network_multicast_address_combo" ),
316                     gtk_toggle_button_get_active( togglebutton ) );
317
318     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
319                     "network_multicast_port_label" ),
320                     gtk_toggle_button_get_active( togglebutton ) );
321     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
322                     "network_multicast_port" ),
323                     gtk_toggle_button_get_active( togglebutton ) );
324
325     GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
326 }
327
328
329 void GtkNetworkOpenChannel( GtkToggleButton *togglebutton,
330                                        gpointer user_data )
331 {
332     GtkWidget *     p_open;
333
334     p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
335     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
336                     "network_channel_address_label" ),
337                     gtk_toggle_button_get_active( togglebutton ) );
338     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
339                     "network_channel_address_combo" ),
340                     gtk_toggle_button_get_active( togglebutton ) );
341
342     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
343                     "network_channel_port_label" ),
344                     gtk_toggle_button_get_active( togglebutton ) );
345     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
346                     "network_channel_port" ),
347                     gtk_toggle_button_get_active( togglebutton ) );
348
349     GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
350 }
351
352 void GtkNetworkOpenHTTP( GtkToggleButton *togglebutton,
353                                          gpointer user_data )
354 {   
355     GtkWidget *     p_open;
356
357     p_open = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
358     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
359                     "network_http_url_label" ),
360                     gtk_toggle_button_get_active( togglebutton ) );
361     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_open ),
362                     "network_http_url" ),
363                     gtk_toggle_button_get_active( togglebutton ) );
364
365     GtkNetworkOpenChanged( GTK_WIDGET( togglebutton ), user_data );
366 }
367
368 /*****************************************************************************
369  * Open satellite callbacks
370  *****************************************************************************
371  * The following callbacks are related to the satellite card manager.
372  *****************************************************************************/
373 gboolean GtkSatOpenShow( GtkWidget       *widget,
374                          gpointer         user_data)
375 {
376     GtkOpenShow( GtkGetIntf( widget ), 3 );
377
378     return TRUE;
379 }
380
381 static void GtkSatOpenChanged( GtkWidget * button, gpointer user_data )
382 {
383     GString *       p_target = g_string_new( "" );
384
385     g_string_sprintfa( p_target, "%s://%d,%d,%ld,%d", "satellite",
386                        gtk_spin_button_get_value_as_int(
387                               GTK_SPIN_BUTTON( lookup_widget(
388                                   GTK_WIDGET(button), "sat_freq" ) ) ),
389                        !GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET( button ),
390                                                "sat_pol_vert" ) )->active,
391                        strtol( gtk_entry_get_text( GTK_ENTRY( GTK_COMBO( 
392                                lookup_widget( GTK_WIDGET( button ), "sat_fec" )
393                                )->entry ) ), NULL, 10 ),
394                        gtk_spin_button_get_value_as_int(
395                               GTK_SPIN_BUTTON( lookup_widget(
396                                   GTK_WIDGET(button), "sat_srate" ) ) ) );
397
398     gtk_entry_set_text( GTK_ENTRY( lookup_widget(
399                                    GTK_WIDGET(button), "entry_open" ) ),
400                         p_target->str );
401     g_string_free( p_target, TRUE );
402 }
403
404 void
405 GtkSatOpenToggle                       (GtkToggleButton *togglebutton,
406                                         gpointer         user_data)
407 {
408     if( togglebutton->active )
409     {
410         GtkSatOpenChanged( GTK_WIDGET( togglebutton ), user_data );
411     }
412 }
413
414 /******************************
415   ******************************/
416
417 static void GtkOpenShow( intf_thread_t *p_intf, int i_page )
418 {
419     char *psz_var;
420     GtkWidget *p_notebook;
421
422     /* If we have already created this window, do nothing */
423     if( GTK_IS_WIDGET( p_intf->p_sys->p_open ) )
424     {
425         goto setpage;
426     }
427
428     p_intf->p_sys->p_open = create_intf_open();
429     gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_open ),
430                          "p_intf", p_intf );
431
432     /* FileOpen stuff */
433     psz_var = config_GetPsz( p_intf, "search-path" );
434     if( psz_var )
435     {
436         gtk_file_selection_set_filename( GTK_FILE_SELECTION(
437             p_intf->p_sys->p_open ), psz_var );
438         free( psz_var );
439     }
440
441     /* Disc stuff */
442     psz_var = config_GetPsz( p_intf, "dvd" );
443     if( psz_var )
444     {
445         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
446             GTK_OBJECT( p_intf->p_sys->p_open ), "disc_name" ) ),
447             psz_var );
448         free( psz_var );
449     }
450
451     /* Network stuff */
452     gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
453         GTK_OBJECT( p_intf->p_sys->p_open ), "network_udp_port" ) ),
454         config_GetInt( p_intf, "server-port" ) );
455
456     psz_var = config_GetPsz( p_intf, "channel-server" );
457     if( psz_var )
458     {
459         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
460             GTK_OBJECT( p_intf->p_sys->p_open ), "network_channel_address" ) ),
461             psz_var );
462         free( psz_var );
463     }
464
465     gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
466         GTK_OBJECT( p_intf->p_sys->p_open ), "network_http_url" ) ),
467         "http://" );
468
469     gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
470         GTK_OBJECT( p_intf->p_sys->p_open ), "network_channel_port" ) ),
471         config_GetInt( p_intf, "channel-port" ) );
472
473     gtk_toggle_button_set_active( gtk_object_get_data(
474         GTK_OBJECT( p_intf->p_sys->p_open ), "network_channel" ),
475         config_GetInt( p_intf, "network-channel" ) );
476
477     /* Satellite stuff */
478     psz_var = config_GetPsz( p_intf, "frequency" );
479     if( psz_var )
480     {
481         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
482             GTK_OBJECT( p_intf->p_sys->p_open ), "sat_freq" ) ),
483             psz_var );
484         free( psz_var );
485     }
486
487     psz_var = config_GetPsz( p_intf, "symbol-rate" );
488     if( psz_var )
489     {
490         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
491             GTK_OBJECT( p_intf->p_sys->p_open ), "sat_srate" ) ),
492             psz_var );
493         free( psz_var );
494     }
495
496     /* Set the right page */
497 setpage:
498     p_notebook = lookup_widget( GTK_WIDGET( p_intf->p_sys->p_open ),
499                                 "open_notebook" );
500     gtk_notebook_set_page( GTK_NOTEBOOK( p_notebook ), i_page );
501
502     gtk_widget_show( p_intf->p_sys->p_open );
503     gdk_window_raise( p_intf->p_sys->p_open->window );
504 }
505
506 void GtkOpenOk( GtkButton * button, gpointer user_data )
507 {
508     /* Check what was pressed */
509     intf_thread_t * p_intf = GtkGetIntf( button );
510     playlist_t *    p_playlist;
511     GtkCList *      p_playlist_clist;
512     gchar *         psz_target;
513
514     /* Hide the dialog box */
515     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
516
517     /* Update the playlist */
518     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
519     if( p_playlist == NULL )
520     {
521         return;
522     }
523
524     psz_target = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
525                                        GTK_WIDGET(button), "entry_open" ) ) );
526     playlist_Add( p_playlist, (char*)psz_target,
527                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
528
529     /* catch the GTK CList */
530     p_playlist_clist = GTK_CLIST( gtk_object_get_data(
531         GTK_OBJECT( p_intf->p_sys->p_playwin ), "playlist_clist" ) );
532     /* update the plugin display */
533     GtkRebuildCList( p_playlist_clist, p_playlist );
534
535     vlc_object_release( p_playlist );
536 }
537
538 void GtkOpenCancel( GtkButton * button, gpointer user_data )
539 {
540     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
541 }
542
543 void GtkOpenChanged( GtkWidget * button, gpointer user_data )
544 {
545     intf_thread_t * p_intf = GtkGetIntf( button );
546     GtkWidget *p_notebook;
547     int i_page;
548
549     p_notebook = lookup_widget( GTK_WIDGET( p_intf->p_sys->p_open ),
550                                 "open_notebook" );
551     i_page = gtk_notebook_get_current_page( GTK_NOTEBOOK( p_notebook ) );
552
553     switch( i_page )
554     {
555         case 0:
556             GtkFileOpenChanged( button, NULL );
557             break;
558         case 1:
559             GtkDiscOpenChanged( button, NULL );
560             break;
561         case 2:
562             GtkNetworkOpenChanged( button, NULL );
563             break;
564         case 3:
565             GtkSatOpenChanged( button, NULL );
566             break;
567     }
568 }
569