9b1ae8ccebba7f2085db686148866a0b6654c7fb
[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 <QHBoxLayout>
30
31 #define ICON_SIZE 128
32
33 static void *DoRequest( intf_thread_t *, vout_thread_t *, int*,int*,
34                         unsigned int *, unsigned int * );
35 static void DoRelease( intf_thread_t *, void * );
36 static int DoControl( intf_thread_t *, void *, int, va_list );
37
38 bool need_update;
39
40 VideoWidget::VideoWidget( intf_thread_t *_p_i, bool _always ) : QFrame( NULL ),
41                                                                p_intf( _p_i )
42 {
43     vlc_mutex_init( p_intf, &lock );
44     always = _always;
45
46     p_intf->pf_request_window  = ::DoRequest;
47     p_intf->pf_release_window  = ::DoRelease;
48     p_intf->pf_control_window  = ::DoControl;
49     p_intf->p_sys->p_video = this;
50     p_vout = NULL;
51
52     setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
53
54     connect( DialogsProvider::getInstance(NULL)->fixed_timer,
55              SIGNAL( timeout() ), this, SLOT( update() ) );
56
57     if( always )
58     {
59        DrawBackground();
60     }
61     need_update = false;
62 }
63
64 void VideoWidget::update()
65 {
66     if( need_update )
67     {
68         p_intf->p_sys->p_mi->resize( p_intf->p_sys->p_mi->sizeHint() );
69         need_update = false;
70     }
71 }
72
73 VideoWidget::~VideoWidget()
74 {
75     vlc_mutex_lock( &lock );
76     if( p_vout )
77     {
78         if( !p_intf->psz_switch_intf )
79         {
80             if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
81                 vout_Control( p_vout, VOUT_REPARENT );
82         }
83         else
84         {
85             if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
86                 vout_Control( p_vout, VOUT_CLOSE );
87         }
88     }
89     p_intf->pf_request_window = NULL;
90     p_intf->pf_release_window = NULL;
91     p_intf->pf_control_window = NULL;
92     vlc_mutex_unlock( &lock );
93     vlc_mutex_destroy( &lock );
94
95     if( always )
96         CleanBackground();
97 }
98
99 QSize VideoWidget::sizeHint() const
100 {
101     return p_intf->p_sys->p_mi->videoSize;
102 }
103
104 static void *DoRequest( intf_thread_t *p_intf, vout_thread_t *p_vout,
105                         int *pi1, int *pi2, unsigned int*pi3,unsigned int*pi4)
106 {
107     return p_intf->p_sys->p_video->Request( p_vout, pi1, pi2, pi3, pi4 );
108 }
109
110 void *VideoWidget::Request( vout_thread_t *p_nvout, int *pi_x, int *pi_y,
111                            unsigned int *pi_width, unsigned int *pi_height )
112 {
113     if( p_vout )
114     {
115         msg_Dbg( p_intf, "embedded video already in use" );
116         return NULL;
117     }
118     p_vout = p_nvout;
119
120    setMinimumSize( 1,1 );
121     p_intf->p_sys->p_mi->videoSize = QSize( *pi_width, *pi_height );
122     updateGeometry();
123     need_update = true;
124     return  (void*)winId();
125 }
126
127 static void DoRelease( intf_thread_t *p_intf, void *p_win )
128 {
129     return p_intf->p_sys->p_video->Release( p_win );
130 }
131
132 void VideoWidget::resizeEvent( QResizeEvent *e )
133 {
134     if( !always )return;
135     if( e->size().height() < ICON_SIZE -1 )
136         label->setMaximumWidth( e->size().height() );
137     else
138         label->setMaximumWidth( ICON_SIZE );
139 }
140
141 void VideoWidget::Release( void *p_win )
142 {
143     p_vout = NULL;
144     if( config_GetInt( p_intf, "qt-always-video" ) == 0 )
145     {
146         p_intf->p_sys->p_mi->videoSize = QSize ( 1,1 );
147         updateGeometry();
148         need_update = true;
149     }
150 }
151
152 static int DoControl( intf_thread_t *p_intf, void *p_win, int i_q, va_list a )
153 {
154     return p_intf->p_sys->p_video->Control( p_win, i_q, a );
155 }
156
157 int VideoWidget::DrawBackground()
158 {
159     setAutoFillBackground( true );
160     plt =  palette();
161     plt.setColor( QPalette::Active, QPalette::Window , Qt::black );
162     plt.setColor( QPalette::Inactive, QPalette::Window , Qt::black );
163     setPalette( plt );
164
165     backgroundLayout = new QHBoxLayout;
166     label = new QLabel( "" );
167     label->setMaximumHeight( ICON_SIZE );
168     label->setMaximumWidth( ICON_SIZE );
169     label->setScaledContents( true );
170     label->setPixmap( QPixmap( ":/vlc128.png" ) );
171     backgroundLayout = new QHBoxLayout;
172     backgroundLayout->addWidget( label );
173     setLayout( backgroundLayout );
174     return 0;
175 }
176
177 int VideoWidget::CleanBackground()
178 {
179     backgroundLayout->takeAt(0);
180     delete backgroundLayout;
181     return 0;
182 }
183
184 int VideoWidget::Control( void *p_window, int i_query, va_list args )
185 {
186     int i_ret = VLC_EGENERIC;
187     vlc_mutex_lock( &lock );
188     switch( i_query )
189     {
190         case VOUT_GET_SIZE:
191         {
192             unsigned int *pi_width  = va_arg( args, unsigned int * );
193             unsigned int *pi_height = va_arg( args, unsigned int * );
194             *pi_width = frame->width();
195             *pi_height = frame->height();
196             i_ret = VLC_SUCCESS;
197             break;
198         }
199         case VOUT_SET_SIZE:
200         {
201             unsigned int i_width  = va_arg( args, unsigned int );
202             unsigned int i_height = va_arg( args, unsigned int );
203
204             if( !i_width && p_vout ) i_width = p_vout->i_window_width;
205             if( !i_height && p_vout ) i_height = p_vout->i_window_height;
206             p_intf->p_sys->p_mi->videoSize = QSize( i_width, i_height );
207             updateGeometry();
208             need_update = true;
209             i_ret = VLC_SUCCESS;
210             break;
211         }
212         case VOUT_SET_STAY_ON_TOP:
213         {
214             /// \todo
215             break;
216         }
217         default:
218             msg_Warn( p_intf, "unsupported control query" );
219             break;
220     }
221     vlc_mutex_unlock( &lock );
222     return i_ret;
223 }