00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "videowidget.h"
00022 #include "mediaplayerstate.h"
00023
00024
00025 #include <qpe/mediaplayerplugininterface.h>
00026 #include <qpe/config.h>
00027 #include <qpe/qpeapplication.h>
00028 #include <opie2/odebug.h>
00029 #include <opie2/oresource.h>
00030
00031
00032 #include <qbitmap.h>
00033 #include <qdir.h>
00034 #include <qslider.h>
00035
00036
00037 #ifdef Q_WS_QWS
00038 # define USE_DIRECT_PAINTER
00039 # include <qdirectpainter_qws.h>
00040 # include <qgfxraster_qws.h>
00041 #endif
00042
00043
00044 extern MediaPlayerState *mediaPlayerState;
00045
00046
00047 static const int xo = 2;
00048 static const int yo = 0;
00049
00050
00051 struct MediaButton {
00052
00053 bool isToggle, isHeld, isDown;
00054
00055 };
00056
00057
00058
00059 MediaButton videoButtons[] = {
00060 { FALSE, FALSE, FALSE },
00061 { FALSE, FALSE, FALSE },
00062 { FALSE, FALSE, FALSE },
00063 { FALSE, FALSE, FALSE },
00064 { FALSE, FALSE, FALSE },
00065 { FALSE, FALSE, FALSE },
00066 { TRUE, FALSE, FALSE }
00067 };
00068
00069
00070
00071 const char *skinV_mask_file_names[7] = {
00072 "stop","play","back","fwd","up","down","full"
00073 };
00074
00075 static const int numVButtons = (sizeof(videoButtons)/sizeof(MediaButton));
00076
00077 VideoWidget::VideoWidget(QWidget* parent, const char* name, WFlags f) :
00078 QWidget( parent, name, f ), scaledWidth( 0 ), scaledHeight( 0 )
00079 {
00080 setCaption( tr("OpiePlayer") );
00081 Config cfg("OpiePlayer");
00082
00083 cfg.setGroup("Options");
00084 skin = cfg.readEntry("Skin","default");
00085
00086 QString skinPath;
00087 skinPath = "opieplayer2/skins/" + skin;
00088 if(!QDir(QString(getenv("OPIEDIR")) +"/pics/"+skinPath).exists())
00089 skinPath = "opieplayer2/skins/default";
00090
00091
00092
00093
00094 pixBg = new QPixmap( Opie::Core::OResource::loadPixmap( QString("%1/background").arg(skinPath) ) );
00095 imgUp = new QImage( Opie::Core::OResource::loadImage( QString("%1/skinV_up").arg(skinPath) ) );
00096 imgDn = new QImage( Opie::Core::OResource::loadImage( QString("%1/skinV_down").arg(skinPath) ) );
00097
00098 imgButtonMask = new QImage( imgUp->width(), imgUp->height(), 8, 255 );
00099 imgButtonMask->fill( 0 );
00100
00101 for ( int i = 0; i < 7; i++ ) {
00102 QString filename = QString( QPEApplication::qpeDir() + "pics/" + skinPath +
00103 "/skinV_mask_" + skinV_mask_file_names[i] + ".png" );
00104
00105 masks[i] = new QBitmap( filename );
00106
00107 if ( !masks[i]->isNull() ) {
00108 QImage imgMask = masks[i]->convertToImage();
00109 uchar **dest = imgButtonMask->jumpTable();
00110 for ( int y = 0; y < imgUp->height(); y++ ) {
00111 uchar *line = dest[y];
00112 for ( int x = 0; x < imgUp->width(); x++ ) {
00113 if ( !qRed( imgMask.pixel( x, y ) ) )
00114 line[x] = i + 1;
00115 }
00116 }
00117 }
00118 }
00119 for ( int i = 0; i < 7; i++ ) {
00120 buttonPixUp[i] = NULL;
00121 buttonPixDown[i] = NULL;
00122 }
00123
00124 QWidget *d = QApplication::desktop();
00125 int width = d->width();
00126 int height = d->height();
00127
00128 if( (width != pixBg->width() ) || (height != pixBg->height() ) ) {
00129 QImage img;
00130 img = pixBg->convertToImage();
00131 pixBg->convertFromImage( img.smoothScale( width, height));
00132 }
00133
00134 setBackgroundPixmap( *pixBg );
00135 currentFrame = new QImage( 220 + 2, 160, (QPixmap::defaultDepth() == 16) ? 16 : 32 );
00136 slider = new QSlider( Qt::Horizontal, this );
00137 slider->setMinValue( 0 );
00138 slider->setMaxValue( 1 );
00139
00140 slider->setBackgroundPixmap( *pixBg );
00141 slider->setFocusPolicy( QWidget::NoFocus );
00142
00143
00144 connect(slider,SIGNAL(sliderPressed()),this,SLOT(sliderPressed()));
00145 connect(slider,SIGNAL(sliderReleased()),this,SLOT(sliderReleased()));
00146
00147 connect(mediaPlayerState,SIGNAL(lengthChanged(long)),this,SLOT(setLength(long)));
00148 connect(mediaPlayerState,SIGNAL(positionChanged(long)),this,SLOT(setPosition(long)));
00149 connect(mediaPlayerState,SIGNAL(positionUpdated(long)),this,SLOT(setPosition(long)));
00150 connect(mediaPlayerState,SIGNAL(viewChanged(char)),this,SLOT(setView(char)));
00151
00152 connect(mediaPlayerState,SIGNAL(playingToggled(bool)),this,SLOT(setPlaying(bool)));
00153
00154
00155 setLength( mediaPlayerState->length() );
00156 setPosition( mediaPlayerState->position() );
00157 setFullscreen( mediaPlayerState->fullscreen() );
00158
00159
00160
00161 }
00162
00163
00164 VideoWidget::~VideoWidget() {
00165
00166 for ( int i = 0; i < 7; i++ )
00167 {
00168 delete buttonPixUp[i];
00169 delete buttonPixDown[i];
00170 }
00171
00172 delete pixBg;
00173 delete imgUp;
00174 delete imgDn;
00175 delete imgButtonMask;
00176 for ( int i = 0; i < 7; i++ )
00177 {
00178 delete masks[i];
00179 }
00180
00181
00182
00183
00184 }
00185
00186
00187 static bool videoSliderBeingMoved = FALSE;
00188
00189 QPixmap *combineVImageWithBackground( QImage img, QPixmap bg, QPoint offset ) {
00190 QPixmap pix( img.width(), img.height() );
00191 QPainter p( &pix );
00192 p.drawTiledPixmap( pix.rect(), bg, offset );
00193 p.drawImage( 0, 0, img );
00194 return new QPixmap( pix );
00195 }
00196
00197 QPixmap *maskVPixToMask( QPixmap pix, QBitmap mask ) {
00198 QPixmap *pixmap = new QPixmap( pix );
00199 pixmap->setMask( mask );
00200 return pixmap;
00201 }
00202
00203 void VideoWidget::resizeEvent( QResizeEvent * ) {
00204 int h = height();
00205 int w = width();
00206
00207
00208
00209 slider->setFixedWidth( w - 20 );
00210 slider->setGeometry( QRect( 15, h - 22, w - 90, 20 ) );
00211 slider->setBackgroundOrigin( QWidget::ParentOrigin );
00212 slider->setFocusPolicy( QWidget::NoFocus );
00213 slider->setBackgroundPixmap( *pixBg );
00214
00215 xoff = 0;
00216 if(w>h)
00217 yoff = 0;
00218 else
00219 yoff = 185;
00220 QPoint p( xoff, yoff );
00221
00222 QPixmap *pixUp = combineVImageWithBackground( *imgUp, *pixBg, p );
00223 QPixmap *pixDn = combineVImageWithBackground( *imgDn, *pixBg, p );
00224
00225 for ( int i = 0; i < 7; i++ )
00226 {
00227 if ( !masks[i]->isNull() )
00228 {
00229 delete buttonPixUp[i];
00230 delete buttonPixDown[i];
00231 buttonPixUp[i] = maskVPixToMask( *pixUp, *masks[i] );
00232 buttonPixDown[i] = maskVPixToMask( *pixDn, *masks[i] );
00233 }
00234 }
00235
00236 delete pixUp;
00237 delete pixDn;
00238 }
00239
00240
00241 void VideoWidget::sliderPressed() {
00242 videoSliderBeingMoved = TRUE;
00243 }
00244
00245
00246 void VideoWidget::sliderReleased() {
00247 videoSliderBeingMoved = FALSE;
00248 if ( slider->width() == 0 )
00249 return;
00250 long val = long((double)slider->value() * mediaPlayerState->length() / slider->width());
00251 mediaPlayerState->setPosition( val );
00252 }
00253
00254
00255 void VideoWidget::setPosition( long i ) {
00256 updateSlider( i, mediaPlayerState->length() );
00257 }
00258
00259
00260 void VideoWidget::setLength( long max ) {
00261 updateSlider( mediaPlayerState->position(), max );
00262 }
00263
00264
00265 void VideoWidget::setView( char view ) {
00266 if ( view == 'v' )
00267 {
00268 makeVisible();
00269 }
00270 else
00271 {
00272
00273 scaledWidth = 0;
00274 scaledHeight = 0;
00275 hide();
00276 }
00277 }
00278
00279
00280 void VideoWidget::updateSlider( long i, long max ) {
00281
00282 if ( max == 0 )
00283 return;
00284 int width = slider->width();
00285 int val = int((double)i * width / max);
00286 if ( !mediaPlayerState->fullscreen() && !videoSliderBeingMoved )
00287 {
00288 if ( slider->value() != val )
00289 slider->setValue( val );
00290 if ( slider->maxValue() != width )
00291 slider->setMaxValue( width );
00292 }
00293 }
00294
00295
00296 void VideoWidget::setToggleButton( int i, bool down ) {
00297 if ( down != videoButtons[i].isDown )
00298 toggleButton( i );
00299 }
00300
00301
00302 void VideoWidget::toggleButton( int i ) {
00303 videoButtons[i].isDown = !videoButtons[i].isDown;
00304 QPainter p(this);
00305 paintButton ( &p, i );
00306 }
00307
00308
00309 void VideoWidget::paintButton( QPainter *p, int i ) {
00310 if ( videoButtons[i].isDown )
00311 {
00312 p->drawPixmap( xoff, yoff, *buttonPixDown[i] );
00313 }
00314 else
00315 {
00316 p->drawPixmap( xoff, yoff, *buttonPixUp[i] );
00317 }
00318 }
00319
00320
00321 void VideoWidget::mouseMoveEvent( QMouseEvent *event ) {
00322 for ( int i = 0; i < numVButtons; i++ ) {
00323 if ( event->state() == QMouseEvent::LeftButton ) {
00324
00325 int x = event->pos().x() - xoff;
00326 int y = event->pos().y() - yoff;
00327
00328 bool isOnButton = ( x > 0 && y > 0 && x < imgButtonMask->width()
00329 && y < imgButtonMask->height()
00330 && imgButtonMask->pixelIndex( x, y ) == i + 1 );
00331
00332 if ( isOnButton && !videoButtons[i].isHeld ) {
00333 videoButtons[i].isHeld = TRUE;
00334 toggleButton(i);
00335
00336 switch (i) {
00337 case VideoVolUp:
00338 emit moreClicked();
00339 return;
00340 case VideoVolDown:
00341 emit lessClicked();
00342 return;
00343 }
00344 } else if ( !isOnButton && videoButtons[i].isHeld ) {
00345 videoButtons[i].isHeld = FALSE;
00346 toggleButton(i);
00347 }
00348 } else {
00349
00350 if ( videoButtons[i].isHeld ) {
00351 videoButtons[i].isHeld = FALSE;
00352 if ( !videoButtons[i].isToggle ) {
00353 setToggleButton( i, FALSE );
00354 }
00355
00356 switch(i) {
00357
00358 case VideoPlay: {
00359
00360 if( !mediaPlayerState->playing()) {
00361 mediaPlayerState->setPlaying( true);
00362 setToggleButton( i-1, false );
00363 setToggleButton( i, false );
00364 return;
00365 }
00366 if( mediaPlayerState->isPaused ) {
00367
00368 setToggleButton( i, FALSE );
00369 mediaPlayerState->setPaused( FALSE );
00370 return;
00371 } else if( !mediaPlayerState->isPaused ) {
00372
00373 setToggleButton( i, TRUE );
00374 mediaPlayerState->setPaused( TRUE );
00375 return;
00376 } else {
00377 return;
00378 }
00379 }
00380
00381 case VideoStop: mediaPlayerState->setPlaying( FALSE ); setToggleButton( i+1, true); setToggleButton( i, true ); return;
00382 case VideoNext: mediaPlayerState->setNext(); return;
00383 case VideoPrevious: mediaPlayerState->setPrev(); return;
00384 case VideoVolUp: emit moreReleased(); return;
00385 case VideoVolDown: emit lessReleased(); return;
00386 case VideoFullscreen: mediaPlayerState->setFullscreen( TRUE ); makeVisible(); return;
00387 }
00388 }
00389 }
00390 }
00391 }
00392
00393
00394 void VideoWidget::mousePressEvent( QMouseEvent *event ) {
00395 mouseMoveEvent( event );
00396 }
00397
00398
00399 void VideoWidget::mouseReleaseEvent( QMouseEvent *event ) {
00400 if ( mediaPlayerState->fullscreen() )
00401 {
00402 mediaPlayerState->setFullscreen( FALSE );
00403 makeVisible();
00404 }
00405 mouseMoveEvent( event );
00406
00407 }
00408
00409
00410 void VideoWidget::makeVisible() {
00411 if ( mediaPlayerState->fullscreen() )
00412 {
00413 setBackgroundMode( QWidget::NoBackground );
00414 showFullScreen();
00415 resize( qApp->desktop()->size() );
00416 slider->hide();
00417 }
00418 else
00419 {
00420 setBackgroundPixmap( *pixBg );
00421 showNormal();
00422 QPEApplication::showWidget( this );
00423 slider->show();
00424 }
00425 }
00426
00427
00428 void VideoWidget::paintEvent( QPaintEvent * pe) {
00429 QPainter p( this );
00430
00431 if ( mediaPlayerState->fullscreen() ) {
00432
00433 p.setBrush( QBrush( Qt::black ) );
00434 p.drawRect( rect() );
00435 } else {
00436 if ( !pe->erased() ) {
00437
00438 QPixmap pix( pe->rect().size() );
00439 QPainter p( &pix );
00440 p.translate( -pe->rect().topLeft().x(), -pe->rect().topLeft().y() );
00441 p.drawTiledPixmap( pe->rect(), *pixBg, pe->rect().topLeft() );
00442 for ( int i = 0; i < numVButtons; i++ ) {
00443 paintButton( &p, i );
00444 }
00445 QPainter p2( this );
00446 p2.drawPixmap( pe->rect().topLeft(), pix );
00447 } else {
00448 QPainter p( this );
00449 for ( int i = 0; i < numVButtons; i++ )
00450 paintButton( &p, i );
00451 }
00452 slider->repaint( TRUE );
00453 }
00454 }
00455
00456
00457 void VideoWidget::closeEvent( QCloseEvent* ) {
00458 mediaPlayerState->setList();
00459 }
00460
00461
00462 bool VideoWidget::playVideo() {
00463 bool result = FALSE;
00464
00465 int stream = 0;
00466
00467 int sw = mediaPlayerState->curDecoder()->videoWidth( stream );
00468 int sh = mediaPlayerState->curDecoder()->videoHeight( stream );
00469 int dd = QPixmap::defaultDepth();
00470 int w = height();
00471 int h = width();
00472
00473 QWidget *d = QApplication::desktop();
00474 int d_width = d->width();
00475 int d_height = d->height();
00476
00477 ColorFormat format = (dd == 16) ? RGB565 : BGRA8888;
00478
00479 if ( mediaPlayerState->fullscreen() )
00480 {
00481 #ifdef USE_DIRECT_PAINTER
00482 QDirectPainter p(this);
00483
00484 if ( ( qt_screen->transformOrientation() == 3 ) &&
00485 ( ( dd == 16 ) || ( dd == 32 ) ) && ( p.numRects() == 1 ) )
00486 {
00487
00488 w = d_width;
00489 h = d_height;
00490
00491 if ( mediaPlayerState->scaled() )
00492 {
00493
00494 if ( w * sh > sw * h )
00495 w = sw * h / sh;
00496 else
00497 h = sh * w / sw;
00498 }
00499 else
00500 {
00501 w = sw;
00502 h = sh;
00503 }
00504
00505 w--;
00506 QPoint roff = qt_screen->mapToDevice( p.offset(), QSize( qt_screen->width(), qt_screen->height() ) );
00507
00508 int ox = roff.x() - height() + 2 + (height() - w) / 2;
00509 int oy = roff.y() + (width() - h) / 2;
00510 int sx = 0, sy = 0;
00511
00512 uchar* fp = p.frameBuffer() + p.lineStep() * oy;
00513 fp += dd * ox / 8;
00514 uchar **jt = new uchar*[h];
00515
00516 for ( int i = h; i; i-- )
00517 {
00518 jt[h - i] = fp;
00519 fp += p.lineStep();
00520 }
00521
00522 result = mediaPlayerState->curDecoder()->videoReadScaledFrame( jt, sx, sy, sw, sh, w, h, format, 0) == 0;
00523
00524 delete [] jt;
00525 }
00526 else
00527 {
00528 #endif
00529 QPainter p(this);
00530 w = d_width;
00531 h = d_height;
00532
00533 if ( mediaPlayerState->scaled() )
00534 {
00535
00536 if ( w * sh > sw * h )
00537 w = sw * h / sh;
00538 else
00539 h = sh * w / sw;
00540 }
00541 else
00542 {
00543 w = sw;
00544 h = sh;
00545 }
00546
00547 int bytes = ( dd == 16 ) ? 2 : 4;
00548 QImage tempFrame( w, h, bytes << 3 );
00549 result = mediaPlayerState->curDecoder()->videoReadScaledFrame( tempFrame.jumpTable(),
00550 0, 0, sw, sh, w, h, format, 0) == 0;
00551
00552 if ( result && mediaPlayerState->fullscreen() )
00553 {
00554
00555 int rw = h, rh = w;
00556 QImage rotatedFrame( rw, rh, bytes << 3 );
00557
00558 ushort* in = (ushort*)tempFrame.bits();
00559 ushort* out = (ushort*)rotatedFrame.bits();
00560 int spl = rotatedFrame.bytesPerLine() / bytes;
00561
00562 for (int x=0; x<h; x++)
00563 {
00564 if ( bytes == 2 )
00565 {
00566 ushort* lout = out++ + (w - 1)*spl;
00567 for (int y=0; y<w; y++) {
00568 *lout=*in++;
00569 lout-=spl;
00570 }
00571 }
00572 else
00573 {
00574 ulong* _out = (ulong *)out;
00575 ulong* lout = _out++ + (w - 1)*spl;
00576 for (int y=0; y<w; y++)
00577 {
00578 ulong *_in = (ulong*)in;
00579 *lout=*_in++;
00580 lout-=spl;
00581 }
00582 }
00583 }
00584
00585 p.drawImage( (240 - rw) / 2, (320 - rh) / 2, rotatedFrame, 0, 0, rw, rh );
00586 }
00587 #ifdef USE_DIRECT_PAINTER
00588 }
00589 #endif
00590 }
00591 else
00592 {
00593
00594 w = 220;
00595 h = 160;
00596
00597
00598 if ( w * sh > sw * h )
00599 w = sw * h / sh;
00600 else
00601 h = sh * w / sw;
00602
00603 result = mediaPlayerState->curDecoder()->videoReadScaledFrame( currentFrame->jumpTable(), 0, 0, sw, sh, w, h, format, 0) == 0;
00604
00605 QPainter p( this );
00606 int deskW = qApp->desktop()->width();
00607
00608 if ( scaledWidth != w || scaledHeight != h )
00609 {
00610 p.setBrush( QBrush( Qt::black ) );
00611 p.drawRect( ( deskW -scaledWidth)/2, 20, scaledWidth, 160 );
00612 }
00613
00614 scaledWidth = w;
00615 scaledHeight = h;
00616
00617 if ( result )
00618 {
00619 p.drawImage( (deskW - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
00620 }
00621
00622 }
00623
00624 return result;
00625 }
00626
00627
00628
00629 void VideoWidget::keyReleaseEvent( QKeyEvent *e)
00630 {
00631 switch ( e->key() )
00632 {
00634 case Key_Home:
00635 break;
00636 case Key_F9:
00637 break;
00638 case Key_F10:
00639
00640 break;
00641 case Key_F11:
00642 break;
00643 case Key_F12:
00644 break;
00645 case Key_F13:
00646 break;
00647 case Key_Space:
00648 {
00649 if(mediaPlayerState->playing())
00650 {
00651 mediaPlayerState->setPlaying(FALSE);
00652 }
00653 else
00654 {
00655 mediaPlayerState->setPlaying(TRUE);
00656 }
00657 }
00658 break;
00659 case Key_Down:
00660
00661
00662
00663
00664 break;
00665 case Key_Up:
00666
00667
00668
00669
00670 break;
00671 case Key_Right:
00672 mediaPlayerState->setNext();
00673 break;
00674 case Key_Left:
00675 mediaPlayerState->setPrev();
00676 break;
00677 case Key_Escape:
00678 break;
00679
00680 };
00681 }