]> git.sesse.net Git - vlc/blob - plugins/familiar/familiar_callbacks.c
?
[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.11 2002/10/29 20:53:30 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 <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>                                              /* off_t */
32 #include <dirent.h>
33 #include <unistd.h>
34
35 #include <videolan/vlc.h>
36
37 #include "stream_control.h"
38 #include "input_ext-intf.h"
39
40 #include "interface.h"
41 #include "intf_playlist.h"
42
43 #include "video.h"
44 #include "video_output.h"
45
46 #ifdef HAVE_CONFIG_H
47 #  include <config.h>
48 #endif
49
50 #include <gtk/gtk.h>
51
52 #include "familiar_callbacks.h"
53 #include "familiar_interface.h"
54 #include "familiar_support.h"
55 #include "familiar.h"
56
57 #include "netutils.h"
58
59 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url );
60 char* get_file_perm(const char *path);
61
62 /*****************************************************************************
63  * Useful function to retrieve p_intf
64  ****************************************************************************/
65 void * __GtkGetIntf( GtkWidget * widget )
66 {
67     void *p_data;
68
69     if( GTK_IS_MENU_ITEM( widget ) )
70     {
71         /* Look for a GTK_MENU */
72         while( widget->parent && !GTK_IS_MENU( widget ) )
73         {
74             widget = widget->parent;
75         }
76
77         /* Maybe this one has the data */
78         p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
79         if( p_data )
80         {
81             return p_data;
82         }
83
84         /* Otherwise, the parent widget has it */
85         widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
86     }
87
88     /* We look for the top widget */
89     widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
90
91     p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
92
93     return p_data;
94 }
95
96 /*****************************************************************************
97  * Helper functions for URL changes in Media and Preferences notebook pages.
98  ****************************************************************************/
99 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
100 {
101     intf_thread_t *p_intf = GtkGetIntf( widget );
102     int            i_end = p_main->p_playlist->i_size;
103
104     // Add p_url to playlist .... but how ?
105     if( p_main->p_playlist )
106     {
107        intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_url );
108     }
109
110     if (p_intf->p_sys->b_autoplayfile)
111     {
112        /* end current item, select added item  */
113        if( p_input_bank->pp_input[0] != NULL )
114        {
115            p_input_bank->pp_input[0]->b_eof = 1;
116        }
117        intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
118
119        if( p_input_bank->pp_input[0] != NULL )
120        {
121            input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
122            p_main->p_playlist->b_stopped = 0;
123        }
124     }
125 }
126
127 /*****************************************************************
128  * Read directory helper function.
129  ****************************************************************/
130 void ReadDirectory( GtkCList *clist, char *psz_dir )
131 {
132     intf_thread_t *p_intf = GtkGetIntf( clist );
133     struct dirent **namelist=NULL;
134     int n=-1;
135     int status=-1;
136
137     printf( "Read directory: %s\n", psz_dir );
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, NULL, NULL);
146
147 //    printf( "n=%d\n", n);
148     if (n<0)
149         perror("scandir");
150     else
151     {
152         gchar *ppsz_text[2];
153         int i;
154
155         if( p_intf->p_sys->p_clist == NULL )
156            intf_ErrMsg("ReadDirectory - ERROR p_intf->p_sys->p_clist == NULL");
157         gtk_clist_freeze( p_intf->p_sys->p_clist );
158         gtk_clist_clear( p_intf->p_sys->p_clist );
159         for (i=0; i<n; i++)
160         {
161             /* This is a list of strings. */
162             ppsz_text[0] =  &(namelist[i])->d_name[0];
163             ppsz_text[1] =  get_file_perm(&(namelist[i])->d_name[0]);
164  //           printf( "Entry: %s, %s\n", &(namelist[i])->d_name[0], ppsz_text[1] );
165             if (strcmp(ppsz_text[1],"") == 0)
166                 intf_ErrMsg("File system error unknown filetype encountered.");
167             gtk_clist_insert( p_intf->p_sys->p_clist, i, ppsz_text );
168             free(namelist[i]);
169         }
170         gtk_clist_thaw( p_intf->p_sys->p_clist );
171         free(namelist);
172     }
173 }
174
175 void OpenDirectory( GtkCList *clist, char *psz_dir )
176 {
177     intf_thread_t *p_intf = GtkGetIntf( clist );
178     gchar *ppsz_text[2];
179     int row=0;
180
181     char* dir_path;
182     DIR* dir;
183     struct dirent* entry=NULL;
184     char entry_path[PATH_MAX+1];
185     size_t path_len;
186
187     if (psz_dir)
188        dir_path = psz_dir;
189     else
190        dir_path = ".";
191
192     strncpy( &entry_path[0], dir_path, sizeof(entry_path) );
193     /* always force end of string */
194     entry_path[PATH_MAX+1]='\0';
195     path_len = strlen(dir_path);
196     /* Make sure we do not run over our buffer here */
197     if (path_len > PATH_MAX)
198         path_len = PATH_MAX;
199     /* Add backslash to directory path */
200     if (entry_path[path_len-1] != '/')
201     {
202       entry_path[path_len] = '/';
203       entry_path[path_len+1] = '\0';
204       ++path_len;
205     }
206  printf( "path_len=%d\n", path_len );
207  printf( "entry_path=%s\n", entry_path);
208
209     if( p_intf->p_sys->p_clist == NULL )
210        intf_ErrMsg("OpenDirectory - ERROR p_intf->p_sys->p_clist == NULL");
211     gtk_clist_freeze( p_intf->p_sys->p_clist );
212     gtk_clist_clear( p_intf->p_sys->p_clist );
213
214     dir = opendir(dir_path);
215     if (!dir) perror("opendir");
216     while( (entry = readdir(dir))!=NULL )
217     {
218       if (!entry) perror("readdir");
219  printf( "sizeof(entry->d_name)=%d\n",sizeof(&(entry)->d_name[0]) );
220  printf( "entry->d_name=%s\n",&(entry->d_name)[0] );
221
222       strncpy( entry_path + path_len, &(entry)->d_name[0], sizeof(entry_path) - path_len );
223       /* always force end of string */
224       entry_path[PATH_MAX+1]='\0';
225       /* This is a list of strings. */
226       ppsz_text[0] = &(entry)->d_name[0];
227       ppsz_text[1] = get_file_perm(entry_path);
228  printf( "%-18s %s\n", ppsz_text[1], &(entry)->d_name[0] );
229 //      gtk_clist_insert( p_intf->p_sys->p_clist, row, ppsz_text );
230       row++;
231     }
232     closedir(dir);
233
234     gtk_clist_thaw( p_intf->p_sys->p_clist );
235 }
236
237 char* get_file_perm(const char *path)
238 {
239     struct stat st;
240     char *perm;
241
242     perm = (char *) malloc(sizeof(char)*10);
243     strncpy( perm, "----------", sizeof("----------"));
244     if (lstat(path, &st)==0)
245     {
246         if (S_ISLNK(st.st_mode))
247             perm[0]= 'l';
248         else if (S_ISDIR(st.st_mode))
249             perm[0]= 'd';
250         else if (S_ISCHR(st.st_mode))
251             perm[0]= 'c';
252         else if (S_ISBLK(st.st_mode))
253             perm[0]= 'b';
254         else if (S_ISFIFO(st.st_mode))
255             perm[0]= 'f';
256         else if (S_ISSOCK(st.st_mode))
257             perm[0]= 's';
258         else if (S_ISREG(st.st_mode))
259             perm[0]= '-';
260         else /* Unknown type is an error */
261             perm[0]= '?';
262         /* Get file permissions */
263         /* User */
264         if (st.st_mode & S_IRUSR)
265             perm[1]= 'r';
266         if (st.st_mode & S_IWUSR)
267             perm[2]= 'w';
268         if (st.st_mode & S_IXUSR)
269         {
270             if (st.st_mode & S_ISUID)
271                 perm[3] = 's';
272             else
273                 perm[3]= 'x';
274         }
275         else if (st.st_mode & S_ISUID)
276             perm[3] = 'S';
277         /* Group */
278         if (st.st_mode & S_IRGRP)
279             perm[4]= 'r';
280         if (st.st_mode & S_IWGRP)
281             perm[5]= 'w';
282         if (st.st_mode & S_IXGRP)
283         {
284             if (st.st_mode & S_ISGID)
285                 perm[6] = 's';
286             else
287                 perm[6]= 'x';
288         }
289         else if (st.st_mode & S_ISGID)
290             perm[6] = 'S';
291         /* Other */
292         if (st.st_mode & S_IROTH)
293             perm[7]= 'r';
294         if (st.st_mode & S_IWOTH)
295             perm[8]= 'w';
296         if (st.st_mode & S_IXOTH)
297         {
298             // 'sticky' bit
299             if (st.st_mode &S_ISVTX)
300                 perm[9] = 't';
301             else
302                 perm[9]= 'x';
303         }
304         else if (st.st_mode &S_ISVTX)
305             perm[9]= 'T';
306     }
307     return perm;
308 }
309
310 /*
311  * Main interface callbacks
312  */
313
314 gboolean GtkExit( GtkWidget       *widget,
315                   gpointer         user_data )
316 {
317     intf_thread_t *p_intf = GtkGetIntf( widget );
318
319     vlc_mutex_lock( &p_intf->change_lock );
320     p_intf->b_die = 1;
321     vlc_mutex_unlock( &p_intf->change_lock );
322
323     return TRUE;
324 }
325
326 void
327 on_toolbar_open_clicked                (GtkButton       *button,
328                                         gpointer         user_data)
329 {
330     intf_thread_t *p_intf = GtkGetIntf( button );
331
332     if (p_intf->p_sys->p_notebook)
333     {
334        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
335        gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
336     }
337     gdk_window_raise( p_intf->p_sys->p_window->window );
338     if (p_intf->p_sys->p_clist)
339     {
340        ReadDirectory(p_intf->p_sys->p_clist, ".");
341 //       OpenDirectory(p_intf->p_sys->p_clist, ".");
342     }
343 }
344
345
346 void
347 on_toolbar_preferences_clicked         (GtkButton       *button,
348                                         gpointer         user_data)
349 {
350     intf_thread_t *p_intf = GtkGetIntf( button );
351
352     if (p_intf->p_sys->p_notebook)
353     {
354        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
355        gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
356     }
357     gdk_window_raise( p_intf->p_sys->p_window->window );
358 }
359
360
361 void
362 on_toolbar_rewind_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         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_SLOWER );
370     }
371 }
372
373
374 void
375 on_toolbar_pause_clicked               (GtkButton       *button,
376                                         gpointer         user_data)
377 {
378 //    intf_thread_t *  p_intf = GtkGetIntf( button );
379
380     if( p_input_bank->pp_input[0] != NULL )
381     {
382         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PAUSE );
383     }
384 }
385
386
387 void
388 on_toolbar_play_clicked                (GtkButton       *button,
389                                         gpointer         user_data)
390 {
391     intf_thread_t *  p_intf = GtkGetIntf( button );
392
393     if( p_input_bank->pp_input[0] != NULL )
394     {
395         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
396         p_main->p_playlist->b_stopped = 0;
397         gdk_window_lower( p_intf->p_sys->p_window->window );
398     }
399     else
400     {
401         vlc_mutex_lock( &p_main->p_playlist->change_lock );
402
403         if( p_main->p_playlist->b_stopped )
404         {
405             if( p_main->p_playlist->i_size )
406             {
407                 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
408                 intf_PlaylistJumpto( p_main->p_playlist,
409                                      p_main->p_playlist->i_index );
410             }
411             else
412             {
413                 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
414                 /* simulate on open button click */
415                 on_toolbar_open_clicked(button,user_data);
416             }
417         }
418         else
419         {
420             vlc_mutex_unlock( &p_main->p_playlist->change_lock );
421         }
422     }
423 }
424
425
426 void
427 on_toolbar_stop_clicked                (GtkButton       *button,
428                                         gpointer         user_data)
429 {
430     intf_thread_t *  p_intf = GtkGetIntf( button );
431
432     if( p_input_bank->pp_input[0] != NULL )
433     {
434         /* end playing item */
435         p_input_bank->pp_input[0]->b_eof = 1;
436
437         /* update playlist */
438         vlc_mutex_lock( &p_main->p_playlist->change_lock );
439
440         p_main->p_playlist->i_index--;
441         p_main->p_playlist->b_stopped = 1;
442
443         vlc_mutex_unlock( &p_main->p_playlist->change_lock );
444         gdk_window_raise( p_intf->p_sys->p_window->window );
445     }
446 }
447
448
449 void
450 on_toolbar_forward_clicked             (GtkButton       *button,
451                                         gpointer         user_data)
452 {
453 //    intf_thread_t *  p_intf = GtkGetIntf( button );
454
455     if( p_input_bank->pp_input[0] != NULL )
456     {
457         input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_FASTER );
458     }
459 }
460
461
462 void
463 on_toolbar_about_clicked               (GtkButton       *button,
464                                         gpointer         user_data)
465 {
466     intf_thread_t *p_intf = GtkGetIntf( button );
467
468     // Toggle notebook
469     if (p_intf->p_sys->p_notebook)
470     {
471         gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
472         gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
473     }
474     gdk_window_raise( p_intf->p_sys->p_window->window );
475 }
476
477
478 void
479 on_comboURL_entry_changed              (GtkEditable     *editable,
480                                         gpointer         user_data)
481 {
482     intf_thread_t * p_intf = GtkGetIntf( editable );
483     gchar *       psz_url;
484     struct stat st;
485
486     psz_url = gtk_entry_get_text(GTK_ENTRY(editable));
487     if( (strncmp("file://",(const char *) psz_url,7)==0) ||
488         (strncmp("udp://",(const char *) psz_url,6)==0) ||
489         (strncmp("udp4://",(const char *) psz_url,7)==0) ||
490         (strncmp("udp6://",(const char *) psz_url,7)==0) ||
491         (strncmp("udpstream://",(const char *) psz_url,12)==0) ||
492         (strncmp("rtp://",(const char *) psz_url,6)==0) ||
493         (strncmp("rtp4://",(const char *) psz_url,7)==0) ||
494         (strncmp("rtp6://",(const char *) psz_url,7)==0) ||
495         (strncmp("rtpstream://",(const char *) psz_url,12)==0) ||
496         (strncmp("ftp://",(const char *) psz_url,6)==0) ||
497         (strncmp("http://",(const char *) psz_url,7)==0) )
498     {
499         MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
500     }
501     else if (lstat((char*)psz_url, &st)==0)
502     {
503         if (S_ISDIR(st.st_mode))
504            ReadDirectory(p_intf->p_sys->p_clist, psz_url);
505 //           OpenDirectory(p_intf->p_sys->p_clist, psz_url);
506         else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
507                  (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
508                  (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
509         {
510            MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
511         }
512    }
513 }
514
515 void
516 on_clistmedia_click_column             (GtkCList        *clist,
517                                         gint             column,
518                                         gpointer         user_data)
519 {
520     static GtkSortType sort_type = GTK_SORT_ASCENDING;
521
522     // Should sort on column
523     switch(sort_type)
524     {
525         case GTK_SORT_ASCENDING:
526             sort_type = GTK_SORT_DESCENDING;
527             break;
528         case GTK_SORT_DESCENDING:
529             sort_type = GTK_SORT_ASCENDING;
530             break;
531     }
532     gtk_clist_freeze( clist );
533     gtk_clist_set_sort_type( clist, sort_type );
534     gtk_clist_sort( clist );
535     gtk_clist_thaw( clist );
536 }
537
538
539 void
540 on_clistmedia_select_row               (GtkCList        *clist,
541                                         gint             row,
542                                         gint             column,
543                                         GdkEvent        *event,
544                                         gpointer         user_data)
545 {
546 //    intf_thread_t *p_intf = GtkGetIntf( clist );
547     intf_thread_t *p_intf = p_main->p_intf;
548     gchar *text[2];
549     gint ret;
550     struct stat st;
551
552     ret = gtk_clist_get_text (p_intf->p_sys->p_clist, row, 0, text);
553     if (ret)
554     {
555         if (lstat((char*)text[0], &st)==0)
556         {
557             if (S_ISDIR(st.st_mode))
558                ReadDirectory(p_intf->p_sys->p_clist, text[0]);
559 //               OpenDirectory(p_intf->p_sys->p_clist, text[0]);
560             else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
561                      (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
562                      (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
563             {
564                MediaURLOpenChanged(GTK_WIDGET(p_intf->p_sys->p_clist), text[0]);
565             }
566        }
567     }
568 }
569
570 void
571 on_cbautoplay_toggled                  (GtkToggleButton *togglebutton,
572                                         gpointer         user_data)
573 {
574 };
575
576
577 gboolean
578 on_familiar_delete_event               (GtkWidget       *widget,
579                                         GdkEvent        *event,
580                                         gpointer         user_data)
581 {
582     GtkExit( GTK_WIDGET( widget ), user_data );
583     return TRUE;
584 }
585
586
587 void
588 on_buttonSave_clicked                  (GtkButton       *button,
589                                         gpointer         user_data)
590 {
591     intf_thread_t * p_intf = GtkGetIntf( button );
592     on_buttonApply_clicked( button, user_data );
593     config_PutIntVariable( "familiar-autoplayfile", p_intf->p_sys->b_autoplayfile );
594 //    config_SaveConfigFile( NULL );
595 }
596
597
598 void
599 on_buttonApply_clicked                 (GtkButton       *button,
600                                         gpointer         user_data)
601 {
602     intf_thread_t * p_intf = GtkGetIntf( button );
603     GtkWidget *cbautoplay;
604
605     cbautoplay = GTK_WIDGET( gtk_object_get_data(
606                    GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
607     p_intf->p_sys->b_autoplayfile = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(cbautoplay));
608 }
609
610
611 void
612 on_buttonCancel_clicked                (GtkButton       *button,
613                                         gpointer         user_data)
614 {
615     intf_thread_t * p_intf = GtkGetIntf( button );
616     GtkWidget *cbautoplay;
617
618     cbautoplay = GTK_WIDGET( gtk_object_get_data(
619                  GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
620     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(cbautoplay),p_intf->p_sys->b_autoplayfile);
621 }
622