00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifdef HAVE_CONFIG_H
00012 #include <config.h>
00013 #endif
00014
00015 #include <time.h>
00016 #ifdef HAVE_USLEEP
00017 #include <unistd.h>
00018 #endif
00019 #include <qaccel.h>
00020 #include <qcursor.h>
00021
00022 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00023 #include <X11/Xlib.h>
00024 #include <X11/Xutil.h>
00025 #else
00026 #define XEvent void
00027 #endif
00028
00029 #include <kaction.h>
00030 #include <klocale.h>
00031 #include "kvideowidget.h"
00032
00033
00034 class KFullscreenVideoWidget : public KVideoWidget
00035 {
00036 public:
00037 KFullscreenVideoWidget( KVideoWidget *parent = 0, const char *name = 0 );
00038
00039 protected:
00040 virtual void windowActivationChange( bool );
00041 virtual bool x11Event( XEvent *event );
00042
00043 private:
00044 KVideoWidget *videoWidget;
00045 };
00046
00047 KFullscreenVideoWidget::KFullscreenVideoWidget( KVideoWidget *parent, const char *name )
00048 : KVideoWidget( 0, name )
00049 {
00050 this->videoWidget = parent;
00051 setEraseColor( black );
00052 setCursor(QCursor(Qt::BlankCursor));
00053 }
00054
00055 void KFullscreenVideoWidget::windowActivationChange( bool )
00056 {
00057 if (!isActiveWindow())
00058 {
00059 videoWidget->setWindowed();
00060 }
00061 }
00062
00063 bool KFullscreenVideoWidget::x11Event( XEvent *event )
00064 {
00065 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00066 if (event->type == ClientMessage &&
00067 event->xclient.message_type ==
00068 XInternAtom( qt_xdisplay(), "VPO_RESIZE_NOTIFY", False ))
00069 {
00070 videoWidget->resizeNotify( event->xclient.data.l[0], event->xclient.data.l[1] );
00071 }
00072 #endif
00073 return false;
00074 }
00075
00076 KVideoWidget::KVideoWidget( KXMLGUIClient *clientParent, QWidget *parent, const char *name, WFlags f )
00077 : KXMLGUIClient( clientParent ),
00078 QWidget( parent, name, f )
00079 {
00080 init();
00081
00082 QString toolbarName = i18n("Video Toolbar");
00083 setXML(QString("<!DOCTYPE kpartgui>\n<kpartgui name=\"kvideowidget\" version=\"1\"><MenuBar><Menu name=\"edit\"><Separator/><Action name=\"double_size\"/><Action name=\"normal_size\"/><Action name=\"half_size\"/><Separator/><Action name=\"fullscreen_mode\"/></Menu></MenuBar><Toolbar name=\"VideoToolbar\"><text>Video Toolbar</text><Action name=\"fullscreen_mode\"/></Toolbar></kpartgui>"), true);
00084 }
00085
00086 KVideoWidget::KVideoWidget( QWidget *parent, const char *name, WFlags f )
00087 : QWidget( parent, name, f )
00088 {
00089 init();
00090 }
00091
00092 void KVideoWidget::init(void)
00093 {
00094 setMinimumSize(0, 0);
00095 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
00096 setFocusPolicy( ClickFocus );
00097
00098 fullscreenWidget = 0;
00099 poVideo = Arts::VideoPlayObject::null();
00100 videoWidth = 0;
00101 videoHeight = 0;
00102
00103
00104 new KToggleAction( i18n("Fullscreen &Mode"), "window_fullscreen",
00105 CTRL+SHIFT+Key_F, this, SLOT(fullscreenActivated()),
00106 actionCollection(), "fullscreen_mode" );
00107 new KRadioAction( i18n("&Half Size"), ALT+Key_0,
00108 this, SLOT(halfSizeActivated()),
00109 actionCollection(), "half_size" );
00110 new KRadioAction( i18n("&Normal Size"), ALT+Key_1,
00111 this, SLOT(normalSizeActivated()),
00112 actionCollection(), "normal_size" );
00113 new KRadioAction( i18n("&Double Size"), ALT+Key_2,
00114 this, SLOT(doubleSizeActivated()),
00115 actionCollection(), "double_size" );
00116
00117 ((KToggleAction *)action( "half_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
00118 ((KToggleAction *)action( "normal_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
00119 ((KToggleAction *)action( "double_size" ))->setExclusiveGroup( "KVideoWidget::zoom" );
00120
00121 action("double_size")->setEnabled(false);
00122 action("half_size")->setEnabled(false);
00123 action("normal_size")->setEnabled(false);
00124 action("fullscreen_mode")->setEnabled(false);
00125 }
00126
00127 KVideoWidget::~KVideoWidget()
00128 {
00129 if (isEmbedded())
00130 {
00131 poVideo.x11WindowId( -1 );
00132 poVideo = Arts::VideoPlayObject::null();
00133 }
00134
00135 delete fullscreenWidget;
00136 }
00137
00138 void KVideoWidget::embed( Arts::VideoPlayObject vpo )
00139 {
00140 bool enable;
00141 if (vpo.isNull())
00142 {
00143 if (isEmbedded())
00144 {
00145 poVideo.x11WindowId( -1 );
00146 poVideo = Arts::VideoPlayObject::null();
00147 }
00148
00149 setBackgroundMode( PaletteBackground );
00150 repaint();
00151
00152
00153 videoWidth = 0;
00154 videoHeight = 0;
00155
00156 if (isHalfSize() || isNormalSize() || isDoubleSize())
00157 emit adaptSize( 0, 0 );
00158
00159 enable = false;
00160 updateGeometry();
00161 }
00162 else
00163 {
00164 if (isEmbedded())
00165 {
00166 poVideo.x11WindowId( -1 );
00167 }
00168
00169 poVideo = vpo;
00170
00171
00172 if (fullscreenWidget)
00173 {
00174 poVideo.x11WindowId( fullscreenWidget->winId() );
00175 fullscreenWidget->setBackgroundMode( NoBackground );
00176
00177 setEraseColor( black );
00178 }
00179 else
00180 {
00181 poVideo.x11WindowId( winId() );
00182 setBackgroundMode( NoBackground );
00183 }
00184 enable = true;
00185 }
00186 action("double_size")->setEnabled(enable);
00187 action("half_size")->setEnabled(enable);
00188 action("normal_size")->setEnabled(enable);
00189 action("fullscreen_mode")->setEnabled(enable);
00190 }
00191
00192 QImage KVideoWidget::snapshot( Arts::VideoPlayObject vpo )
00193 {
00194 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00195 Window root;
00196 Pixmap pixmap;
00197 XImage *xImage;
00198 unsigned int width, height, border, depth;
00199 int x, y;
00200
00201 if (vpo.isNull() || (long)(pixmap = vpo.x11Snapshot()) == -1)
00202 return QImage();
00203
00204
00205 XGetGeometry( qt_xdisplay(), pixmap, &root, &x, &y, &width, &height, &border, &depth );
00206
00207 xImage = XGetImage( qt_xdisplay(), pixmap, 0, 0, width, height, 1, XYPixmap );
00208
00209 if (xImage == 0)
00210 {
00211 XFreePixmap( qt_xdisplay(), pixmap );
00212 return QImage();
00213 }
00214
00215
00216 QImage qImage = QImage( (uchar *)xImage->data, width/32, height, 32, (QRgb *)0, 0, QImage::IgnoreEndian ).copy();
00217
00218
00219 XDestroyImage( xImage );
00220 XFreePixmap( qt_xdisplay(), pixmap );
00221
00222 return qImage;
00223 #else
00224 return 0;
00225 #endif
00226 }
00227
00228 bool KVideoWidget::isEmbedded()
00229 {
00230 return !poVideo.isNull();
00231 }
00232
00233 bool KVideoWidget::isFullscreen()
00234 {
00235 return ((KToggleAction *)action( "fullscreen_mode" ))->isChecked();
00236 }
00237
00238 bool KVideoWidget::isHalfSize()
00239 {
00240 return ((KToggleAction *)action( "half_size" ))->isChecked();
00241 }
00242
00243 bool KVideoWidget::isNormalSize()
00244 {
00245 return ((KToggleAction *)action( "normal_size" ))->isChecked();
00246 }
00247
00248 bool KVideoWidget::isDoubleSize()
00249 {
00250 return ((KToggleAction *)action( "double_size" ))->isChecked();
00251 }
00252
00253 void KVideoWidget::setFullscreen()
00254 {
00255 if (!isFullscreen())
00256 {
00257 ((KToggleAction *)action( "fullscreen_mode" ))->setChecked( true );
00258 fullscreenActivated();
00259 }
00260 }
00261
00262 void KVideoWidget::setWindowed()
00263 {
00264 if (isFullscreen())
00265 {
00266 ((KToggleAction *)action( "fullscreen_mode" ))->setChecked( false );
00267 fullscreenActivated();
00268 }
00269 }
00270
00271 void KVideoWidget::setHalfSize()
00272 {
00273 ((KToggleAction *)action( "half_size" ))->setChecked( true );
00274 halfSizeActivated();
00275 }
00276
00277 void KVideoWidget::setNormalSize()
00278 {
00279 ((KToggleAction *)action( "normal_size" ))->setChecked( true );
00280 normalSizeActivated();
00281 }
00282
00283 void KVideoWidget::setDoubleSize()
00284 {
00285 ((KToggleAction *)action( "double_size" ))->setChecked( true );
00286 doubleSizeActivated();
00287 }
00288
00289 QSize KVideoWidget::sizeHint() const
00290 {
00291 return QSize( videoWidth, videoHeight );
00292 }
00293
00294 int KVideoWidget::heightForWidth( int w ) const
00295 {
00296 if(videoWidth == 0)
00297 return 0;
00298 else
00299 return int( double(w)*double(videoHeight)/double(videoWidth) );
00300 }
00301
00302 void KVideoWidget::mousePressEvent( QMouseEvent *event )
00303 {
00304 QPoint pos = mapToGlobal( event->pos() );
00305
00306 emit mouseButtonPressed( event->button(), pos, event->state() );
00307
00308
00309 if ( event->button() == RightButton )
00310 emit rightButtonPressed( pos );
00311 }
00312
00313 void KVideoWidget::mouseDoubleClickEvent( QMouseEvent *event )
00314 {
00315 emit mouseButtonDoubleClick( mapToGlobal( event->pos() ), event->state() );
00316 }
00317
00318 void KVideoWidget::resizeEvent( QResizeEvent *event )
00319 {
00320 QWidget::resizeEvent( event );
00321
00322 if (width() > minimumWidth() || height() > minimumHeight())
00323 {
00324 if (width() == QMAX( (videoWidth / 2), minimumWidth() ) &&
00325 height() == QMAX( (videoHeight / 2), minimumHeight() ))
00326 ((KToggleAction *)action( "half_size" ))->setChecked( true );
00327 else if (width() == QMAX( videoWidth, minimumWidth() ) &&
00328 height() == QMAX( videoHeight, minimumHeight() ))
00329 ((KToggleAction *)action( "normal_size" ))->setChecked( true );
00330 else if (width() == QMAX( (2 * videoWidth), minimumWidth() ) &&
00331 height() == QMAX( (2 * videoHeight), minimumHeight() ))
00332 ((KToggleAction *)action( "double_size" ))->setChecked( true );
00333 else
00334 {
00335 ((KToggleAction *)action( "half_size" ))->setChecked( false );
00336 ((KToggleAction *)action( "normal_size" ))->setChecked( false );
00337 ((KToggleAction *)action( "double_size" ))->setChecked( false );
00338 }
00339 }
00340 }
00341
00342 void KVideoWidget::resizeNotify( int width, int height )
00343 {
00344 if(!isEmbedded()) return;
00345
00346 videoWidth = width;
00347 videoHeight = height;
00348
00349 if (isHalfSize())
00350 emit adaptSize( (videoWidth / 2), (videoHeight / 2) );
00351 else if (isNormalSize())
00352 emit adaptSize( videoWidth, videoHeight );
00353 else if (isDoubleSize())
00354 emit adaptSize( (2 * videoWidth), (2 * videoHeight) );
00355
00356 updateGeometry();
00357 }
00358
00359 bool KVideoWidget::x11Event( XEvent *event )
00360 {
00361 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00362 if (event->type == ClientMessage &&
00363 event->xclient.message_type ==
00364 XInternAtom( qt_xdisplay(), "VPO_RESIZE_NOTIFY", False ))
00365 {
00366 resizeNotify( event->xclient.data.l[0], event->xclient.data.l[1] );
00367 }
00368 #endif
00369 return false;
00370 }
00371
00372 void KVideoWidget::fullscreenActivated()
00373 {
00374 if (isFullscreen() == (fullscreenWidget != 0))
00375 return;
00376
00377 if (isFullscreen())
00378 {
00379 fullscreenWidget = new KFullscreenVideoWidget( this );
00380
00381
00382 connect( fullscreenWidget, SIGNAL(mouseButtonPressed( int, const QPoint &, int )),
00383 this, SIGNAL(mouseButtonPressed( int, const QPoint &, int)) );
00384
00385 connect( fullscreenWidget, SIGNAL(mouseButtonDoubleClick( const QPoint &, int )),
00386 this, SIGNAL(mouseButtonDoubleClick( const QPoint &, int )) );
00387
00388
00389 connect( fullscreenWidget, SIGNAL(rightButtonPressed(const QPoint &)),
00390 this, SIGNAL(rightButtonPressed(const QPoint &)) );
00391
00392
00393 QAccel *a = new QAccel( fullscreenWidget );
00394 a->connectItem( a->insertItem( Key_Escape ),
00395 this, SLOT(setWindowed()) );
00396
00397 fullscreenWidget->setFocus();
00398 fullscreenWidget->showFullScreen();
00399
00400 if (isEmbedded())
00401 {
00402 poVideo.x11WindowId( fullscreenWidget->winId() );
00403 fullscreenWidget->setBackgroundMode( NoBackground );
00404 }
00405 }
00406 else
00407 {
00408 if (isEmbedded())
00409 {
00410 poVideo.x11WindowId( winId() );
00411 setBackgroundMode( NoBackground );
00412 }
00413
00414 delete fullscreenWidget;
00415 fullscreenWidget = 0;
00416 }
00417 }
00418
00419 void KVideoWidget::halfSizeActivated()
00420 {
00421 if (isHalfSize())
00422 {
00423 if(isEmbedded()) emit adaptSize( (videoWidth / 2), (videoHeight / 2) );
00424 setWindowed();
00425 }
00426 }
00427
00428 void KVideoWidget::normalSizeActivated()
00429 {
00430 if (isNormalSize())
00431 {
00432 if(isEmbedded()) emit adaptSize( videoWidth, videoHeight );
00433 setWindowed();
00434 }
00435 }
00436
00437 void KVideoWidget::doubleSizeActivated()
00438 {
00439 if (isDoubleSize())
00440 {
00441 if(isEmbedded()) emit adaptSize( (2 * videoWidth), (2 * videoHeight) );
00442 setWindowed();
00443 }
00444 }
00445
00446 #include "kvideowidget.moc"