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.7 2003/11/08 16:04:05 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);
469 /* Add a new row to the playlist treeview model */
470 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
471 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
472 0, filename, /* Add path to it !!! */
477 g_print("Error obtaining pointer to Play List");
481 onFileListRow (GtkTreeView *treeview,
483 GtkTreeViewColumn *column,
486 GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
488 if (gtk_tree_selection_count_selected_rows(selection) == 1)
495 /* This might be a directory selection */
496 model = gtk_tree_view_get_model(treeview);
498 g_print( "Error: model is a null pointer\n" );
499 if (!gtk_tree_model_get_iter(model, &iter, path))
500 g_print( "Error: could not get iter from model\n" );
502 gtk_tree_model_get(model, &iter, 0, &filename, -1);
504 if (stat((char*)filename, &st)==0)
506 if (S_ISDIR(st.st_mode))
508 GtkListStore *p_model = NULL;
510 /* Get new directory listing */
511 p_model = gtk_list_store_new (5,
518 g_print( "ERROR: model has a NULL pointer\n" );
519 ReadDirectory(p_model, filename);
521 /* Update TreeView with new model */
522 gtk_tree_view_set_model(treeview, (GtkTreeModel*) p_model);
523 g_object_unref(p_model);
527 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
533 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
539 onFileListColumns (GtkTreeView *treeview,
542 g_print("onFileListColumn\n");
547 onFileListRowSelected (GtkTreeView *treeview,
548 gboolean start_editing,
551 g_print("onFileListRowSelected\n");
557 onAddFileToPlaylist (GtkButton *button,
560 GtkTreeView *treeview = NULL;
562 treeview = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvFileList");
565 onFileListRow(treeview, NULL, NULL, NULL );
571 onEntryMRLChanged (GtkEditable *editable,
578 onEntryMRLEditingDone (GtkCellEditable *celleditable,
581 g_print("onMRLEditingDone\n");
586 NetworkBuildMRL (GtkEditable *editable,
589 GtkSpinButton *networkPort = NULL;
590 GtkEntry *entryMRL = NULL;
591 GtkEntry *networkMRLType = NULL;
592 GtkEntry *networkAddress = NULL;
593 GtkEntry *networkProtocol = NULL;
594 GtkEntry *networkType = NULL;
595 const gchar *mrlType;
596 const gchar *mrlAddress;
598 const gchar *mrlProtocol;
599 const gchar *mrlNetworkType;
600 #define VLC_MAX_MRL 256
601 char text[VLC_MAX_MRL];
604 entryMRL = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryMRL" );
606 networkMRLType = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkMRLType" );
607 networkAddress = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkAddress" );
608 networkPort = (GtkSpinButton*) lookup_widget( GTK_WIDGET(editable), "entryNetworkPort" );
609 networkProtocol = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkProtocolType" );
610 networkType = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkType" );
612 mrlType = gtk_entry_get_text(GTK_ENTRY(networkMRLType));
613 mrlAddress = gtk_entry_get_text(GTK_ENTRY(networkAddress));
614 mrlPort = gtk_spin_button_get_value_as_int(networkPort);
615 mrlProtocol = gtk_entry_get_text(GTK_ENTRY(networkProtocol));
616 mrlNetworkType = gtk_entry_get_text(GTK_ENTRY(networkType));
618 /* Build MRL from parts ;-) */
619 pos = snprintf( &text[0], VLC_MAX_MRL, "%s", (char*)mrlType);
620 if (strncasecmp( (char*)mrlProtocol, "IPv6",4)==0 )
622 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "6://" );
623 if (strncasecmp( (char*)mrlNetworkType, "multicast",9)==0)
625 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "@" );
627 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "[%s]:%d", (char*)mrlAddress, (int)mrlPort );
631 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "://" );
632 if (strncasecmp( (char*)mrlNetworkType, "multicast",9)==0)
634 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "@" );
636 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "%s:%d", (char*)mrlAddress, (int)mrlPort );
639 if (pos >= VLC_MAX_MRL)
640 text[VLC_MAX_MRL-1]='\0';
642 gtk_entry_set_text(entryMRL,text);
647 onAddNetworkPlaylist (GtkButton *button,
650 GtkEntry *p_mrl = NULL;
651 GtkTreeView *p_tvplaylist = NULL;
652 GtkTreeModel *p_play_model;
653 GtkTreeIter p_play_iter;
654 const gchar *mrl_name;
656 p_mrl = (GtkEntry*) lookup_widget(GTK_WIDGET(button),"entryMRL" );
659 mrl_name = gtk_entry_get_text(p_mrl);
661 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvPlaylist");
662 if (NULL != p_tvplaylist)
664 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
666 /* Add a new row to the playlist treeview model */
667 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
668 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
669 0, mrl_name, /* Add path to it !!! */
678 onV4LAudioChanged (GtkEditable *editable,
686 onEntryV4LAudioEditingDone (GtkCellEditable *celleditable,
694 onV4LVideoChanged (GtkEditable *editable,
702 onEntryV4LVideoEditingDone (GtkCellEditable *celleditable,
710 onAddCameraToPlaylist (GtkButton *button,
718 onVideoDeviceChanged (GtkEditable *editable,
726 onEntryVideoDeviceEditingDone (GtkCellEditable *celleditable,
734 onVideoCodecChanged (GtkEditable *editable,
742 onEntryVideoCodecEditingDone (GtkCellEditable *celleditable,
750 onVideoBitrateChanged (GtkEditable *editable,
758 onVideoBitrateEditingDone (GtkCellEditable *celleditable,
766 onAudioDeviceChanged (GtkEditable *editable,
774 onEntryAudioDeviceEditingDone (GtkCellEditable *celleditable,
782 onAudioCodecChanged (GtkEditable *editable,
790 onEntryAudioCodecEditingDone (GtkCellEditable *celleditable,
798 onAudioBitrateChanged (GtkEditable *editable,
806 onAudioBitrateEditingDone (GtkCellEditable *celleditable,
814 onAddServerToPlaylist (GtkButton *button,
822 PlaylistEvent (GtkWidget *widget,
826 g_print("onPlaylistEvent\n");
832 onPlaylistColumnsChanged (GtkTreeView *treeview,
835 g_print("onPlaylistColumnsChanged\n");
840 onPlaylistRowSelected (GtkTreeView *treeview,
841 gboolean start_editing,
844 g_print("onPlaylistRowSelected\n");
850 onPlaylistRow (GtkTreeView *treeview,
852 GtkTreeViewColumn *column,
855 g_print("onPlaylistRow\n");
860 onUpdatePlaylist (GtkButton *button,
868 onDeletePlaylist (GtkButton *button,
876 onClearPlaylist (GtkButton *button,
884 onPreferenceSave (GtkButton *button,
892 onPreferenceApply (GtkButton *button,
900 onPreferenceCancel (GtkButton *button,
909 onNetworkMRLAdd (GtkContainer *container,