input_manager.cpp 19.4 KB
Newer Older
1 2 3
/*****************************************************************************
 * input_manager.cpp : Manage an input and interact with its GUI elements
 ****************************************************************************
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 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
25 26 27
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
28

29
#include "qt4.hpp"
30 31 32
#include "input_manager.hpp"
#include "dialogs_provider.hpp"

33 34 35 36
static int ChangeVideo( vlc_object_t *p_this, const char *var, vlc_value_t o,
                        vlc_value_t n, void *param );
static int ChangeAudio( vlc_object_t *p_this, const char *var, vlc_value_t o,
                        vlc_value_t n, void *param );
37 38
static int ItemChanged( vlc_object_t *, const char *,
                        vlc_value_t, vlc_value_t, void * );
39
static int PLItemChanged( vlc_object_t *, const char *,
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
40
                        vlc_value_t, vlc_value_t, void * );
41 42 43 44 45 46 47 48
static int InterfaceChanged( vlc_object_t *, const char *,
                            vlc_value_t, vlc_value_t, void * );
static int ItemStateChanged( vlc_object_t *, const char *,
                        vlc_value_t, vlc_value_t, void * );
static int ItemRateChanged( vlc_object_t *, const char *,
                        vlc_value_t, vlc_value_t, void * );
static int ItemTitleChanged( vlc_object_t *, const char *,
                        vlc_value_t, vlc_value_t, void * );
49 50
static int VolumeChanged( vlc_object_t *, const char *,
                        vlc_value_t, vlc_value_t, void * );
51

52 53
/**********************************************************************
 * InputManager implementation
54 55 56
 **********************************************************************
 * The Input Manager can be the main one around the playlist
 * But can also be used for VLM dialog or similar
57 58
 **********************************************************************/

59 60 61
InputManager::InputManager( QObject *parent, intf_thread_t *_p_intf) :
                           QObject( parent ), p_intf( _p_intf )
{
62
    i_old_playing_status = END_S;
63
    old_name = "";
64
    p_input = NULL;
65
    i_rate = 0;
66 67 68 69
}

InputManager::~InputManager()
{
70
    delInput();
71 72
}

73 74 75
/* Define the Input used.
   Add the callbacks on input
   p_input is yield once here */
76 77
void InputManager::setInput( input_thread_t *_p_input )
{
78
    delInput();
79
    p_input = _p_input;
80
    b_had_audio = b_had_video = b_has_audio = b_has_video = false;
81
    if( p_input && !( p_input->b_dead || p_input->b_die ) )
82
    {
83
        vlc_object_yield( p_input );
84
        emit statusChanged( PLAYING_S );
85 86 87 88
        UpdateMeta();
        UpdateTracks();
        UpdateTitle();
        UpdateArt();
89
        addCallbacks();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
90 91 92 93
        i_input_id = input_GetItem( p_input )->i_id;
    }
    else
    {
94 95
        p_input = NULL;
        i_input_id = 0;
96 97
    }
}
98

99 100 101
/* delete Input if it ever existed.
   Delete the callbacls on input
   p_input is released once here */
102 103 104 105
void InputManager::delInput()
{
    if( p_input )
    {
106
        delCallbacks();
107
        vlc_object_release( p_input );
108 109
        i_old_playing_status = END_S;

110
        i_input_id = 0;
111 112 113 114 115 116
        old_name=qfu("");
        artUrl = qfu("");
        emit positionUpdated( 0.0, 0 ,0 );
        emit statusChanged( END_S );
        emit nameChanged( "" );
        emit artChanged( "" );
117
        p_input = NULL;
118
    }
119 120
}

121
/* Add the callbacks on Input. Self explanatory */
122
void InputManager::addCallbacks()
123
{
124 125 126 127 128 129 130 131 132
    /* We don't care about:
       - spu-es
       - chapter
       - programs
       - audio-delay
       - spu-delay
       - bookmark
       - position, time, length, because they are included in intf-change
     */
133 134
    /* src/input/input.c:1629 */
    var_AddCallback( p_input, "state", ItemStateChanged, this );
135
    /* src/input/es-out.c:550 */
136
    var_AddCallback( p_input, "audio-es", ChangeAudio, this );
137
    /* src/input/es-out.c:551 */
138 139 140
    var_AddCallback( p_input, "video-es", ChangeVideo, this );
    /* src/input/input.c:1765 */
    var_AddCallback( p_input, "rate", ItemRateChanged, this );
141 142
    var_AddCallback( p_input, "rate-faster", ItemRateChanged, this );
    var_AddCallback( p_input, "rate-slower", ItemRateChanged, this );
143 144 145 146 147 148
    /* src/input/input.c:2003 */
    var_AddCallback( p_input, "title", ItemTitleChanged, this );
    /* src/input/input.c:734 for timers update*/
    var_AddCallback( p_input, "intf-change", InterfaceChanged, this );
}

