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 $
7 * Authors: Jean-Paul Saman <jpsaman@wxs.nl>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <sys/types.h> /* off_t */
35 #include <videolan/vlc.h>
37 #include "stream_control.h"
38 #include "input_ext-intf.h"
40 #include "interface.h"
41 #include "intf_playlist.h"
44 #include "video_output.h"
52 #include "familiar_callbacks.h"
53 #include "familiar_interface.h"
54 #include "familiar_support.h"
59 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url );
60 char* get_file_perm(const char *path);
62 /*****************************************************************************
63 * Useful function to retrieve p_intf
64 ****************************************************************************/
65 void * __GtkGetIntf( GtkWidget * widget )
69 if( GTK_IS_MENU_ITEM( widget ) )
71 /* Look for a GTK_MENU */
72 while( widget->parent && !GTK_IS_MENU( widget ) )
74 widget = widget->parent;
77 /* Maybe this one has the data */
78 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
84 /* Otherwise, the parent widget has it */
85 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
88 /* We look for the top widget */
89 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
91 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
96 /*****************************************************************************
97 * Helper functions for URL changes in Media and Preferences notebook pages.
98 ****************************************************************************/
99 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
101 intf_thread_t *p_intf = GtkGetIntf( widget );
102 int i_end = p_main->p_playlist->i_size;
104 // Add p_url to playlist .... but how ?
105 if( p_main->p_playlist )
107 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_url );
110 if (p_intf->p_sys->b_autoplayfile)
112 /* end current item, select added item */
113 if( p_input_bank->pp_input[0] != NULL )
115 p_input_bank->pp_input[0]->b_eof = 1;
117 intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
119 if( p_input_bank->pp_input[0] != NULL )
121 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
122 p_main->p_playlist->b_stopped = 0;
127 /*****************************************************************
128 * Read directory helper function.
129 ****************************************************************/
130 void ReadDirectory( GtkCList *clist, char *psz_dir )
132 intf_thread_t *p_intf = GtkGetIntf( clist );
133 struct dirent **namelist=NULL;
137 printf( "Read directory: %s\n", psz_dir );
140 status = chdir(psz_dir);
143 intf_ErrMsg("File is not a directory.");
145 n = scandir(".", &namelist, NULL, NULL);
147 // printf( "n=%d\n", n);
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 );
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 );
170 gtk_clist_thaw( p_intf->p_sys->p_clist );
175 void OpenDirectory( GtkCList *clist, char *psz_dir )
177 intf_thread_t *p_intf = GtkGetIntf( clist );
183 struct dirent* entry=NULL;
184 char entry_path[PATH_MAX+1];
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)
199 /* Add backslash to directory path */
200 if (entry_path[path_len-1] != '/')
202 entry_path[path_len] = '/';
203 entry_path[path_len+1] = '\0';
206 printf( "path_len=%d\n", path_len );
207 printf( "entry_path=%s\n", entry_path);
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 );
214 dir = opendir(dir_path);
215 if (!dir) perror("opendir");
216 while( (entry = readdir(dir))!=NULL )
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] );
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 );
234 gtk_clist_thaw( p_intf->p_sys->p_clist );
237 char* get_file_perm(const char *path)
242 perm = (char *) malloc(sizeof(char)*10);
243 strncpy( perm, "----------", sizeof("----------"));
244 if (lstat(path, &st)==0)
246 if (S_ISLNK(st.st_mode))
248 else if (S_ISDIR(st.st_mode))
250 else if (S_ISCHR(st.st_mode))
252 else if (S_ISBLK(st.st_mode))
254 else if (S_ISFIFO(st.st_mode))
256 else if (S_ISSOCK(st.st_mode))
258 else if (S_ISREG(st.st_mode))
260 else /* Unknown type is an error */
262 /* Get file permissions */
264 if (st.st_mode & S_IRUSR)
266 if (st.st_mode & S_IWUSR)
268 if (st.st_mode & S_IXUSR)
270 if (st.st_mode & S_ISUID)
275 else if (st.st_mode & S_ISUID)
278 if (st.st_mode & S_IRGRP)
280 if (st.st_mode & S_IWGRP)
282 if (st.st_mode & S_IXGRP)
284 if (st.st_mode & S_ISGID)
289 else if (st.st_mode & S_ISGID)
292 if (st.st_mode & S_IROTH)
294 if (st.st_mode & S_IWOTH)
296 if (st.st_mode & S_IXOTH)
299 if (st.st_mode &S_ISVTX)
304 else if (st.st_mode &S_ISVTX)
311 * Main interface callbacks
314 gboolean GtkExit( GtkWidget *widget,
317 intf_thread_t *p_intf = GtkGetIntf( widget );
319 vlc_mutex_lock( &p_intf->change_lock );
321 vlc_mutex_unlock( &p_intf->change_lock );
327 on_toolbar_open_clicked (GtkButton *button,
330 intf_thread_t *p_intf = GtkGetIntf( button );
332 if (p_intf->p_sys->p_notebook)
334 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
335 gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
337 gdk_window_raise( p_intf->p_sys->p_window->window );
338 if (p_intf->p_sys->p_clist)
340 ReadDirectory(p_intf->p_sys->p_clist, ".");
341 // OpenDirectory(p_intf->p_sys->p_clist, ".");
347 on_toolbar_preferences_clicked (GtkButton *button,
350 intf_thread_t *p_intf = GtkGetIntf( button );
352 if (p_intf->p_sys->p_notebook)
354 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
355 gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
357 gdk_window_raise( p_intf->p_sys->p_window->window );
362 on_toolbar_rewind_clicked (GtkButton *button,
365 // intf_thread_t * p_intf = GtkGetIntf( button );
367 if( p_input_bank->pp_input[0] != NULL )
369 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_SLOWER );
375 on_toolbar_pause_clicked (GtkButton *button,
378 // intf_thread_t * p_intf = GtkGetIntf( button );
380 if( p_input_bank->pp_input[0] != NULL )
382 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PAUSE );
388 on_toolbar_play_clicked (GtkButton *button,
391 intf_thread_t * p_intf = GtkGetIntf( button );
393 if( p_input_bank->pp_input[0] != NULL )
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 );
401 vlc_mutex_lock( &p_main->p_playlist->change_lock );
403 if( p_main->p_playlist->b_stopped )
405 if( p_main->p_playlist->i_size )
407 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
408 intf_PlaylistJumpto( p_main->p_playlist,
409 p_main->p_playlist->i_index );
413 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
414 /* simulate on open button click */
415 on_toolbar_open_clicked(button,user_data);
420 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
427 on_toolbar_stop_clicked (GtkButton *button,
430 intf_thread_t * p_intf = GtkGetIntf( button );
432 if( p_input_bank->pp_input[0] != NULL )
434 /* end playing item */
435 p_input_bank->pp_input[0]->b_eof = 1;
437 /* update playlist */
438 vlc_mutex_lock( &p_main->p_playlist->change_lock );
440 p_main->p_playlist->i_index--;
441 p_main->p_playlist->b_stopped = 1;
443 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
444 gdk_window_raise( p_intf->p_sys->p_window->window );
450 on_toolbar_forward_clicked (GtkButton *button,
453 // intf_thread_t * p_intf = GtkGetIntf( button );
455 if( p_input_bank->pp_input[0] != NULL )
457 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_FASTER );
463 on_toolbar_about_clicked (GtkButton *button,
466 intf_thread_t *p_intf = GtkGetIntf( button );
469 if (p_intf->p_sys->p_notebook)
471 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
472 gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
474 gdk_window_raise( p_intf->p_sys->p_window->window );
479 on_comboURL_entry_changed (GtkEditable *editable,
482 intf_thread_t * p_intf = GtkGetIntf( editable );
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) )
499 MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
501 else if (lstat((char*)psz_url, &st)==0)
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)) )
510 MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
516 on_clistmedia_click_column (GtkCList *clist,
520 static GtkSortType sort_type = GTK_SORT_ASCENDING;
522 // Should sort on column
525 case GTK_SORT_ASCENDING:
526 sort_type = GTK_SORT_DESCENDING;
528 case GTK_SORT_DESCENDING:
529 sort_type = GTK_SORT_ASCENDING;
532 gtk_clist_freeze( clist );
533 gtk_clist_set_sort_type( clist, sort_type );
534 gtk_clist_sort( clist );
535 gtk_clist_thaw( clist );
540 on_clistmedia_select_row (GtkCList *clist,
546 // intf_thread_t *p_intf = GtkGetIntf( clist );
547 intf_thread_t *p_intf = p_main->p_intf;
552 ret = gtk_clist_get_text (p_intf->p_sys->p_clist, row, 0, text);
555 if (lstat((char*)text[0], &st)==0)
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)) )
564 MediaURLOpenChanged(GTK_WIDGET(p_intf->p_sys->p_clist), text[0]);
571 on_cbautoplay_toggled (GtkToggleButton *togglebutton,
578 on_familiar_delete_event (GtkWidget *widget,
582 GtkExit( GTK_WIDGET( widget ), user_data );
588 on_buttonSave_clicked (GtkButton *button,
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 );
599 on_buttonApply_clicked (GtkButton *button,
602 intf_thread_t * p_intf = GtkGetIntf( button );
603 GtkWidget *cbautoplay;
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));
612 on_buttonCancel_clicked (GtkButton *button,
615 intf_thread_t * p_intf = GtkGetIntf( button );
616 GtkWidget *cbautoplay;
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);