]> git.sesse.net Git - vlc/blob - plugins/gtk/gtk_open.c
Some heavy changes today:
[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.12 2001/12/30 07:09:55 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 <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         p_intf->p_sys->p_fileopen = create_intf_fileopen();
70         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_fileopen ),
71                              "p_intf", p_intf );
72
73         gtk_file_selection_set_filename( GTK_FILE_SELECTION(
74             p_intf->p_sys->p_fileopen ),
75             main_GetPszVariable( INTF_PATH_VAR, INTF_PATH_DEFAULT ) );
76     }
77
78     gtk_widget_show( p_intf->p_sys->p_fileopen );
79     gdk_window_raise( p_intf->p_sys->p_fileopen->window );
80
81     return TRUE;
82 }
83
84
85 void GtkFileOpenCancel( GtkButton * button, gpointer user_data )
86 {
87     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
88 }
89
90 void GtkFileOpenOk( GtkButton * button, gpointer user_data )
91 {
92     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_fileopen" );
93     GtkCList *      p_playlist_clist;
94     GtkWidget *     p_filesel;
95     gchar *         psz_filename;
96     int             i_end = p_main->p_playlist->i_size;
97
98     /* hide the file selector */
99     p_filesel = gtk_widget_get_toplevel( GTK_WIDGET(button) );
100     gtk_widget_hide( p_filesel );
101
102     /* add the new file to the interface playlist */
103     psz_filename =
104         gtk_file_selection_get_filename( GTK_FILE_SELECTION( p_filesel ) );
105     intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_filename );
106
107     /* catch the GTK CList */
108     p_playlist_clist = GTK_CLIST( gtk_object_get_data(
109         GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
110     /* update the plugin display */
111     GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
112
113     /* end current item, select added item  */
114     if( p_intf->p_input != NULL )
115     {
116         p_intf->p_input->b_eof = 1;
117     }
118
119     intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
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                           GdkEventButton  *event,
129                           gpointer         user_data)
130 {
131     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
132
133     if( !GTK_IS_WIDGET( p_intf->p_sys->p_disc ) )
134     {
135         p_intf->p_sys->p_disc = create_intf_disc();
136         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_disc ),
137                              "p_intf", p_intf );
138     }
139
140     gtk_widget_show( p_intf->p_sys->p_disc );
141     gdk_window_raise( p_intf->p_sys->p_disc->window );
142
143     return TRUE;
144 }
145
146
147 void GtkDiscOpenDvd( GtkToggleButton * togglebutton, gpointer user_data )
148 {
149     if( togglebutton->active )
150     {
151         gtk_entry_set_text(
152           GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton), "disc_name" ) ),
153           main_GetPszVariable( INPUT_DVD_DEVICE_VAR, INPUT_DVD_DEVICE_DEFAULT )
154         );
155     }
156 }
157
158 void GtkDiscOpenVcd( GtkToggleButton * togglebutton, gpointer user_data )
159 {
160     if( togglebutton->active )
161     {
162         gtk_entry_set_text(
163           GTK_ENTRY( lookup_widget( GTK_WIDGET(togglebutton), "disc_name" ) ),
164           main_GetPszVariable( INPUT_VCD_DEVICE_VAR, INPUT_VCD_DEVICE_DEFAULT )
165         );
166     }
167 }
168
169 void GtkDiscOpenOk( GtkButton * button, gpointer user_data )
170 {
171     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_disc" );
172     GtkCList *      p_playlist_clist;
173     char *          psz_device, *psz_source, *psz_method;
174     int             i_end = p_main->p_playlist->i_size;
175
176     gtk_widget_hide( p_intf->p_sys->p_disc );
177     psz_device = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
178                                          GTK_WIDGET(button), "disc_name" ) ) );
179
180     /* "dvd:foo" has size 5 + strlen(foo) */
181     psz_source = malloc( 3 /* "dvd" */ + 1 /* ":" */
182                            + strlen( psz_device ) + 1 /* "\0" */ );
183     if( psz_source == NULL )
184     {
185         return;
186     }
187
188     /* Check which method was activated */
189     if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
190                                           "disc_dvd" ) )->active )
191     {
192         psz_method = "dvd";
193     }
194     else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
195                                                "disc_vcd" ) )->active )
196     {
197         psz_method = "vcd";
198     }
199     else
200     {
201         intf_ErrMsg( "intf error: unknown disc type toggle button position" );
202         free( psz_source );
203         return;
204     }
205     
206     /* Select title and chapter */
207     main_PutIntVariable( INPUT_TITLE_VAR, gtk_spin_button_get_value_as_int(
208                               GTK_SPIN_BUTTON( lookup_widget(
209                                   GTK_WIDGET(button), "disc_title" ) ) ) );
210
211     main_PutIntVariable( INPUT_CHAPTER_VAR, gtk_spin_button_get_value_as_int(
212                               GTK_SPIN_BUTTON( lookup_widget(
213                                   GTK_WIDGET(button), "disc_chapter" ) ) ) );
214
215     /* Build source name and add it to playlist */
216     sprintf( psz_source, "%s:%s", psz_method, psz_device );
217     intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
218     free( psz_source );
219
220     /* catch the GTK CList */
221     p_playlist_clist = GTK_CLIST( gtk_object_get_data(
222         GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
223
224     /* update the display */
225     GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
226
227     /* stop current item, select added item */
228     if( p_intf->p_input != NULL )
229     {
230         p_intf->p_input->b_eof = 1;
231     }
232
233     intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
234 }
235
236
237 void GtkDiscOpenCancel( GtkButton * button, gpointer user_data )
238 {
239     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
240 }
241
242
243 /*****************************************************************************
244  * Network stream callbacks
245  *****************************************************************************
246  * The following callbacks are related to the network stream manager.
247  *****************************************************************************/
248 gboolean GtkNetworkOpenShow( GtkWidget       *widget,
249                              GdkEventButton  *event,
250                              gpointer         user_data )
251 {
252     intf_thread_t *p_intf = GetIntf( GTK_WIDGET(widget), (char*)user_data );
253
254     if( !GTK_IS_WIDGET( p_intf->p_sys->p_network ) )
255     {
256         p_intf->p_sys->p_network = create_intf_network();
257         gtk_object_set_data( GTK_OBJECT( p_intf->p_sys->p_network ),
258                              "p_intf", p_intf );
259
260         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
261             GTK_OBJECT( p_intf->p_sys->p_network ), "network_server" ) ),
262             main_GetPszVariable( INPUT_SERVER_VAR,
263                                  INPUT_SERVER_DEFAULT ) );
264
265         gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
266             GTK_OBJECT( p_intf->p_sys->p_network ), "network_port" ) ),
267             main_GetIntVariable( INPUT_PORT_VAR,
268                                  INPUT_PORT_DEFAULT ) );
269
270         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
271             GTK_OBJECT( p_intf->p_sys->p_network ), "network_broadcast" ) ),
272             main_GetPszVariable( INPUT_BCAST_ADDR_VAR,
273                                  INPUT_BCAST_ADDR_DEFAULT ) );
274
275         gtk_entry_set_text( GTK_ENTRY( gtk_object_get_data(
276             GTK_OBJECT( p_intf->p_sys->p_network ), "network_channel" ) ),
277             main_GetPszVariable( INPUT_CHANNEL_SERVER_VAR,
278                                  INPUT_CHANNEL_SERVER_DEFAULT ) );
279
280         gtk_spin_button_set_value( GTK_SPIN_BUTTON( gtk_object_get_data(
281             GTK_OBJECT( p_intf->p_sys->p_network ), "network_channel_port" ) ),
282             main_GetIntVariable( INPUT_CHANNEL_PORT_VAR,
283                                  INPUT_CHANNEL_PORT_DEFAULT ) );
284
285         gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT(
286             p_intf->p_sys->p_network ), "network_channel_check" ),
287             main_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR,
288                                  INPUT_NETWORK_CHANNEL_DEFAULT ) );
289             
290         gtk_toggle_button_set_active( gtk_object_get_data( GTK_OBJECT(
291             p_intf->p_sys->p_network ), "network_broadcast_check" ),
292             main_GetIntVariable( INPUT_BROADCAST_VAR,
293                                  INPUT_BROADCAST_DEFAULT ) );
294     }
295
296     gtk_widget_show( p_intf->p_sys->p_network );
297     gdk_window_raise( p_intf->p_sys->p_network->window );
298
299     return TRUE;
300 }
301
302
303 void GtkNetworkOpenOk( GtkButton *button, gpointer user_data )
304 {
305     intf_thread_t * p_intf = GetIntf( GTK_WIDGET(button), "intf_network" );
306     GtkCList *      p_playlist_clist;
307     char *          psz_source, *psz_server, *psz_protocol;
308     unsigned int    i_port;
309     boolean_t       b_broadcast;
310     boolean_t       b_channel;
311     int             i_end = p_main->p_playlist->i_size;
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( p_intf->p_input != NULL )
319     {
320         p_intf->p_input->b_eof = 1;
321     }
322
323     /* Check which protocol was activated */
324     if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
325                                           "network_ts" ) )->active )
326     {
327         psz_protocol = "udpstream";
328     }
329     else if( GTK_TOGGLE_BUTTON( lookup_widget( GTK_WIDGET(button),
330                                                "network_rtp" ) )->active )
331     {
332         psz_protocol = "rtp";
333     }
334     else
335     {
336         intf_ErrMsg( "intf error: unknown protocol toggle button position" );
337         return;
338     }
339
340     /* Manage channel server */
341     b_channel = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
342         lookup_widget( GTK_WIDGET(button), "network_channel_check" ) ) );
343     main_PutIntVariable( INPUT_NETWORK_CHANNEL_VAR, b_channel );
344     if( b_channel )
345     {
346         char *          psz_channel;
347         unsigned int    i_channel_port;
348
349         if( p_main->p_channel == NULL )
350         {
351             network_ChannelCreate();
352         }
353
354         psz_channel = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
355                              GTK_WIDGET(button), "network_channel" ) ) );
356         i_channel_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
357             lookup_widget( GTK_WIDGET(button), "network_channel_port" ) ) );
358
359         main_PutPszVariable( INPUT_CHANNEL_SERVER_VAR, psz_channel );
360         if( i_channel_port < 65536 )
361         {
362             main_PutIntVariable( INPUT_CHANNEL_PORT_VAR, i_channel_port );
363         }
364
365         p_intf->p_sys->b_playing = 1;
366
367     }
368     else
369     {
370         /* Get the port number and make sure it will not
371          * overflow 5 characters */
372         i_port = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(
373                      lookup_widget( GTK_WIDGET(button), "network_port" ) ) );
374         if( i_port > 65535 )
375         {
376             intf_ErrMsg( "intf error: invalid port %i", i_port );
377         }
378
379         /* do we have a broadcast address */
380         b_broadcast = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
381             lookup_widget( GTK_WIDGET(button), "network_broadcast_check" ) ) );
382         if( b_broadcast )
383         {
384             char *  psz_broadcast;
385             psz_broadcast = gtk_entry_get_text( GTK_ENTRY( lookup_widget(
386                             GTK_WIDGET(button), "network_broadcast" ) ) );
387             /* Allocate room for "protocol://server:port" */
388             psz_source = malloc( strlen( psz_protocol ) + 3 /* "://" */
389                                    + strlen( psz_server ) + 1 /* ":" */
390                                    + 5 /* 0-65535 */
391                                    + strlen( psz_broadcast ) + 2 /* "::" */ 
392                                    + 1 /* "\0" */ );
393             if( psz_source == NULL )
394             {
395                 return;
396             }
397
398             /* Build source name and add it to playlist */
399             sprintf( psz_source, "%s://%s:%i/%s", psz_protocol,
400                                                   psz_server,
401                                                   i_port,
402                                                   psz_broadcast );
403         }
404         else
405         {
406             /* Allocate room for "protocol://server:port" */
407             psz_source = malloc( strlen( psz_protocol ) + 3 /* "://" */
408                                    + strlen( psz_server ) + 1 /* ":" */
409                                    + 5 /* 0-65535 */ + 1 /* "\0" */ );
410             if( psz_source == NULL )
411             {
412                 return;
413             }
414            
415             /* Build source name and add it to playlist */
416             sprintf( psz_source, "%s://%s:%i",
417                      psz_protocol, psz_server, i_port );
418         }
419
420         intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, psz_source );
421         free( psz_source );
422         
423         /* catch the GTK CList */
424         p_playlist_clist = GTK_CLIST( gtk_object_get_data(
425             GTK_OBJECT( p_intf->p_sys->p_playlist ), "playlist_clist" ) );
426         /* update the display */
427         GtkRebuildCList( p_playlist_clist, p_main->p_playlist );
428
429         intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
430     }
431 }
432
433 void GtkNetworkOpenCancel( GtkButton * button, gpointer user_data)
434 {
435     gtk_widget_hide( gtk_widget_get_toplevel( GTK_WIDGET (button) ) );
436 }
437
438
439 void GtkNetworkOpenBroadcast( GtkToggleButton * togglebutton,
440                               gpointer user_data )
441 {
442     GtkWidget *     p_network;
443
444     p_network = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
445
446     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
447             "network_broadcast_combo" ),
448             gtk_toggle_button_get_active( togglebutton ) );
449
450     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
451             "network_broadcast" ),
452             gtk_toggle_button_get_active( togglebutton ) );
453 }
454
455
456 void GtkNetworkOpenChannel( GtkToggleButton * togglebutton,
457                             gpointer user_data )
458 {
459     GtkWidget *     p_network;
460     boolean_t       b_channel;
461     boolean_t       b_broadcast;
462
463     p_network = gtk_widget_get_toplevel( GTK_WIDGET (togglebutton) );
464     b_channel = gtk_toggle_button_get_active( togglebutton );
465     b_broadcast = gtk_toggle_button_get_active( gtk_object_get_data(
466                   GTK_OBJECT( p_network ), "network_broadcast_check" ) );
467         
468     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
469             "network_channel_combo" ), b_channel ) ;
470
471     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
472             "network_channel" ), b_channel );
473
474     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
475             "network_channel_port" ), b_channel );
476
477     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
478             "network_channel_port_label" ), b_channel );
479
480     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
481             "network_server_combo" ), ! b_channel );
482
483     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
484             "network_server_label" ), ! b_channel );
485
486     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
487             "network_server" ), ! b_channel );
488
489     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
490             "network_port_label" ), ! b_channel );
491
492     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
493             "network_port" ), ! b_channel );
494
495     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
496             "network_broadcast_check" ), ! b_channel );
497     
498     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
499             "network_broadcast_combo" ), b_broadcast && ! b_channel );
500
501     gtk_widget_set_sensitive( gtk_object_get_data( GTK_OBJECT( p_network ),
502             "network_broadcast" ), b_broadcast && ! b_channel );
503 }
504
505
506 /****************************************************************************
507  * Callbacks for menuitem
508  ****************************************************************************/
509 void GtkFileOpenActivate( GtkMenuItem * menuitem, gpointer user_data )
510 {
511     GtkFileOpenShow( GTK_WIDGET( menuitem ), NULL, user_data );
512 }
513
514
515 void GtkDiscOpenActivate( GtkMenuItem * menuitem, gpointer user_data )
516 {
517     GtkDiscOpenShow( GTK_WIDGET( menuitem ), NULL, user_data );
518 }
519
520
521 void GtkNetworkOpenActivate( GtkMenuItem * menuitem, gpointer user_data )
522 {
523     GtkNetworkOpenShow( GTK_WIDGET( menuitem ), NULL, user_data );
524 }
525