149
/* Delete the callbacks on Input. Self explanatory */
150
void InputManager::delCallbacks()
151
{
152 153 154 155
    var_DelCallback( p_input, "audio-es", ChangeAudio, this );
    var_DelCallback( p_input, "video-es", ChangeVideo, this );
    var_DelCallback( p_input, "state", ItemStateChanged, this );
    var_DelCallback( p_input, "rate", ItemRateChanged, this );
156 157
    var_DelCallback( p_input, "rate-faster", ItemRateChanged, this );
    var_DelCallback( p_input, "rate-slower", ItemRateChanged, this );
158 159
    var_DelCallback( p_input, "title", ItemTitleChanged, this );
    var_DelCallback( p_input, "intf-change", InterfaceChanged, this );
160 161
}

162
/* Convert the event from the callbacks in actions */
163 164 165
void InputManager::customEvent( QEvent *event )
{
    int type = event->type();
166
    IMEvent *ple = static_cast<IMEvent *>(event);
167

168 169 170 171
    if ( type != PositionUpdate_Type &&
         type != ItemChanged_Type &&
         type != ItemRateChanged_Type &&
         type != ItemTitleChanged_Type &&
172 173
         type != ItemStateChanged_Type )
        return;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
174

175 176
    if( !p_input || p_input->b_die || p_input->b_dead )
        return;
177 178
    if( ( type != PositionUpdate_Type && type != ItemRateChanged_Type )
         && ( i_input_id != ple->i_id ) )
179
        return;
180 181 182
    if( type != PositionUpdate_Type )
        msg_Dbg( p_intf, "New Event: type %i", type );

183
    /* Actions */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
184
    switch( type )
185
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
186
    case PositionUpdate_Type:
187
        UpdatePosition();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
188 189
        break;
    case ItemChanged_Type:
190
        UpdateMeta();
191
        UpdateTracks();
192
        UpdateTitle();
193
        UpdateArt();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
194 195 196 197 198 199
        break;
    case ItemRateChanged_Type:
        UpdateRate();
        break;
    case ItemTitleChanged_Type:
        UpdateTitle();
200
        UpdateMeta();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
201 202
        break;
    case ItemStateChanged_Type:
203 204 205
        UpdateStatus();
        UpdateTracks();
        break;
206
    }
207
}
208

209
void InputManager::UpdatePosition()
210 211 212 213 214 215 216 217 218 219
{
     /* Update position */
     int i_length, i_time; /* Int is enough, since we store seconds */
     float f_pos;
     i_length = var_GetTime(  p_input , "length" ) / 1000000;
     i_time = var_GetTime(  p_input , "time") / 1000000;
     f_pos = var_GetFloat(  p_input , "position" );
     emit positionUpdated( f_pos, i_time, i_length );
}

220
void InputManager::UpdateTitle()
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
{
     /* Update navigation status */
     vlc_value_t val; val.i_int = 0;
     var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
     if( val.i_int > 0 )
     {
         val.i_int = 0;
         var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
         emit navigationChanged( (val.i_int > 0) ? 1 : 2 );
     }
     else
     {
         emit navigationChanged( 0 );
     }
}

237
void InputManager::UpdateStatus()
238 239 240 241 242 243 244 245 246 247 248
{
     /* Update playing status */
     vlc_value_t val; val.i_int = 0;
     var_Get( p_input, "state", &val );
     if( i_old_playing_status != val.i_int )
     {
         i_old_playing_status = val.i_int;
         emit statusChanged( val.i_int );
     }
}

249
void InputManager::UpdateRate()
250 251 252 253 254 255 256 257
{
     /* Update Rate */
     int i_new_rate = var_GetInteger( p_input, "rate");
     if( i_new_rate != i_rate )
     {
         i_rate = i_new_rate;
         /* Update rate */
         emit rateChanged( i_rate );
258
     }
259 260
}

