]> git.sesse.net Git - vlc/blob - modules/gui/skins/src/vlcproc.cpp
* modules/gui/skins/*: Added a "playondrop" attribute to the "Window"
[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.51 2003/10/22 19:12:56 ipkiss 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 }
432 //---------------------------------------------------------------------------
433
434 void VlcProc::DropFile( unsigned int param1, long param2 )
435 {
436     // Get pointer to file
437     char *FileName = (char *)param1;
438
439     // Add the new file to the playlist
440     if( p_intf->p_sys->p_playlist != NULL )
441     {
442         if( param2 == 0 )
443         {
444             // Enqueue the item
445             playlist_Add( p_intf->p_sys->p_playlist, FileName, 0, 0,
446                           PLAYLIST_APPEND, PLAYLIST_END );
447         }
448         else
449         {
450             // Enqueue and play the item
451             playlist_Add( p_intf->p_sys->p_playlist, FileName, 0, 0,
452                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
453         }
454     }
455
456     // VLC_DROP must be called with a pointer to a char else it will
457     // ******** SEGFAULT ********
458     // The delete is here because the processus in asynchronous
459     delete[] FileName;
460
461     // Refresh interface
462     InterfaceRefresh();
463 }
464 //---------------------------------------------------------------------------
465
466
467
468
469 //---------------------------------------------------------------------------
470 // Stream Control
471 //---------------------------------------------------------------------------
472 void VlcProc::PauseStream()
473 {
474     if( p_intf->p_sys->p_playlist == NULL )
475         return;
476
477     playlist_Command( p_intf->p_sys->p_playlist, PLAYLIST_PAUSE, 0 );
478
479     // Refresh interface
480     InterfaceRefresh();
481 }
482 //---------------------------------------------------------------------------
483 void VlcProc::PlayStream()
484 {
485     if( p_intf->p_sys->p_playlist == NULL )
486         return;
487
488     if( !p_intf->p_sys->p_playlist->i_size )
489     {
490         p_intf->p_sys->p_dialogs->ShowOpen( true );
491         InterfaceRefresh();
492         return;
493     }
494
495     playlist_Play( p_intf->p_sys->p_playlist );
496
497     // Refresh interface
498     InterfaceRefresh();
499 }
500 //---------------------------------------------------------------------------
501 void VlcProc::StopStream()
502 {
503     if( p_intf->p_sys->p_playlist == NULL )
504         return;
505     playlist_Stop( p_intf->p_sys->p_playlist );
506
507     // Refresh interface
508     InterfaceRefresh();
509 }
510 //---------------------------------------------------------------------------
511 void VlcProc::NextStream()
512 {
513     if( p_intf->p_sys->p_playlist == NULL )
514         return;
515
516     playlist_Next( p_intf->p_sys->p_playlist );
517
518     // Refresh interface
519     InterfaceRefresh();
520 }
521 //---------------------------------------------------------------------------
522 void VlcProc::PrevStream()
523 {
524     if( p_intf->p_sys->p_playlist == NULL )
525         return;
526
527     playlist_Prev( p_intf->p_sys->p_playlist );
528
529     // Refresh interface
530     InterfaceRefresh();
531 }
532 //---------------------------------------------------------------------------
533 void VlcProc::MoveStream( long Pos )
534 {
535     if( p_intf->p_sys->p_input == NULL )
536         return;
537
538     off_t i_seek = (off_t)(Pos *
539         p_intf->p_sys->p_input->stream.p_selected_area->i_size
540         / SLIDER_RANGE);
541
542     input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
543
544     // Refresh interface
545     InterfaceRefresh();
546 }
547 //---------------------------------------------------------------------------
548
549
550
551 //---------------------------------------------------------------------------
552 // Fullscreen
553 //---------------------------------------------------------------------------
554 void VlcProc::FullScreen()
555 {
556     vout_thread_t *p_vout;
557
558     if( p_intf->p_sys->p_input == NULL )
559         return;
560
561     p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
562                                                VLC_OBJECT_VOUT, FIND_CHILD );
563     if( p_vout == NULL )
564         return;
565
566     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
567     vlc_object_release( p_vout );
568 }
569 //---------------------------------------------------------------------------
570
571
572
573 //---------------------------------------------------------------------------
574 // Volume Control
575 //---------------------------------------------------------------------------
576 void VlcProc::ChangeVolume( unsigned int msg, long param )
577 {
578     audio_volume_t volume;
579     switch( msg )
580     {
581         case VLC_VOLUME_MUTE:
582             aout_VolumeMute( p_intf, NULL );
583             break;
584         case VLC_VOLUME_UP:
585             aout_VolumeUp( p_intf, 1, NULL );
586             break;
587         case VLC_VOLUME_DOWN:
588             aout_VolumeDown( p_intf, 1, NULL );
589             break;
590         case VLC_VOLUME_SET:
591             aout_VolumeSet( p_intf, param * (AOUT_VOLUME_DEFAULT * 2) /
592                             SLIDER_RANGE );
593             break;
594     }
595     aout_VolumeGet( p_intf, &volume );
596 }
597 //---------------------------------------------------------------------------