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