1 /*****************************************************************************
2 * pda_callbacks.c : Callbacks for the pda Linux Gtk+ plugin.
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: pda_callbacks.c,v 1.10 2003/11/09 15:55:23 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 *****************************************************************************/
27 #include <sys/types.h> /* off_t */
45 #include "pda_callbacks.h"
46 #include "pda_interface.h"
47 #include "pda_support.h"
50 static char* get_file_stat(const char *path, uid_t *uid, gid_t *gid, off_t *size);
52 /*****************************************************************************
53 * Useful function to retrieve p_intf
54 ****************************************************************************/
55 void * E_(__GtkGetIntf)( GtkWidget * widget )
59 if( GTK_IS_MENU_ITEM( widget ) )
61 /* Look for a GTK_MENU */
62 while( widget->parent && !GTK_IS_MENU( widget ) )
64 widget = widget->parent;
67 /* Maybe this one has the data */
68 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
74 /* Otherwise, the parent widget has it */
75 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
78 /* We look for the top widget */
79 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
81 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
86 void PlaylistRebuildListStore( GtkListStore * p_list, playlist_t * p_playlist )
96 vlc_mutex_lock( &p_playlist->object_lock );
97 for( i_dummy = p_playlist->i_size ; i_dummy-- ; )
99 ppsz_text[0] = p_playlist->pp_items[i_dummy]->psz_name;
100 ppsz_text[1] = "no info";
101 gtk_list_store_append (p_list, &iter);
102 gtk_list_store_set (p_list, &iter,
107 vlc_mutex_unlock( &p_playlist->object_lock );
111 /*****************************************************************************
112 * Helper functions for URL changes in Media and Preferences notebook pages.
113 ****************************************************************************/
114 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
116 intf_thread_t *p_intf = GtkGetIntf( widget );
117 playlist_t *p_playlist;
118 GtkTreeView *p_tvplaylist;
120 p_playlist = (playlist_t *)
121 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
123 if( p_playlist == NULL)
130 if (p_intf->p_sys->b_autoplayfile)
132 playlist_Add( p_playlist, (char*)psz_url, 0, 0,
133 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END);
137 playlist_Add( p_playlist, (char*)psz_url, 0, 0,
138 PLAYLIST_APPEND, PLAYLIST_END );
140 vlc_object_release( p_playlist );
142 p_tvplaylist = (GtkTreeView*) lookup_widget( GTK_WIDGET(widget), "tvPlaylist" );
145 GtkListStore *p_liststore;
146 p_liststore = (GtkListStore *) gtk_tree_view_get_model(p_tvplaylist);
147 PlaylistRebuildListStore(p_liststore, p_playlist);
152 /*****************************************************************
153 * Read directory helper function.
154 ****************************************************************/
155 void ReadDirectory(GtkListStore *p_list, char *psz_dir )
158 struct dirent **namelist;
161 g_print("changing to dir %s\n", psz_dir);
164 status = chdir(psz_dir);
166 g_print( "permision denied\n" );
168 n = scandir(".", &namelist, 0, alphasort);
180 /* XXX : kludge temporaire pour yopy */
182 ppsz_text[1] = get_file_stat("..", &uid, &gid, &size);
187 /* Add a new row to the model */
188 gtk_list_store_append (p_list, &iter);
189 gtk_list_store_set (p_list, &iter,
197 if (ppsz_text[1]) free(ppsz_text[1]);
202 if (namelist[i]->d_name[0] != '.')
204 /* This is a list of strings. */
205 ppsz_text[0] = namelist[i]->d_name;
206 ppsz_text[1] = get_file_stat(namelist[i]->d_name, &uid, &gid, &size);
211 g_print( "(%d) file: %s permission: %s user: %ull group: %ull size: %ull\n", i, ppsz_text[0], ppsz_text[1], uid, gid, size );
213 gtk_list_store_append (p_list, &iter);
214 gtk_list_store_set (p_list, &iter,
222 if (ppsz_text[1]) free(ppsz_text[1]);
229 static char* get_file_stat(const char *path, uid_t *uid, gid_t *gid, off_t *size)
234 perm = (char *) malloc(sizeof(char)*10);
235 strncpy( perm, "----------", sizeof("----------"));
236 if (lstat(path, &st)==0)
238 /* user, group, filesize */
242 /* determine permission modes */
243 if (S_ISLNK(st.st_mode))
245 else if (S_ISDIR(st.st_mode))
247 else if (S_ISCHR(st.st_mode))
249 else if (S_ISBLK(st.st_mode))
251 else if (S_ISFIFO(st.st_mode))
253 else if (S_ISSOCK(st.st_mode))
255 else if (S_ISREG(st.st_mode))
257 else /* Unknown type is an error */
259 /* Get file permissions */
261 if (st.st_mode & S_IRUSR)
263 if (st.st_mode & S_IWUSR)
265 if (st.st_mode & S_IXUSR)
267 if (st.st_mode & S_ISUID)
272 else if (st.st_mode & S_ISUID)
275 if (st.st_mode & S_IRGRP)
277 if (st.st_mode & S_IWGRP)
279 if (st.st_mode & S_IXGRP)
281 if (st.st_mode & S_ISGID)
286 else if (st.st_mode & S_ISGID)
289 if (st.st_mode & S_IROTH)
291 if (st.st_mode & S_IWOTH)
293 if (st.st_mode & S_IXOTH)
296 if (st.st_mode &S_ISVTX)
301 else if (st.st_mode &S_ISVTX)
308 * Main interface callbacks
312 onPDADeleteEvent (GtkWidget *widget,
316 intf_thread_t *p_intf = GtkGetIntf( widget );
318 msg_Dbg( p_intf, "about to exit vlc ... " );
319 vlc_mutex_lock( &p_intf->change_lock );
320 p_intf->p_vlc->b_die = VLC_TRUE;
321 vlc_mutex_unlock( &p_intf->change_lock );
322 msg_Dbg( p_intf, "about to exit vlc ... signalled" );
329 onRewind (GtkButton *button,
332 intf_thread_t * p_intf = GtkGetIntf( button );
334 if( p_intf->p_sys->p_input != NULL )
336 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
342 onPause (GtkButton *button,
345 intf_thread_t * p_intf = GtkGetIntf( button );
347 if( p_intf->p_sys->p_input != NULL )
349 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
355 onPlay (GtkButton *button,
358 intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET( button ) );
359 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
363 vlc_mutex_lock( &p_playlist->object_lock );
364 if( p_playlist->i_size )
366 vlc_mutex_unlock( &p_playlist->object_lock );
367 playlist_Play( p_playlist );
371 vlc_mutex_unlock( &p_playlist->object_lock );
373 vlc_object_release( p_playlist );
379 onStop (GtkButton *button,
382 intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET( button ) );
383 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
387 playlist_Stop( p_playlist );
388 vlc_object_release( p_playlist );
394 onForward (GtkButton *button,
397 intf_thread_t * p_intf = GtkGetIntf( button );
399 if( p_intf->p_sys->p_input != NULL )
401 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
407 onAbout (GtkButton *button,
410 intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
413 if (p_intf->p_sys->p_notebook)
415 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
416 gtk_notebook_set_page(p_intf->p_sys->p_notebook,6);
422 SliderRelease (GtkWidget *widget,
423 GdkEventButton *event,
426 intf_thread_t *p_intf = GtkGetIntf( widget );
428 vlc_mutex_lock( &p_intf->change_lock );
429 p_intf->p_sys->b_slider_free = 1;
430 vlc_mutex_unlock( &p_intf->change_lock );
437 SliderPress (GtkWidget *widget,
438 GdkEventButton *event,
441 intf_thread_t *p_intf = GtkGetIntf( widget );
443 vlc_mutex_lock( &p_intf->change_lock );
444 p_intf->p_sys->b_slider_free = 0;
445 vlc_mutex_unlock( &p_intf->change_lock );
450 void addSelectedToPlaylist(GtkTreeModel *model,
455 GtkTreeView *p_tvplaylist = NULL;
458 gtk_tree_model_get(model, iter, 0, &filename, -1);
460 /* Add to playlist object. */
461 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(userdata), "tvPlaylist");
464 GtkTreeModel *p_play_model;
465 GtkTreeIter p_play_iter;
467 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
471 /* Add a new row to the playlist treeview model */
472 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
473 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
474 0, filename, /* Add path to it !!! */
482 onFileListRow (GtkTreeView *treeview,
484 GtkTreeViewColumn *column,
487 GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
489 if (gtk_tree_selection_count_selected_rows(selection) == 1)
496 /* This might be a directory selection */
497 model = gtk_tree_view_get_model(treeview);
499 g_print( "Error: model is a null pointer\n" );
500 if (!gtk_tree_model_get_iter(model, &iter, path))
501 g_print( "Error: could not get iter from model\n" );
503 gtk_tree_model_get(model, &iter, 0, &filename, -1);
505 if (stat((char*)filename, &st)==0)
507 if (S_ISDIR(st.st_mode))
509 GtkListStore *p_model = NULL;
511 /* Get new directory listing */
512 p_model = gtk_list_store_new (5,
520 ReadDirectory(p_model, filename);
522 /* Update TreeView with new model */
523 gtk_tree_view_set_model(treeview, (GtkTreeModel*) p_model);
524 g_object_unref(p_model);
529 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
535 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
541 onFileListColumns (GtkTreeView *treeview,
544 g_print("onFileListColumn\n");
549 onFileListRowSelected (GtkTreeView *treeview,
550 gboolean start_editing,
553 g_print("onFileListRowSelected\n");
559 onAddFileToPlaylist (GtkButton *button,
562 GtkTreeView *treeview = NULL;
564 treeview = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvFileList");
567 onFileListRow(treeview, NULL, NULL, NULL );
573 NetworkBuildMRL (GtkEditable *editable,
576 GtkSpinButton *networkPort = NULL;
577 GtkEntry *entryMRL = NULL;
578 GtkEntry *networkType = NULL;
579 GtkEntry *networkAddress = NULL;
580 GtkEntry *networkProtocol = NULL;
581 const gchar *mrlNetworkType;
582 const gchar *mrlAddress;
583 const gchar *mrlProtocol;
585 #define VLC_MAX_MRL 256
586 char text[VLC_MAX_MRL];
589 entryMRL = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryMRL" );
591 networkType = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkType" );
592 networkAddress = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkAddress" );
593 networkPort = (GtkSpinButton*) lookup_widget( GTK_WIDGET(editable), "entryNetworkPort" );
594 networkProtocol = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkProtocolType" );
596 mrlNetworkType = gtk_entry_get_text(GTK_ENTRY(networkType));
597 mrlAddress = gtk_entry_get_text(GTK_ENTRY(networkAddress));
598 mrlPort = gtk_spin_button_get_value_as_int(networkPort);
599 mrlProtocol = gtk_entry_get_text(GTK_ENTRY(networkProtocol));
601 /* Build MRL from parts ;-) */
602 pos = snprintf( &text[0], VLC_MAX_MRL, "%s://", (char*)mrlProtocol);
603 if (strncasecmp( (char*)mrlNetworkType, "multicast",9)==0)
605 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "@" );
607 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "%s:%d", (char*)mrlAddress, (int)mrlPort );
609 if (pos >= VLC_MAX_MRL)
610 text[VLC_MAX_MRL-1]='\0';
612 gtk_entry_set_text(entryMRL,text);
617 onAddNetworkPlaylist (GtkButton *button,
620 GtkEntry *p_mrl = NULL;
621 GtkTreeView *p_tvplaylist = NULL;
622 GtkTreeModel *p_play_model;
623 GtkTreeIter p_play_iter;
624 const gchar *mrl_name;
626 p_mrl = (GtkEntry*) lookup_widget(GTK_WIDGET(button),"entryMRL" );
629 mrl_name = gtk_entry_get_text(p_mrl);
631 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvPlaylist");
632 if (NULL != p_tvplaylist)
634 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
636 /* Add a new row to the playlist treeview model */
637 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
638 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
639 0, mrl_name, /* Add path to it !!! */
648 onAddCameraToPlaylist (GtkButton *button,
656 PlaylistEvent (GtkWidget *widget,
660 g_print("onPlaylistEvent\n");
666 onPlaylistColumnsChanged (GtkTreeView *treeview,
669 g_print("onPlaylistColumnsChanged\n");
674 onPlaylistRowSelected (GtkTreeView *treeview,
675 gboolean start_editing,
678 g_print("onPlaylistRowSelected\n");
684 onPlaylistRow (GtkTreeView *treeview,
686 GtkTreeViewColumn *column,
689 g_print("onPlaylistRow\n");
694 onUpdatePlaylist (GtkButton *button,
702 onDeletePlaylist (GtkButton *button,
710 onClearPlaylist (GtkButton *button,
718 onPreferenceSave (GtkButton *button,
726 onPreferenceApply (GtkButton *button,
734 onPreferenceCancel (GtkButton *button,
743 onNetworkMRLAdd (GtkContainer *container,
753 V4LBuildMRL (GtkEditable *editable,
756 // GtkSpinButton *networkPort = NULL;
757 // GtkEntry *entryMRL = NULL;
763 onAddTranscodeToPlaylist (GtkButton *button,