261
void InputManager::UpdateMeta()
262
{
263 264
    /* Update text, name and nowplaying */
    QString text;
265

266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
    char *psz_name = input_item_GetTitle( input_GetItem( p_input ) );
    if( EMPTY_STR( psz_name ) )
    {
        free( psz_name );
        psz_name = input_item_GetName( input_GetItem( p_input ) );
    }

    char *psz_nowplaying =
        input_item_GetNowPlaying( input_GetItem( p_input ) );
    if( !EMPTY_STR( psz_nowplaying ) )
    {
        text.sprintf( "%s - %s", psz_nowplaying, psz_name );
    }
    else
    {
        char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) );
        if( !EMPTY_STR( psz_artist ) )
        {
            text.sprintf( "%s - %s", psz_artist, psz_name );
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
286 287 288
        else
        {
            text.sprintf( "%s", psz_name );
289 290
        }
        free( psz_artist );
291 292 293 294 295 296 297 298 299
    }
    free( psz_name );
    free( psz_nowplaying );

    if( old_name != text )
    {
        emit nameChanged( text );
        old_name=text;
    }
300
}
301

302 303
void InputManager::UpdateTracks()
{
304 305 306 307 308 309 310
    /* Has Audio, has Video Tracks ? */
    vlc_value_t val;
    var_Change( p_input, "audio-es", VLC_VAR_CHOICESCOUNT, &val, NULL );
    b_has_audio = val.i_int > 0;
    var_Change( p_input, "video-es", VLC_VAR_CHOICESCOUNT, &val, NULL );
    b_has_video = val.i_int > 0;

311 312
    msg_Dbg( p_input, "I have audio-video: %i %i", b_has_audio, b_has_video );

313
    /* Update ZVBI status */
314
#ifdef ZVBI_COMPILED
315 316
    /* Update teletext status*/
    emit teletextEnabled( true );/* FIXME */
317 318 319
#endif
}

Jean-Baptiste Kempf's avatar
 
Jean-Baptiste Kempf committed
320
void InputManager::UpdateArt()
321 322 323 324 325 326 327 328 329
{
    /* Update Art meta */
    QString url;
    char *psz_art = input_item_GetArtURL( input_GetItem( p_input ) );
    url.sprintf("%s", psz_art );
    free( psz_art );
    if( artUrl != url )
    {
        artUrl = url.replace( "file://",QString("" ) );
330 331
        /* Taglib seems to define a attachment://, It won't work yet */
        artUrl = url.replace( "attachment://",QString("" ) );
332 333 334 335 336
        emit artChanged( artUrl );
        msg_Dbg( p_intf, "Art:  %s", qtu( artUrl ) );
    }
}

337
/* User update of the slider */
Clément Stenac's avatar
Clément Stenac committed
338 339
void InputManager::sliderUpdate( float new_pos )
{
340 341
    if( hasInput() )
        var_SetFloat( p_input, "position", new_pos );
Clément Stenac's avatar
Clément Stenac committed
342
}
343

344
/* User togglePlayPause */
345 346 347 348
void InputManager::togglePlayPause()
{
    vlc_value_t state;
    var_Get( p_input, "state", &state );
349
    state.i_int = ( state.i_int != PLAYING_S ) ? PLAYING_S : PAUSE_S;
350 351 352 353
    var_Set( p_input, "state", state );
    emit statusChanged( state.i_int );
}

354 355 356 357
void InputManager::sectionPrev()
{
    if( hasInput() )
    {
358
        int i_type = var_Type( p_input, "next-chapter" );
359 360 361 362 363 364 365 366 367 368
        vlc_value_t val; val.b_bool = VLC_TRUE;
        var_Set( p_input, (i_type & VLC_VAR_TYPE) != 0 ?
                            "prev-chapter":"prev-title", val );
    }
}

void InputManager::sectionNext()
{
    if( hasInput() )
    {
369
        int i_type = var_Type( p_input, "next-chapter" );
370 371 372 373 374 375 376 377 378
        vlc_value_t val; val.b_bool = VLC_TRUE;
        var_Set( p_input, (i_type & VLC_VAR_TYPE) != 0 ?
                            "next-chapter":"next-title", val );
    }
}

void InputManager::sectionMenu()
{
    if( hasInput() )
379
        var_SetInteger( p_input, "title 0", 2 );
380 381
}

382
#ifdef ZVBI_COMPILED
383 384
void InputManager::telexGotoPage( int page )
{
385
    if( hasInput() )
386 387 388 389 390 391 392 393 394 395
    {
        vlc_object_t *p_vbi;
        p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
                    "zvbi", FIND_ANYWHERE );
        if( p_vbi )
        {
            var_SetInteger( p_vbi, "vbi-page", page );
            vlc_object_release( p_vbi );
        }
    }
396 397 398 399
}

