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