]> git.sesse.net Git - vlc/blob - modules/gui/qt4/input_manager.cpp
[Qt] Win Compilation fix.
[vlc] / modules / gui / qt4 / input_manager.cpp
1 /*****************************************************************************
2  * input_manager.cpp : Manage an input and interact with its GUI elements
3  ****************************************************************************
4  * Copyright (C) 2006-2008 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Ilkka Ollakka  <ileoo@videolan.org>
9  *          Jean-Baptiste <jb@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include "qt4.hpp"
30 #include "input_manager.hpp"
31 #include "dialogs_provider.hpp"
32
33 static int ChangeSPU( vlc_object_t *p_this, const char *var, vlc_value_t o,
34                       vlc_value_t n, void *param );
35
36 static int ChangeTeletext( vlc_object_t *p_this, const char *var, vlc_value_t o,
37                            vlc_value_t n, void *param );
38
39 static int ItemChanged( vlc_object_t *, const char *,
40                         vlc_value_t, vlc_value_t, void * );
41 static int PLItemChanged( vlc_object_t *, const char *,
42                         vlc_value_t, vlc_value_t, void * );
43 static int InterfaceChanged( vlc_object_t *, const char *,
44                             vlc_value_t, vlc_value_t, void * );
45 static int StatisticsUpdated( vlc_object_t *, const char *,
46                             vlc_value_t, vlc_value_t, void * );
47 static int InterfaceVoutChanged( vlc_object_t *, const char *,
48                                  vlc_value_t, vlc_value_t, void * );
49 static int ItemStateChanged( vlc_object_t *, const char *,
50                         vlc_value_t, vlc_value_t, void * );
51 static int ItemRateChanged( vlc_object_t *, const char *,
52                         vlc_value_t, vlc_value_t, void * );
53 static int ItemTitleChanged( vlc_object_t *, const char *,
54                         vlc_value_t, vlc_value_t, void * );
55 static int VolumeChanged( vlc_object_t *, const char *,
56                         vlc_value_t, vlc_value_t, void * );
57
58 /**********************************************************************
59  * InputManager implementation
60  **********************************************************************
61  * The Input Manager can be the main one around the playlist
62  * But can also be used for VLM dialog or similar
63  **********************************************************************/
64
65 InputManager::InputManager( QObject *parent, intf_thread_t *_p_intf) :
66                            QObject( parent ), p_intf( _p_intf )
67 {
68     i_old_playing_status = END_S;
69     oldName      = "";
70     artUrl       = "";
71     p_input      = NULL;
72     i_rate       = 0;
73     i_input_id   = 0;
74     b_video      = false;
75     timeA        = 0;
76     timeB        = 0;
77
78 }
79
80 InputManager::~InputManager()
81 {
82     delInput();
83 }
84
85 /* Define the Input used.
86    Add the callbacks on input
87    p_input is held once here */
88 void InputManager::setInput( input_thread_t *_p_input )
89 {
90     delInput();
91     p_input = _p_input;
92     if( p_input && !( p_input->b_dead || !vlc_object_alive (p_input) ) )
93     {
94         vlc_object_hold( p_input );
95         emit statusChanged( PLAYING_S );
96         UpdateMeta();
97         UpdateArt();
98         UpdateTeletext();
99         UpdateNavigation();
100         UpdateVout();
101         addCallbacks();
102         i_input_id = input_GetItem( p_input )->i_id;
103     }
104     else
105     {
106         p_input = NULL;
107         i_input_id = 0;
108         emit rateChanged( INPUT_RATE_DEFAULT );
109     }
110 }
111
112 /* delete Input if it ever existed.
113    Delete the callbacls on input
114    p_input is released once here */
115 void InputManager::delInput()
116 {
117     if( p_input )
118     {
119         delCallbacks();
120         i_old_playing_status = END_S;
121         i_input_id = 0;
122         oldName    = "";
123         artUrl     = "";
124         b_video    = false;
125         timeA      = 0;
126         timeB      = 0;
127         emit positionUpdated( -1.0, 0 ,0 );
128         emit statusChanged( END_S );
129         emit nameChanged( "" );
130         emit artChanged( NULL );
131         emit rateChanged( INPUT_RATE_DEFAULT );
132         emit voutChanged( false );
133         vlc_object_release( p_input );
134         p_input = NULL;
135         UpdateTeletext();
136     }
137 }
138
139 /* Add the callbacks on Input. Self explanatory */
140 void InputManager::addCallbacks()
141 {
142     /* We don't care about:
143        - chapter
144        - programs
145        - audio-delay
146        - spu-delay
147        - bookmark
148        - position, time, length, because they are included in intf-change
149      */
150     /* src/input/input.c:1629 */
151     var_AddCallback( p_input, "state", ItemStateChanged, this );
152     /* src/input/es-out.c:552 */
153     var_AddCallback( p_input, "spu-es", ChangeSPU, this );
154     /* emit UpdateStatus so that main_interface updates controls
155      * if there is new videotracks (mpeg-ts)*/
156     var_AddCallback( p_input, "video-es", ItemStateChanged, this );
157     /* src/input/es-out.c: */
158     var_AddCallback( p_input, "teletext-es", ChangeTeletext, this );
159     /* src/input/input.c:1765 */
160     var_AddCallback( p_input, "rate-change", ItemRateChanged, this );
161     /* src/input/input.c:2003 */
162     var_AddCallback( p_input, "title", ItemTitleChanged, this );
163     /* src/input/input.c:734 for timers update*/
164     var_AddCallback( p_input, "intf-change", InterfaceChanged, this );
165     /* src/input/input.c:710 for statistics update*/
166     var_AddCallback( p_input, "stats-change", StatisticsUpdated, this );
167     /* src/input/input.c for vout creation/destruction */
168     var_AddCallback( p_input, "intf-change-vout", InterfaceVoutChanged, this );
169 }
170
171 /* Delete the callbacks on Input. Self explanatory */
172 void InputManager::delCallbacks()
173 {
174     var_DelCallback( p_input, "spu-es", ChangeSPU, this );
175     var_DelCallback( p_input, "video-es", ItemStateChanged, this );
176     var_DelCallback( p_input, "teletext-es", ChangeTeletext, this );
177     var_DelCallback( p_input, "state", ItemStateChanged, this );
178     var_DelCallback( p_input, "rate-change", ItemRateChanged, this );
179     var_DelCallback( p_input, "title", ItemTitleChanged, this );
180     var_DelCallback( p_input, "intf-change", InterfaceChanged, this );
181     var_DelCallback( p_input, "stats-change", StatisticsUpdated, this );
182     var_DelCallback( p_input, "intf-change-vout", InterfaceVoutChanged, this );
183 }
184
185 /* Convert the event from the callbacks in actions */
186 void InputManager::customEvent( QEvent *event )
187 {
188     int i_type = event->type();
189     IMEvent *ple = static_cast<IMEvent *>(event);
190
191     if ( i_type != PositionUpdate_Type &&
192          i_type != ItemChanged_Type &&
193          i_type != ItemRateChanged_Type &&
194          i_type != ItemTitleChanged_Type &&
195          i_type != ItemSpuChanged_Type &&
196          i_type != ItemTeletextChanged_Type &&
197          i_type != ItemStateChanged_Type &&
198          i_type != StatisticsUpdate_Type &&
199          i_type != InterfaceVoutUpdate_Type )
200         return;
201
202     if( i_type == ItemStateChanged_Type )
203     {
204         UpdateNavigation();
205         UpdateTeletext();
206     }
207
208     if( !hasInput() ) return;
209
210     if( ( i_type != PositionUpdate_Type  &&
211           i_type != ItemRateChanged_Type &&
212           i_type != ItemSpuChanged_Type &&
213           i_type != ItemTeletextChanged_Type &&
214           i_type != ItemStateChanged_Type &&
215           i_type != StatisticsUpdate_Type &&
216           i_type != InterfaceVoutUpdate_Type
217         )
218         && ( i_input_id != ple->i_id ) )
219         return;
220
221     if( i_type != PositionUpdate_Type &&
222         i_type != StatisticsUpdate_Type )
223         msg_Dbg( p_intf, "New Event: type %i", i_type );
224
225     /* Actions */
226     switch( i_type )
227     {
228     case PositionUpdate_Type:
229         UpdatePosition();
230         break;
231     case StatisticsUpdate_Type:
232         UpdateStats();
233         break;
234     case ItemChanged_Type:
235         UpdateMeta();
236         UpdateStatus();
237         UpdateArt();
238         break;
239     case ItemStateChanged_Type:
240         UpdateStatus();
241         UpdateNavigation();
242         UpdateMeta();
243         break;
244     case ItemTitleChanged_Type:
245         UpdateNavigation();
246         UpdateMeta();
247         break;
248     case ItemRateChanged_Type:
249         UpdateRate();
250         break;
251     case ItemSpuChanged_Type:
252         UpdateSPU();
253         break;
254     case ItemTeletextChanged_Type:
255         UpdateTeletext();
256         break;
257     case InterfaceVoutUpdate_Type:
258         UpdateVout();
259         break;
260     default:
261         msg_Warn( p_intf, "This shouldn't happen: %i", i_type );
262     }
263 }
264
265 void InputManager::UpdateStats()
266 {
267     emit statisticsUpdated( input_GetItem( p_input ) );
268 }
269
270 void InputManager::UpdatePosition()
271 {
272     /* Update position */
273     int i_length, i_time; /* Int is enough, since we store seconds */
274     float f_pos;
275     i_length = var_GetTime(  p_input , "length" ) / 1000000;
276     i_time = var_GetTime(  p_input , "time") / 1000000;
277     f_pos = var_GetFloat(  p_input , "position" );
278     emit positionUpdated( f_pos, i_time, i_length );
279 }
280
281 void InputManager::UpdateNavigation()
282 {
283     /* Update navigation status */
284     vlc_value_t val; val.i_int = 0;
285
286     if( hasInput() )
287         var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
288
289     if( val.i_int > 0 )
290     {
291         emit titleChanged( true );
292         /* p_input != NULL since val.i_int != 0 */
293         val.i_int = 0;
294         var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
295         emit chapterChanged( (val.i_int > 0) );
296     }
297     else
298         emit titleChanged( false );
299 }
300
301 void InputManager::UpdateStatus()
302 {
303     /* Update playing status */
304     vlc_value_t val; val.i_int = 0;
305     var_Get( p_input, "state", &val );
306     if( i_old_playing_status != val.i_int )
307     {
308         i_old_playing_status = val.i_int;
309         emit statusChanged( val.i_int );
310     }
311 }
312
313 void InputManager::UpdateRate()
314 {
315     /* Update Rate */
316     int i_new_rate = var_GetInteger( p_input, "rate");
317     if( i_new_rate != i_rate )
318     {
319         i_rate = i_new_rate;
320         /* Update rate */
321         emit rateChanged( i_rate );
322     }
323 }
324
325 void InputManager::UpdateMeta()
326 {
327     /* Update text, name and nowplaying */
328     QString text;
329
330     /* Try to get the Title, then the Name */
331     char *psz_name = input_item_GetTitle( input_GetItem( p_input ) );
332     if( EMPTY_STR( psz_name ) )
333     {
334         free( psz_name );
335         psz_name = input_item_GetName( input_GetItem( p_input ) );
336     }
337
338     /* Try to get the nowplaying */
339     char *psz_nowplaying =
340         input_item_GetNowPlaying( input_GetItem( p_input ) );
341     if( !EMPTY_STR( psz_nowplaying ) )
342     {
343         text.sprintf( "%s - %s", psz_nowplaying, psz_name );
344     }
345     else  /* Do it ourself */
346     {
347         char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) );
348
349         if( !EMPTY_STR( psz_artist ) )
350             text.sprintf( "%s - %s", psz_artist, psz_name );
351         else
352             text.sprintf( "%s", psz_name );
353
354         free( psz_artist );
355     }
356     /* Free everything */
357     free( psz_name );
358     free( psz_nowplaying );
359
360     /* If we have Nothing */
361     if( text.isEmpty() )
362     {
363         psz_name = input_item_GetURI( input_GetItem( p_input ) );
364         text.sprintf( "%s", psz_name );
365         text = text.remove( 0, text.lastIndexOf( DIR_SEP ) + 1 );
366         free( psz_name );
367     }
368
369     if( oldName != text )
370     {
371         emit nameChanged( text );
372         oldName=text;
373     }
374 }
375
376 bool InputManager::hasAudio()
377 {
378     if( hasInput() )
379     {
380         vlc_value_t val;
381         var_Change( p_input, "audio-es", VLC_VAR_CHOICESCOUNT, &val, NULL );
382         return val.i_int > 0;
383     }
384     return false;
385 }
386
387 void InputManager::UpdateSPU()
388 {
389     UpdateTeletext();
390 }
391
392 void InputManager::UpdateTeletext()
393 {
394     if( hasInput() )
395         telexActivation( var_GetInteger( p_input, "teletext-es" ) >= 0 );
396     else
397         telexActivation( false );
398 }
399
400 void InputManager::UpdateVout()
401 {
402     if( hasInput() )
403     {
404         bool b_old_video = b_video;
405
406         vlc_object_t *p_vout = (vlc_object_t*)vlc_object_find( p_input,
407                                          VLC_OBJECT_VOUT, FIND_CHILD );
408         b_video = p_vout != NULL;
409         if( p_vout )
410             vlc_object_release( p_vout );
411         if( !!b_old_video != !!b_video )
412             emit voutChanged( b_video );
413     }
414 }
415
416 void InputManager::UpdateArt()
417 {
418     /* Update Art meta */
419     emit artChanged( input_GetItem( p_input ) );
420 }
421
422 /* User update of the slider */
423 void InputManager::sliderUpdate( float new_pos )
424 {
425     if( hasInput() )
426         var_SetFloat( p_input, "position", new_pos );
427 }
428
429 /* User togglePlayPause */
430 void InputManager::togglePlayPause()
431 {
432     vlc_value_t state;
433     if( hasInput() )
434     {
435         var_Get( p_input, "state", &state );
436         state.i_int = ( state.i_int != PLAYING_S ) ? PLAYING_S : PAUSE_S;
437         var_Set( p_input, "state", state );
438         emit statusChanged( state.i_int );
439     }
440 }
441
442 void InputManager::sectionPrev()
443 {
444     if( hasInput() )
445     {
446         int i_type = var_Type( p_input, "next-chapter" );
447         vlc_value_t val; val.b_bool = true;
448         var_Set( p_input, (i_type & VLC_VAR_TYPE) != 0 ?
449                             "prev-chapter":"prev-title", val );
450     }
451 }
452
453 void InputManager::sectionNext()
454 {
455     if( hasInput() )
456     {
457         int i_type = var_Type( p_input, "next-chapter" );
458         vlc_value_t val; val.b_bool = true;
459         var_Set( p_input, (i_type & VLC_VAR_TYPE) != 0 ?
460                             "next-chapter":"next-title", val );
461     }
462 }
463
464 void InputManager::sectionMenu()
465 {
466     if( hasInput() )
467     {
468         vlc_value_t val, text;
469         vlc_value_t root;
470
471         if( var_Change( p_input, "title  0", VLC_VAR_GETLIST, &val, &text ) < 0 )
472             return;
473
474         /* XXX is it "Root" or "Title" we want here ?" (set 0 by default) */
475         root.i_int = 0;
476         for( int i = 0; i < val.p_list->i_count; i++ )
477         {
478             if( !strcmp( text.p_list->p_values[i].psz_string, "Title" ) )
479                 root.i_int = i;
480         }
481         var_Change( p_input, "title  0", VLC_VAR_FREELIST, &val, &text );
482
483         var_Set( p_input, "title  0", root );
484     }
485 }
486
487 /*
488  *  Teletext Functions
489  */
490
491 /* Set a new Teletext Page */
492 void InputManager::telexSetPage( int page )
493 {
494     if( hasInput() )
495     {
496         const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
497         const int i_spu_es = var_GetInteger( p_input, "spu-es" );
498
499         if( i_teletext_es >= 0 && i_teletext_es == i_spu_es )
500         {
501             vlc_object_t *p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
502                         "zvbi", FIND_ANYWHERE );
503             if( p_vbi )
504             {
505                 var_SetInteger( p_vbi, "vbi-page", page );
506                 vlc_object_release( p_vbi );
507                 emit newTelexPageSet( page );
508             }
509         }
510     }
511 }
512
513 /* Set the transparency on teletext */
514 void InputManager::telexSetTransparency( bool b_transparentTelextext )
515 {
516     if( hasInput() )
517     {
518         vlc_object_t *p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
519                     "zvbi", FIND_ANYWHERE );
520         if( p_vbi )
521         {
522             var_SetBool( p_vbi, "vbi-opaque", b_transparentTelextext );
523             vlc_object_release( p_vbi );
524             emit teletextTransparencyActivated( b_transparentTelextext );
525         }
526     }
527 }
528
529 void InputManager::telexActivation( bool b_enabled )
530 {
531     if( hasInput() )
532     {
533         const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
534         const int i_spu_es = var_GetInteger( p_input, "spu-es" );
535
536         /* Teletext is possible. Show the buttons */
537         b_enabled = (i_teletext_es >= 0);
538         emit teletextPossible( b_enabled );
539         if( !b_enabled ) return;
540
541         /* If Teletext is selected */
542         if( i_teletext_es == i_spu_es )
543         {
544             /* Activate the buttons */
545             teletextActivated( true );
546
547             /* Then, find the current page */
548             int i_page = 100;
549             vlc_object_t *p_vbi = (vlc_object_t *)
550                 vlc_object_find_name( p_input, "zvbi", FIND_ANYWHERE );
551             if( p_vbi )
552             {
553                 i_page = var_GetInteger( p_vbi, "vbi-page" );
554                 vlc_object_release( p_vbi );
555                 emit newTelexPageSet( i_page );
556             }
557         }
558     }
559     else
560         emit teletextPossible( b_enabled );
561 }
562
563 void InputManager::activateTeletext( bool b_enable )
564 {
565     if( hasInput() )
566     {
567         const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
568         if( i_teletext_es >= 0 )
569         {
570             var_SetInteger( p_input, "spu-es", b_enable ? i_teletext_es : -1 );
571         }
572     }
573 }
574
575 void InputManager::slower()
576 {
577     if( hasInput() )
578         var_SetVoid( p_input, "rate-slower" );
579 }
580
581 void InputManager::faster()
582 {
583     if( hasInput() )
584         var_SetVoid( p_input, "rate-faster" );
585 }
586
587 void InputManager::normalRate()
588 {
589     if( hasInput() )
590         var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT );
591 }
592
593 void InputManager::setRate( int new_rate )
594 {
595     if( hasInput() )
596         var_SetInteger( p_input, "rate", new_rate );
597 }
598
599 void InputManager::setAtoB()
600 {
601     if( !timeA )
602     {
603         timeA = var_GetTime( THEMIM->getInput(), "time"  );
604     }
605     else if( !timeB )
606     {
607         timeB = var_GetTime( THEMIM->getInput(), "time"  );
608         var_SetTime( THEMIM->getInput(), "time" , timeA );
609     }
610     else
611     {
612         timeA = 0;
613         timeB = 0;
614     }
615     emit AtoBchanged( (timeA != 0 ), (timeB != 0 ) );
616 }
617
618 /* Function called regularly when in an AtoB loop */
619 void InputManager::AtoBLoop( int i_time )
620 {
621     if( timeB )
622     {
623         if( ( i_time >= (int)( timeB/1000000 ) )
624             || ( i_time < (int)( timeA/1000000 ) ) )
625             var_SetTime( THEMIM->getInput(), "time" , timeA );
626     }
627 }
628
629 /**********************************************************************
630  * MainInputManager implementation. Wrap an input manager and
631  * take care of updating the main playlist input.
632  * Used in the main playlist Dialog
633  **********************************************************************/
634 MainInputManager * MainInputManager::instance = NULL;
635
636 MainInputManager::MainInputManager( intf_thread_t *_p_intf )
637                  : QObject(NULL), p_intf( _p_intf )
638 {
639     p_input = NULL;
640     im = new InputManager( this, p_intf );
641
642     var_AddCallback( THEPL, "item-change", ItemChanged, im );
643     var_AddCallback( THEPL, "playlist-current", PLItemChanged, this );
644     var_AddCallback( THEPL, "activity", PLItemChanged, this );
645
646     var_AddCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this );
647
648     /* Warn our embedded IM about input changes */
649     CONNECT( this, inputChanged( input_thread_t * ),
650              im, setInput( input_thread_t * ) );
651
652     /* emit check if playlist has allready started playing */
653     vlc_value_t val;
654     var_Change( THEPL, "playlist-current", VLC_VAR_CHOICESCOUNT, &val, NULL );
655     IMEvent *event = new IMEvent( ItemChanged_Type, val.i_int);
656     QApplication::postEvent( this, static_cast<QEvent*>(event) );
657
658 }
659
660 MainInputManager::~MainInputManager()
661 {
662     if( p_input )
663     {
664        var_DelCallback( p_input, "state", PLItemChanged, this );
665        vlc_object_release( p_input );
666        emit inputChanged( NULL );
667     }
668
669     var_DelCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this );
670
671     var_DelCallback( THEPL, "activity", PLItemChanged, this );
672     var_DelCallback( THEPL, "item-change", ItemChanged, im );
673
674     var_DelCallback( THEPL, "playlist-current", PLItemChanged, this );
675 }
676
677 void MainInputManager::customEvent( QEvent *event )
678 {
679     int type = event->type();
680     if ( type != ItemChanged_Type && type != VolumeChanged_Type )
681         return;
682
683     // msg_Dbg( p_intf, "New MainIM Event of type: %i", type );
684     if( type == VolumeChanged_Type )
685     {
686         emit volumeChanged();
687         return;
688     }
689
690     /* Should be PLItemChanged Event */
691     if( !p_intf->p_sys->b_isDialogProvider )
692     {
693         vlc_mutex_lock( &p_intf->change_lock );
694         if( p_input && ( p_input->b_dead || !vlc_object_alive (p_input) ) )
695         {
696             var_DelCallback( p_input, "state", PLItemChanged, this );
697             vlc_object_release( p_input );
698             emit inputChanged( NULL );
699             p_input = NULL;
700             vlc_mutex_unlock( &p_intf->change_lock );
701             return;
702         }
703
704         if( !p_input )
705         {
706             p_input = playlist_CurrentInput(THEPL);
707             if( p_input )
708             {
709                 var_AddCallback( p_input, "state", PLItemChanged, this );
710                 emit inputChanged( p_input );
711             }
712         }
713         vlc_mutex_unlock( &p_intf->change_lock );
714     }
715     else
716     {
717         /* we are working as a dialogs provider */
718         playlist_t *p_playlist = pl_Hold( p_intf );
719         p_input = playlist_CurrentInput( p_playlist );
720         if( p_input )
721         {
722             emit inputChanged( p_input );
723             vlc_object_release( p_input );
724         }
725         pl_Release( p_intf );
726     }
727 }
728
729 /* Playlist Control functions */
730 void MainInputManager::stop()
731 {
732    playlist_Stop( THEPL );
733 }
734
735 void MainInputManager::next()
736 {
737    playlist_Next( THEPL );
738 }
739
740 void MainInputManager::prev()
741 {
742    playlist_Prev( THEPL );
743 }
744
745 void MainInputManager::togglePlayPause()
746 {
747     /* No input, play */
748     if( !p_input )
749         playlist_Play( THEPL );
750     else
751         getIM()->togglePlayPause();
752 }
753
754 /* Static callbacks */
755
756 /* IM */
757 static int InterfaceChanged( vlc_object_t *p_this, const char *psz_var,
758                            vlc_value_t oldval, vlc_value_t newval, void *param )
759 {
760     /* FIXME remove that static variable */
761     static int counter = 0;
762
763     InputManager *im = (InputManager*)param;
764
765     counter = ++counter % 4;
766     if(!counter) return VLC_SUCCESS;
767
768     IMEvent *event = new IMEvent( PositionUpdate_Type, 0 );
769     QApplication::postEvent( im, static_cast<QEvent*>(event) );
770     return VLC_SUCCESS;
771 }
772
773 static int StatisticsUpdated( vlc_object_t *p_this, const char *psz_var,
774                            vlc_value_t oldval, vlc_value_t newval, void *param )
775 {
776     InputManager *im = (InputManager*)param;
777
778     IMEvent *event = new IMEvent( StatisticsUpdate_Type, 0 );
779     QApplication::postEvent( im, static_cast<QEvent*>(event) );
780     return VLC_SUCCESS;
781 }
782
783 static int InterfaceVoutChanged( vlc_object_t *p_this, const char *psz_var,
784                                  vlc_value_t oldval, vlc_value_t newval, void *param )
785 {
786     InputManager *im = (InputManager*)param;
787
788     IMEvent *event = new IMEvent( InterfaceVoutUpdate_Type, 0 );
789     QApplication::postEvent( im, static_cast<QEvent*>(event) );
790     return VLC_SUCCESS;
791 }
792
793 static int ItemStateChanged( vlc_object_t *p_this, const char *psz_var,
794                            vlc_value_t oldval, vlc_value_t newval, void *param )
795 {
796     InputManager *im = (InputManager*)param;
797
798     IMEvent *event = new IMEvent( ItemStateChanged_Type, 0 );
799     QApplication::postEvent( im, static_cast<QEvent*>(event) );
800     return VLC_SUCCESS;
801 }
802
803 static int ItemRateChanged( vlc_object_t *p_this, const char *psz_var,
804                            vlc_value_t oldval, vlc_value_t newval, void *param )
805 {
806     InputManager *im = (InputManager*)param;
807
808     IMEvent *event = new IMEvent( ItemRateChanged_Type, 0 );
809     QApplication::postEvent( im, static_cast<QEvent*>(event) );
810     return VLC_SUCCESS;
811 }
812
813 static int ItemTitleChanged( vlc_object_t *p_this, const char *psz_var,
814                            vlc_value_t oldval, vlc_value_t newval, void *param )
815 {
816     InputManager *im = (InputManager*)param;
817
818     IMEvent *event = new IMEvent( ItemTitleChanged_Type, 0 );
819     QApplication::postEvent( im, static_cast<QEvent*>(event) );
820     return VLC_SUCCESS;
821 }
822
823 static int ItemChanged( vlc_object_t *p_this, const char *psz_var,
824                         vlc_value_t oldval, vlc_value_t newval, void *param )
825 {
826     InputManager *im = (InputManager*)param;
827
828     IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int );
829     QApplication::postEvent( im, static_cast<QEvent*>(event) );
830     return VLC_SUCCESS;
831 }
832
833 static int ChangeSPU( vlc_object_t *p_this, const char *var, vlc_value_t o,
834                         vlc_value_t n, void *param )
835 {
836     InputManager *im = (InputManager*)param;
837     IMEvent *event = new IMEvent( ItemSpuChanged_Type, 0 );
838     QApplication::postEvent( im, static_cast<QEvent*>(event) );
839     return VLC_SUCCESS;
840 }
841
842 static int ChangeTeletext( vlc_object_t *p_this, const char *var, vlc_value_t o,
843                            vlc_value_t n, void *param )
844 {
845
846     InputManager *im = (InputManager*)param;
847     IMEvent *event = new IMEvent( ItemTeletextChanged_Type, 0 );
848     QApplication::postEvent( im, static_cast<QEvent*>(event) );
849     return VLC_SUCCESS;
850 }
851
852 /* MIM */
853 static int PLItemChanged( vlc_object_t *p_this, const char *psz_var,
854                         vlc_value_t oldval, vlc_value_t newval, void *param )
855 {
856     MainInputManager *mim = (MainInputManager*)param;
857
858     IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int );
859     QApplication::postEvent( mim, static_cast<QEvent*>(event) );
860     return VLC_SUCCESS;
861 }
862
863 static int VolumeChanged( vlc_object_t *p_this, const char *psz_var,
864                         vlc_value_t oldval, vlc_value_t newval, void *param )
865 {
866     MainInputManager *mim = (MainInputManager*)param;
867
868     IMEvent *event = new IMEvent( VolumeChanged_Type, newval.i_int );
869     QApplication::postEvent( mim, static_cast<QEvent*>(event) );
870     return VLC_SUCCESS;
871 }
872