void InputManager::telexToggle( bool b_enabled )
{
400 401 402 403 404
    int i_page = 0;

    if( b_enabled )
        i_page = 100;
    telexGotoPage( i_page );
405 406 407 408
}

void InputManager::telexSetTransparency( bool b_transp )
{
409
    if( hasInput() )
410 411 412 413 414 415 416 417 418 419
    {
        vlc_object_t *p_vbi;
        p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
                    "zvbi", FIND_ANYWHERE );
        if( p_vbi )
        {
            var_SetBool( p_input->p_libvlc, "vbi-opaque", b_transp );
            vlc_object_release( p_vbi );
        }
    }
420
}
421
#endif
422

Clément Stenac's avatar
Clément Stenac committed
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
void InputManager::slower()
{
    if( hasInput() )
        var_SetVoid( p_input, "rate-slower" );
}

void InputManager::faster()
{
    if( hasInput() )
        var_SetVoid( p_input, "rate-faster" );
}

void InputManager::normalRate()
{
    if( hasInput() )
        var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT );
}

441 442 443 444 445 446
void InputManager::setRate( int new_rate )
{
    if( hasInput() )
        var_SetInteger( p_input, "rate", new_rate );
}

447 448
/**********************************************************************
 * MainInputManager implementation. Wrap an input manager and
449 450
 * take care of updating the main playlist input.
 * Used in the main playlist Dialog
451 452 453
 **********************************************************************/
MainInputManager * MainInputManager::instance = NULL;

454 455
MainInputManager::MainInputManager( intf_thread_t *_p_intf )
                 : QObject(NULL), p_intf( _p_intf )
456 457 458
{
    p_input = NULL;
    im = new InputManager( this, p_intf );
459

460
//    var_AddCallback( THEPL, "item-change", PLItemChanged, this );
461
    var_AddCallback( THEPL, "item-change", ItemChanged, im );
462 463
    var_AddCallback( THEPL, "playlist-current", PLItemChanged, this );
    var_AddCallback( THEPL, "activity", PLItemChanged, this );
464

465
    var_AddCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this );
466

467 468 469
    // No necessary, I think TODO REMOVE ME at the end
    //var_AddCallback( THEPL, "intf-change", ItemChanged, im );

470
    /* Warn our embedded IM about input changes */
471
    CONNECT( this, inputChanged( input_thread_t * ),
472
             im, setInput( input_thread_t * ) );
473 474
}

Clément Stenac's avatar
Clément Stenac committed
475 476
MainInputManager::~MainInputManager()
{
477 478
    if( p_input )
    {
479 480
       var_DelCallback( p_input, "state", PLItemChanged, this );
       vlc_object_release( p_input );
481 482
       emit inputChanged( NULL );
    }
483

484
    var_DelCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this );
485 486

    var_DelCallback( THEPL, "activity", PLItemChanged, this );
487
    var_DelCallback( THEPL, "item-change", ItemChanged, im );
488
//    var_DelCallback( THEPL, "item-change", PLItemChanged, this );
489

490
    var_DelCallback( THEPL, "playlist-current", PLItemChanged, this );
Clément Stenac's avatar
Clément Stenac committed
491 492
}

