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.5 2003/11/07 13:01:51 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 );
110 /*****************************************************************************
111 * Helper functions for URL changes in Media and Preferences notebook pages.
112 ****************************************************************************/
113 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
115 intf_thread_t *p_intf = GtkGetIntf( widget );
116 playlist_t *p_playlist;
117 GtkTreeView *p_tvplaylist;
119 p_playlist = (playlist_t *)
120 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
122 if( p_playlist == NULL)
129 if (p_intf->p_sys->b_autoplayfile)
131 playlist_Add( p_playlist, (char*)psz_url, 0, 0,
132 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END);
136 playlist_Add( p_playlist, (char*)psz_url, 0, 0,
137 PLAYLIST_APPEND, PLAYLIST_END );
139 vlc_object_release( p_playlist );
141 p_tvplaylist = (GtkTreeView*) lookup_widget( GTK_WIDGET(widget), "tvPlaylist" );
144 GtkListStore *p_liststore;
145 p_liststore = (GtkListStore *) gtk_tree_view_get_model(p_tvplaylist);
146 PlaylistRebuildListStore(p_liststore, p_playlist);
151 /*****************************************************************
152 * Read directory helper function.
153 ****************************************************************/
154 void ReadDirectory(GtkListStore *p_list, char *psz_dir )
157 struct dirent **namelist;
160 g_print("changing to dir %s\n", psz_dir);
163 status = chdir(psz_dir);
165 g_print( "permision denied\n" );
167 n = scandir(".", &namelist, 0, alphasort);
179 /* XXX : kludge temporaire pour yopy */
181 ppsz_text[1] = get_file_stat("..", &uid, &gid, &size);
186 /* Add a new row to the model */
187 gtk_list_store_append (p_list, &iter);
188 gtk_list_store_set (p_list, &iter,
196 if (ppsz_text[1]) free(ppsz_text[1]);
201 if (namelist[i]->d_name[0] != '.')
203 /* This is a list of strings. */
204 ppsz_text[0] = namelist[i]->d_name;
205 ppsz_text[1] = get_file_stat(namelist[i]->d_name, &uid, &gid, &size);
210 g_print( "(%d) file: %s permission: %s user: %ull group: %ull size: %ull\n", i, ppsz_text[0], ppsz_text[1], uid, gid, size );
212 gtk_list_store_append (p_list, &iter);
213 gtk_list_store_set (p_list, &iter,
221 if (ppsz_text[1]) free(ppsz_text[1]);
228 static char* get_file_stat(const char *path, uid_t *uid, gid_t *gid, off_t *size)
233 perm = (char *) malloc(sizeof(char)*10);
234 strncpy( perm, "----------", sizeof("----------"));
235 if (lstat(path, &st)==0)
237 /* user, group, filesize */
241 /* determine permission modes */
242 if (S_ISLNK(st.st_mode))
244 else if (S_ISDIR(st.st_mode))
246 else if (S_ISCHR(st.st_mode))
248 else if (S_ISBLK(st.st_mode))
250 else if (S_ISFIFO(st.st_mode))
252 else if (S_ISSOCK(st.st_mode))
254 else if (S_ISREG(st.st_mode))
256 else /* Unknown type is an error */
258 /* Get file permissions */
260 if (st.st_mode & S_IRUSR)
262 if (st.st_mode & S_IWUSR)
264 if (st.st_mode & S_IXUSR)
266 if (st.st_mode & S_ISUID)
271 else if (st.st_mode & S_ISUID)
274 if (st.st_mode & S_IRGRP)
276 if (st.st_mode & S_IWGRP)
278 if (st.st_mode & S_IXGRP)
280 if (st.st_mode & S_ISGID)
285 else if (st.st_mode & S_ISGID)
288 if (st.st_mode & S_IROTH)
290 if (st.st_mode & S_IWOTH)
292 if (st.st_mode & S_IXOTH)
295 if (st.st_mode &S_ISVTX)
300 else if (st.st_mode &S_ISVTX)
307 * Main interface callbacks
311 onPDADeleteEvent (GtkWidget *widget,
315 intf_thread_t *p_intf = GtkGetIntf( widget );
317 msg_Dbg( p_intf, "about to exit vlc ... " );
318 vlc_mutex_lock( &p_intf->change_lock );
319 p_intf->p_vlc->b_die = VLC_TRUE;
320 vlc_mutex_unlock( &p_intf->change_lock );
321 msg_Dbg( p_intf, "about to exit vlc ... signalled" );
328 onFileOpen (GtkButton *button,
331 intf_thread_t *p_intf = GtkGetIntf( button );
332 GtkListStore *p_list;
334 if (p_intf->p_sys->p_notebook)
336 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
337 gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
339 gdk_window_raise( p_intf->p_sys->p_window->window );
340 if (p_intf->p_sys->p_tvfile)
342 /* Get new directory listing */
343 p_list = gtk_list_store_new (5,
349 ReadDirectory(p_list, ".");
351 /* Update TreeView */
352 gtk_tree_view_set_model(p_intf->p_sys->p_tvfile, (GtkTreeModel*) p_list);
353 g_object_unref(p_list);
359 onPlaylist (GtkButton *button,
362 intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
365 if (p_intf->p_sys->p_notebook)
367 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
368 gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
370 gdk_window_raise( p_intf->p_sys->p_window->window );
375 onPreferences (GtkButton *button,
378 intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET( button ) );
380 if (p_intf->p_sys->p_notebook)
382 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
383 gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
385 gdk_window_raise( p_intf->p_sys->p_window->window );
390 onRewind (GtkButton *button,
393 intf_thread_t * p_intf = GtkGetIntf( button );
395 if( p_intf->p_sys->p_input != NULL )
397 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
403 onPause (GtkButton *button,
406 intf_thread_t * p_intf = GtkGetIntf( button );
408 if( p_intf->p_sys->p_input != NULL )
410 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
416 onPlay (GtkButton *button,
419 intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET( button ) );
420 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
422 if( p_playlist == NULL )
424 /* Display open page */
425 onFileOpen(button,user_data);
428 /* If the playlist is empty, open a file requester instead */
429 vlc_mutex_lock( &p_playlist->object_lock );
430 if( p_playlist->i_size )
432 vlc_mutex_unlock( &p_playlist->object_lock );
433 playlist_Play( p_playlist );
434 vlc_object_release( p_playlist );
435 gdk_window_lower( p_intf->p_sys->p_window->window );
439 vlc_mutex_unlock( &p_playlist->object_lock );
440 vlc_object_release( p_playlist );
441 /* Display open page */
442 onFileOpen(button,user_data);
448 onStop (GtkButton *button,
451 intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET( button ) );
452 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
456 playlist_Stop( p_playlist );
457 vlc_object_release( p_playlist );
458 gdk_window_raise( p_intf->p_sys->p_window->window );
464 onForward (GtkButton *button,
467 intf_thread_t * p_intf = GtkGetIntf( button );
469 if( p_intf->p_sys->p_input != NULL )
471 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
477 onAbout (GtkButton *button,
480 intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
483 if (p_intf->p_sys->p_notebook)
485 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
486 gtk_notebook_set_page(p_intf->p_sys->p_notebook,3);
488 gdk_window_raise( p_intf->p_sys->p_window->window );
493 SliderRelease (GtkWidget *widget,
494 GdkEventButton *event,
497 intf_thread_t *p_intf = GtkGetIntf( widget );
499 vlc_mutex_lock( &p_intf->change_lock );
500 p_intf->p_sys->b_slider_free = 1;
501 vlc_mutex_unlock( &p_intf->change_lock );
508 SliderPress (GtkWidget *widget,
509 GdkEventButton *event,
512 intf_thread_t *p_intf = GtkGetIntf( widget );
514 vlc_mutex_lock( &p_intf->change_lock );
515 p_intf->p_sys->b_slider_free = 0;
516 vlc_mutex_unlock( &p_intf->change_lock );
521 void addSelectedToPlaylist(GtkTreeModel *model,
526 GtkTreeView *p_tvplaylist = NULL;
529 gtk_tree_model_get(model, iter, 0, &filename, -1);
531 /* Add to playlist object. */
532 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(userdata), "tvPlaylist");
535 GtkTreeModel *p_play_model;
536 GtkTreeIter p_play_iter;
538 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
539 /* Add a new row to the playlist treeview model */
540 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
541 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
542 0, filename, /* Add path to it !!! */
545 /* do we need to unref ?? */
548 g_print("Error obtaining pointer to Play List");
552 onFileListRow (GtkTreeView *treeview,
554 GtkTreeViewColumn *column,
557 GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
559 if (gtk_tree_selection_count_selected_rows(selection) == 1)
566 /* This might be a directory selection */
567 model = gtk_tree_view_get_model(treeview);
569 g_print( "Error: model is a null pointer\n" );
570 if (!gtk_tree_model_get_iter(model, &iter, path))
571 g_print( "Error: could not get iter from model\n" );
573 gtk_tree_model_get(model, &iter, 0, &filename, -1);
575 if (stat((char*)filename, &st)==0)
577 if (S_ISDIR(st.st_mode))
579 GtkListStore *p_model = NULL;
581 /* Get new directory listing */
582 p_model = gtk_list_store_new (5,
589 g_print( "ERROR: model has a NULL pointer\n" );
590 ReadDirectory(p_model, filename);
592 /* Update TreeView with new model */
593 gtk_tree_view_set_model(treeview, (GtkTreeModel*) p_model);
594 g_object_unref(p_model);
598 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
604 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
610 onFileListColumns (GtkTreeView *treeview,
613 g_print("onFileListColumn\n");
618 onFileListRowSelected (GtkTreeView *treeview,
619 gboolean start_editing,
622 g_print("onFileListRowSelected\n");
628 onAddFileToPlaylist (GtkButton *button,
631 GtkTreeView *treeview = NULL;
633 treeview = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvFileList");
636 onFileListRow(treeview, NULL, NULL, NULL );
642 onEntryMRLChanged (GtkEditable *editable,
645 g_print("onMRLChanged\n");
650 onEntryMRLEditingDone (GtkCellEditable *celleditable,
653 g_print("onMRLEditingDone\n");
658 onNetworkPortChanged (GtkEditable *editable,
666 onEntryNetworkPortEditingDone (GtkCellEditable *celleditable,
674 onNetworkAddressChanged (GtkEditable *editable,
682 onEntryNetworkAddressEditingDone (GtkCellEditable *celleditable,
690 onNetworkTypeChanged (GtkEditable *editable,
698 onEntryNetworkTypeEditingDone (GtkCellEditable *celleditable,
706 onProtocolTypeChanged (GtkEditable *editable,
714 onEntryProtocolTypeEditingDone (GtkCellEditable *celleditable,
722 onMRLTypeChanged (GtkEditable *editable,
730 onEntryMRLTypeEditingDone (GtkCellEditable *celleditable,
738 onStreamTypeChanged (GtkEditable *editable,
746 onEntryStreamTypeEditingDone (GtkCellEditable *celleditable,
754 onAddNetworkPlaylist (GtkButton *button,
760 p_mrl = (GtkEntry*) lookup_widget(GTK_WIDGET(button),"" );
763 GtkTreeView *p_tvplaylist = NULL;
764 GtkTreeModel *p_play_model;
765 GtkTreeIter p_play_iter;
768 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvPlaylist");
771 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
772 /* Add a new row to the playlist treeview model */
773 gtk_list_store_append (p_play_model, &p_play_iter);
774 gtk_list_store_set (p_play_model, &p_play_iter,
775 0, name, /* Add path to it !!! */
778 /* do we need to unref ?? */
781 // msg_Err(p_intf, "Error obtaining pointer to Play List");
782 g_print("Error obtaining pointer to Play List");
789 onV4LAudioChanged (GtkEditable *editable,
797 onEntryV4LAudioEditingDone (GtkCellEditable *celleditable,
805 onV4LVideoChanged (GtkEditable *editable,
813 onEntryV4LVideoEditingDone (GtkCellEditable *celleditable,
821 onAddCameraToPlaylist (GtkButton *button,
829 onVideoDeviceChanged (GtkEditable *editable,
837 onEntryVideoDeviceEditingDone (GtkCellEditable *celleditable,
845 onVideoCodecChanged (GtkEditable *editable,
853 onEntryVideoCodecEditingDone (GtkCellEditable *celleditable,
861 onVideoBitrateChanged (GtkEditable *editable,
869 onVideoBitrateEditingDone (GtkCellEditable *celleditable,
877 onAudioDeviceChanged (GtkEditable *editable,
885 onEntryAudioDeviceEditingDone (GtkCellEditable *celleditable,
893 onAudioCodecChanged (GtkEditable *editable,
901 onEntryAudioCodecEditingDone (GtkCellEditable *celleditable,
909 onAudioBitrateChanged (GtkEditable *editable,
917 onAudioBitrateEditingDone (GtkCellEditable *celleditable,
925 onAddServerToPlaylist (GtkButton *button,
933 PlaylistEvent (GtkWidget *widget,
937 g_print("onPlaylistEvent\n");
943 onPlaylistColumnsChanged (GtkTreeView *treeview,
946 g_print("onPlaylistColumnsChanged\n");
951 onPlaylistRowSelected (GtkTreeView *treeview,
952 gboolean start_editing,
955 g_print("onPlaylistRowSelected\n");
961 onPlaylistRow (GtkTreeView *treeview,
963 GtkTreeViewColumn *column,
966 g_print("onPlaylistRow\n");
971 onUpdatePlaylist (GtkButton *button,
979 onDeletePlaylist (GtkButton *button,
987 onClearPlaylist (GtkButton *button,
995 onPreferenceSave (GtkButton *button,
1003 onPreferenceApply (GtkButton *button,
1011 onPreferenceCancel (GtkButton *button,