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