]> git.sesse.net Git - vlc/blob - modules/gui/skins/src/vlcproc.cpp
fc26a54632afc4a76ca7aa3e5c2ac9c1d648a8d9
[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.53 2004/01/05 13:07:03 zorglub 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_ON_TOP:
131             for( list<SkinWindow *>::const_iterator win =
132                     p_intf->p_sys->p_theme->WindowList.begin();
133                 win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
134             {
135                 (*win)->ToggleOnTop();
136             }
137             // Set the indicator to the new state
138             p_intf->p_sys->b_on_top = !p_intf->p_sys->b_on_top;
139             return true;
140
141         case VLC_DROP:
142             DropFile( evt->GetParam1(), evt->GetParam2() );
143             return true;
144
145         case VLC_PLAY:
146             PlayStream();
147             return true;
148
149         case VLC_PAUSE:
150             PauseStream();
151             return true;
152
153         case VLC_STOP:
154             StopStream();
155             return true;
156
157         case VLC_NEXT:
158             NextStream();
159             return true;
160
161         case VLC_PREV:
162             PrevStream();
163             return true;
164
165         case VLC_PLAYLIST_ADD_FILE:
166             p_intf->p_sys->p_dialogs->ShowOpen( false );
167             InterfaceRefresh();
168             return true;
169
170         case VLC_LOG_SHOW:
171             p_intf->p_sys->p_dialogs->ShowMessages();
172             return true;
173
174         case VLC_PREFS_SHOW:
175             p_intf->p_sys->p_dialogs->ShowPrefs();
176             return true;
177
178         case VLC_INFO_SHOW:
179             p_intf->p_sys->p_dialogs->ShowFileInfo();
180             return true;
181
182         case VLC_INTF_REFRESH:
183             InterfaceRefresh();
184             return true;
185
186         case VLC_TEST_ALL_CLOSED:
187             return EventProcEnd();
188
189         case VLC_QUIT:
190             return false;
191
192         case VLC_CHANGE_TRAY:
193             p_intf->p_sys->p_theme->ChangeTray();
194             return true;
195
196         case VLC_CHANGE_TASKBAR:
197             p_intf->p_sys->p_theme->ChangeTaskbar();
198             return true;
199
200         default:
201             return true;
202     }
203 }
204 //---------------------------------------------------------------------------
205 bool VlcProc::EventProcEnd()
206 {
207     if( p_intf->p_sys->b_all_win_closed )
208         return true;
209
210     list<SkinWindow *>::const_iterator win;
211
212     // If a window has been closed, test if all are closed !
213     for( win = p_intf->p_sys->p_theme->WindowList.begin();
214          win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
215     {
216         if( !(*win)->IsHidden() )   // Not all windows closed
217         {
218             return true;
219         }
220     }
221
222     // All window are closed
223     switch( p_intf->p_sys->i_close_status )
224     {
225         case VLC_QUIT:
226             // Save config before exiting
227             p_intf->p_sys->p_theme->SaveConfig();
228             break;
229     }
230
231     // Send specified event
232     OSAPI_PostMessage( NULL, p_intf->p_sys->i_close_status, 0, 0 );
233
234     // Reset values
235     p_intf->p_sys->i_close_status = VLC_NOTHING;
236     p_intf->p_sys->b_all_win_closed = true;
237
238     // Return true
239     return true;
240 }
241 //---------------------------------------------------------------------------
242 bool VlcProc::IsClosing()
243 {
244     if( p_intf->b_die && p_intf->p_sys->i_close_status != VLC_QUIT )
245     {
246         p_intf->p_sys->i_close_status = VLC_QUIT;
247         OSAPI_PostMessage( NULL, VLC_HIDE, VLC_QUIT, 0 );
248     }
249     return true;
250 }
251 //---------------------------------------------------------------------------
252
253
254
255
256 //---------------------------------------------------------------------------
257 // Private methods
258 //---------------------------------------------------------------------------
259
260 // Refresh callback
261 int VlcProc::RefreshCallback( vlc_object_t *p_this, const char *psz_variable,
262         vlc_value_t old_val, vlc_value_t new_val, void *param )
263 {
264     ( (VlcProc*)param )->InterfaceRefresh();
265     return VLC_SUCCESS;
266 }
267
268 // Interface show/hide callback
269 int VlcProc::IntfShowCallback( vlc_object_t *p_this, const char *psz_variable,
270         vlc_value_t old_val, vlc_value_t new_val, void *param )
271 {
272     if( new_val.b_bool == VLC_TRUE )
273     {
274         OSAPI_PostMessage( NULL, VLC_SHOW, 1, 0 );
275     }
276     else
277     {
278         OSAPI_PostMessage( NULL, VLC_HIDE, 1, 0 );
279     }
280     return VLC_SUCCESS;
281 }
282
283 void VlcProc::InterfaceRefresh()
284 {
285     // Shortcut pointers
286     intf_sys_t  *Sys      = p_intf->p_sys;
287     Theme       *Thema    = Sys->p_theme;
288     playlist_t  *PlayList = Sys->p_playlist;
289
290     // Refresh
291     if( PlayList != NULL )
292     {
293         vlc_mutex_lock( &PlayList->object_lock );
294
295         // Refresh stream control controls ! :)
296         switch( PlayList->i_status )
297         {
298             case PLAYLIST_STOPPED:
299                 EnabledEvent( "time", false );
300                 EnabledEvent( "stop", false );
301                 EnabledEvent( "play", true );
302                 EnabledEvent( "pause", false );
303                 break;
304             case PLAYLIST_RUNNING:
305                 EnabledEvent( "time", true );
306                 EnabledEvent( "stop", true );
307                 EnabledEvent( "play", false );
308                 EnabledEvent( "pause", true );
309                 break;
310             case PLAYLIST_PAUSED:
311                 EnabledEvent( "time", true );
312                 EnabledEvent( "stop", true );
313                 EnabledEvent( "play", true );
314                 EnabledEvent( "pause", false );
315                 break;
316         }
317
318         // Refresh next and prev buttons
319         if( PlayList->i_index == 0 || PlayList->i_size == 1 )
320             EnabledEvent( "prev", false );
321         else
322             EnabledEvent( "prev", true );
323
324         if( PlayList->i_index == PlayList->i_size - 1 || PlayList->i_size == 1 )
325             EnabledEvent( "next", false );
326         else
327             EnabledEvent( "next", true );
328
329         // Update file name
330         if( PlayList->i_index >= 0 && PlayList->i_index != Sys->i_index )
331         {
332             string long_name = PlayList->pp_items[PlayList->i_index]->psz_name;
333             int pos = long_name.rfind( DIRECTORY_SEPARATOR, long_name.size() );
334
335             // Complete file name
336             Thema->EvtBank->Get( "file_name" )->PostTextMessage(
337                 PlayList->pp_items[PlayList->i_index]->psz_name );
338             // File name without path
339             Thema->EvtBank->Get( "title" )->PostTextMessage(
340                 PlayList->pp_items[PlayList->i_index]->psz_name + pos + 1 );
341         }
342
343         // Update playlists
344         if( PlayList->i_index != Sys->i_index ||
345             PlayList->i_size != Sys->i_size )
346         {
347             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
348             Sys->i_size  = PlayList->i_size;
349             Sys->i_index = PlayList->i_index;
350         }
351
352         vlc_mutex_unlock( &PlayList->object_lock );
353     }
354     else
355     {
356         EnabledEvent( "time", false );
357         EnabledEvent( "stop",  false );
358         EnabledEvent( "play",  false );
359         EnabledEvent( "pause", false );
360         EnabledEvent( "prev",  false );
361         EnabledEvent( "next",  false );
362
363         // Update playlists
364         if( Sys->i_size > 0 )
365         {
366             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
367             Sys->i_size  = 0;
368         }
369     }
370 }
371 //---------------------------------------------------------------------------
372 void VlcProc::EnabledEvent( string type, bool state )
373 {
374     OSAPI_PostMessage( NULL, CTRL_ENABLED, (unsigned int)
375         p_intf->p_sys->p_theme->EvtBank->Get( type ), (int)state );
376
377     if( !state )
378     {
379         OSAPI_PostMessage( NULL, CTRL_SYNCHRO, (unsigned int)
380             p_intf->p_sys->p_theme->EvtBank->Get( type ), (int)false );
381     }
382 }
383 //---------------------------------------------------------------------------
384
385
386 //---------------------------------------------------------------------------
387 // Common VLC procedures
388 //---------------------------------------------------------------------------
389 void VlcProc::LoadSkin()
390 {
391     if( p_intf->p_sys->p_new_theme_file == NULL )
392     {
393         p_intf->p_sys->p_dialogs->ShowOpenSkin( 0 /*none blocking*/ );
394     }
395     else
396     {
397         // Place a new theme in the global structure, because it will
398         // be filled by the parser
399         // We save the old one to restore it in case of problem
400         Theme *oldTheme = p_intf->p_sys->p_theme;
401         p_intf->p_sys->p_theme = (Theme *)new OSTheme( p_intf );
402
403         // Run the XML parser
404         ThemeLoader *Loader = new ThemeLoader( p_intf );
405         if( Loader->Load( p_intf->p_sys->p_new_theme_file ) )
406         {
407             // Everything went well
408             msg_Dbg( p_intf, "New theme successfully loaded" );
409             delete (OSTheme *)oldTheme;
410
411             // Show the theme
412             p_intf->p_sys->p_theme->InitTheme();
413             p_intf->p_sys->p_theme->ShowTheme();
414         }
415         else
416         {
417             msg_Warn( p_intf, "A problem occurred when loading the new theme,"
418                       " restoring the previous one" );
419             delete (OSTheme *)p_intf->p_sys->p_theme;
420             p_intf->p_sys->p_theme = oldTheme;
421
422             // Show the theme
423             p_intf->p_sys->p_theme->ShowTheme();
424         }
425         delete Loader;
426
427         // Uninitialize new theme
428         free( p_intf->p_sys->p_new_theme_file );
429         p_intf->p_sys->p_new_theme_file = NULL;
430
431         OSAPI_PostMessage( NULL, VLC_INTF_REFRESH, 0, (int)true );
432     }
433 }
434 //---------------------------------------------------------------------------
435
436 void VlcProc::DropFile( unsigned int param1, long param2 )
437 {
438     // Get pointer to file
439     char *FileName = (char *)param1;
440
441     // Add the new file to the playlist
442     if( p_intf->p_sys->p_playlist != NULL )
443     {
444         if( param2 == 0 )
445         {
446             // Enqueue the item
447             playlist_Add( p_intf->p_sys->p_playlist, FileName, FileName,
448                           PLAYLIST_APPEND, PLAYLIST_END );
449         }
450         else
451         {
452             // Enqueue and play the item
453             playlist_Add( p_intf->p_sys->p_playlist, FileName, FileName,
454                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
455         }
456     }
457
458     // VLC_DROP must be called with a pointer to a char else it will
459     // ******** SEGFAULT ********
460     // The delete is here because the processus in asynchronous
461     delete[] FileName;
462
463     // Refresh interface
464     InterfaceRefresh();
465 }
466 //---------------------------------------------------------------------------
467
468
469
470
471 //---------------------------------------------------------------------------
472 // Stream Control
473 //---------------------------------------------------------------------------
474 void VlcProc::PauseStream()
475 {
476     if( p_intf->p_sys->p_playlist == NULL )
477         return;
478
479     playlist_Command( p_intf->p_sys->p_playlist, PLAYLIST_PAUSE, 0 );
480
481     // Refresh interface
482     InterfaceRefresh();
483 }
484 //---------------------------------------------------------------------------
485 void VlcProc::PlayStream()
486 {
487     if( p_intf->p_sys->p_playlist == NULL )
488         return;
489
490     if( !p_intf->p_sys->p_playlist->i_size )
491     {
492         p_intf->p_sys->p_dialogs->ShowOpen( true );
493         InterfaceRefresh();
494         return;
495     }
496
497     playlist_Play( p_intf->p_sys->p_playlist );
498
499     // Refresh interface
500     InterfaceRefresh();
501 }
502 //---------------------------------------------------------------------------
503 void VlcProc::StopStream()
504 {
505     if( p_intf->p_sys->p_playlist == NULL )
506         return;
507     playlist_Stop( p_intf->p_sys->p_playlist );
508
509     // Refresh interface
510     InterfaceRefresh();
511 }
512 //---------------------------------------------------------------------------
513 void VlcProc::NextStream()
514 {
515     if( p_intf->p_sys->p_playlist == NULL )
516         return;
517
518     playlist_Next( p_intf->p_sys->p_playlist );
519
520     // Refresh interface
521     InterfaceRefresh();
522 }
523 //---------------------------------------------------------------------------
524 void VlcProc::PrevStream()
525 {
526     if( p_intf->p_sys->p_playlist == NULL )
527         return;
528
529     playlist_Prev( p_intf->p_sys->p_playlist );
530
531     // Refresh interface
532     InterfaceRefresh();
533 }
534 //---------------------------------------------------------------------------
535 void VlcProc::MoveStream( long Pos )
536 {
537     if( p_intf->p_sys->p_input == NULL )
538         return;
539
540     off_t i_seek = (off_t)(Pos *
541         p_intf->p_sys->p_input->stream.p_selected_area->i_size
542         / SLIDER_RANGE);
543
544     input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
545
546     // Refresh interface
547     InterfaceRefresh();
548 }
549 //---------------------------------------------------------------------------
550
551
552
553 //---------------------------------------------------------------------------
554 // Fullscreen
555 //---------------------------------------------------------------------------
556 void VlcProc::FullScreen()
557 {
558     vout_thread_t *p_vout;
559
560     if( p_intf->p_sys->p_input == NULL )
561         return;
562
563     p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
564                                                VLC_OBJECT_VOUT, FIND_CHILD );
565     if( p_vout == NULL )
566         return;
567
568     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
569     vlc_object_release( p_vout );
570 }
571 //---------------------------------------------------------------------------
572
573
574
575 //---------------------------------------------------------------------------
576 // Volume Control
577 //---------------------------------------------------------------------------
578 void VlcProc::ChangeVolume( unsigned int msg, long param )
579 {
580     audio_volume_t volume;
581     switch( msg )
582     {
583         case VLC_VOLUME_MUTE:
584             aout_VolumeMute( p_intf, NULL );
585             break;
586         case VLC_VOLUME_UP:
587             aout_VolumeUp( p_intf, 1, NULL );
588             break;
589         case VLC_VOLUME_DOWN:
590             aout_VolumeDown( p_intf, 1, NULL );
591             break;
592         case VLC_VOLUME_SET:
593             aout_VolumeSet( p_intf, param * (AOUT_VOLUME_DEFAULT * 2) /
594                             SLIDER_RANGE );
595             break;
596     }
597     aout_VolumeGet( p_intf, &volume );
598 }
599 //---------------------------------------------------------------------------