]> git.sesse.net Git - vlc/blob - modules/gui/pda/callbacks.c
2a7a02bfcc1b831c9e943d521dc51f88beb25c46
[vlc] / modules / gui / pda / callbacks.c
1 /*****************************************************************************
2  * callbacks.c : Callbacks for the pda Linux Gtk+ plugin.
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: callbacks.c,v 1.2 2003/11/07 13:01:51 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
39 #ifdef HAVE_CONFIG_H
40 #  include <config.h>
41 #endif
42
43 #include <gtk/gtk.h>
44
45 #include "playlist.h"
46 #include "callbacks.h"
47 #include "interface.h"
48 #include "support.h"
49 #include "pda.h"
50
51 static char* get_file_perm(const char *path);
52
53 /*****************************************************************************
54  * Useful function to retrieve p_intf
55  ****************************************************************************/
56 void * E_(__GtkGetIntf)( GtkWidget * widget )
57 {
58     void *p_data;
59
60     if( GTK_IS_MENU_ITEM( widget ) )
61     {
62         /* Look for a GTK_MENU */
63         while( widget->parent && !GTK_IS_MENU( widget ) )
64         {
65             widget = widget->parent;
66         }
67
68         /* Maybe this one has the data */
69         p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
70         if( p_data )
71         {
72             return p_data;
73         }
74
75         /* Otherwise, the parent widget has it */
76         widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
77     }
78
79     /* We look for the top widget */
80     widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
81
82     p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
83
84     return p_data;
85 }
86
87 /*****************************************************************************
88  * Helper functions for URL changes in Media and Preferences notebook pages.
89  ****************************************************************************/
90 void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
91 {
92     intf_thread_t *p_intf = GtkGetIntf( widget );
93     playlist_t *p_playlist;
94
95     // Add p_url to playlist .... but how ?
96     p_playlist = (playlist_t *)
97              vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
98
99     if( p_playlist ==  NULL)
100     {
101         return;
102     }
103     
104     if( p_playlist )
105     {
106         if (p_intf->p_sys->b_autoplayfile)
107         {
108             playlist_Add( p_playlist, (char*)psz_url, 0, 0, 
109                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END);
110         }
111         else
112         {
113             playlist_Add( p_playlist, (char*)psz_url, 0, 0, 
114                           PLAYLIST_APPEND, PLAYLIST_END );
115         }
116         vlc_object_release(  p_playlist );
117         PDARebuildCList( p_intf->p_sys->p_clistplaylist, p_playlist);
118     }
119 }
120
121 /*****************************************************************
122  * Read directory helper function.
123  ****************************************************************/
124 void ReadDirectory( GtkCList *clist, char *psz_dir )
125 {
126     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(clist) );
127     struct dirent **namelist;
128     int n=-1, status=-1;
129
130     msg_Dbg(p_intf, "changing to dir %s", psz_dir);
131     if (psz_dir)
132     {
133        status = chdir(psz_dir);
134        if (status<0)
135           msg_Err( p_intf, "permision denied" );                        
136     }
137     n = scandir(".", &namelist, 0, alphasort);
138     
139     if (n<0)
140         perror("scandir");
141     else
142     {
143         int i, ctr=0;
144         gchar *ppsz_text[5];
145
146         msg_Dbg( p_intf, "updating interface" );
147         gtk_clist_freeze( clist );
148         gtk_clist_clear( clist );
149
150         /* XXX : kludge temporaire pour yopy */
151         ppsz_text[0]="..";
152         ppsz_text[1] = get_file_perm("..");
153         ppsz_text[2] = "";
154         ppsz_text[3] = "";
155         ppsz_text[4] = "";
156         gtk_clist_insert( GTK_CLIST(clist), ctr++, ppsz_text );
157
158         /* kludge */                
159         for (i=0; i<n; i++)
160         {
161             if (namelist[i]->d_name[0] != '.')
162             {
163                 /* This is a list of strings. */
164                 ppsz_text[0] = namelist[i]->d_name;
165                 ppsz_text[1] = get_file_perm(namelist[i]->d_name);
166                 ppsz_text[2] = "";
167                 ppsz_text[3] = "";
168                 ppsz_text[4] = "";
169                 //            msg_Dbg(p_intf, "(%d) file: %s permission: %s", i, ppsz_text[0], ppsz_text[1] );
170                 gtk_clist_insert( GTK_CLIST(clist), ctr++, ppsz_text );
171             }
172         }
173         gtk_clist_thaw( clist );
174         free(namelist);
175     }
176
177     /* now switch to the "file" tab */
178     if (p_intf->p_sys->p_mediabook)
179     {
180        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_mediabook) );
181        gtk_notebook_set_page(p_intf->p_sys->p_mediabook,0);
182     }
183 }
184
185 static char* get_file_perm(const char *path)
186 {
187     struct stat st;
188     char *perm;
189
190     perm = (char *) malloc(sizeof(char)*10);
191     strncpy( perm, "----------", sizeof("----------"));
192     if (lstat(path, &st)==0)
193     {
194         if (S_ISLNK(st.st_mode))
195             perm[0]= 'l';
196         else if (S_ISDIR(st.st_mode))
197             perm[0]= 'd';
198         else if (S_ISCHR(st.st_mode))
199             perm[0]= 'c';
200         else if (S_ISBLK(st.st_mode))
201             perm[0]= 'b';
202         else if (S_ISFIFO(st.st_mode))
203             perm[0]= 'f';
204         else if (S_ISSOCK(st.st_mode))
205             perm[0]= 's';
206         else if (S_ISREG(st.st_mode))
207             perm[0]= '-';
208         else /* Unknown type is an error */
209             perm[0]= '?';
210         /* Get file permissions */
211         /* User */
212         if (st.st_mode & S_IRUSR)
213             perm[1]= 'r';
214         if (st.st_mode & S_IWUSR)
215             perm[2]= 'w';
216         if (st.st_mode & S_IXUSR)
217         {
218             if (st.st_mode & S_ISUID)
219                 perm[3] = 's';
220             else
221                 perm[3]= 'x';
222         }
223         else if (st.st_mode & S_ISUID)
224             perm[3] = 'S';
225         /* Group */
226         if (st.st_mode & S_IRGRP)
227             perm[4]= 'r';
228         if (st.st_mode & S_IWGRP)
229             perm[5]= 'w';
230         if (st.st_mode & S_IXGRP)
231         {
232             if (st.st_mode & S_ISGID)
233                 perm[6] = 's';
234             else
235                 perm[6]= 'x';
236         }
237         else if (st.st_mode & S_ISGID)
238             perm[6] = 'S';
239         /* Other */
240         if (st.st_mode & S_IROTH)
241             perm[7]= 'r';
242         if (st.st_mode & S_IWOTH)
243             perm[8]= 'w';
244         if (st.st_mode & S_IXOTH)
245         {
246             // 'sticky' bit
247             if (st.st_mode &S_ISVTX)
248                 perm[9] = 't';
249             else
250                 perm[9]= 'x';
251         }
252         else if (st.st_mode &S_ISVTX)
253             perm[9]= 'T';
254     }
255     return perm;
256 }
257
258 /*
259  * Main interface callbacks
260  */
261 gboolean PDAExit( GtkWidget       *widget,
262                        gpointer         user_data )
263 {
264     intf_thread_t *p_intf = GtkGetIntf( widget );
265
266     vlc_mutex_lock( &p_intf->change_lock );
267     p_intf->p_vlc->b_die = VLC_TRUE;
268     vlc_mutex_unlock( &p_intf->change_lock );
269
270     return TRUE;
271 }
272
273 void
274 on_toolbar_open_clicked                (GtkButton       *button,
275                                         gpointer         user_data)
276 {
277     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET( button ) );
278
279     if (p_intf->p_sys->p_notebook)
280     {
281        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
282        gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
283     }
284     if (p_intf->p_sys->p_mediabook)
285     {
286        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_mediabook) );
287        gtk_notebook_set_page(p_intf->p_sys->p_mediabook,0);
288     }
289     gdk_window_raise( p_intf->p_sys->p_window->window );
290     if (p_intf->p_sys->p_clist)
291     {
292        ReadDirectory(p_intf->p_sys->p_clist, ".");
293     }
294 }
295
296 void
297 on_toolbar_preferences_clicked         (GtkButton       *button,
298                                         gpointer         user_data)
299 {
300     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET( button ) );
301
302     if (p_intf->p_sys->p_notebook)
303     {
304        gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
305        gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
306     }
307     gdk_window_raise( p_intf->p_sys->p_window->window );
308 }
309
310 void
311 on_toolbar_rewind_clicked              (GtkButton       *button,
312                                         gpointer         user_data)
313 {
314     intf_thread_t *  p_intf = GtkGetIntf( button );
315
316     if( p_intf->p_sys->p_input != NULL )
317     {
318         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
319     }
320 }
321
322 void
323 on_toolbar_pause_clicked               (GtkButton       *button,
324                                         gpointer         user_data)
325 {
326     intf_thread_t *  p_intf = GtkGetIntf( button );
327
328     if( p_intf->p_sys->p_input != NULL )
329     {
330         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
331     }
332 }
333
334 void
335 on_toolbar_play_clicked                (GtkButton       *button,
336                                         gpointer         user_data)
337 {
338      intf_thread_t *  p_intf = GtkGetIntf( GTK_WIDGET( button ) );
339      playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
340
341      if( p_playlist == NULL )
342      {
343          /* Display open page */
344          on_toolbar_open_clicked(button,user_data);
345      }
346
347      /* If the playlist is empty, open a file requester instead */
348      vlc_mutex_lock( &p_playlist->object_lock );
349      if( p_playlist->i_size )
350      {
351          vlc_mutex_unlock( &p_playlist->object_lock );
352          playlist_Play( p_playlist );
353          vlc_object_release( p_playlist );
354          gdk_window_lower( p_intf->p_sys->p_window->window );
355      }
356      else
357      {
358          vlc_mutex_unlock( &p_playlist->object_lock );
359          vlc_object_release( p_playlist );
360          /* Display open page */
361          on_toolbar_open_clicked(button,user_data);
362     }
363 }
364
365 void
366 on_toolbar_stop_clicked                (GtkButton       *button,
367                                         gpointer         user_data)
368 {
369     intf_thread_t *  p_intf = GtkGetIntf( GTK_WIDGET( button ) );
370     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
371                                                        FIND_ANYWHERE );
372     if( p_playlist)
373     {
374         playlist_Stop( p_playlist );
375         vlc_object_release( p_playlist );
376         gdk_window_raise( p_intf->p_sys->p_window->window );
377     }
378 }
379
380 void
381 on_toolbar_forward_clicked             (GtkButton       *button,
382                                         gpointer         user_data)
383 {
384     intf_thread_t *  p_intf = GtkGetIntf( button );
385
386     if( p_intf->p_sys->p_input != NULL )
387     {
388         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
389     }
390 }
391
392 void
393 on_toolbar_playlist_clicked            (GtkButton       *button,
394                                         gpointer         user_data)
395 {
396     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
397
398     // Toggle notebook
399     if (p_intf->p_sys->p_notebook)
400     {
401         gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
402         gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
403     }
404     gdk_window_raise( p_intf->p_sys->p_window->window );
405 }
406
407 void
408 on_toolbar_about_clicked               (GtkButton       *button,
409                                         gpointer         user_data)
410 {
411     intf_thread_t *p_intf = GtkGetIntf( GTK_WIDGET(button) );
412
413     // Toggle notebook
414     if (p_intf->p_sys->p_notebook)
415     {
416         gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
417         gtk_notebook_set_page(p_intf->p_sys->p_notebook,3);
418     }
419     gdk_window_raise( p_intf->p_sys->p_window->window );
420 }
421
422 void
423 on_comboURL_entry_changed              (GtkEditable     *editable,
424                                         gpointer         user_data)
425 {
426     intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET(editable) );
427     gchar *       psz_url;
428     struct stat   st;
429     
430     psz_url = gtk_entry_get_text(GTK_ENTRY(editable));
431 /*    if( (strncmp("file://",(const char *) psz_url,7)==0) ||
432         (strncmp("udp://",(const char *) psz_url,6)==0) ||
433         (strncmp("udp4://",(const char *) psz_url,7)==0) ||
434         (strncmp("udp6://",(const char *) psz_url,7)==0) ||
435         (strncmp("udpstream://",(const char *) psz_url,12)==0) ||
436         (strncmp("rtp://",(const char *) psz_url,6)==0) ||
437         (strncmp("rtp4://",(const char *) psz_url,7)==0) ||
438         (strncmp("rtp6://",(const char *) psz_url,7)==0) ||
439         (strncmp("rtpstream://",(const char *) psz_url,12)==0) ||
440         (strncmp("ftp://",(const char *) psz_url,6)==0) ||
441         (strncmp("mms://",(const char *) psz_url,6)==0) ||
442         (strncmp("http://",(const char *) psz_url,7)==0) )
443     {
444         MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
445     }
446     else */
447     if (stat((char*)psz_url, &st)==0)
448     {
449         if (S_ISDIR(st.st_mode))
450         {
451             if (!p_intf->p_sys->p_clist)
452                 msg_Err(p_intf, "p_clist pointer invalid!!" );
453             ReadDirectory(p_intf->p_sys->p_clist, psz_url);
454         }
455         else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
456             (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
457             (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
458         {
459             MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
460         }
461     }
462 }
463
464 void
465 on_clistmedia_click_column             (GtkCList        *clist,
466                                         gint             column,
467                                         gpointer         user_data)
468 {
469     static GtkSortType sort_type = GTK_SORT_ASCENDING;
470
471     // Should sort on column
472     switch(sort_type)
473     {
474         case GTK_SORT_ASCENDING:
475             sort_type = GTK_SORT_DESCENDING;
476             break;
477         case GTK_SORT_DESCENDING:
478             sort_type = GTK_SORT_ASCENDING;
479             break;
480     }
481     gtk_clist_freeze( clist );
482     gtk_clist_set_sort_type( clist, sort_type );
483     gtk_clist_sort( clist );
484     gtk_clist_thaw( clist );
485 }
486
487 void
488 on_clistmedia_select_row               (GtkCList        *clist,
489                                         gint             row,
490                                         gint             column,
491                                         GdkEvent        *event,
492                                         gpointer         user_data)
493 {
494     intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET(clist) );
495     gchar *text[2];
496     gint ret;
497     struct stat st;
498
499     if (!p_intf->p_sys->p_clist)
500                 msg_Err(p_intf, "p_clist pointer is invalid.");
501     ret = gtk_clist_get_text (p_intf->p_sys->p_clist, row, 0, text);
502     if (ret)
503     {
504         if (stat((char*)text[0], &st)==0)
505         {
506             if (S_ISDIR(st.st_mode))
507                ReadDirectory(p_intf->p_sys->p_clist, text[0]);
508             else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
509                      (S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
510                      (S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
511             {
512                MediaURLOpenChanged(GTK_WIDGET(p_intf->p_sys->p_clist), text[0]);
513             }
514        }
515     }
516 }
517
518 void
519 on_cbautoplay_toggled                  (GtkToggleButton *togglebutton,
520                                         gpointer         user_data)
521 {
522 }
523
524 gboolean
525 on_pda_delete_event               (GtkWidget       *widget,
526                                         GdkEvent        *event,
527                                         gpointer         user_data)
528 {
529     PDAExit( GTK_WIDGET( widget ), user_data );
530     return TRUE;
531 }
532
533 /* Slider Management */
534 gboolean
535 PDASliderRelease                  (GtkWidget       *widget,
536                                         GdkEventButton  *event,
537                                         gpointer         user_data)
538 {
539     intf_thread_t *p_intf = GtkGetIntf( widget );
540
541     vlc_mutex_lock( &p_intf->change_lock );
542     p_intf->p_sys->b_slider_free = 1;
543     vlc_mutex_unlock( &p_intf->change_lock );
544
545     return FALSE;
546 }
547
548 gboolean
549 PDASliderPress                    (GtkWidget       *widget,
550                                         GdkEventButton  *event,
551                                         gpointer         user_data)
552 {
553     intf_thread_t *p_intf = GtkGetIntf( widget );
554
555     vlc_mutex_lock( &p_intf->change_lock );
556     p_intf->p_sys->b_slider_free = 0;
557     vlc_mutex_unlock( &p_intf->change_lock );
558
559     return FALSE;
560 }
561
562 void
563 PDAMrlGo                          (GtkButton       *button,
564                                         gpointer         user_data)
565 {
566     intf_thread_t *  p_intf = GtkGetIntf( button );
567
568     MediaURLOpenChanged( GTK_WIDGET( button ),
569             gtk_entry_get_text(p_intf->p_sys->p_mrlentry ) );
570 }
571
572 void
573 PDAPreferencesApply               (GtkButton       *button,
574                                         gpointer         user_data)
575 {
576     intf_thread_t * p_intf = GtkGetIntf( GTK_WIDGET(button) );
577     
578     GtkToggleButton * p_autopl_button = GTK_GET( TOGGLE_BUTTON, "cbautoplay" );
579     if (gtk_toggle_button_get_active(p_autopl_button))
580     {
581         p_intf->p_sys->b_autoplayfile = 1;
582     }
583     else
584     {
585         p_intf->p_sys->b_autoplayfile = 0;
586     }
587 }
588