b347cc7286acce1a0be284320ec66d941aba463b
[vlc.git] / modules / gui / skins / src / vlcproc.cpp
1 /*****************************************************************************
2  * vlcproc.cpp: VlcProc class
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: vlcproc.cpp,v 1.5 2003/04/12 21:43:27 asmax 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
27 //--- VLC -------------------------------------------------------------------
28 #include <vlc/vlc.h>
29 #include <vlc/intf.h>
30 #include <vlc/aout.h>
31 #include <vlc/vout.h>
32
33
34 //--- SKIN ------------------------------------------------------------------
35 #include "os_api.h"
36 #include "dialog.h"
37 #include "os_dialog.h"
38 #include "event.h"
39 #include "banks.h"
40 #include "theme.h"
41 #include "os_theme.h"
42 #include "themeloader.h"
43 #include "window.h"
44 #include "vlcproc.h"
45 #include "skin_common.h"
46
47
48
49 //---------------------------------------------------------------------------
50 // VlcProc
51 //---------------------------------------------------------------------------
52 VlcProc::VlcProc( intf_thread_t *_p_intf )
53 {
54     p_intf = _p_intf;
55 }
56 //---------------------------------------------------------------------------
57 bool VlcProc::EventProc( Event *evt )
58 {
59     switch( evt->GetMessage() )
60     {
61         case VLC_STREAMPOS:
62             MoveStream( evt->GetParam2() );
63             return true;
64
65         case VLC_VOLUME_CHANGE:
66             ChangeVolume( evt->GetParam1(), evt->GetParam2() );
67             return true;
68
69         case VLC_FULLSCREEN:
70             FullScreen();
71             return true;
72
73         case VLC_HIDE:
74             for( list<Window *>::const_iterator win =
75                     p_intf->p_sys->p_theme->WindowList.begin();
76                  win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
77             {
78                 (*win)->OnStartThemeVisible = !(*win)->IsHidden();
79             }
80             p_intf->p_sys->i_close_status = (int)evt->GetParam1();
81             OSAPI_PostMessage( NULL, WINDOW_CLOSE, 1, 0 );
82             return true;
83
84         case VLC_SHOW:
85             for( list<Window *>::const_iterator win =
86                     p_intf->p_sys->p_theme->WindowList.begin();
87                  win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
88             {
89                 if( (*win)->OnStartThemeVisible )
90                     OSAPI_PostMessage( (*win), WINDOW_OPEN, 1, 0 );
91             }
92             p_intf->p_sys->b_all_win_closed = false;
93             return true;
94
95         case VLC_OPEN:
96             OpenFile( true );
97             return true;
98
99         case VLC_LOAD_SKIN:
100             LoadSkin();
101             return true;
102
103         case VLC_DROP:
104             DropFile( evt->GetParam1() );
105             return true;
106
107         case VLC_PLAY:
108             PlayStream();
109             return true;
110
111         case VLC_PAUSE:
112             PauseStream();
113             return true;
114
115         case VLC_STOP:
116             StopStream();
117             return true;
118
119         case VLC_NEXT:
120             NextStream();
121             return true;
122
123         case VLC_PREV:
124             PrevStream();
125             return true;
126
127         case VLC_PLAYLIST_ADD_FILE:
128             OpenFile( false );
129             return true;
130
131         case VLC_LOG_SHOW:
132             p_intf->p_sys->p_theme->ShowLog( evt->GetParam2() );
133             return true;
134
135         case VLC_LOG_CLEAR:
136             p_intf->p_sys->p_theme->ClearLog();
137             return true;
138
139         case VLC_INTF_REFRESH:
140             InterfaceRefresh( (bool)evt->GetParam2() );
141             return true;
142
143         case VLC_TEST_ALL_CLOSED:
144             return EventProcEnd();
145
146         case VLC_QUIT:
147             return false;
148
149         case VLC_CHANGE_TRAY:
150             p_intf->p_sys->p_theme->ChangeTray();
151             return true;
152
153         case VLC_CHANGE_TASKBAR:
154             p_intf->p_sys->p_theme->ChangeTaskbar();
155             return true;
156
157         case VLC_NET_ADDUDP:
158             AddNetworkUDP( (int)evt->GetParam2() );
159             return true;
160
161         default:
162             return true;
163     }
164 }
165 //---------------------------------------------------------------------------
166 bool VlcProc::EventProcEnd()
167 {
168     if( p_intf->p_sys->b_all_win_closed )
169         return true;
170
171     list<Window *>::const_iterator win;
172
173     // If a window has been closed, test if all are closed !
174     for( win = p_intf->p_sys->p_theme->WindowList.begin();
175          win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
176     {
177         if( !(*win)->IsHidden() )   // Not all windows closed
178         {
179             return true;
180         }
181     }
182
183     // All window are closed
184     switch( p_intf->p_sys->i_close_status )
185     {
186         case VLC_QUIT:
187             // Save config before exiting
188             p_intf->p_sys->p_theme->SaveConfig();
189             break;
190     }
191
192     // Send specified event
193     OSAPI_PostMessage( NULL, p_intf->p_sys->i_close_status, 0, 0 );
194
195     // Reset values
196     p_intf->p_sys->i_close_status = VLC_NOTHING;
197     p_intf->p_sys->b_all_win_closed = true;
198
199     // Return true
200     return true;
201 }
202 //---------------------------------------------------------------------------
203 bool VlcProc::IsClosing()
204 {
205     if( p_intf->b_die && p_intf->p_sys->i_close_status != VLC_QUIT )
206     {
207         p_intf->p_sys->i_close_status = VLC_QUIT;
208         OSAPI_PostMessage( NULL, VLC_HIDE, VLC_QUIT, 0 );
209     }
210     return true;
211 }
212 //---------------------------------------------------------------------------
213
214
215
216
217 //---------------------------------------------------------------------------
218 // Private methods
219 //---------------------------------------------------------------------------
220 void VlcProc::InterfaceRefresh( bool All )
221 {
222     // Shortcut pointers
223     intf_sys_t  *Sys      = p_intf->p_sys;
224     Theme       *Thema    = Sys->p_theme;
225     playlist_t  *PlayList = Sys->p_playlist;
226
227
228     // Refresh
229     if( PlayList != NULL && Sys->p_input != NULL &&
230         Sys->p_input->stream.b_seekable )
231     {
232         // Refresh stream control controls ! :)
233         switch( PlayList->i_status )
234         {
235             case PLAYLIST_STOPPED:
236                 EnabledEvent( "time", false );
237                 EnabledEvent( "stop", false );
238                 EnabledEvent( "play", true );
239                 EnabledEvent( "pause", false );
240                 break;
241             case PLAYLIST_RUNNING:
242                 EnabledEvent( "time", true );
243                 EnabledEvent( "stop", true );
244                 EnabledEvent( "play", false );
245                 EnabledEvent( "pause", true );
246                 break;
247             case PLAYLIST_PAUSED:
248                 EnabledEvent( "time", true );
249                 EnabledEvent( "stop", true );
250                 EnabledEvent( "play", true );
251                 EnabledEvent( "pause", false );
252                 break;
253         }
254
255         // Refresh next and prev buttons
256         if( PlayList->i_index == 0 || PlayList->i_size == 1 )
257             EnabledEvent( "prev", false );
258         else
259             EnabledEvent( "prev", true );
260
261         if( PlayList->i_index == PlayList->i_size - 1 || PlayList->i_size == 1 )
262             EnabledEvent( "next", false );
263         else
264             EnabledEvent( "next", true );
265
266
267         // Update file name text
268         if( PlayList->i_index != Sys->i_index )
269         {
270             Thema->EvtBank->Get( "file_name" )->PostTextMessage(
271                 PlayList->pp_items[PlayList->i_index]->psz_name );
272         }
273
274         // Update playlists
275         if( PlayList->i_index != Sys->i_index ||
276             PlayList->i_size != Sys->i_size )
277         {
278             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
279             Sys->i_size  = PlayList->i_size;
280             Sys->i_index = PlayList->i_index;
281         }
282     }
283     else
284     {
285         EnabledEvent( "time", false );
286         EnabledEvent( "stop",  false );
287         EnabledEvent( "play",  false );
288         EnabledEvent( "pause", false );
289         EnabledEvent( "prev",  false );
290         EnabledEvent( "next",  false );
291
292         // Update playlists
293         if( Sys->i_size > 0 )
294         {
295             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
296             Sys->i_size  = 0;
297         }
298     }
299
300 }
301 //---------------------------------------------------------------------------
302 void VlcProc::EnabledEvent( string type, bool state )
303 {
304     OSAPI_PostMessage( NULL, CTRL_ENABLED, (unsigned int)
305         p_intf->p_sys->p_theme->EvtBank->Get( type ), (int)state );
306 }
307 //---------------------------------------------------------------------------
308
309
310
311 //---------------------------------------------------------------------------
312 // Common VLC procedures
313 //---------------------------------------------------------------------------
314 void VlcProc::LoadSkin()
315 {
316     if( p_intf->p_sys->p_new_theme_file == NULL )
317     {
318         // Initialize file structure
319         OpenFileDialog *OpenFile;
320         OpenFile = (OpenFileDialog *)new OSOpenFileDialog( p_intf,
321             _("Change skin - Open new file"), false );
322         OpenFile->AddFilter( _("Skin files"), "*.vlt" );
323         OpenFile->AddFilter( _("Skin files"), "*.xml" );
324         OpenFile->AddFilter( _("All files"), "*.*" );
325
326         // Open dialog box
327         if( OpenFile->Open() )
328         {
329             p_intf->p_sys->p_new_theme_file =
330                 new char[OpenFile->FileList.front().length()];
331
332             strcpy( p_intf->p_sys->p_new_theme_file,
333                     OpenFile->FileList.front().c_str() );
334
335             // Tell vlc to change skin after hiding interface
336             OSAPI_PostMessage( NULL, VLC_HIDE, VLC_LOAD_SKIN, 0 );
337         }
338
339         // Free memory
340         delete OpenFile;
341     }
342     else
343     {
344         // Place a new theme in the global structure, because it will
345         // be filled by the parser
346         // We save the old one to restore it in case of problem
347         Theme *oldTheme = p_intf->p_sys->p_theme;
348         p_intf->p_sys->p_theme = (Theme *)new OSTheme( p_intf );
349
350         // Run the XML parser
351         ThemeLoader *Loader = new ThemeLoader( p_intf );
352         if( Loader->Load( p_intf->p_sys->p_new_theme_file ) )
353         {
354             // Everything went well
355             msg_Dbg( p_intf, "New theme successfully loaded" );
356             delete (OSTheme *)oldTheme;
357
358             // Show the theme
359             p_intf->p_sys->p_theme->InitTheme();
360             p_intf->p_sys->p_theme->ShowTheme();
361         }
362         else
363         {
364             msg_Warn( p_intf, "A problem occurred when loading the new theme,"
365                       " restoring the previous one" );
366             delete (OSTheme *)p_intf->p_sys->p_theme;
367             p_intf->p_sys->p_theme = oldTheme;
368
369             // Show the theme
370             p_intf->p_sys->p_theme->ShowTheme();
371         }
372         delete Loader;
373
374         // Uninitialize new theme
375         delete (char *)p_intf->p_sys->p_new_theme_file;
376         p_intf->p_sys->p_new_theme_file = NULL;
377     }
378 }
379 //---------------------------------------------------------------------------
380 void VlcProc::OpenFile( bool play )
381 {
382     // Initialize file structure
383     OpenFileDialog *OpenFile;
384     if( play )
385     {
386         OpenFile = (OpenFileDialog *)new OSOpenFileDialog( p_intf,
387             _("Open file"), false );
388     }
389     else
390     {
391         OpenFile = (OpenFileDialog *)new OSOpenFileDialog( p_intf,
392             _("Add file"), true );
393     }
394     OpenFile->AddFilter( _("All files"), "*.*" );
395
396     // Check if palylist is available
397     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
398     if( p_playlist == NULL )
399         return;
400
401     // Open dialog box and launch file
402     if( OpenFile->Open() )
403     {
404         list<string>::const_iterator file;
405         for( file = OpenFile->FileList.begin();
406              file != OpenFile->FileList.end(); file++ )
407         {
408             playlist_Add( p_playlist, (*file).c_str(), PLAYLIST_APPEND,
409                           PLAYLIST_END );
410         }
411
412         // Refreshing
413         if( play )
414         {
415             // Play
416             p_intf->p_sys->p_theme->EvtBank->Get( "play" )->SendEvent();
417         }
418
419         // Refresh interface !
420         p_intf->p_sys->p_theme->EvtBank->Get( "playlist_refresh" )
421             ->PostSynchroMessage();
422         InterfaceRefresh();
423     }
424
425     // Free memory
426     delete OpenFile;
427 }
428 //---------------------------------------------------------------------------
429 void VlcProc::DropFile( unsigned int param )
430 {
431     // Get pointer to file
432     char *FileName = (char *)param;
433
434     // Add the new file to the playlist
435     if( p_intf->p_sys->p_playlist != NULL )
436     {
437         if( config_GetInt( p_intf, "enqueue" ) )
438         {
439             playlist_Add( p_intf->p_sys->p_playlist, FileName,
440                           PLAYLIST_APPEND, PLAYLIST_END );
441         }
442         else
443         {
444             playlist_Add( p_intf->p_sys->p_playlist, FileName,
445                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
446         }
447     }
448
449     // VLC_DROP must be called with a pointer to a char else it will
450     // ******** SEGFAULT ********
451     // The delete is here because the processus in asynchronous
452     delete[] FileName;
453
454     // Refresh interface
455     InterfaceRefresh();
456
457 }
458 //---------------------------------------------------------------------------
459
460
461
462
463 //---------------------------------------------------------------------------
464 // Stream Control
465 //---------------------------------------------------------------------------
466 void VlcProc::PauseStream()
467 {
468     if( p_intf->p_sys->p_input == NULL )
469         return;
470     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
471
472     // Refresh interface
473     InterfaceRefresh();
474 }
475 //---------------------------------------------------------------------------
476 void VlcProc::PlayStream()
477 {
478     if( p_intf->p_sys->p_playlist == NULL )
479         return;
480     if( !p_intf->p_sys->p_playlist->i_size )
481         return;
482
483     playlist_Play( p_intf->p_sys->p_playlist );
484
485     // Refresh interface
486     InterfaceRefresh();
487 }
488 //---------------------------------------------------------------------------
489 void VlcProc::StopStream()
490 {
491     if( p_intf->p_sys->p_playlist == NULL )
492         return;
493     playlist_Stop( p_intf->p_sys->p_playlist );
494
495     // Refresh interface
496     InterfaceRefresh();
497 }
498 //---------------------------------------------------------------------------
499 void VlcProc::NextStream()
500 {
501     if( p_intf->p_sys->p_playlist == NULL )
502         return;
503
504     playlist_Next( p_intf->p_sys->p_playlist );
505
506     // Refresh interface
507     InterfaceRefresh();
508 }
509 //---------------------------------------------------------------------------
510 void VlcProc::PrevStream()
511 {
512     if( p_intf->p_sys->p_playlist == NULL )
513         return;
514
515     playlist_Prev( p_intf->p_sys->p_playlist );
516
517     // Refresh interface
518     InterfaceRefresh();
519 }
520 //---------------------------------------------------------------------------
521 void VlcProc::MoveStream( long Pos )
522 {
523     if( p_intf->p_sys->p_input == NULL )
524         return;
525
526     off_t i_seek = (off_t)(Pos *
527         p_intf->p_sys->p_input->stream.p_selected_area->i_size
528         / SLIDER_RANGE);
529
530     input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
531
532     // Refresh interface
533     InterfaceRefresh();
534 }
535 //---------------------------------------------------------------------------
536
537
538
539 //---------------------------------------------------------------------------
540 // Fullscreen
541 //---------------------------------------------------------------------------
542 void VlcProc::FullScreen()
543 {
544     vout_thread_t *p_vout;
545
546     if( p_intf->p_sys->p_input == NULL )
547         return;
548
549     p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
550                                                VLC_OBJECT_VOUT, FIND_CHILD );
551     if( p_vout == NULL )
552         return;
553
554     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
555     vlc_object_release( p_vout );
556 }
557 //---------------------------------------------------------------------------
558
559
560
561 //---------------------------------------------------------------------------
562 // Volume Control
563 //---------------------------------------------------------------------------
564 void VlcProc::ChangeVolume( unsigned int msg, long param )
565 {
566     audio_volume_t volume;
567     switch( msg )
568     {
569         case VLC_VOLUME_MUTE:
570             aout_VolumeMute( p_intf, NULL );
571             break;
572         case VLC_VOLUME_UP:
573             aout_VolumeUp( p_intf, 1, NULL );
574             break;
575         case VLC_VOLUME_DOWN:
576             aout_VolumeDown( p_intf, 1, NULL );
577             break;
578         case VLC_VOLUME_SET:
579             aout_VolumeSet( p_intf, param * AOUT_VOLUME_MAX / SLIDER_RANGE );
580             break;
581     }
582     aout_VolumeGet( p_intf, &volume );
583
584 /* FIXME: kludge */
585 #ifdef WIN32
586     PostMessage( NULL, CTRL_SET_SLIDER,
587         (unsigned int)
588             p_intf->p_sys->p_theme->EvtBank->Get( "volume_refresh" ),
589         (int)( volume * SLIDER_RANGE / AOUT_VOLUME_MAX ) );
590 #else
591   fprintf(stderr, "WARNING: FIXME in vlcproc.cpp !!!");
592 #endif
593 }
594 //---------------------------------------------------------------------------
595
596
597 //---------------------------------------------------------------------------
598 // Network
599 //---------------------------------------------------------------------------
600 void VlcProc::AddNetworkUDP( int port )
601 {
602     config_PutInt( p_intf, "network-channel", VLC_FALSE );
603
604     // Build source name
605     char *s_port = new char[5];
606     sprintf( s_port, "%i", port );
607     string source = "udp:@:" + (string)s_port;
608     delete[] s_port;
609
610     playlist_Add( p_intf->p_sys->p_playlist, (char *)source.c_str(),
611         PLAYLIST_APPEND, PLAYLIST_END );
612
613     // Refresh interface !
614     p_intf->p_sys->p_theme->EvtBank->Get( "playlist_refresh" )
615         ->PostSynchroMessage();
616     InterfaceRefresh();
617 }
618 //---------------------------------------------------------------------------
619
620