]> git.sesse.net Git - vlc/blob - modules/gui/skins/src/vlcproc.cpp
053a65a2af5e90225f51da0bb3c7a61a0bab192c
[vlc] / modules / gui / skins / src / vlcproc.cpp
1 /*****************************************************************************
2  * vlcproc.cpp: VlcProc class
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: vlcproc.cpp,v 1.47 2003/10/17 16:40:09 gbazin Exp $
6  *
7  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8  *          Emmanuel Puig    <karibu@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,
23  * USA.
24  *****************************************************************************/
25
26 //--- VLC -------------------------------------------------------------------
27 #include <vlc/vlc.h>
28 #include <vlc/intf.h>
29 #include <vlc/aout.h>
30 #include <vlc/vout.h>
31
32 //--- SKIN ------------------------------------------------------------------
33 #include "../os_api.h"
34 #include "event.h"
35 #include "banks.h"
36 #include "theme.h"
37 #include "../os_theme.h"
38 #include "themeloader.h"
39 #include "window.h"
40 #include "vlcproc.h"
41 #include "skin_common.h"
42 #include "dialogs.h"
43
44 //---------------------------------------------------------------------------
45 // VlcProc
46 //---------------------------------------------------------------------------
47 VlcProc::VlcProc( intf_thread_t *_p_intf )
48 {
49     p_intf = _p_intf;
50
51     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
52         VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
53     if( p_playlist != NULL )
54     {
55         // We want to be notified of playlit changes
56         var_AddCallback( p_playlist, "intf-change", RefreshCallback, this );
57
58         // Raise/lower interface with middle click on vout
59         var_AddCallback( p_playlist, "intf-show", IntfShowCallback, this );
60
61         vlc_object_release( p_playlist );
62     }
63 }
64 //---------------------------------------------------------------------------
65 VlcProc::~VlcProc()
66 {
67     // Remove the refresh callback
68     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
69         VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
70     if( p_playlist != NULL )
71     {
72         var_DelCallback( p_playlist, "intf-change", RefreshCallback, this );
73         var_DelCallback( p_playlist, "intf-show", IntfShowCallback, this );
74         vlc_object_release( p_playlist );
75     }
76 }
77 //---------------------------------------------------------------------------
78 bool VlcProc::EventProc( Event *evt )
79 {
80     switch( evt->GetMessage() )
81     {
82         case VLC_STREAMPOS:
83             MoveStream( evt->GetParam2() );
84             return true;
85
86         case VLC_VOLUME_CHANGE:
87             ChangeVolume( evt->GetParam1(), evt->GetParam2() );
88             return true;
89
90         case VLC_FULLSCREEN:
91             FullScreen();
92             return true;
93
94         case VLC_HIDE:
95             for( list<SkinWindow *>::const_iterator win =
96                     p_intf->p_sys->p_theme->WindowList.begin();
97                  win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
98             {
99                 (*win)->OnStartThemeVisible = !(*win)->IsHidden();
100             }
101             p_intf->p_sys->i_close_status = (int)evt->GetParam1();
102             OSAPI_PostMessage( NULL, WINDOW_CLOSE, 1, 0 );
103             return true;
104
105         case VLC_SHOW:
106             for( list<SkinWindow *>::const_iterator win =
107                     p_intf->p_sys->p_theme->WindowList.begin();
108                  win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
109             {
110                 if( (*win)->OnStartThemeVisible )
111                     OSAPI_PostMessage( (*win), WINDOW_OPEN, 1, 0 );
112             }
113             p_intf->p_sys->b_all_win_closed = false;
114             return true;
115
116         case VLC_OPEN:
117             p_intf->p_sys->p_dialogs->ShowOpen( true );
118             InterfaceRefresh();
119             return true;
120
121         case VLC_NET:
122             p_intf->p_sys->p_dialogs->ShowNet();
123             InterfaceRefresh();
124             return true;
125
126         case VLC_LOAD_SKIN:
127             LoadSkin();
128             return true;
129
130         case VLC_DROP:
131             DropFile( evt->GetParam1() );
132             return true;
133
134         case VLC_PLAY:
135             PlayStream();
136             return true;
137
138         case VLC_PAUSE:
139             PauseStream();
140             return true;
141
142         case VLC_STOP:
143             StopStream();
144             return true;
145
146         case VLC_NEXT:
147             NextStream();
148             return true;
149
150         case VLC_PREV:
151             PrevStream();
152             return true;
153
154         case VLC_PLAYLIST_ADD_FILE:
155             p_intf->p_sys->p_dialogs->ShowOpen( false );
156             InterfaceRefresh();
157             return true;
158
159         case VLC_LOG_SHOW:
160             p_intf->p_sys->p_dialogs->ShowMessages();
161             return true;
162
163         case VLC_PREFS_SHOW:
164             p_intf->p_sys->p_dialogs->ShowPrefs();
165             return true;
166
167         case VLC_INFO_SHOW:
168             p_intf->p_sys->p_dialogs->ShowFileInfo();
169             return true;
170
171         case VLC_INTF_REFRESH:
172             InterfaceRefresh();
173             return true;
174
175         case VLC_TEST_ALL_CLOSED:
176             return EventProcEnd();
177
178         case VLC_QUIT:
179             return false;
180
181         case VLC_CHANGE_TRAY:
182             p_intf->p_sys->p_theme->ChangeTray();
183             return true;
184
185         case VLC_CHANGE_TASKBAR:
186             p_intf->p_sys->p_theme->ChangeTaskbar();
187             return true;
188
189         default:
190             return true;
191     }
192 }
193 //---------------------------------------------------------------------------
194 bool VlcProc::EventProcEnd()
195 {
196     if( p_intf->p_sys->b_all_win_closed )
197         return true;
198
199     list<SkinWindow *>::const_iterator win;
200
201     // If a window has been closed, test if all are closed !
202     for( win = p_intf->p_sys->p_theme->WindowList.begin();
203          win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
204     {
205         if( !(*win)->IsHidden() )   // Not all windows closed
206         {
207             return true;
208         }
209     }
210
211     // All window are closed
212     switch( p_intf->p_sys->i_close_status )
213     {
214         case VLC_QUIT:
215             // Save config before exiting
216             p_intf->p_sys->p_theme->SaveConfig();
217             break;
218     }
219
220     // Send specified event
221     OSAPI_PostMessage( NULL, p_intf->p_sys->i_close_status, 0, 0 );
222
223     // Reset values
224     p_intf->p_sys->i_close_status = VLC_NOTHING;
225     p_intf->p_sys->b_all_win_closed = true;
226
227     // Return true
228     return true;
229 }
230 //---------------------------------------------------------------------------
231 bool VlcProc::IsClosing()
232 {
233     if( p_intf->b_die && p_intf->p_sys->i_close_status != VLC_QUIT )
234     {
235         p_intf->p_sys->i_close_status = VLC_QUIT;
236         OSAPI_PostMessage( NULL, VLC_HIDE, VLC_QUIT, 0 );
237     }
238     return true;
239 }
240 //---------------------------------------------------------------------------
241
242
243
244
245 //---------------------------------------------------------------------------
246 // Private methods
247 //---------------------------------------------------------------------------
248
249 // Refresh callback
250 int VlcProc::RefreshCallback( vlc_object_t *p_this, const char *psz_variable,
251         vlc_value_t old_val, vlc_value_t new_val, void *param )
252 {
253     ( (VlcProc*)param )->InterfaceRefresh();
254     return VLC_SUCCESS;
255 }
256
257 // Interface show/hide callback
258 int VlcProc::IntfShowCallback( vlc_object_t *p_this, const char *psz_variable,
259         vlc_value_t old_val, vlc_value_t new_val, void *param )
260 {
261     if( new_val.b_bool == VLC_TRUE )
262     {
263         OSAPI_PostMessage( NULL, VLC_SHOW, 1, 0 );
264     }
265     else
266     {
267         OSAPI_PostMessage( NULL, VLC_HIDE, 1, 0 );
268     }
269     return VLC_SUCCESS;
270 }
271
272 void VlcProc::InterfaceRefresh()
273 {
274     // Shortcut pointers
275     intf_sys_t  *Sys      = p_intf->p_sys;
276     Theme       *Thema    = Sys->p_theme;
277     playlist_t  *PlayList = Sys->p_playlist;
278
279     // Refresh
280     if( PlayList != NULL )
281     {
282         vlc_mutex_lock( &PlayList->object_lock );
283
284         // Refresh stream control controls ! :)
285         switch( PlayList->i_status )
286         {
287             case PLAYLIST_STOPPED:
288                 EnabledEvent( "time", false );
289                 EnabledEvent( "stop", false );
290                 EnabledEvent( "play", true );
291                 EnabledEvent( "pause", false );
292                 break;
293             case PLAYLIST_RUNNING:
294                 EnabledEvent( "time", true );
295                 EnabledEvent( "stop", true );
296                 EnabledEvent( "play", false );
297                 EnabledEvent( "pause", true );
298                 break;
299             case PLAYLIST_PAUSED:
300                 EnabledEvent( "time", true );
301                 EnabledEvent( "stop", true );
302                 EnabledEvent( "play", true );
303                 EnabledEvent( "pause", false );
304                 break;
305         }
306
307         // Refresh next and prev buttons
308         if( PlayList->i_index == 0 || PlayList->i_size == 1 )
309             EnabledEvent( "prev", false );
310         else
311             EnabledEvent( "prev", true );
312
313         if( PlayList->i_index == PlayList->i_size - 1 || PlayList->i_size == 1 )
314             EnabledEvent( "next", false );
315         else
316             EnabledEvent( "next", true );
317
318         // Update file name
319         if( PlayList->i_index >= 0 && PlayList->i_index != Sys->i_index )
320         {
321             string long_name = PlayList->pp_items[PlayList->i_index]->psz_name;
322             int pos = long_name.rfind( DIRECTORY_SEPARATOR, long_name.size() );
323
324             // Complete file name
325             Thema->EvtBank->Get( "file_name" )->PostTextMessage(
326                 PlayList->pp_items[PlayList->i_index]->psz_name );
327             // File name without path
328             Thema->EvtBank->Get( "title" )->PostTextMessage(
329                 PlayList->pp_items[PlayList->i_index]->psz_name + pos + 1 );
330         }
331
332         // Update playlists
333         if( PlayList->i_index != Sys->i_index ||
334             PlayList->i_size != Sys->i_size )
335         {
336             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
337             Sys->i_size  = PlayList->i_size;
338             Sys->i_index = PlayList->i_index;
339         }
340
341         vlc_mutex_unlock( &PlayList->object_lock );
342     }
343     else
344     {
345         EnabledEvent( "time", false );
346         EnabledEvent( "stop",  false );
347         EnabledEvent( "play",  false );
348         EnabledEvent( "pause", false );
349         EnabledEvent( "prev",  false );
350         EnabledEvent( "next",  false );
351
352         // Update playlists
353         if( Sys->i_size > 0 )
354         {
355             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
356             Sys->i_size  = 0;
357         }
358     }
359 }
360 //---------------------------------------------------------------------------
361 void VlcProc::EnabledEvent( string type, bool state )
362 {
363     OSAPI_PostMessage( NULL, CTRL_ENABLED, (unsigned int)
364         p_intf->p_sys->p_theme->EvtBank->Get( type ), (int)state );
365 }
366 //---------------------------------------------------------------------------
367
368
369 //---------------------------------------------------------------------------
370 // Common VLC procedures
371 //---------------------------------------------------------------------------
372 void VlcProc::LoadSkin()
373 {
374     if( p_intf->p_sys->p_new_theme_file == NULL )
375     {
376         p_intf->p_sys->p_dialogs->ShowOpenSkin( 0 /*none blocking*/ );
377     }
378     else
379     {
380         // Place a new theme in the global structure, because it will
381         // be filled by the parser
382         // We save the old one to restore it in case of problem
383         Theme *oldTheme = p_intf->p_sys->p_theme;
384         p_intf->p_sys->p_theme = (Theme *)new OSTheme( p_intf );
385
386         // Run the XML parser
387         ThemeLoader *Loader = new ThemeLoader( p_intf );
388         if( Loader->Load( p_intf->p_sys->p_new_theme_file ) )
389         {
390             // Everything went well
391             msg_Dbg( p_intf, "New theme successfully loaded" );
392             delete (OSTheme *)oldTheme;
393
394             // Show the theme
395             p_intf->p_sys->p_theme->InitTheme();
396             p_intf->p_sys->p_theme->ShowTheme();
397         }
398         else
399         {
400             msg_Warn( p_intf, "A problem occurred when loading the new theme,"
401                       " restoring the previous one" );
402             delete (OSTheme *)p_intf->p_sys->p_theme;
403             p_intf->p_sys->p_theme = oldTheme;
404
405             // Show the theme
406             p_intf->p_sys->p_theme->ShowTheme();
407         }
408         delete Loader;
409
410         // Uninitialize new theme
411         delete[] p_intf->p_sys->p_new_theme_file;
412         p_intf->p_sys->p_new_theme_file = NULL;
413     }
414 }
415 //---------------------------------------------------------------------------
416
417 void VlcProc::DropFile( unsigned int param )
418 {
419     // Get pointer to file
420     char *FileName = (char *)param;
421
422     // Add the new file to the playlist
423     if( p_intf->p_sys->p_playlist != NULL )
424     {
425         if( config_GetInt( p_intf, "enqueue" ) )
426         {
427             playlist_Add( p_intf->p_sys->p_playlist, FileName, 0, 0,
428                           PLAYLIST_APPEND, PLAYLIST_END );
429         }
430         else
431         {
432             playlist_Add( p_intf->p_sys->p_playlist, FileName, 0, 0,
433                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
434         }
435     }
436
437     // VLC_DROP must be called with a pointer to a char else it will
438     // ******** SEGFAULT ********
439     // The delete is here because the processus in asynchronous
440     delete[] FileName;
441
442     // Refresh interface
443     InterfaceRefresh();
444
445 }
446 //---------------------------------------------------------------------------
447
448
449
450
451 //---------------------------------------------------------------------------
452 // Stream Control
453 //---------------------------------------------------------------------------
454 void VlcProc::PauseStream()
455 {
456     if( p_intf->p_sys->p_input == NULL )
457         return;
458     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
459
460     // Refresh interface
461     InterfaceRefresh();
462 }
463 //---------------------------------------------------------------------------
464 void VlcProc::PlayStream()
465 {
466     if( p_intf->p_sys->p_playlist == NULL )
467         return;
468
469     if( !p_intf->p_sys->p_playlist->i_size )
470     {
471         p_intf->p_sys->p_dialogs->ShowOpen( true );
472         InterfaceRefresh();
473         return;
474     }
475
476     playlist_Play( p_intf->p_sys->p_playlist );
477
478     // Refresh interface
479     InterfaceRefresh();
480 }
481 //---------------------------------------------------------------------------
482 void VlcProc::StopStream()
483 {
484     if( p_intf->p_sys->p_playlist == NULL )
485         return;
486     playlist_Stop( p_intf->p_sys->p_playlist );
487
488     // Refresh interface
489     InterfaceRefresh();
490 }
491 //---------------------------------------------------------------------------
492 void VlcProc::NextStream()
493 {
494     if( p_intf->p_sys->p_playlist == NULL )
495         return;
496
497     playlist_Next( p_intf->p_sys->p_playlist );
498
499     // Refresh interface
500     InterfaceRefresh();
501 }
502 //---------------------------------------------------------------------------
503 void VlcProc::PrevStream()
504 {
505     if( p_intf->p_sys->p_playlist == NULL )
506         return;
507
508     playlist_Prev( p_intf->p_sys->p_playlist );
509
510     // Refresh interface
511     InterfaceRefresh();
512 }
513 //---------------------------------------------------------------------------
514 void VlcProc::MoveStream( long Pos )
515 {
516     if( p_intf->p_sys->p_input == NULL )
517         return;
518
519     off_t i_seek = (off_t)(Pos *
520         p_intf->p_sys->p_input->stream.p_selected_area->i_size
521         / SLIDER_RANGE);
522
523     input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
524
525     // Refresh interface
526     InterfaceRefresh();
527 }
528 //---------------------------------------------------------------------------
529
530
531
532 //---------------------------------------------------------------------------
533 // Fullscreen
534 //---------------------------------------------------------------------------
535 void VlcProc::FullScreen()
536 {
537     vout_thread_t *p_vout;
538
539     if( p_intf->p_sys->p_input == NULL )
540         return;
541
542     p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
543                                                VLC_OBJECT_VOUT, FIND_CHILD );
544     if( p_vout == NULL )
545         return;
546
547     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
548     vlc_object_release( p_vout );
549 }
550 //---------------------------------------------------------------------------
551
552
553
554 //---------------------------------------------------------------------------
555 // Volume Control
556 //---------------------------------------------------------------------------
557 void VlcProc::ChangeVolume( unsigned int msg, long param )
558 {
559     audio_volume_t volume;
560     switch( msg )
561     {
562         case VLC_VOLUME_MUTE:
563             aout_VolumeMute( p_intf, NULL );
564             break;
565         case VLC_VOLUME_UP:
566             aout_VolumeUp( p_intf, 1, NULL );
567             break;
568         case VLC_VOLUME_DOWN:
569             aout_VolumeDown( p_intf, 1, NULL );
570             break;
571         case VLC_VOLUME_SET:
572             aout_VolumeSet( p_intf, param * (AOUT_VOLUME_DEFAULT * 2) /
573                             SLIDER_RANGE );
574             break;
575     }
576     aout_VolumeGet( p_intf, &volume );
577
578 }
579 //---------------------------------------------------------------------------