kvideowidget.cpp

00001 /*
00002    This file is part of KDE/aRts (Noatun) - xine integration
00003    Copyright (C) 2002 Ewald Snel <ewald@rambo.its.tudelft.nl>
00004    Copyright (C) 2002 Neil Stevens <neil@qualityassistant.com>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License version 2 as published by the Free Software Foundation.
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     // Setup actions
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     // Resize GUI
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     // Don't reset fullscreen mode for video playlists
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     // Get 32bit RGBA image data (stored in 1bpp pixmap)
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     // Convert 32bit RGBA image data into Qt image
00216     QImage qImage = QImage( (uchar *)xImage->data, width/32, height, 32, (QRgb *)0, 0, QImage::IgnoreEndian ).copy();
00217 
00218     // Free X11 resources and return Qt image
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     // ### Remove in KDE4
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     // Interconnect mouse button signals
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     // ### Remove in KDE4
00389      connect( fullscreenWidget, SIGNAL(rightButtonPressed(const QPoint &)),
00390         this, SIGNAL(rightButtonPressed(const QPoint &)) );
00391          
00392     // Leave fullscreen mode with <Escape> key
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"
KDE Home | KDE Accessibility Home | Description of Access Keys