493
void MainInputManager::customEvent( QEvent *event )
494
{
495
    int type = event->type();
496 497 498
    if ( type != ItemChanged_Type && type != VolumeChanged_Type )
        return;

499
    // msg_Dbg( p_intf, "New MainIM Event of type: %i", type );
500 501 502
    if( type == VolumeChanged_Type )
    {
        emit volumeChanged();
503
        return;
504
    }
505

506
    /* Should be PLItemChanged Event */
507
    if( VLC_OBJECT_INTF == p_intf->i_object_type )
508
    {
509
        vlc_mutex_lock( &p_intf->change_lock );
510
        if( p_input && ( p_input->b_dead || p_input->b_die ) )
511
        {
512 513
            var_DelCallback( p_input, "state", PLItemChanged, this );
            vlc_object_release( p_input );
514
            emit inputChanged( NULL );
515
            p_input = NULL;
516 517
            vlc_mutex_unlock( &p_intf->change_lock );
            return;
518
        }
519

520 521 522 523
        if( !p_input )
        {
            QPL_LOCK;
            p_input = THEPL->p_input;
524
            if( p_input && !( p_input->b_die || p_input->b_dead) )
525
            {
526 527
                vlc_object_yield( p_input );
                var_AddCallback( p_input, "state", PLItemChanged, this );
528 529
                emit inputChanged( p_input );
            }
530 531
            else
                p_input = NULL;
532 533 534 535
            QPL_UNLOCK;
        }
        vlc_mutex_unlock( &p_intf->change_lock );
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
536 537
    else
    {
538
        /* we are working as a dialogs provider */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
539 540
        playlist_t *p_playlist = (playlist_t *) vlc_object_find( p_intf,
                                       VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
541
        if( p_playlist )
542
        {
543
            p_input = p_playlist->p_input;
544 545 546 547
            emit inputChanged( p_input );
        }
    }
}
548

549
/* Playlist Control functions */
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
void MainInputManager::stop()
{
   playlist_Stop( THEPL );
}

void MainInputManager::next()
{
   playlist_Next( THEPL );
}

void MainInputManager::prev()
{
   playlist_Prev( THEPL );
}

565 566 567 568 569 570 571 572 573
void MainInputManager::togglePlayPause()
{
    if( p_input == NULL )
    {
        playlist_Play( THEPL );
        return;
    }
    getIM()->togglePlayPause();
}
574

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
575 576 577
/* Static callbacks */

/* IM */
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
static int InterfaceChanged( vlc_object_t *p_this, const char *psz_var,
                           vlc_value_t oldval, vlc_value_t newval, void *param )
{
    static int counter = 0;
    InputManager *im = (InputManager*)param;

    counter = counter++ % 4;
    if(!counter)
        return VLC_SUCCESS;
    IMEvent *event = new IMEvent( PositionUpdate_Type, 0 );
    QApplication::postEvent( im, static_cast<QEvent*>(event) );
    return VLC_SUCCESS;
}

static int ItemStateChanged( vlc_object_t *p_this, const char *psz_var,
                            vlc_value_t oldval, vlc_value_t newval, void *param )
{
    InputManager *im = (InputManager*)param;

    IMEvent *event = new IMEvent( ItemStateChanged_Type, 0 );
    QApplication::postEvent( im, static_cast<QEvent*>(event) );
    return VLC_SUCCESS;
}

static int ItemRateChanged( vlc_object_t *p_this, const char *psz_var,
                            vlc_value_t oldval, vlc_value_t newval, void *param )
{
    InputManager *im = (InputManager*)param;
606
    
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
    IMEvent *event = new IMEvent( ItemRateChanged_Type, 0 );
    QApplication::postEvent( im, static_cast<QEvent*>(event) );
    return VLC_SUCCESS;
}

static int ItemTitleChanged( vlc_object_t *p_this, const char *psz_var,
                            vlc_value_t oldval, vlc_value_t newval, void *param )
{
    InputManager *im = (InputManager*)param;

    IMEvent *event = new IMEvent( ItemTitleChanged_Type, 0 );
    QApplication::postEvent( im, static_cast<QEvent*>(event) );
    return VLC_SUCCESS;
}

static int ItemChanged( vlc_object_t *p_this, const char *psz_var,
                        vlc_value_t oldval, vlc_value_t newval, void *param )
{
    InputManager *im = (InputManager*)param;

    IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int );
    QApplication::postEvent( im, static_cast<QEvent*>(event) );
    return VLC_SUCCESS;
}
631

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
632

633 634 635 636 637
static int ChangeAudio( vlc_object_t *p_this, const char *var, vlc_value_t o,
                        vlc_value_t n, void *param )
{
    InputManager *im = (InputManager*)param;
    im->b_has_audio = true;
638
    return VLC_SUCCESS;
639
}
640

641 642 643 644 645
static int ChangeVideo( vlc_object_t *p_this, const char *var, vlc_value_t o,
                        vlc_value_t n, void *param )
{
    InputManager *im = (InputManager*)param;
    im->b_has_video = true;
646
    return VLC_SUCCESS;
647
}
648

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
649
/* MIM */
650
static int PLItemChanged( vlc_object_t *p_this, const char *psz_var,
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
651 652
                        vlc_value_t oldval, vlc_value_t newval, void *param )
{
653
    MainInputManager *mim = (MainInputManager*)param;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
654 655

    IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int );
656
    QApplication::postEvent( mim, static_cast<QEvent*>(event) );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
657 658 659 660 661 662
    return VLC_SUCCESS;
}

static int VolumeChanged( vlc_object_t *p_this, const char *psz_var,
                        vlc_value_t oldval, vlc_value_t newval, void *param )
{
663
    MainInputManager *mim = (MainInputManager*)param;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
664 665

    IMEvent *event = new IMEvent( VolumeChanged_Type, newval.i_int );
666
    QApplication::postEvent( mim, static_cast<QEvent*>(event) );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
667 668 669
    return VLC_SUCCESS;
}