]> git.sesse.net Git - vlc/blob - modules/gui/skins/src/vlcproc.cpp
* Fixing a refresh bug when opening an open file dialog box
[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.3 2003/03/20 09:29:07 karibu 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         default:
158             return true;
159     }
160 }
161 //---------------------------------------------------------------------------
162 bool VlcProc::EventProcEnd()
163 {
164     if( p_intf->p_sys->b_all_win_closed )
165         return true;
166
167     list<Window *>::const_iterator win;
168
169     // If a window has been closed, test if all are closed !
170     for( win = p_intf->p_sys->p_theme->WindowList.begin();
171          win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
172     {
173         if( !(*win)->IsHidden() )   // Not all windows closed
174         {
175             return true;
176         }
177     }
178
179     // All window are closed
180     switch( p_intf->p_sys->i_close_status )
181     {
182         case VLC_QUIT:
183             // Save config before exiting
184             p_intf->p_sys->p_theme->SaveConfig();
185             break;
186     }
187
188     // Send specified event
189     OSAPI_PostMessage( NULL, p_intf->p_sys->i_close_status, 0, 0 );
190
191     // Reset values
192     p_intf->p_sys->i_close_status = VLC_NOTHING;
193     p_intf->p_sys->b_all_win_closed = true;
194
195     // Return true
196     return true;
197 }
198 //---------------------------------------------------------------------------
199 bool VlcProc::IsClosing()
200 {
201     if( p_intf->b_die && p_intf->p_sys->i_close_status != VLC_QUIT )
202     {
203         p_intf->p_sys->i_close_status = VLC_QUIT;
204         OSAPI_PostMessage( NULL, VLC_HIDE, VLC_QUIT, 0 );
205     }
206     return true;
207 }
208 //---------------------------------------------------------------------------
209
210
211
212
213 //---------------------------------------------------------------------------
214 // Private methods
215 //---------------------------------------------------------------------------
216 void VlcProc::InterfaceRefresh( bool All )
217 {
218     // Shortcut pointers
219     intf_sys_t  *Sys      = p_intf->p_sys;
220     Theme       *Thema    = Sys->p_theme;
221     playlist_t  *PlayList = Sys->p_playlist;
222
223
224     // Refresh
225     if( PlayList != NULL && Sys->p_input != NULL &&
226         Sys->p_input->stream.b_seekable )
227     {
228         // Refresh stream control controls ! :)
229         switch( PlayList->i_status )
230         {
231             case PLAYLIST_STOPPED:
232                 EnabledEvent( "time", false );
233                 EnabledEvent( "stop", false );
234                 EnabledEvent( "play", true );
235                 EnabledEvent( "pause", false );
236                 break;
237             case PLAYLIST_RUNNING:
238                 EnabledEvent( "time", true );
239                 EnabledEvent( "stop", true );
240                 EnabledEvent( "play", false );
241                 EnabledEvent( "pause", true );
242                 break;
243             case PLAYLIST_PAUSED:
244                 EnabledEvent( "time", true );
245                 EnabledEvent( "stop", true );
246                 EnabledEvent( "play", true );
247                 EnabledEvent( "pause", false );
248                 break;
249         }
250
251         // Refresh next and prev buttons
252         if( PlayList->i_index == 0 || PlayList->i_size == 1 )
253             EnabledEvent( "prev", false );
254         else
255             EnabledEvent( "prev", true );
256
257         if( PlayList->i_index == PlayList->i_size - 1 || PlayList->i_size == 1 )
258             EnabledEvent( "next", false );
259         else
260             EnabledEvent( "next", true );
261
262
263         // Update file name text
264         if( PlayList->i_index != Sys->i_index )
265         {
266             Thema->EvtBank->Get( "file_name" )->PostTextMessage(
267                 PlayList->pp_items[PlayList->i_index]->psz_name );
268         }
269
270         // Update playlists
271         if( PlayList->i_index != Sys->i_index ||
272             PlayList->i_size != Sys->i_size )
273         {
274             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
275             Sys->i_size  = PlayList->i_size;
276             Sys->i_index = PlayList->i_index;
277         }
278     }
279     else
280     {
281         EnabledEvent( "time", false );
282         EnabledEvent( "stop",  false );
283         EnabledEvent( "play",  false );
284         EnabledEvent( "pause", false );
285         EnabledEvent( "prev",  false );
286         EnabledEvent( "next",  false );
287
288         // Update playlists
289         if( Sys->i_size > 0 )
290         {
291             Thema->EvtBank->Get( "playlist_refresh" )->PostSynchroMessage();
292             Sys->i_size  = 0;
293         }
294     }
295
296 }
297 //---------------------------------------------------------------------------
298 void VlcProc::EnabledEvent( string type, bool state )
299 {
300     OSAPI_PostMessage( NULL, CTRL_ENABLED, (unsigned int)
301         p_intf->p_sys->p_theme->EvtBank->Get( type ), (int)state );
302 }
303 //---------------------------------------------------------------------------
304
305
306
307 //---------------------------------------------------------------------------
308 // Common VLC procedures
309 //---------------------------------------------------------------------------
310 void VlcProc::LoadSkin()
311 {
312     if( p_intf->p_sys->p_new_theme_file == NULL )
313     {
314         // Initialize file structure
315         OpenFileDialog *OpenFile;
316         OpenFile = (OpenFileDialog *)new OSOpenFileDialog( p_intf,
317             _("Change skin - Open new file"), false );
318         OpenFile->AddFilter( _("Skin files"), "*.vlt" );
319         OpenFile->AddFilter( _("Skin files"), "*.xml" );
320         OpenFile->AddFilter( _("All files"), "*.*" );
321
322         // Open dialog box
323         if( OpenFile->Open() )
324         {
325             p_intf->p_sys->p_new_theme_file =
326                 new char[OpenFile->FileList.front().length()];
327
328             strcpy( p_intf->p_sys->p_new_theme_file,
329                     OpenFile->FileList.front().c_str() );
330
331             // Tell vlc to change skin after hiding interface
332             OSAPI_PostMessage( NULL, VLC_HIDE, VLC_LOAD_SKIN, 0 );
333         }
334
335         // Free memory
336         delete OpenFile;
337     }
338     else
339     {
340         // Place a new theme in the global structure, because it will
341         // be filled by the parser
342         // We save the old one to restore it in case of problem
343         Theme *oldTheme = p_intf->p_sys->p_theme;
344         p_intf->p_sys->p_theme = (Theme *)new OSTheme( p_intf );
345
346         // Run the XML parser
347         ThemeLoader *Loader = new ThemeLoader( p_intf );
348         if( Loader->Load( p_intf->p_sys->p_new_theme_file ) )
349         {
350             // Everything went well
351             msg_Dbg( p_intf, "New theme successfully loaded" );
352             delete (OSTheme *)oldTheme;
353
354             // Show the theme
355             p_intf->p_sys->p_theme->InitTheme();
356             p_intf->p_sys->p_theme->ShowTheme();
357         }
358         else
359         {
360             msg_Warn( p_intf, "A problem occurred when loading the new theme,"
361                       " restoring the previous one" );
362             delete (OSTheme *)p_intf->p_sys->p_theme;
363             p_intf->p_sys->p_theme = oldTheme;
364
365             // Show the theme
366             p_intf->p_sys->p_theme->ShowTheme();
367         }
368         delete Loader;
369
370         // Uninitialize new theme
371         delete (char *)p_intf->p_sys->p_new_theme_file;
372         p_intf->p_sys->p_new_theme_file = NULL;
373     }
374 }
375 //---------------------------------------------------------------------------
376 void VlcProc::OpenFile( bool play )
377 {
378     // Initialize file structure
379     OpenFileDialog *OpenFile;
380     if( play )
381     {
382         OpenFile = (OpenFileDialog *)new OSOpenFileDialog( p_intf,
383             _("Open file"), false );
384     }
385     else
386     {
387         OpenFile = (OpenFileDialog *)new OSOpenFileDialog( p_intf,
388             _("Add file"), true );
389     }
390     OpenFile->AddFilter( _("All files"), "*.*" );
391
392     // Check if palylist is available
393     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
394     if( p_playlist == NULL )
395         return;
396
397     // Open dialog box and launch file
398     if( OpenFile->Open() )
399     {
400         list<string>::const_iterator file;
401         for( file = OpenFile->FileList.begin();
402              file != OpenFile->FileList.end(); file++ )
403         {
404             playlist_Add( p_playlist, (*file).c_str(), PLAYLIST_APPEND,
405                           PLAYLIST_END );
406         }
407
408         // Refreshing
409         if( play )
410         {
411             // Play
412             p_intf->p_sys->p_theme->EvtBank->Get( "play" )->SendEvent();
413         }
414
415         // Refresh interface !
416         p_intf->p_sys->p_theme->EvtBank->Get( "playlist_refresh" )
417             ->PostSynchroMessage();
418         InterfaceRefresh();
419     }
420
421     // Free memory
422     delete OpenFile;
423 }
424 //---------------------------------------------------------------------------
425 void VlcProc::DropFile( unsigned int param )
426 {
427     // Get pointer to file
428     char *FileName = (char *)param;
429
430     // Add the new file to the playlist
431     if( p_intf->p_sys->p_playlist != NULL )
432     {
433         if( config_GetInt( p_intf, "enqueue" ) )
434         {
435             playlist_Add( p_intf->p_sys->p_playlist, FileName,
436                           PLAYLIST_APPEND, PLAYLIST_END );
437         }
438         else
439         {
440             playlist_Add( p_intf->p_sys->p_playlist, FileName,
441                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
442         }
443     }
444
445     // VLC_DROP must be called with a pointer to a char else it will
446     // ******** SEGFAULT ********
447     // The delete is here because the processus in asynchronous
448     delete[] FileName;
449
450     // Refresh interface
451     InterfaceRefresh();
452
453 }
454 //---------------------------------------------------------------------------
455
456
457
458
459 //---------------------------------------------------------------------------
460 // Stream Control
461 //---------------------------------------------------------------------------
462 void VlcProc::PauseStream()
463 {
464     if( p_intf->p_sys->p_input == NULL )
465         return;
466     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
467
468     // Refresh interface
469     InterfaceRefresh();
470 }
471 //---------------------------------------------------------------------------
472 void VlcProc::PlayStream()
473 {
474     if( p_intf->p_sys->p_playlist == NULL )
475         return;
476     if( !p_intf->p_sys->p_playlist->i_size )
477         return;
478
479     playlist_Play( p_intf->p_sys->p_playlist );
480
481     // Refresh interface
482     InterfaceRefresh();
483 }
484 //---------------------------------------------------------------------------
485 void VlcProc::StopStream()
486 {
487     if( p_intf->p_sys->p_playlist == NULL )
488         return;
489     playlist_Stop( p_intf->p_sys->p_playlist );
490
491     // Refresh interface
492     InterfaceRefresh();
493 }
494 //---------------------------------------------------------------------------
495 void VlcProc::NextStream()
496 {
497     if( p_intf->p_sys->p_playlist == NULL )
498         return;
499
500     playlist_Next( p_intf->p_sys->p_playlist );
501
502     // Refresh interface
503     InterfaceRefresh();
504 }
505 //---------------------------------------------------------------------------
506 void VlcProc::PrevStream()
507 {
508     if( p_intf->p_sys->p_playlist == NULL )
509         return;
510
511     playlist_Prev( p_intf->p_sys->p_playlist );
512
513     // Refresh interface
514     InterfaceRefresh();
515 }
516 //---------------------------------------------------------------------------
517 void VlcProc::MoveStream( long Pos )
518 {
519     if( p_intf->p_sys->p_input == NULL )
520         return;
521
522     off_t i_seek = (off_t)(Pos *
523         p_intf->p_sys->p_input->stream.p_selected_area->i_size
524         / SLIDER_RANGE);
525
526     input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
527
528     // Refresh interface
529     InterfaceRefresh();
530 }
531 //---------------------------------------------------------------------------
532
533
534
535 //---------------------------------------------------------------------------
536 // Fullscreen
537 //---------------------------------------------------------------------------
538 void VlcProc::FullScreen()
539 {
540     vout_thread_t *p_vout;
541
542     if( p_intf->p_sys->p_input == NULL )
543         return;
544
545     p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
546                                                VLC_OBJECT_VOUT, FIND_CHILD );
547     if( p_vout == NULL )
548         return;
549
550     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
551     vlc_object_release( p_vout );
552 }
553 //---------------------------------------------------------------------------
554
555
556
557 //---------------------------------------------------------------------------
558 // Volume Control
559 //---------------------------------------------------------------------------
560 void VlcProc::ChangeVolume( unsigned int msg, long param )
561 {
562     audio_volume_t volume;
563     switch( msg )
564     {
565         case VLC_VOLUME_MUTE:
566             aout_VolumeMute( p_intf, NULL );
567             break;
568         case VLC_VOLUME_UP:
569             aout_VolumeUp( p_intf, 1, NULL );
570             break;
571         case VLC_VOLUME_DOWN:
572             aout_VolumeDown( p_intf, 1, NULL );
573             break;
574         case VLC_VOLUME_SET:
575             aout_VolumeSet( p_intf, param * AOUT_VOLUME_MAX / SLIDER_RANGE );
576             break;
577     }
578     aout_VolumeGet( p_intf, &volume );
579
580     PostMessage( NULL, CTRL_SET_SLIDER,
581         (unsigned int)
582             p_intf->p_sys->p_theme->EvtBank->Get( "volume_refresh" ),
583         (int)( volume * SLIDER_RANGE / AOUT_VOLUME_MAX ) );
584 }
585 //---------------------------------------------------------------------------