]> git.sesse.net Git - vlc/blob - plugins/familiar/familiar_callbacks.c
Handling of URL is now fixed.
[vlc] / plugins / familiar / familiar_callbacks.c
1 /*****************************************************************************
2  * familiar_callbacks.c : Callbacks for the Familiar Linux Gtk+ plugin.
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: familiar_callbacks.c,v 1.6.2.9 2002/10/10 20:33:12 jpsaman Exp $
6  *
7  * Authors: Jean-Paul Saman <jpsaman@wxs.nl>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <sys/types.h>                                              /* off_t */
28 #include <stdlib.h>
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <dirent.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35
36 #include <videolan/vlc.h>
37
38 #include "stream_control.h"
39 #include "input_ext-intf.h"
40
41 #include "interface.h"
42 #include "intf_playlist.h"
43
44 #include "video.h"
45 #include "video_output.h"
46
47 #ifdef HAVE_CONFIG_H
48 #  include <config.h>
49 #endif
50
51 #include <gtk/gtk.h>
52
53 #include "familiar_callbacks.h"
54 #include "familiar_interface.h"
55 #include "familiar_support.h"
56 #include "familiar.h"
57
58 #include "netutils.h"
59
60 static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url );
61 static char* get_file_perm(const char *path);
62
63 /*****************************************************************************
64  * Useful function to retrieve p_intf
65  ****************************************************************************/
66 void * __GtkGetIntf( GtkWidget * widget )
67 {
68     void *p_data;
69
70     if( GTK_IS_MENU_ITEM( widget ) )
71     {
72         /* Look for a GTK_MENU */
73         while( widget->parent && !GTK_IS_MENU( widget ) )
74         {
75             widget = widget->parent;
76         }
77
78         /* Maybe this one has the data */
79         p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
80         if( p_data )
81         {
82             return p_data;
83         }
84
85         /* Otherwise, the parent widget has it */
86         widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
87     }
88
89     /* We look for the top widget */
90     widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
91
92     p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
93
94     return p_data;
95 }
96
97 /*****************************************************************************
98  * Helper functions for URL changes in Media and Preferences notebook pages.
99  ****************************************************************************/
100 static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
101 {
102     intf_thread_t *p_intf = GtkGetIntf( widget );
103     int            i_end = p_main->p_playlist->i_size;
104
105     // Add p_url to playlist .... but how ?
106     if( p_main->p_playlist )
107     {
108        intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_url );
109     }
110
111     if (p_intf->p_sys->b_autoplayfile)
112     {
113        /* end current item, select added item  */
114        if( p_input_bank->pp_input[0] != NULL )
115        {
116            p_input_bank->pp_input[0]->b_eof = 1;
117        }
118        intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
119
120        if( p_input_bank->pp_input[0] != NULL )
121        {
122            input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
123            p_main->p_playlist->b_stopped = 0;
124        }
125     }
126 }
127
128 /*****************************************************************
129  * Read directory helper function.
130  ****************************************************************/
131 void ReadDirectory( GtkCList *clist, char *psz_dir )
132 {
133     intf_thread_t *p_intf = GtkGetIntf( clist );
134     struct dirent **namelist;
135     int n=-1;
136     int status=-1;
137
138     if (psz_dir)
139     {
140        status = chdir(psz_dir);
141     }
142     if (status<0)
143       intf_ErrMsg("File is not a directory.");
144     else
145       n = scandir(".", &namelist, 0, NULL);
146
147     if (n<0)
148         perror("scandir");
149     else
150     {
151         gchar *ppsz_text[2];
152         int i;
153
154         if( p_intf->p_sys->p_clist == NULL )
155            intf_ErrMsg("ReadDirectory - ERROR p_intf->p_sys->p_clist == NULL");
156         gtk_clist_freeze( p_intf->p_sys->p_clist );
157         gtk_clist_clear( p_intf->p_sys->p_clist );
158         for (i=0; i<n; i++)
159         {
160             /* This is a list of strings. */
161             ppsz_text[0] = namelist[i]->d_name;
162             ppsz_text[1] = get_file_perm(namelist[i]->d_name);
163             if (strcmp(ppsz_text[1],"") == 0)
164                 intf_ErrMsg("File system error unknown filetype encountered.");
165             gtk_clist_insert( p_intf->p_sys->p_clist, i, ppsz_text );
166             free(namelist[i]);
167         }
168         gtk_clist_thaw( p_intf->p_sys->p_clist );
169         free(namelist);
170     }
171 }
172
173 static char* get_file_perm(const char *path)
174 {
175     struct stat st;
176     char *perm;
177
178     perm = (char *) malloc(sizeof(char)*10);
179     strncpy( perm, "----------", sizeof("----------"));
180     if (lstat(path, &st)==0)
181     {
182         if (S_ISLNK(st.st_mode))
183             perm[0]= 'l';
184         else if (S_ISDIR(st.st_mode))
185             perm[0]= 'd';
186         else if (S_ISCHR(st.st_mode))
187             perm[0]= 'c';
188         else if (S_ISBLK(st.st_mode))
189             perm[0]= 'b';
190         else if (S_ISFIFO(st.st_mode))
191             perm[0]= 'f';
192         else if (S_ISSOCK(st.st_mode))
193             perm[0]= 's';
194         else if (S_ISREG(st.st_mode))
195             perm[0]= '-';
196         else /* Unknown type is an error */
197             perm[0]= '?';
198         /* Get file permissions */
199         /* User */
200         if (st.st_mode & S_IRUSR)
201             perm[1]= 'r';
202         if (st.st_mode & S_IWUSR)
203             perm[2]= 'w';
204         if (st.st_mode & S_IXUSR)
205         {
206             if (st.st_mode & S_ISUID)
207                 perm[3] = 's';
208             else
209                 perm[3]= 'x';
210         }
211         else if (st.st_mode & S_ISUID)
212             perm[3] = 'S';
213         /* Group */
214         if (st.st_mode & S_IRGRP)
215             perm[4]= 'r';
216         if (st.st_mode & S_IWGRP)
217             perm[5]= 'w';
218         if (st.st_mode & S_IXGRP)
219         {
220             if (st.st_mode & S_ISGID)
221                 perm[6] = 's';
222             else
223                 perm[6]= 'x';
224         }
225         else if (st.st_mode & S_ISGID)
226             perm[6] = 'S';
227         /* Other */
228         if (st.st_mode & S_IROTH)
229             perm[7]= 'r';
230         if (st.st_mode & S_IWOTH)
231             perm[8]= 'w';
232         if (st.st_mode & S_IXOTH)
233         {
234             // 'sticky' bit
235             if (st.st_mode &S_ISVTX)
236                 perm[9] = 't';
237             else
238                 perm[9]= 'x';
239         }
240         else if (st.st_mode &S_ISVTX)
241             perm[9]= 'T';
242     }
243     return perm;
244 }
245
246 /*
247  * Main interface callbacks
248  */
249
250 gboolean GtkExit( GtkWidget       *widget,
251                   gpointer         user_data )
252 {
253     intf_thread_t *p_intf = GtkGetIntf( widget );
254
255     vlc_mutex_lock( &p_intf->change_lock );
256     p_intf->b_die = 1;
257     vlc_mutex_unlock( &p_intf->change_lock );
258
259     return TRUE;
260 }
261
262 void
263 on_toolbar_open_clicked                (GtkButton       *button,
264                                         gpointer         user_data)
265 {
266     intf_thread_t *p_intf = GtkGetIntf( button );
267
268     if (p_intf->p_sys->p_notebook)
269     {
270        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
271        gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
272     }
273     gdk_window_raise( p_intf->p_sys->p_window->window );
274     if (p_intf->p_sys->p_clist)
275     {
276        ReadDirectory(p_intf->p_sys->p_clist, ".");
277     }
278 }
279
280
281 void
282 on_toolbar_preferences_clicked         (GtkButton       *button,
283                                         gpointer         user_data)
284 {
285     intf_thread_t *p_intf = GtkGetIntf( button );
286
287     if (p_intf->p_sys->p_notebook)
288     {
289        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
290        gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
291     }
292     gdk_window_raise( p_intf->p_sys->p_window->window );
293 }
294
295
296 void
297 on_toolbar_rewind_clicked              (GtkButton       *button,
298                                         gpointer         user_data)
299 {
300 //    intf_thread_t *  p_intf = GtkGetIntf( button );
301
302     if( p_input_bank->pp_input[0] != NULL )
303     {
304         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_SLOWER );
305     }
306 }
307
308
309 void
310 on_toolbar_pause_clicked               (GtkButton       *button,
311                                         gpointer         user_data)
312 {
313 //    intf_thread_t *  p_intf = GtkGetIntf( button );
314
315     if( p_input_bank->pp_input[0] != NULL )
316     {
317         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PAUSE );
318     }
319 }
320
321
322 void
323 on_toolbar_play_clicked                (GtkButton       *button,
324                                         gpointer         user_data)
325 {
326     intf_thread_t *  p_intf = GtkGetIntf( button );
327
328     if( p_input_bank->pp_input[0] != NULL )
329     {
330         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
331         p_main->p_playlist->b_stopped = 0;
332         gdk_window_lower( p_intf->p_sys->p_window->window );
333     }
334     else
335     {
336         vlc_mutex_lock( &p_main->p_playlist->change_lock );
337
338         if( p_main->p_playlist->b_stopped )
339         {
340             if( p_main->p_playlist->i_size )
341             {
342                 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
343                 intf_PlaylistJumpto( p_main->p_playlist,
344                                      p_main->p_playlist->i_index );
345             }
346             else
347             {
348                 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
349                 /* simulate on open button click */
350                 on_toolbar_open_clicked(button,user_data);
351             }
352         }
353         else
354         {
355             vlc_mutex_unlock( &p_main->p_playlist->change_lock );
356         }
357     }
358 }
359
360
361 void
362 on_toolbar_stop_clicked                (GtkButton       *button,
363                                         gpointer         user_data)
364 {
365     intf_thread_t *  p_intf = GtkGetIntf( button );
366
367     if( p_input_bank->pp_input[0] != NULL )
368     {
369         /* end playing item */
370         p_input_bank->pp_input[0]->b_eof = 1;
371
372         /* update playlist */
373         vlc_mutex_lock( &p_main->p_playlist->change_lock );
374
375         p_main->p_playlist->i_index--;
376         p_main->p_playlist->b_stopped = 1;
377
378         vlc_mutex_unlock( &p_main->p_playlist->change_lock );
379         gdk_window_raise( p_intf->p_sys->p_window->window );
380     }
381 }
382
383
384 void
385 on_toolbar_forward_clicked             (GtkButton       *button,
386                                         gpointer         user_data)
387 {
388 //    intf_thread_t *  p_intf = GtkGetIntf( button );
389
390     if( p_input_bank->pp_input[0] != NULL )
391     {
392         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_FASTER );
393     }
394 }
395
396
397 void
398 on_toolbar_about_clicked               (GtkButton       *button,
399                                         gpointer         user_data)
400 {
401     intf_thread_t *p_intf = GtkGetIntf( button );
402
403     // Toggle notebook
404     if (p_intf->p_sys->p_notebook)
405     {
406         gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
407         gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
408     }
409     gdk_window_raise( p_intf->p_sys->p_window->window );
410 }
411
412
413 void
414 on_comboURL_entry_changed              (GtkEditable     *editable,
415                                         gpointer         user_data)
416 {
417     intf_thread_t * p_intf = GtkGetIntf( editable );
418     gchar *       psz_url;
419     struct stat st;
420
421     psz_url = gtk_entry_get_text(GTK_ENTRY(editable));
422     if( (strncmp("file://",(const char *) psz_url,7)==0) ||
423                     (strncmp("udp://",(const char *) psz_url,6)==0) ||
424                     (strncmp("udp4://",(const char *) psz_url,7)==0) ||         
425                         (strncmp("udp6://",(const char *) psz_url,7)==0) ||
426                     (strncmp("udpstream://",(const char *) psz_url,12)==0) ||
427                     (strncmp("rtp://",(const char *) psz_url,6)==0) ||
428                     (strncmp("rtp4://",(const char *) psz_url,7)==0) ||
429                     (strncmp("rtp6://",(const char *) psz_url,7)==0) ||
430                     (strncmp("rtpstream://",(const char *) psz_url,12)==0) ||
431                     (strncmp("http://",(const char *) psz_url,7)==0) )
432         {
433                 intf_ErrMsg( "comboURL change event - open URL" );
434         MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
435     }
436     else if (lstat((char*)psz_url, &st)==0)
437     {
438         if (S_ISDIR(st.st_mode))
439            ReadDirectory(p_intf->p_sys->p_clist, psz_url);
440         else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
441                  (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
442                  (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
443         {
444            MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
445         }
446    }
447 }
448
449 void
450 on_clistmedia_click_column             (GtkCList        *clist,
451                                         gint             column,
452                                         gpointer         user_data)
453 {
454     static GtkSortType sort_type = GTK_SORT_ASCENDING;
455
456     // Should sort on column
457     switch(sort_type)
458     {
459         case GTK_SORT_ASCENDING:
460             sort_type = GTK_SORT_DESCENDING;
461             break;
462         case GTK_SORT_DESCENDING:
463             sort_type = GTK_SORT_ASCENDING;
464             break;
465     }
466     gtk_clist_freeze( clist );
467     gtk_clist_set_sort_type( clist, sort_type );
468     gtk_clist_sort( clist );
469     gtk_clist_thaw( clist );
470 }
471
472
473 void
474 on_clistmedia_select_row               (GtkCList        *clist,
475                                         gint             row,
476                                         gint             column,
477                                         GdkEvent        *event,
478                                         gpointer         user_data)
479 {
480 //    intf_thread_t *p_intf = GtkGetIntf( clist );
481     intf_thread_t *p_intf = p_main->p_intf;
482     gchar *text[2];
483     gint ret;
484     struct stat st;
485
486     ret = gtk_clist_get_text (p_intf->p_sys->p_clist, row, 0, text);
487     if (ret)
488     {
489         if (lstat((char*)text[0], &st)==0)
490         {
491             if (S_ISDIR(st.st_mode))
492                ReadDirectory(p_intf->p_sys->p_clist, text[0]);
493             else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
494                      (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
495                      (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
496             {
497                MediaURLOpenChanged(GTK_WIDGET(p_intf->p_sys->p_clist), text[0]);
498             }
499        }
500     }
501 }
502
503 void
504 on_cbautoplay_toggled                  (GtkToggleButton *togglebutton,
505                                         gpointer         user_data)
506 {
507 };
508
509
510 gboolean
511 on_familiar_delete_event               (GtkWidget       *widget,
512                                         GdkEvent        *event,
513                                         gpointer         user_data)
514 {
515     GtkExit( GTK_WIDGET( widget ), user_data );
516     return TRUE;
517 }
518
519
520 void
521 on_buttonSave_clicked                  (GtkButton       *button,
522                                         gpointer         user_data)
523 {
524     intf_thread_t * p_intf = GtkGetIntf( button );
525     on_buttonApply_clicked( button, user_data );
526     config_PutIntVariable( "familiar-autoplayfile", p_intf->p_sys->b_autoplayfile );
527 //    config_SaveConfigFile( NULL );
528 }
529
530
531 void
532 on_buttonApply_clicked                 (GtkButton       *button,
533                                         gpointer         user_data)
534 {
535     intf_thread_t * p_intf = GtkGetIntf( button );
536     GtkWidget *cbautoplay;
537
538     cbautoplay = GTK_WIDGET( gtk_object_get_data(
539                    GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
540     p_intf->p_sys->b_autoplayfile = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(cbautoplay));
541 }
542
543
544 void
545 on_buttonCancel_clicked                (GtkButton       *button,
546                                         gpointer         user_data)
547 {
548     intf_thread_t * p_intf = GtkGetIntf( button );
549     GtkWidget *cbautoplay;
550
551     cbautoplay = GTK_WIDGET( gtk_object_get_data(
552                  GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
553     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(cbautoplay),p_intf->p_sys->b_autoplayfile);
554 }
555