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