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.12 2003/11/09 19:49:48 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 #define VLC_MAX_MRL 256
52 static char* get_file_stat(const char *path, uid_t *uid, gid_t *gid, off_t *size);
54 /*****************************************************************************
55 * Useful function to retrieve p_intf
56 ****************************************************************************/
57 void * E_(__GtkGetIntf)( GtkWidget * widget )
61 if( GTK_IS_MENU_ITEM( widget ) )
63 /* Look for a GTK_MENU */
64 while( widget->parent && !GTK_IS_MENU( widget ) )
66 widget = widget->parent;
69 /* Maybe this one has the data */
70 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
76 /* Otherwise, the parent widget has it */
77 widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
80 /* We look for the top widget */
81 widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
83 p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
88 void PlaylistRebuildListStore( GtkListStore * p_list, playlist_t * p_playlist )
98 vlc_mutex_lock( &p_playlist->object_lock );
99 for( i_dummy = p_playlist->i_size ; i_dummy-- ; )
101 ppsz_text[0] = p_playlist->pp_items[i_dummy]->psz_name;
102 ppsz_text[1] = "no info";
103 gtk_list_store_append (p_list, &iter);
104 gtk_list_store_set (p_list, &iter,
109 vlc_mutex_unlock( &p_playlist->object_lock );
113 /*****************************************************************************
114 * Helper functions for URL changes in Media and Preferences notebook pages.
115 ****************************************************************************/
116 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
118 intf_thread_t *p_intf = GtkGetIntf( widget );
119 playlist_t *p_playlist;
120 GtkTreeView *p_tvplaylist;
122 p_playlist = (playlist_t *)
123 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
125 if( p_playlist == NULL)
132 if (p_intf->p_sys->b_autoplayfile)
134 playlist_Add( p_playlist, (char*)psz_url, 0, 0,
135 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END);
139 playlist_Add( p_playlist, (char*)psz_url, 0, 0,
140 PLAYLIST_APPEND, PLAYLIST_END );
142 vlc_object_release( p_playlist );
144 p_tvplaylist = (GtkTreeView*) lookup_widget( GTK_WIDGET(widget), "tvPlaylist" );
147 GtkListStore *p_liststore;
148 p_liststore = (GtkListStore *) gtk_tree_view_get_model(p_tvplaylist);
149 PlaylistRebuildListStore(p_liststore, p_playlist);
154 /*****************************************************************
155 * Read directory helper function.
156 ****************************************************************/
157 void ReadDirectory(GtkListStore *p_list, char *psz_dir )
160 struct dirent **namelist;
163 g_print("changing to dir %s\n", psz_dir);
166 status = chdir(psz_dir);
168 g_print( "permision denied\n" );
170 n = scandir(".", &namelist, 0, alphasort);
182 /* XXX : kludge temporaire pour yopy */
184 ppsz_text[1] = get_file_stat("..", &uid, &gid, &size);
189 /* Add a new row to the model */
190 gtk_list_store_append (p_list, &iter);
191 gtk_list_store_set (p_list, &iter,
199 if (ppsz_text[1]) free(ppsz_text[1]);
204 if (namelist[i]->d_name[0] != '.')
206 /* This is a list of strings. */
207 ppsz_text[0] = namelist[i]->d_name;
208 ppsz_text[1] = get_file_stat(namelist[i]->d_name, &uid, &gid, &size);
213 g_print( "(%d) file: %s permission: %s user: %ull group: %ull size: %ull\n", i, ppsz_text[0], ppsz_text[1], uid, gid, size );
215 gtk_list_store_append (p_list, &iter);
216 gtk_list_store_set (p_list, &iter,
224 if (ppsz_text[1]) free(ppsz_text[1]);
231 static char* get_file_stat(const char *path, uid_t *uid, gid_t *gid, off_t *size)
236 perm = (char *) malloc(sizeof(char)*10);
237 strncpy( perm, "----------", sizeof("----------"));
238 if (lstat(path, &st)==0)
240 /* user, group, filesize */
244 /* determine permission modes */
245 if (S_ISLNK(st.st_mode))
247 else if (S_ISDIR(st.st_mode))
249 else if (S_ISCHR(st.st_mode))
251 else if (S_ISBLK(st.st_mode))
253 else if (S_ISFIFO(st.st_mode))
255 else if (S_ISSOCK(st.st_mode))
257 else if (S_ISREG(st.st_mode))
259 else /* Unknown type is an error */
261 /* Get file permissions */
263 if (st.st_mode & S_IRUSR)
265 if (st.st_mode & S_IWUSR)
267 if (st.st_mode & S_IXUSR)
269 if (st.st_mode & S_ISUID)
274 else if (st.st_mode & S_ISUID)
277 if (st.st_mode & S_IRGRP)
279 if (st.st_mode & S_IWGRP)
281 if (st.st_mode & S_IXGRP)
283 if (st.st_mode & S_ISGID)
288 else if (st.st_mode & S_ISGID)
291 if (st.st_mode & S_IROTH)
293 if (st.st_mode & S_IWOTH)
295 if (st.st_mode & S_IXOTH)
298 if (st.st_mode &S_ISVTX)
303 else if (st.st_mode &S_ISVTX)
310 * Main interface callbacks
314 onPDADeleteEvent (GtkWidget *widget,
318 intf_thread_t *p_intf = GtkGetIntf( widget );
320 msg_Dbg( p_intf, "about to exit vlc ... " );
321 vlc_mutex_lock( &p_intf->change_lock );
322 p_intf->p_vlc->b_die = VLC_TRUE;
323 vlc_mutex_unlock( &p_intf->change_lock );
324 msg_Dbg( p_intf, "about to exit vlc ... signalled" );
331 onRewind (GtkButton *button,
334 intf_thread_t * p_intf = GtkGetIntf( button );
336 if (p_intf->p_sys->p_input != NULL)
338 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
344 onPause (GtkButton *button,
347 intf_thread_t * p_intf = GtkGetIntf( button );
349 if (p_intf->p_sys->p_input != NULL)
351 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
357 onPlay (GtkButton *button,
360 intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET( button ) );
361 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
365 vlc_mutex_lock( &p_playlist->object_lock );
366 if (p_playlist->i_size)
368 vlc_mutex_unlock( &p_playlist->object_lock );
369 playlist_Play( p_playlist );
373 vlc_mutex_unlock( &p_playlist->object_lock );
375 vlc_object_release( p_playlist );
381 onStop (GtkButton *button,
384 intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET( button ) );
385 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
389 playlist_Stop( p_playlist );
390 vlc_object_release( p_playlist );
396 onForward (GtkButton *button,
399 intf_thread_t *p_intf = GtkGetIntf( button );
401 if (p_intf->p_sys->p_input != NULL)
403 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
409 onAbout (GtkButton *button,
412 intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
415 if (p_intf->p_sys->p_notebook)
417 gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
418 gtk_notebook_set_page(p_intf->p_sys->p_notebook,6);
424 SliderRelease (GtkWidget *widget,
425 GdkEventButton *event,
428 intf_thread_t *p_intf = GtkGetIntf( widget );
430 vlc_mutex_lock( &p_intf->change_lock );
431 p_intf->p_sys->b_slider_free = 1;
432 vlc_mutex_unlock( &p_intf->change_lock );
439 SliderPress (GtkWidget *widget,
440 GdkEventButton *event,
443 intf_thread_t *p_intf = GtkGetIntf( widget );
445 vlc_mutex_lock( &p_intf->change_lock );
446 p_intf->p_sys->b_slider_free = 0;
447 vlc_mutex_unlock( &p_intf->change_lock );
452 void addSelectedToPlaylist(GtkTreeModel *model,
457 GtkTreeView *p_tvplaylist = NULL;
460 gtk_tree_model_get(model, iter, 0, &filename, -1);
462 /* Add to playlist object. */
463 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(userdata), "tvPlaylist");
466 GtkTreeModel *p_play_model;
467 GtkTreeIter p_play_iter;
469 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
473 /* Add a new row to the playlist treeview model */
474 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
475 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
476 0, filename, /* Add path to it !!! */
484 onFileListRow (GtkTreeView *treeview,
486 GtkTreeViewColumn *column,
489 GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
491 if (gtk_tree_selection_count_selected_rows(selection) == 1)
498 /* This might be a directory selection */
499 model = gtk_tree_view_get_model(treeview);
501 g_print( "Error: model is a null pointer\n" );
502 if (!gtk_tree_model_get_iter(model, &iter, path))
503 g_print( "Error: could not get iter from model\n" );
505 gtk_tree_model_get(model, &iter, 0, &filename, -1);
507 if (stat((char*)filename, &st)==0)
509 if (S_ISDIR(st.st_mode))
511 GtkListStore *p_model = NULL;
513 /* Get new directory listing */
514 p_model = gtk_list_store_new (5,
522 ReadDirectory(p_model, filename);
524 /* Update TreeView with new model */
525 gtk_tree_view_set_model(treeview, (GtkTreeModel*) p_model);
526 g_object_unref(p_model);
531 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
537 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
543 onFileListColumns (GtkTreeView *treeview,
546 g_print("onFileListColumn\n");
551 onFileListRowSelected (GtkTreeView *treeview,
552 gboolean start_editing,
555 g_print("onFileListRowSelected\n");
561 onAddFileToPlaylist (GtkButton *button,
564 GtkTreeView *treeview = NULL;
566 treeview = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvFileList");
569 onFileListRow(treeview, NULL, NULL, NULL );
575 NetworkBuildMRL (GtkEditable *editable,
578 GtkSpinButton *networkPort = NULL;
579 GtkEntry *entryMRL = NULL;
580 GtkEntry *networkType = NULL;
581 GtkEntry *networkAddress = NULL;
582 GtkEntry *networkProtocol = NULL;
583 const gchar *mrlNetworkType;
584 const gchar *mrlAddress;
585 const gchar *mrlProtocol;
587 char text[VLC_MAX_MRL];
590 entryMRL = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryMRL" );
592 networkType = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkType" );
593 networkAddress = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkAddress" );
594 networkPort = (GtkSpinButton*) lookup_widget( GTK_WIDGET(editable), "entryNetworkPort" );
595 networkProtocol = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkProtocolType" );
597 mrlNetworkType = gtk_entry_get_text(GTK_ENTRY(networkType));
598 mrlAddress = gtk_entry_get_text(GTK_ENTRY(networkAddress));
599 mrlPort = gtk_spin_button_get_value_as_int(networkPort);
600 mrlProtocol = gtk_entry_get_text(GTK_ENTRY(networkProtocol));
602 /* Build MRL from parts ;-) */
603 pos = snprintf( &text[0], VLC_MAX_MRL, "%s://", (char*)mrlProtocol);
604 if (strncasecmp( (char*)mrlNetworkType, "multicast",9)==0)
606 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "@" );
608 pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "%s:%d", (char*)mrlAddress, (int)mrlPort );
610 if (pos >= VLC_MAX_MRL)
611 text[VLC_MAX_MRL-1]='\0';
613 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,
651 GtkTreeView *p_tvplaylist = NULL;
652 GtkTreeModel *p_play_model;
653 GtkTreeIter p_play_iter;
655 GtkSpinButton *entryV4LChannel = NULL;
656 GtkSpinButton *entryV4LFrequency = NULL;
657 GtkSpinButton *entryV4LSampleRate = NULL;
658 GtkSpinButton *entryV4LQuality = NULL;
659 GtkSpinButton *entryV4LTuner = NULL;
661 gint i_v4l_frequency;
662 gint i_v4l_samplerate;
666 GtkEntry *entryV4LVideoDevice = NULL;
667 GtkEntry *entryV4LAudioDevice = NULL;
668 GtkEntry *entryV4LNorm = NULL;
669 GtkEntry *entryV4LSize = NULL;
670 GtkEntry *entryV4LSoundDirection = NULL;
671 const gchar *p_v4l_video_device;
672 const gchar *p_v4l_audio_device;
673 const gchar *p_v4l_norm;
674 const gchar *p_v4l_size;
675 const gchar *p_v4l_sound_direction;
678 GtkCheckButton *checkV4LMJPEG = NULL;
679 GtkSpinButton *entryV4LDecimation = NULL;
680 gboolean b_v4l_mjpeg;
681 gint i_v4l_decimation;
684 char v4l_mrl[VLC_MAX_MRL];
687 pos = snprintf( &v4l_mrl[0], VLC_MAX_MRL, "v4l://");
689 entryV4LChannel = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LChannel" );
690 entryV4LFrequency = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LFrequency" );
691 entryV4LSampleRate = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LSampleRate" );
692 entryV4LQuality = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LQuality" );
693 entryV4LTuner = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LTuner" );
695 entryV4LVideoDevice = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LVideoDevice" );
696 entryV4LAudioDevice = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LAudioDevice" );
697 entryV4LNorm = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LNorm" );
698 entryV4LSize = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LSize" );
699 entryV4LSoundDirection = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LSoundDirection" );
701 i_v4l_channel = gtk_spin_button_get_value_as_int(entryV4LChannel);
702 i_v4l_frequency = gtk_spin_button_get_value_as_int(entryV4LFrequency);
703 i_v4l_samplerate = gtk_spin_button_get_value_as_int(entryV4LSampleRate);
704 i_v4l_quality = gtk_spin_button_get_value_as_int(entryV4LQuality);
705 i_v4l_tuner = gtk_spin_button_get_value_as_int(entryV4LTuner);
707 p_v4l_video_device = gtk_entry_get_text(GTK_ENTRY(entryV4LVideoDevice));
708 p_v4l_audio_device = gtk_entry_get_text(GTK_ENTRY(entryV4LAudioDevice));
709 p_v4l_norm = gtk_entry_get_text(GTK_ENTRY(entryV4LNorm));
710 p_v4l_size = gtk_entry_get_text(GTK_ENTRY(entryV4LSize));
711 p_v4l_sound_direction = gtk_entry_get_text(GTK_ENTRY(entryV4LSoundDirection));
713 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":%s", (char*)p_v4l_video_device );
714 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":adev=%s", (char*)p_v4l_audio_device );
715 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":norm=%s", (char*)p_v4l_norm );
716 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":size=%s", (char*)p_v4l_size );
717 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":%s", (char*)p_v4l_sound_direction );
719 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":channel=%d", (int)i_v4l_channel );
720 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":frequency=%d", (int)i_v4l_frequency );
721 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":samplerate=%d", (int)i_v4l_samplerate );
722 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":quality=%d", (int)i_v4l_quality );
723 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":tuner=%d", (int)i_v4l_tuner );
726 checkV4LMJPEG = (GtkCheckButton*) lookup_widget( GTK_WIDGET(button), "checkV4LMJPEG" );
727 b_v4l_mjpeg = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkV4LMJPEG));
730 entryV4LDecimation = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LDecimation" );
731 i_v4l_decimation = gtk_spin_button_get_value_as_int(entryV4LDecimation);
732 pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":mjpeg:%d", (int)i_v4l_decimation );
736 if (pos >= VLC_MAX_MRL)
737 v4l_mrl[VLC_MAX_MRL-1]='\0';
739 g_print( "%s\n", v4l_mrl );
740 p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvPlaylist");
741 if (NULL != p_tvplaylist)
743 p_play_model = gtk_tree_view_get_model(p_tvplaylist);
745 /* Add a new row to the playlist treeview model */
746 gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
747 gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
756 PlaylistEvent (GtkWidget *widget,
760 g_print("onPlaylistEvent\n");
766 onPlaylistColumnsChanged (GtkTreeView *treeview,
769 g_print("onPlaylistColumnsChanged\n");
774 onPlaylistRowSelected (GtkTreeView *treeview,
775 gboolean start_editing,
778 g_print("onPlaylistRowSelected\n");
784 onPlaylistRow (GtkTreeView *treeview,
786 GtkTreeViewColumn *column,
789 g_print("onPlaylistRow\n");
794 onUpdatePlaylist (GtkButton *button,
802 onDeletePlaylist (GtkButton *button,
810 onClearPlaylist (GtkButton *button,
818 onPreferenceSave (GtkButton *button,
826 onPreferenceApply (GtkButton *button,
834 onPreferenceCancel (GtkButton *button,
843 onNetworkMRLAdd (GtkContainer *container,
851 onAddTranscodeToPlaylist (GtkButton *button,