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.12 2002/10/30 22:42:26 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 static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url );
60 static 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 static 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;
137 printf( "Read directory: %s\n", psz_dir );
140 status = chdir(psz_dir);
142 intf_ErrMsg("File is not a directory.");
144 n = scandir(psz_dir, &namelist, 0, NULL);
146 printf( "n=%d\n", n);
154 gtk_clist_freeze( p_intf->p_sys->p_clist );
155 gtk_clist_clear( p_intf->p_sys->p_clist );
158 /* This is a list of strings. */
159 ppsz_text[0] = namelist[i]->d_name;
160 ppsz_text[1] = get_file_perm(namelist[i]->d_name);
161 printf( "Entry: %s, %s\n", namelist[i]->d_name, ppsz_text[1] );
162 gtk_clist_insert( p_intf->p_sys->p_clist, i, ppsz_text );
165 gtk_clist_thaw( p_intf->p_sys->p_clist );
170 void OpenDirectory( GtkCList *clist, char *psz_dir )
172 intf_thread_t *p_intf = GtkGetIntf( clist );
178 struct dirent* entry=NULL;
179 char entry_path[PATH_MAX+1];
187 strncpy( &entry_path[0], dir_path, sizeof(entry_path) );
188 /* always force end of string */
189 entry_path[PATH_MAX+1]='\0';
190 path_len = strlen(dir_path);
191 /* Make sure we do not run over our buffer here */
192 if (path_len > PATH_MAX)
194 /* Add backslash to directory path */
195 if (entry_path[path_len-1] != '/')
197 entry_path[path_len] = '/';
198 entry_path[path_len+1] = '\0';
201 printf( "path_len=%d\n", path_len );
202 printf( "entry_path=%s\n", entry_path);
204 if( p_intf->p_sys->p_clist == NULL )
205 intf_ErrMsg("OpenDirectory - ERROR p_intf->p_sys->p_clist == NULL");
206 gtk_clist_freeze( p_intf->p_sys->p_clist );
207 gtk_clist_clear( p_intf->p_sys->p_clist );
209 dir = opendir(dir_path);
210 if (!dir) perror("opendir");
211 while( (entry = readdir(dir))!=NULL )
213 if (!entry) perror("readdir");
214 printf( "sizeof(entry->d_name)=%d\n",sizeof(&(entry)->d_name[0]) );
215 printf( "entry->d_name=%s\n",&(entry->d_name)[0] );
217 strncpy( entry_path + path_len, &(entry)->d_name[0], sizeof(entry_path) - path_len );
218 /* always force end of string */
219 entry_path[PATH_MAX+1]='\0';
220 /* This is a list of strings. */
221 ppsz_text[0] = &(entry)->d_name[0];
222 ppsz_text[1] = get_file_perm(entry_path);
223 printf( "%-18s %s\n", ppsz_text[1], &(entry)->d_name[0] );
224 // gtk_clist_insert( p_intf->p_sys->p_clist, row, ppsz_text );
229 gtk_clist_thaw( p_intf->p_sys->p_clist );
232 static char* get_file_perm(const char *path)
237 perm = (char *) malloc(sizeof(char)*10);
238 strncpy( perm, "----------", sizeof("----------"));
239 if (lstat(path, &st)==0)
241 if (S_ISLNK(st.st_mode))
243 else if (S_ISDIR(st.st_mode))
245 else if (S_ISCHR(st.st_mode))
247 else if (S_ISBLK(st.st_mode))
249 else if (S_ISFIFO(st.st_mode))
251 else if (S_ISSOCK(st.st_mode))
253 else if (S_ISREG(st.st_mode))
255 else /* Unknown type is an error */
257 /* Get file permissions */
259 if (st.st_mode & S_IRUSR)
261 if (st.st_mode & S_IWUSR)
263 if (st.st_mode & S_IXUSR)
265 if (st.st_mode & S_ISUID)
270 else if (st.st_mode & S_ISUID)
273 if (st.st_mode & S_IRGRP)
275 if (st.st_mode & S_IWGRP)
277 if (st.st_mode & S_IXGRP)
279 if (st.st_mode & S_ISGID)
284 else if (st.st_mode & S_ISGID)
287 if (st.st_mode & S_IROTH)
289 if (st.st_mode & S_IWOTH)
291 if (st.st_mode & S_IXOTH)
294 if (st.st_mode &S_ISVTX)
299 else if (st.st_mode &S_ISVTX)
306 * Main interface callbacks
309 gboolean GtkExit( GtkWidget *widget,
312 intf_thread_t *p_intf = GtkGetIntf( widget );
314 vlc_mutex_lock( &p_intf->change_lock );
316 vlc_mutex_unlock( &p_intf->change_lock );
322 on_toolbar_open_clicked (GtkButton *button,
325 intf_thread_t *p_intf = GtkGetIntf( button );
327 if (p_intf->p_sys->p_notebook)
329 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
330 gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
332 gdk_window_raise( p_intf->p_sys->p_window->window );
333 if (p_intf->p_sys->p_clist)
335 ReadDirectory(p_intf->p_sys->p_clist, ".");
336 // OpenDirectory(p_intf->p_sys->p_clist, ".");
342 on_toolbar_preferences_clicked (GtkButton *button,
345 intf_thread_t *p_intf = GtkGetIntf( button );
347 if (p_intf->p_sys->p_notebook)
349 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
350 gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
352 gdk_window_raise( p_intf->p_sys->p_window->window );
357 on_toolbar_rewind_clicked (GtkButton *button,
360 // intf_thread_t * p_intf = GtkGetIntf( button );
362 if( p_input_bank->pp_input[0] != NULL )
364 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_SLOWER );
370 on_toolbar_pause_clicked (GtkButton *button,
373 // intf_thread_t * p_intf = GtkGetIntf( button );
375 if( p_input_bank->pp_input[0] != NULL )
377 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PAUSE );
383 on_toolbar_play_clicked (GtkButton *button,
386 intf_thread_t * p_intf = GtkGetIntf( button );
388 if( p_input_bank->pp_input[0] != NULL )
390 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
391 p_main->p_playlist->b_stopped = 0;
392 gdk_window_lower( p_intf->p_sys->p_window->window );
396 vlc_mutex_lock( &p_main->p_playlist->change_lock );
398 if( p_main->p_playlist->b_stopped )
400 if( p_main->p_playlist->i_size )
402 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
403 intf_PlaylistJumpto( p_main->p_playlist,
404 p_main->p_playlist->i_index );
408 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
409 /* simulate on open button click */
410 on_toolbar_open_clicked(button,user_data);
415 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
422 on_toolbar_stop_clicked (GtkButton *button,
425 intf_thread_t * p_intf = GtkGetIntf( button );
427 if( p_input_bank->pp_input[0] != NULL )
429 /* end playing item */
430 p_input_bank->pp_input[0]->b_eof = 1;
432 /* update playlist */
433 vlc_mutex_lock( &p_main->p_playlist->change_lock );
435 p_main->p_playlist->i_index--;
436 p_main->p_playlist->b_stopped = 1;
438 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
439 gdk_window_raise( p_intf->p_sys->p_window->window );
445 on_toolbar_forward_clicked (GtkButton *button,
448 // intf_thread_t * p_intf = GtkGetIntf( button );
450 if( p_input_bank->pp_input[0] != NULL )
452 input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_FASTER );
458 on_toolbar_about_clicked (GtkButton *button,
461 intf_thread_t *p_intf = GtkGetIntf( button );
464 if (p_intf->p_sys->p_notebook)
466 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
467 gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
469 gdk_window_raise( p_intf->p_sys->p_window->window );
474 on_comboURL_entry_changed (GtkEditable *editable,
477 intf_thread_t * p_intf = GtkGetIntf( editable );
481 psz_url = gtk_entry_get_text(GTK_ENTRY(editable));
482 if( (strncmp("file://",(const char *) psz_url,7)==0) ||
483 (strncmp("udp://",(const char *) psz_url,6)==0) ||
484 (strncmp("udp4://",(const char *) psz_url,7)==0) ||
485 (strncmp("udp6://",(const char *) psz_url,7)==0) ||
486 (strncmp("udpstream://",(const char *) psz_url,12)==0) ||
487 (strncmp("rtp://",(const char *) psz_url,6)==0) ||
488 (strncmp("rtp4://",(const char *) psz_url,7)==0) ||
489 (strncmp("rtp6://",(const char *) psz_url,7)==0) ||
490 (strncmp("rtpstream://",(const char *) psz_url,12)==0) ||
491 (strncmp("ftp://",(const char *) psz_url,6)==0) ||
492 (strncmp("http://",(const char *) psz_url,7)==0) )
494 MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
496 else if (lstat((char*)psz_url, &st)==0)
498 if (S_ISDIR(st.st_mode))
499 ReadDirectory(p_intf->p_sys->p_clist, psz_url);
500 // OpenDirectory(p_intf->p_sys->p_clist, psz_url);
501 else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
502 (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
503 (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
505 MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
511 on_clistmedia_click_column (GtkCList *clist,
515 static GtkSortType sort_type = GTK_SORT_ASCENDING;
517 // Should sort on column
520 case GTK_SORT_ASCENDING:
521 sort_type = GTK_SORT_DESCENDING;
523 case GTK_SORT_DESCENDING:
524 sort_type = GTK_SORT_ASCENDING;
527 gtk_clist_freeze( clist );
528 gtk_clist_set_sort_type( clist, sort_type );
529 gtk_clist_sort( clist );
530 gtk_clist_thaw( clist );
535 on_clistmedia_select_row (GtkCList *clist,
541 // intf_thread_t *p_intf = GtkGetIntf( clist );
542 intf_thread_t *p_intf = p_main->p_intf;
547 ret = gtk_clist_get_text (p_intf->p_sys->p_clist, row, 0, text);
550 if (lstat((char*)text[0], &st)==0)
552 if (S_ISDIR(st.st_mode))
553 ReadDirectory(p_intf->p_sys->p_clist, text[0]);
554 // OpenDirectory(p_intf->p_sys->p_clist, text[0]);
555 else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
556 (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
557 (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
559 MediaURLOpenChanged(GTK_WIDGET(p_intf->p_sys->p_clist), text[0]);
566 on_cbautoplay_toggled (GtkToggleButton *togglebutton,
573 on_familiar_delete_event (GtkWidget *widget,
577 GtkExit( GTK_WIDGET( widget ), user_data );
583 on_buttonSave_clicked (GtkButton *button,
586 intf_thread_t * p_intf = GtkGetIntf( button );
587 on_buttonApply_clicked( button, user_data );
588 config_PutIntVariable( "familiar-autoplayfile", p_intf->p_sys->b_autoplayfile );
589 // config_SaveConfigFile( NULL );
594 on_buttonApply_clicked (GtkButton *button,
597 intf_thread_t * p_intf = GtkGetIntf( button );
598 GtkWidget *cbautoplay;
600 cbautoplay = GTK_WIDGET( gtk_object_get_data(
601 GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
602 p_intf->p_sys->b_autoplayfile = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(cbautoplay));
607 on_buttonCancel_clicked (GtkButton *button,
610 intf_thread_t * p_intf = GtkGetIntf( button );
611 GtkWidget *cbautoplay;
613 cbautoplay = GTK_WIDGET( gtk_object_get_data(
614 GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
615 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(cbautoplay),p_intf->p_sys->b_autoplayfile);