Preliminary work for better audio visualization handling
[vlc.git] / modules / gui / qt4 / components / video_widget.cpp
1 /*****************************************************************************
2  * video_widget.cpp : Embedded video output
3  ****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "dialogs_provider.hpp"
25 #include <vlc/vout.h>
26 #include "qt4.hpp"
27 #include "components/video_widget.hpp"
28 #include "main_interface.hpp"
29 #include "input_manager.hpp"
30 #include <QHBoxLayout>
31
32 #define ICON_SIZE 128
33
34 static void *DoRequest( intf_thread_t *, vout_thread_t *, int*,int*,
35                         unsigned int *, unsigned int * );
36 static void DoRelease( intf_thread_t *, void * );
37 static int DoControl( intf_thread_t *, void *, int, va_list );
38
39 bool need_update;
40
41 VideoWidget::VideoWidget( intf_thread_t *_p_i, bool _always ) : QFrame( NULL ),
42                                                                p_intf( _p_i )
43 {
44     vlc_mutex_init( p_intf, &lock );
45     always = _always;
46
47     p_intf->pf_request_window  = ::DoRequest;
48     p_intf->pf_release_window  = ::DoRelease;
49     p_intf->pf_control_window  = ::DoControl;
50     p_intf->p_sys->p_video = this;
51     p_vout = NULL;
52
53     setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
54
55     connect( DialogsProvider::getInstance(NULL)->fixed_timer,
56              SIGNAL( timeout() ), this, SLOT( update() ) );
57
58     if( always )
59     {
60        DrawBackground();
61        connect( THEMIM->getIM(), SIGNAL( audioStarted() ),
62                 this, SLOT( hasAudio() ) );
63        connect( THEMIM->getIM(), SIGNAL( audioStarted() ),
64                 this, SLOT( hasVideo() ) );
65     }
66     need_update = false;
67 }
68
69 void VideoWidget::update()
70 {
71     if( need_update )
72     {
73         p_intf->p_sys->p_mi->resize( p_intf->p_sys->p_mi->sizeHint() );
74         need_update = false;
75     }
76 }
77
78 VideoWidget::~VideoWidget()
79 {
80     vlc_mutex_lock( &lock );
81     if( p_vout )
82     {
83         if( !p_intf->psz_switch_intf )
84         {
85             if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
86                 vout_Control( p_vout, VOUT_REPARENT );
87         }
88         else
89         {
90             if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
91                 vout_Control( p_vout, VOUT_CLOSE );
92         }
93     }
94     p_intf->pf_request_window = NULL;
95     p_intf->pf_release_window = NULL;
96     p_intf->pf_control_window = NULL;
97     vlc_mutex_unlock( &lock );
98     vlc_mutex_destroy( &lock );
99
100     if( always )
101         CleanBackground();
102 }
103
104 QSize VideoWidget::sizeHint() const
105 {
106     return p_intf->p_sys->p_mi->videoSize;
107 }
108
109 static void *DoRequest( intf_thread_t *p_intf, vout_thread_t *p_vout,
110                         int *pi1, int *pi2, unsigned int*pi3,unsigned int*pi4)
111 {
112     return p_intf->p_sys->p_video->Request( p_vout, pi1, pi2, pi3, pi4 );
113 }
114
115 void *VideoWidget::Request( vout_thread_t *p_nvout, int *pi_x, int *pi_y,
116                            unsigned int *pi_width, unsigned int *pi_height )
117 {
118     if( p_vout )
119     {
120         msg_Dbg( p_intf, "embedded video already in use" );
121         return NULL;
122     }
123     p_vout = p_nvout;
124
125     // if( THEMIM->getIM()->b_has_video )
126     // {
127     //      We are really running a video
128     //      Close the existing vout
129     //      Set visual to disabled
130     // }
131     // else
132     // {
133     //      We are getting a request for visual
134     //      Just go on.
135     // }
136     // Check THEMIM->b_has_audio. If true, hide audio.
137
138     setMinimumSize( 1,1 );
139     p_intf->p_sys->p_mi->videoSize = QSize( *pi_width, *pi_height );
140     updateGeometry();
141     need_update = true;
142     return  (void*)winId();
143 }
144
145 static void DoRelease( intf_thread_t *p_intf, void *p_win )
146 {
147     return p_intf->p_sys->p_video->Release( p_win );
148 }
149
150 void VideoWidget::resizeEvent( QResizeEvent *e )
151 {
152     if( !always )return;
153     if( e->size().height() < ICON_SIZE -1 )
154         label->setMaximumWidth( e->size().height() );
155     else
156         label->setMaximumWidth( ICON_SIZE );
157 }
158
159 void VideoWidget::Release( void *p_win )
160 {
161     p_vout = NULL;
162     if( config_GetInt( p_intf, "qt-always-video" ) == 0 )
163     {
164         p_intf->p_sys->p_mi->videoSize = QSize ( 1,1 );
165         updateGeometry();
166         need_update = true;
167     }
168 }
169
170 void VideoWidget::hasAudio()
171 {
172     /* We have video already, do nothing */
173     if( THEMIM->getIM()->b_has_video )
174     {
175
176     }
177     else
178     {
179         /* Show the panel to the user */
180         fprintf( stderr, "Showing panel\n" );
181     }
182 }
183
184 void VideoWidget::hasVideo()
185 {
186     // if panel is shown, hide it
187 }
188
189 static int DoControl( intf_thread_t *p_intf, void *p_win, int i_q, va_list a )
190 {
191     return p_intf->p_sys->p_video->Control( p_win, i_q, a );
192 }
193
194 int VideoWidget::DrawBackground()
195 {
196     setAutoFillBackground( true );
197     plt =  palette();
198     plt.setColor( QPalette::Active, QPalette::Window , Qt::black );
199     plt.setColor( QPalette::Inactive, QPalette::Window , Qt::black );
200     setPalette( plt );
201
202     backgroundLayout = new QHBoxLayout;
203     label = new QLabel( "" );
204     label->setMaximumHeight( ICON_SIZE );
205     label->setMaximumWidth( ICON_SIZE );
206     label->setScaledContents( true );
207     label->setPixmap( QPixmap( ":/vlc128.png" ) );
208     backgroundLayout = new QHBoxLayout;
209     backgroundLayout->addWidget( label );
210     setLayout( backgroundLayout );
211     return 0;
212 }
213
214 int VideoWidget::CleanBackground()
215 {
216     backgroundLayout->takeAt(0);
217     delete backgroundLayout;
218     return 0;
219 }
220
221 int VideoWidget::Control( void *p_window, int i_query, va_list args )
222 {
223     int i_ret = VLC_EGENERIC;
224     vlc_mutex_lock( &lock );
225     switch( i_query )
226     {
227         case VOUT_GET_SIZE:
228         {
229             unsigned int *pi_width  = va_arg( args, unsigned int * );
230             unsigned int *pi_height = va_arg( args, unsigned int * );
231             *pi_width = frame->width();
232             *pi_height = frame->height();
233             i_ret = VLC_SUCCESS;
234             break;
235         }
236         case VOUT_SET_SIZE:
237         {
238             unsigned int i_width  = va_arg( args, unsigned int );
239             unsigned int i_height = va_arg( args, unsigned int );
240
241             if( !i_width && p_vout ) i_width = p_vout->i_window_width;
242             if( !i_height && p_vout ) i_height = p_vout->i_window_height;
243             p_intf->p_sys->p_mi->videoSize = QSize( i_width, i_height );
244             updateGeometry();
245             need_update = true;
246             i_ret = VLC_SUCCESS;
247             break;
248         }
249         case VOUT_SET_STAY_ON_TOP:
250         {
251             /// \todo
252             break;
253         }
254         default:
255             msg_Warn( p_intf, "unsupported control query" );
256             break;
257     }
258     vlc_mutex_unlock( &lock );
259     return i_ret;
260 }