]> git.sesse.net Git - vlc/blob - modules/gui/pda/pda_callbacks.c
PDA Interface:
[vlc] / modules / gui / pda / pda_callbacks.c
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.17 2003/11/25 20:41:35 jpsaman Exp $
6  *
7  * Authors: Jean-Paul Saman <jpsaman@wxs.nl>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <sys/types.h>                                              /* off_t */
28 #include <stdlib.h>
29 #include <vlc/vlc.h>
30 #include <vlc/intf.h>
31 #include <vlc/vout.h>
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <dirent.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include <pwd.h>
39 #include <grp.h>
40
41 #ifdef HAVE_CONFIG_H
42 #  include <config.h>
43 #endif
44
45 #include <gtk/gtk.h>
46
47 #include "pda_callbacks.h"
48 #include "pda_interface.h"
49 #include "pda_support.h"
50 #include "pda.h"
51
52 #define VLC_MAX_MRL     256
53
54 static char *get_file_perms(struct stat st);
55
56 /*****************************************************************************
57  * Useful function to retrieve p_intf
58  ****************************************************************************/
59 void * E_(__GtkGetIntf)( GtkWidget * widget )
60 {
61     void *p_data;
62
63     if( GTK_IS_MENU_ITEM( widget ) )
64     {
65         /* Look for a GTK_MENU */
66         while( widget->parent && !GTK_IS_MENU( widget ) )
67         {
68             widget = widget->parent;
69         }
70
71         /* Maybe this one has the data */
72         p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
73         if( p_data )
74         {
75             return p_data;
76         }
77
78         /* Otherwise, the parent widget has it */
79         widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
80     }
81
82     /* We look for the top widget */
83     widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
84
85     p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
86
87     return p_data;
88 }
89
90 void PlaylistAddItem(GtkWidget *widget, gchar *name)
91 {
92     intf_thread_t *p_intf = GtkGetIntf( widget );
93     playlist_t    *p_playlist;
94     GtkTreeView   *p_tvplaylist = NULL;
95
96     p_playlist = (playlist_t *)
97              vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
98
99     if( p_playlist ==  NULL)
100     {   /* Bail out when VLC's playlist object is not found. */
101         return;
102     }
103
104     /* Add to playlist object. */
105     p_tvplaylist = (GtkTreeView *) lookup_widget( GTK_WIDGET(widget), "tvPlaylist");
106     if (p_tvplaylist)
107     {
108         GtkTreeModel *p_play_model;
109         GtkTreeIter   p_play_iter;
110
111         p_play_model = gtk_tree_view_get_model(p_tvplaylist);
112
113         if (p_play_model)
114         {
115             /* Add a new row to the playlist treeview model */
116             gtk_list_store_append (GTK_LIST_STORE(p_play_model), &p_play_iter);
117             gtk_list_store_set (GTK_LIST_STORE(p_play_model), &p_play_iter,
118                                     0, name,   /* Add path to it !!! */
119                                     1, "no info",
120                                     -1 );
121
122             msg_Dbg( p_intf, "Adding files to playlist ...");
123             /* Add to VLC's playlist */
124 #if 0
125             if (p_intf->p_sys->b_autoplayfile)
126             {
127                 playlist_Add( p_playlist, (const char*)name, 0, 0,
128                               PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END);
129             }
130             else
131             {
132                 playlist_Add( p_playlist, (const char*)name, 0, 0,
133                               PLAYLIST_APPEND, PLAYLIST_END );
134             }
135             
136 #endif
137             vlc_object_release( p_playlist );
138             msg_Dbg( p_intf, "done");
139         }
140     }
141 }
142
143 void PlaylistRebuildListStore( GtkListStore * p_list, playlist_t * p_playlist )
144 {
145     GtkTreeIter iter;
146     int         i_dummy;
147     gchar *     ppsz_text[2];
148     GdkColor    red;
149     red.red     = 65535;
150     red.blue    = 0;
151     red.green   = 0;
152
153     vlc_mutex_lock( &p_playlist->object_lock );
154     for( i_dummy = p_playlist->i_size ; i_dummy-- ; )
155     {
156         ppsz_text[0] = p_playlist->pp_items[i_dummy]->psz_name;
157         ppsz_text[1] = "no info";
158         gtk_list_store_append (p_list, &iter);
159         gtk_list_store_set (p_list, &iter,
160                             0, ppsz_text[0],
161                             1, ppsz_text[1],
162                             -1);
163     }
164     vlc_mutex_unlock( &p_playlist->object_lock );
165 }
166
167 /*****************************************************************
168  * Read directory helper function.
169  ****************************************************************/
170 void ReadDirectory(intf_thread_t *p_intf, GtkListStore *p_list, char *psz_dir )
171 {
172     GtkTreeIter    iter;
173     struct dirent **namelist;
174     struct passwd *pw;
175     struct group  *grp;
176     struct stat    st;
177     int n=-1, status=-1;
178
179     msg_Dbg(p_intf, "Changing to dir %s", psz_dir);
180     if (psz_dir)
181     {
182        status = chdir(psz_dir);
183        if (status<0)
184           msg_Dbg(p_intf, "permision denied" );
185     }
186     n = scandir(".", &namelist, 0, alphasort);
187
188     if (n<0)
189         perror("scandir");
190     else
191     {
192         int i;
193         gchar *ppsz_text[4];
194
195         if (lstat("..", &st)==0)
196         {
197             /* user, group  */
198             pw  = getpwuid(st.st_uid);
199             grp = getgrgid(st.st_gid);
200
201             /* XXX : kludge temporaire pour yopy */
202             ppsz_text[0] = "..";
203             ppsz_text[1] = get_file_perms(st);
204             ppsz_text[2] = pw->pw_name;
205             ppsz_text[3] = grp->gr_name;
206
207             /* Add a new row to the model */
208             gtk_list_store_append (p_list, &iter);
209             gtk_list_store_set (p_list, &iter,
210                                 0, ppsz_text[0],
211                                 1, ppsz_text[1],
212                                 2, st.st_size,
213                                 3, ppsz_text[2],
214                                 4, ppsz_text[3],
215                                 -1);
216
217             if (ppsz_text[1]) free(ppsz_text[1]);
218         }
219             /* kludge */
220         for (i=0; i<n; i++)
221         {           
222             if ((namelist[i]->d_name[0] != '.') &&
223                 (lstat(namelist[i]->d_name, &st)==0))
224             {
225                 /* user, group  */
226                 pw  = getpwuid(st.st_uid);
227                 grp = getgrgid(st.st_gid);
228
229                 /* This is a list of strings. */
230                 ppsz_text[0] = namelist[i]->d_name;
231                 ppsz_text[1] = get_file_perms(st);
232                 ppsz_text[2] = pw->pw_name;
233                 ppsz_text[3] = grp->gr_name;
234 #if 0
235                 msg_Dbg(p_intf, "(%d) file: %s permission: %s user: %s group: %s", i, ppsz_text[0], ppsz_text[1], ppsz_text[2], ppsz_text[3] );
236 #endif
237                 gtk_list_store_append (p_list, &iter);
238                 gtk_list_store_set (p_list, &iter,
239                                     0, ppsz_text[0],
240                                     1, ppsz_text[1],
241                                     2, st.st_size,
242                                     3, ppsz_text[2],
243                                     4, ppsz_text[3],
244                                     -1);
245
246                 if (ppsz_text[1]) free(ppsz_text[1]);
247             }
248         }
249         free(namelist);
250     }
251 }
252
253 static char *get_file_perms(const struct stat st)
254 {
255     char  *perm;
256
257     perm = (char *) malloc(sizeof(char)*10);
258     strncpy( perm, "----------", sizeof("----------"));
259
260     /* determine permission modes */
261     if (S_ISLNK(st.st_mode))
262         perm[0]= 'l';
263     else if (S_ISDIR(st.st_mode))
264         perm[0]= 'd';
265     else if (S_ISCHR(st.st_mode))
266         perm[0]= 'c';
267     else if (S_ISBLK(st.st_mode))
268         perm[0]= 'b';
269     else if (S_ISFIFO(st.st_mode))
270         perm[0]= 'f';
271     else if (S_ISSOCK(st.st_mode))
272         perm[0]= 's';
273     else if (S_ISREG(st.st_mode))
274         perm[0]= '-';
275     else /* Unknown type is an error */
276         perm[0]= '?';
277     /* Get file permissions */
278     /* User */
279     if (st.st_mode & S_IRUSR)
280         perm[1]= 'r';
281     if (st.st_mode & S_IWUSR)
282         perm[2]= 'w';
283     if (st.st_mode & S_IXUSR)
284     {
285         if (st.st_mode & S_ISUID)
286             perm[3] = 's';
287         else
288             perm[3]= 'x';
289     }
290     else if (st.st_mode & S_ISUID)
291         perm[3] = 'S';
292     /* Group */
293     if (st.st_mode & S_IRGRP)
294         perm[4]= 'r';
295     if (st.st_mode & S_IWGRP)
296         perm[5]= 'w';
297     if (st.st_mode & S_IXGRP)
298     {
299         if (st.st_mode & S_ISGID)
300             perm[6] = 's';
301         else
302             perm[6]= 'x';
303     }
304     else if (st.st_mode & S_ISGID)
305         perm[6] = 'S';
306     /* Other */
307     if (st.st_mode & S_IROTH)
308         perm[7]= 'r';
309     if (st.st_mode & S_IWOTH)
310         perm[8]= 'w';
311     if (st.st_mode & S_IXOTH)
312     {
313         // 'sticky' bit
314         if (st.st_mode &S_ISVTX)
315             perm[9] = 't';
316         else
317             perm[9]= 'x';
318     }
319     else if (st.st_mode &S_ISVTX)
320         perm[9]= 'T';
321
322     return perm;
323 }
324
325 /*
326  * Main interface callbacks
327  */
328
329 gboolean
330 onPDADeleteEvent                       (GtkWidget       *widget,
331                                         GdkEvent        *event,
332                                         gpointer         user_data)
333 {
334     intf_thread_t *p_intf = GtkGetIntf( widget );
335
336     msg_Dbg( p_intf, "about to exit vlc ... " );
337     vlc_mutex_lock( &p_intf->change_lock );
338     p_intf->p_vlc->b_die = VLC_TRUE;
339     vlc_mutex_unlock( &p_intf->change_lock );
340     msg_Dbg( p_intf, "about to exit vlc ... signalled" );
341
342     return TRUE;
343 }
344
345
346 void
347 onRewind                               (GtkButton       *button,
348                                         gpointer         user_data)
349 {
350     intf_thread_t *  p_intf = GtkGetIntf( button );
351
352     if (p_intf->p_sys->p_input != NULL)
353     {
354         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
355     }
356 }
357
358
359 void
360 onPause                                (GtkButton       *button,
361                                         gpointer         user_data)
362 {
363     intf_thread_t *  p_intf = GtkGetIntf( button );
364
365     if (p_intf->p_sys->p_input != NULL)
366     {
367         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
368     }
369 }
370
371
372 void
373 onPlay                                 (GtkButton       *button,
374                                         gpointer         user_data)
375 {
376     intf_thread_t *  p_intf = GtkGetIntf( GTK_WIDGET( button ) );
377     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
378
379     if (p_playlist)
380     {
381         vlc_mutex_lock( &p_playlist->object_lock );
382         if (p_playlist->i_size)
383         {
384             vlc_mutex_unlock( &p_playlist->object_lock );
385             playlist_Play( p_playlist );
386         }
387         else
388         {
389             vlc_mutex_unlock( &p_playlist->object_lock );
390         }
391         vlc_object_release( p_playlist );
392     }
393 }
394
395
396 void
397 onStop                                 (GtkButton       *button,
398                                         gpointer         user_data)
399 {
400     intf_thread_t *  p_intf = GtkGetIntf( GTK_WIDGET( button ) );
401     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
402                                                        FIND_ANYWHERE );
403     if (p_playlist)
404     {
405         playlist_Stop( p_playlist );
406         vlc_object_release( p_playlist );
407     }
408 }
409
410
411 void
412 onForward                              (GtkButton       *button,
413                                         gpointer         user_data)
414 {
415     intf_thread_t *p_intf = GtkGetIntf( button );
416
417     if (p_intf->p_sys->p_input != NULL)
418     {
419         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
420     }
421 }
422
423
424 void
425 onAbout                                (GtkButton       *button,
426                                         gpointer         user_data)
427 {
428     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
429
430     // Toggle notebook
431     if (p_intf->p_sys->p_notebook)
432     {
433         gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
434         gtk_notebook_set_page(p_intf->p_sys->p_notebook,6);
435     }
436 }
437
438
439 gboolean
440 SliderRelease                          (GtkWidget       *widget,
441                                         GdkEventButton  *event,
442                                         gpointer         user_data)
443 {
444     intf_thread_t *p_intf = GtkGetIntf( widget );
445
446     vlc_mutex_lock( &p_intf->change_lock );
447     p_intf->p_sys->b_slider_free = 1;
448     vlc_mutex_unlock( &p_intf->change_lock );
449
450     return TRUE;
451 }
452
453
454 gboolean
455 SliderPress                            (GtkWidget       *widget,
456                                         GdkEventButton  *event,
457                                         gpointer         user_data)
458 {
459     intf_thread_t *p_intf = GtkGetIntf( widget );
460
461     vlc_mutex_lock( &p_intf->change_lock );
462     p_intf->p_sys->b_slider_free = 0;
463     vlc_mutex_unlock( &p_intf->change_lock );
464
465     return TRUE;
466 }
467
468 void addSelectedToPlaylist(GtkTreeModel *model,
469                                GtkTreePath *path,
470                                GtkTreeIter *iter,
471                                gpointer *userdata)
472 {
473     gchar *filename;
474
475     gtk_tree_model_get(model, iter, 0, &filename, -1);
476
477     PlaylistAddItem(GTK_WIDGET(userdata), filename);
478 }
479
480 void
481 onFileListRow                          (GtkTreeView     *treeview,
482                                         GtkTreePath     *path,
483                                         GtkTreeViewColumn *column,
484                                         gpointer         user_data)
485 {
486     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(treeview) );
487     GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
488
489     if (gtk_tree_selection_count_selected_rows(selection) == 1)
490     {
491         struct stat   st;
492         GtkTreeModel *model;
493         GtkTreeIter   iter;
494         gchar        *filename;
495
496         /* This might be a directory selection */
497         model = gtk_tree_view_get_model(treeview);
498         if (!model)
499         {
500             msg_Err(p_intf, "PDA: Filelist model contains a NULL pointer\n" );
501             return;
502         }
503         if (!gtk_tree_model_get_iter(model, &iter, path))
504         {
505             msg_Err( p_intf, "PDA: Could not get iter from model" );
506             return;
507         }
508
509         gtk_tree_model_get(model, &iter, 0, &filename, -1);
510         if (stat((char*)filename, &st)==0)
511         {
512             if (S_ISDIR(st.st_mode))
513             {
514                 GtkListStore *p_model = NULL;
515
516                 /* Get new directory listing */
517                 p_model = gtk_list_store_new (5,
518                                            G_TYPE_STRING,
519                                            G_TYPE_STRING,
520                                            G_TYPE_UINT64,
521                                            G_TYPE_STRING,
522                                            G_TYPE_STRING);
523                 if (p_model)
524                 {
525                     ReadDirectory(p_intf, p_model, filename);
526
527                     /* Update TreeView with new model */
528                     gtk_tree_view_set_model(treeview, (GtkTreeModel*) p_model);
529                     g_object_unref(p_model);
530                 }
531             }
532             else
533             {
534                 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
535             }
536         }
537     }
538     else
539     {
540         gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);
541     }
542 }
543
544 void
545 onAddFileToPlaylist                    (GtkButton       *button,
546                                         gpointer         user_data)
547 {
548     GtkTreeView       *treeview = NULL;
549
550     treeview = (GtkTreeView *) lookup_widget( GTK_WIDGET(button), "tvFileList");
551     if (treeview)
552     {
553         GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
554
555         gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc) &addSelectedToPlaylist, (gpointer) treeview);    
556     }
557 }
558
559
560 void
561 NetworkBuildMRL                        (GtkEditable     *editable,
562                                         gpointer         user_data)
563 {
564     GtkSpinButton *networkPort = NULL;
565     GtkEntry      *entryMRL = NULL;
566     GtkEntry      *networkType = NULL;
567     GtkEntry      *networkAddress = NULL;
568     GtkEntry      *networkProtocol = NULL;
569     const gchar   *mrlNetworkType;
570     const gchar   *mrlAddress;
571     const gchar   *mrlProtocol;
572     gint           mrlPort;
573     char           text[VLC_MAX_MRL];
574     int            pos = 0;
575
576     entryMRL = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryMRL" );
577
578     networkType     = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkType" );
579     networkAddress  = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkAddress" );
580     networkPort     = (GtkSpinButton*) lookup_widget( GTK_WIDGET(editable), "entryNetworkPort" );
581     networkProtocol = (GtkEntry*) lookup_widget( GTK_WIDGET(editable), "entryNetworkProtocolType" );
582
583     mrlNetworkType = gtk_entry_get_text(GTK_ENTRY(networkType));
584     mrlAddress     = gtk_entry_get_text(GTK_ENTRY(networkAddress));
585     mrlPort        = gtk_spin_button_get_value_as_int(networkPort);
586     mrlProtocol    = gtk_entry_get_text(GTK_ENTRY(networkProtocol));
587
588     /* Build MRL from parts ;-) */
589     pos = snprintf( &text[0], VLC_MAX_MRL, "%s://", (char*)mrlProtocol);
590     if (strncasecmp( (char*)mrlNetworkType, "multicast",9)==0)
591     {
592         pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "@" );
593     }
594     pos += snprintf( &text[pos], VLC_MAX_MRL - pos, "%s:%d", (char*)mrlAddress, (int)mrlPort );
595
596     if (pos >= VLC_MAX_MRL)
597         text[VLC_MAX_MRL-1]='\0';
598
599     gtk_entry_set_text(entryMRL,text);
600 }
601
602 void
603 onAddNetworkPlaylist                   (GtkButton       *button,
604                                         gpointer         user_data)
605 {
606     GtkEntry     *p_mrl = NULL;
607     const gchar  *mrl_name;
608
609     p_mrl = (GtkEntry*) lookup_widget(GTK_WIDGET(button),"entryMRL" );
610     if (p_mrl)
611     {
612         mrl_name = gtk_entry_get_text(p_mrl);
613
614         PlaylistAddItem(GTK_WIDGET(button), (gchar *)mrl_name);
615     }
616 }
617
618
619 void
620 onAddCameraToPlaylist                  (GtkButton       *button,
621                                         gpointer         user_data)
622 {
623     intf_thread_t *p_intf = GtkGetIntf( button );
624
625     GtkSpinButton *entryV4LChannel = NULL;
626     GtkSpinButton *entryV4LFrequency = NULL;
627     GtkSpinButton *entryV4LSampleRate = NULL;
628     GtkSpinButton *entryV4LQuality = NULL;
629     GtkSpinButton *entryV4LTuner = NULL;
630     gint    i_v4l_channel;
631     gint    i_v4l_frequency;
632     gint    i_v4l_samplerate;
633     gint    i_v4l_quality;
634     gint    i_v4l_tuner;
635
636     GtkEntry      *entryV4LVideoDevice = NULL;
637     GtkEntry      *entryV4LAudioDevice = NULL;
638     GtkEntry      *entryV4LNorm = NULL;
639     GtkEntry      *entryV4LSize = NULL;
640     GtkEntry      *entryV4LSoundDirection = NULL;
641     const gchar   *p_v4l_video_device;
642     const gchar   *p_v4l_audio_device;
643     const gchar   *p_v4l_norm;
644     const gchar   *p_v4l_size;
645     const gchar   *p_v4l_sound_direction;
646
647     /* MJPEG only */
648     GtkCheckButton *checkV4LMJPEG = NULL;
649     GtkSpinButton  *entryV4LDecimation = NULL;
650     gboolean        b_v4l_mjpeg;
651     gint            i_v4l_decimation;
652     /* end MJPEG only */
653
654     char v4l_mrl[VLC_MAX_MRL];
655     int pos;
656
657     pos = snprintf( &v4l_mrl[0], VLC_MAX_MRL, "v4l://");
658
659     entryV4LChannel    = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LChannel" );
660     entryV4LFrequency  = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LFrequency" );
661     entryV4LSampleRate = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LSampleRate" );
662     entryV4LQuality    = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LQuality" );
663     entryV4LTuner      = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LTuner" );
664
665     entryV4LVideoDevice  = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LVideoDevice" );
666     entryV4LAudioDevice  = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LAudioDevice" );
667     entryV4LNorm  = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LNorm" );
668     entryV4LSize  = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LSize" );
669     entryV4LSoundDirection  = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryV4LSoundDirection" );
670
671     i_v4l_channel = gtk_spin_button_get_value_as_int(entryV4LChannel);
672     i_v4l_frequency = gtk_spin_button_get_value_as_int(entryV4LFrequency);
673     i_v4l_samplerate = gtk_spin_button_get_value_as_int(entryV4LSampleRate);
674     i_v4l_quality = gtk_spin_button_get_value_as_int(entryV4LQuality);
675     i_v4l_tuner = gtk_spin_button_get_value_as_int(entryV4LTuner);
676
677     p_v4l_video_device = gtk_entry_get_text(GTK_ENTRY(entryV4LVideoDevice));
678     p_v4l_audio_device = gtk_entry_get_text(GTK_ENTRY(entryV4LAudioDevice));
679     p_v4l_norm = gtk_entry_get_text(GTK_ENTRY(entryV4LNorm));
680     p_v4l_size  = gtk_entry_get_text(GTK_ENTRY(entryV4LSize));
681     p_v4l_sound_direction = gtk_entry_get_text(GTK_ENTRY(entryV4LSoundDirection));
682
683     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":%s", (char*)p_v4l_video_device );
684     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":adev=%s", (char*)p_v4l_audio_device );
685     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":norm=%s", (char*)p_v4l_norm );
686     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":size=%s", (char*)p_v4l_size );
687     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":%s", (char*)p_v4l_sound_direction );
688
689     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":channel=%d", (int)i_v4l_channel );
690     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":frequency=%d", (int)i_v4l_frequency );
691     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":samplerate=%d", (int)i_v4l_samplerate );
692     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":quality=%d", (int)i_v4l_quality );
693     pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":tuner=%d", (int)i_v4l_tuner );
694
695     /* MJPEG only */
696     checkV4LMJPEG      = (GtkCheckButton*) lookup_widget( GTK_WIDGET(button), "checkV4LMJPEG" );
697     b_v4l_mjpeg = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkV4LMJPEG));
698     if (b_v4l_mjpeg)
699     {
700         entryV4LDecimation = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryV4LDecimation" );
701         i_v4l_decimation = gtk_spin_button_get_value_as_int(entryV4LDecimation);
702         pos += snprintf( &v4l_mrl[pos], VLC_MAX_MRL - pos, ":mjpeg:%d", (int)i_v4l_decimation );
703     }
704     /* end MJPEG only */
705
706     if (pos >= VLC_MAX_MRL)
707     {
708         v4l_mrl[VLC_MAX_MRL-1]='\0';
709         msg_Err(p_intf, "Media Resource Locator is truncated to: %s", v4l_mrl);
710     }
711
712     PlaylistAddItem(GTK_WIDGET(button), (gchar*) &v4l_mrl);
713 }
714
715
716 gboolean
717 PlaylistEvent                          (GtkWidget       *widget,
718                                         GdkEvent        *event,
719                                         gpointer         user_data)
720 {
721     return FALSE;
722 }
723
724
725 void
726 onPlaylistColumnsChanged               (GtkTreeView     *treeview,
727                                         gpointer         user_data)
728 {
729 }
730
731
732 gboolean
733 onPlaylistRowSelected                  (GtkTreeView     *treeview,
734                                         gboolean         start_editing,
735                                         gpointer         user_data)
736 {
737     return FALSE;
738 }
739
740
741 void
742 onPlaylistRow                          (GtkTreeView     *treeview,
743                                         GtkTreePath     *path,
744                                         GtkTreeViewColumn *column,
745                                         gpointer         user_data)
746 {
747 }
748
749
750 void
751 onUpdatePlaylist                       (GtkButton       *button,
752                                         gpointer         user_data)
753 {
754
755 }
756
757
758 void
759 onDeletePlaylist                       (GtkButton       *button,
760                                         gpointer         user_data)
761 {
762
763 }
764
765
766 void
767 onClearPlaylist                        (GtkButton       *button,
768                                         gpointer         user_data)
769 {
770     intf_thread_t *p_intf = GtkGetIntf( button );
771     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
772                                                        FIND_ANYWHERE );
773     GtkTreeView    *p_tvplaylist;
774     int item;
775
776     msg_Dbg(p_intf, "Clear VLC playlist" );
777
778     if( p_playlist == NULL )
779     {
780         return;
781     }
782
783     vlc_mutex_lock( &p_playlist->object_lock );
784     for(item = p_playlist->i_size - 1 ; item >= 0 ; item-- )
785     {
786         playlist_Delete( p_playlist, item);
787     }
788     vlc_mutex_unlock( &p_playlist->object_lock );
789     vlc_object_release( p_playlist );
790
791     // Remove all entries from the Playlist widget.
792     msg_Dbg(p_intf, "Clear playlist widget" );
793     p_tvplaylist = (GtkTreeView*) lookup_widget( GTK_WIDGET(button), "tvPlaylist");
794     if (p_tvplaylist)
795     {
796         GtkTreeModel *p_play_model;
797
798         p_play_model = gtk_tree_view_get_model(p_tvplaylist);
799         if (p_play_model)
800         {
801             gtk_list_store_clear(GTK_LIST_STORE(p_play_model));
802         }
803     }
804 }
805
806
807 void
808 onPreferenceSave                       (GtkButton       *button,
809                                         gpointer         user_data)
810 {
811     intf_thread_t *p_intf = GtkGetIntf( button );
812
813     msg_Dbg(p_intf, "Preferences Save" );
814 }
815
816
817 void
818 onPreferenceApply                      (GtkButton       *button,
819                                         gpointer         user_data)
820 {
821     intf_thread_t *p_intf = GtkGetIntf( button );
822
823     msg_Dbg(p_intf, "Preferences Apply" );
824 }
825
826
827 void
828 onPreferenceCancel                     (GtkButton       *button,
829                                         gpointer         user_data)
830 {
831     intf_thread_t *p_intf = GtkGetIntf( button );
832
833     msg_Dbg(p_intf, "Preferences Cancel" );
834 }
835
836
837 void
838 onAddTranscodeToPlaylist               (GtkButton       *button,
839                                         gpointer         user_data)
840 {
841     intf_thread_t *p_intf = GtkGetIntf( button );
842
843     GtkEntry       *entryVideoCodec = NULL;
844     GtkSpinButton  *entryVideoBitrate = NULL;
845     GtkSpinButton  *entryVideoBitrateTolerance = NULL;
846     GtkSpinButton  *entryVideoKeyFrameInterval = NULL;
847     GtkCheckButton *checkVideoDeinterlace = NULL;
848     GtkEntry       *entryAudioCodec = NULL;
849     GtkSpinButton  *entryAudioBitrate = NULL;
850     const gchar    *p_video_codec;
851     gint            i_video_bitrate;
852     gint            i_video_bitrate_tolerance;
853     gint            i_video_keyframe_interval;
854     gboolean        b_video_deinterlace;
855     const gchar    *p_audio_codec;
856     gint            i_audio_bitrate;
857
858     GtkEntry       *entryStdAccess = NULL;
859     GtkEntry       *entryStdMuxer = NULL;
860     GtkEntry       *entryStdURL = NULL;
861     GtkSpinButton  *entryStdTTL = NULL;
862     const gchar    *p_std_access;
863     const gchar    *p_std_muxer;
864     const gchar    *p_std_url;
865     gint            i_std_ttl;
866
867     gchar mrl[VLC_MAX_MRL];
868     int   pos;
869
870     pos = snprintf( &mrl[0], VLC_MAX_MRL, "--sout '#transcode{");
871
872     entryVideoCodec   = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryVideoCodec" );
873     entryVideoBitrate = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryVideoBitrate" );
874     entryVideoBitrateTolerance = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryVideoBitrateTolerance" );
875     entryVideoKeyFrameInterval = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryVideoKeyFrameInterval" );
876     
877     p_video_codec = gtk_entry_get_text(GTK_ENTRY(entryVideoCodec));
878     i_video_bitrate = gtk_spin_button_get_value_as_int(entryVideoBitrate);
879     i_video_bitrate_tolerance = gtk_spin_button_get_value_as_int(entryVideoBitrateTolerance);
880     i_video_keyframe_interval = gtk_spin_button_get_value_as_int(entryVideoKeyFrameInterval);
881     
882     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "vcodec=%s,", (char*)p_video_codec );
883     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "vb=%d,", (int)i_video_bitrate );
884     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "vt=%d,", (int)i_video_bitrate_tolerance );
885     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "keyint=%d,", (int)i_video_keyframe_interval );
886
887     checkVideoDeinterlace = (GtkCheckButton*) lookup_widget( GTK_WIDGET(button), "checkVideoDeinterlace" );
888     b_video_deinterlace = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkVideoDeinterlace));
889     if (b_video_deinterlace)
890     {
891         pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "deinterlace," );
892     }
893     entryAudioCodec   = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryAudioCodec" );
894     entryAudioBitrate = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryAudioBitrate" );
895
896     p_audio_codec = gtk_entry_get_text(GTK_ENTRY(entryAudioCodec));
897     i_audio_bitrate = gtk_spin_button_get_value_as_int(entryAudioBitrate);
898
899     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "acodec=%s,", (char*)p_audio_codec );
900     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "ab=%d", (int)i_audio_bitrate );
901
902     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "}:std{" );
903
904     entryStdAccess = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryStdAccess" );
905     entryStdMuxer  = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryStdMuxer" );
906     entryStdURL = (GtkEntry*) lookup_widget( GTK_WIDGET(button), "entryStdURL" );
907     entryStdTTL = (GtkSpinButton*) lookup_widget( GTK_WIDGET(button), "entryStdTTL" );
908
909     p_std_access = gtk_entry_get_text(GTK_ENTRY(entryStdAccess));
910     p_std_muxer = gtk_entry_get_text(GTK_ENTRY(entryStdMuxer));
911     p_std_url = gtk_entry_get_text(GTK_ENTRY(entryStdURL));
912
913     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "access=%s,", (char*)p_std_access);
914     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "mux=%s,", (char*)p_std_muxer);
915     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "url=%s", (char*)p_std_url);
916     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, "}'");
917
918     i_std_ttl = gtk_spin_button_get_value_as_int(entryStdTTL);
919
920     pos += snprintf( &mrl[pos], VLC_MAX_MRL - pos, " --ttl=%d", (int)i_std_ttl);
921
922     if (pos >= VLC_MAX_MRL)
923     {
924         mrl[VLC_MAX_MRL-1]='\0';
925         msg_Err(p_intf, "Media Resource Locator is truncated to: %s", mrl );
926     }
927
928     PlaylistAddItem(GTK_WIDGET(button), (gchar*) &mrl);
929 }
930
931