]> git.sesse.net Git - vlc/blob - modules/gui/familiar/callbacks.c
* ALL: the build mechanism now uses automake. See HACKING for more details.
[vlc] / modules / gui / familiar / callbacks.c
1 /*****************************************************************************
2  * callbacks.c : Callbacks for the Familiar Linux Gtk+ plugin.
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: callbacks.c,v 1.10 2002/09/30 11:05:38 sam 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
30 #include <vlc/vlc.h>
31 #include <vlc/intf.h>
32 #include <vlc/vout.h>
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <dirent.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39
40 #ifdef HAVE_CONFIG_H
41 #  include <config.h>
42 #endif
43
44 #include <gtk/gtk.h>
45
46 #include "callbacks.h"
47 #include "interface.h"
48 #include "support.h"
49 #include "familiar.h"
50
51 /*#include "netutils.h"*/
52
53 static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url );
54 static char* get_file_perm(const char *path);
55
56 /*****************************************************************************
57  * Useful function to retrieve p_intf
58  ****************************************************************************/
59 void * __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 /*****************************************************************************
91  * Helper functions for URL changes in Media and Preferences notebook pages.
92  ****************************************************************************/
93 static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
94 {
95     intf_thread_t *p_intf = GtkGetIntf( widget );
96     playlist_t *p_playlist;
97
98     g_print( "%s\n",psz_url );
99
100     // Add p_url to playlist .... but how ?
101     p_playlist = (playlist_t *)
102              vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
103     if( p_playlist )
104     {
105        playlist_Add( p_playlist, (char*)psz_url,
106                      PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
107        vlc_object_release( p_playlist );
108     }
109 }
110
111 /*****************************************************************
112  * Read directory helper function.
113  ****************************************************************/
114 void ReadDirectory( GtkCList *clist, char *psz_dir )
115 {
116     intf_thread_t *p_intf = GtkGetIntf( clist );
117     struct dirent **namelist;
118     int n,i;
119
120     if (psz_dir)
121        chdir(psz_dir);
122     n = scandir(".", &namelist, 0, NULL);
123
124     if (n<0)
125         perror("scandir");
126     else
127     {
128         gchar *ppsz_text[2];
129
130         gtk_clist_freeze( clist );
131         gtk_clist_clear( clist );
132
133         for (i=0; i<n; i++)
134         {
135             /* This is a list of strings. */
136             ppsz_text[0] = namelist[i]->d_name;
137             ppsz_text[1] = get_file_perm(namelist[i]->d_name);
138             if (strcmp(ppsz_text[1],"") == 0)
139                 msg_Err( p_intf->p_sys->p_input, "File system error unknown filetype encountered.");
140             gtk_clist_insert( clist, i, ppsz_text );
141             free(namelist[i]);
142         }
143         free(namelist);
144         gtk_clist_thaw( clist );
145     }
146 }
147
148 static char* get_file_perm(const char *path)
149 {
150     struct stat st;
151     char *perm;
152
153     perm = (char *) malloc(sizeof(char)*10);
154     strncpy( perm, "----------", sizeof("----------"));
155     if (lstat(path, &st)==0)
156     {
157         if (S_ISLNK(st.st_mode))
158             perm[0]= 'l';
159         else if (S_ISDIR(st.st_mode))
160             perm[0]= 'd';
161         else if (S_ISCHR(st.st_mode))
162             perm[0]= 'c';
163         else if (S_ISBLK(st.st_mode))
164             perm[0]= 'b';
165         else if (S_ISFIFO(st.st_mode))
166             perm[0]= 'f';
167         else if (S_ISSOCK(st.st_mode))
168             perm[0]= 's';
169         else if (S_ISREG(st.st_mode))
170             perm[0]= '-';
171         else /* Unknown type is an error */
172             perm[0]= '?';
173         /* Get file permissions */
174         /* User */
175         if (st.st_mode & S_IRUSR)
176             perm[1]= 'r';
177         if (st.st_mode & S_IWUSR)
178             perm[2]= 'w';
179         if (st.st_mode & S_IXUSR)
180         {
181             if (st.st_mode & S_ISUID)
182                 perm[3] = 's';
183             else
184                 perm[3]= 'x';
185         }
186         else if (st.st_mode & S_ISUID)
187             perm[3] = 'S';
188         /* Group */
189         if (st.st_mode & S_IRGRP)
190             perm[4]= 'r';
191         if (st.st_mode & S_IWGRP)
192             perm[5]= 'w';
193         if (st.st_mode & S_IXGRP)
194         {
195             if (st.st_mode & S_ISGID)
196                 perm[6] = 's';
197             else
198                 perm[6]= 'x';
199         }
200         else if (st.st_mode & S_ISGID)
201             perm[6] = 'S';
202         /* Other */
203         if (st.st_mode & S_IROTH)
204             perm[7]= 'r';
205         if (st.st_mode & S_IWOTH)
206             perm[8]= 'w';
207         if (st.st_mode & S_IXOTH)
208         {
209             // 'sticky' bit
210             if (st.st_mode &S_ISVTX)
211                 perm[9] = 't';
212             else
213                 perm[9]= 'x';
214         }
215         else if (st.st_mode &S_ISVTX)
216             perm[9]= 'T';
217     }
218     return perm;
219 }
220
221 /*
222  * Main interface callbacks
223  */
224
225 gboolean FamiliarExit( GtkWidget       *widget,
226                        gpointer         user_data )
227 {
228     intf_thread_t *p_intf = GtkGetIntf( widget );
229
230     vlc_mutex_lock( &p_intf->change_lock );
231     p_intf->p_vlc->b_die = VLC_TRUE;
232     vlc_mutex_unlock( &p_intf->change_lock );
233
234     return TRUE;
235 }
236
237 void
238 on_toolbar_open_clicked                (GtkButton       *button,
239                                         gpointer         user_data)
240 {
241     intf_thread_t *p_intf = GtkGetIntf( button );
242
243     /* Testing routine */
244 /*
245     GtkCList *clistmedia = NULL;
246     clistmedia = GTK_CLIST( lookup_widget( p_intf->p_sys->p_window,
247                                "clistmedia") );
248     if (GTK_CLIST(clistmedia))
249     {
250         ReadDirectory(clistmedia, ".");
251     }
252 */
253     gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
254     gdk_window_raise( p_intf->p_sys->p_window->window );
255 }
256
257
258 void
259 on_toolbar_preferences_clicked         (GtkButton       *button,
260                                         gpointer         user_data)
261 {
262     intf_thread_t *p_intf = GtkGetIntf( button );
263
264     gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
265     gdk_window_raise( p_intf->p_sys->p_window->window );
266 }
267
268
269 void
270 on_toolbar_rewind_clicked              (GtkButton       *button,
271                                         gpointer         user_data)
272 {
273     intf_thread_t *  p_intf = GtkGetIntf( button );
274
275     if( p_intf->p_sys->p_input )
276     {
277         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
278     }
279 }
280
281
282 void
283 on_toolbar_pause_clicked               (GtkButton       *button,
284                                         gpointer         user_data)
285 {
286     intf_thread_t *  p_intf = GtkGetIntf( button );
287
288     if( p_intf->p_sys->p_input )
289     {
290         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
291     }
292 }
293
294
295 void
296 on_toolbar_play_clicked                (GtkButton       *button,
297                                         gpointer         user_data)
298 {
299     intf_thread_t *  p_intf = GtkGetIntf( button );
300     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
301                                                        FIND_ANYWHERE );
302     if( p_playlist == NULL )
303     {
304         gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
305         gdk_window_raise( p_intf->p_sys->p_window->window );
306         /* Display open page */
307     }
308
309     /* If the playlist is empty, open a file requester instead */
310     vlc_mutex_lock( &p_playlist->object_lock );
311     if( p_playlist->i_size )
312     {
313         vlc_mutex_unlock( &p_playlist->object_lock );
314         playlist_Play( p_playlist );
315         vlc_object_release( p_playlist );
316         gdk_window_lower( p_intf->p_sys->p_window->window );
317     }
318     else
319     {
320         vlc_mutex_unlock( &p_playlist->object_lock );
321         vlc_object_release( p_playlist );
322         /* Display open page */
323     }
324 }
325
326
327 void
328 on_toolbar_stop_clicked                (GtkButton       *button,
329                                         gpointer         user_data)
330 {
331     intf_thread_t *  p_intf = GtkGetIntf( button );
332     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
333                                                        FIND_ANYWHERE );
334     if( p_playlist)
335     {
336         playlist_Stop( p_playlist );
337         vlc_object_release( p_playlist );
338         gdk_window_raise( p_intf->p_sys->p_window->window );
339     }
340 }
341
342
343 void
344 on_toolbar_forward_clicked             (GtkButton       *button,
345                                         gpointer         user_data)
346 {
347     intf_thread_t *  p_intf = GtkGetIntf( button );
348
349     if( p_intf->p_sys->p_input )
350     {
351         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
352     }
353 }
354
355
356 void
357 on_toolbar_about_clicked               (GtkButton       *button,
358                                         gpointer         user_data)
359 {
360     intf_thread_t *p_intf = GtkGetIntf( button );
361
362     // Toggle notebook
363     if (p_intf->p_sys->p_notebook)
364     {
365 /*     if ( gtk_get_data(  GTK_WIDGET(p_intf->p_sys->p_notebook), "visible" ) )
366  *         gtk_widget_hide( GTK_WIDGET(p_intf->p_sys->p_notebook) );
367  *     else
368  */      gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
369     }
370     gdk_window_raise( p_intf->p_sys->p_window->window );
371 }
372
373
374 void
375 on_comboURL_entry_changed              (GtkEditable     *editable,
376                                         gpointer         user_data)
377 {
378     intf_thread_t * p_intf = GtkGetIntf( editable );
379     gchar *       psz_url;
380
381     if (p_intf->p_sys->b_autoplayfile == 1)
382     {
383         psz_url = gtk_entry_get_text(GTK_ENTRY(editable));
384         MediaURLOpenChanged( GTK_WIDGET(editable), psz_url );
385     }
386 }
387
388 void
389 on_clistmedia_click_column             (GtkCList        *clist,
390                                         gint             column,
391                                         gpointer         user_data)
392 {
393     static GtkSortType sort_type = GTK_SORT_ASCENDING;
394
395     // Should sort on column
396     switch(sort_type)
397     {
398         case GTK_SORT_ASCENDING:
399             sort_type = GTK_SORT_DESCENDING;
400             break;
401         case GTK_SORT_DESCENDING:
402             sort_type = GTK_SORT_ASCENDING;
403             break;
404     }
405     gtk_clist_freeze( clist );
406     gtk_clist_set_sort_type( clist, sort_type );
407     gtk_clist_sort( clist );
408     gtk_clist_thaw( clist );
409 }
410
411
412 void
413 on_clistmedia_select_row               (GtkCList        *clist,
414                                         gint             row,
415                                         gint             column,
416                                         GdkEvent        *event,
417                                         gpointer         user_data)
418 {
419     gchar *text[2];
420     gint ret;
421     struct stat st;
422
423     ret = gtk_clist_get_text (clist, row, 0, text);
424     if (ret)
425     {
426         if (lstat((char*)text[0], &st)==0)
427         {
428             if (S_ISDIR(st.st_mode))
429                ReadDirectory(clist, text[0]);
430             else
431                MediaURLOpenChanged(GTK_WIDGET(clist), text[0]);
432        }
433     }
434 }
435
436
437 void
438 on_cbautoplay_toggled                  (GtkToggleButton *togglebutton,
439                                         gpointer         user_data)
440 {
441     intf_thread_t * p_intf = GtkGetIntf( togglebutton );
442
443     if (p_intf->p_sys->b_autoplayfile == 1)
444        p_intf->p_sys->b_autoplayfile = 0;
445     else
446        p_intf->p_sys->b_autoplayfile = 1;
447 }
448
449
450 gboolean
451 on_familiar_delete_event               (GtkWidget       *widget,
452                                         GdkEvent        *event,
453                                         gpointer         user_data)
454 {
455     FamiliarExit( GTK_WIDGET( widget ), user_data );
456     return TRUE;
457 }
458