diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-08-11 07:23:11 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-08-11 07:23:11 +0000 |
commit | 36e2ff4f28c8971e9eb5151389c342e88236e55f (patch) | |
tree | d4fb8ec55c9f15a8f96ee965b35077abdb86e17b /ksmserver/shutdowndlg.cpp | |
parent | ee8b709f80199ea546d69f0742f5325ea0c8c915 (diff) | |
download | tdebase-36e2ff4f28c8971e9eb5151389c342e88236e55f.tar.gz tdebase-36e2ff4f28c8971e9eb5151389c342e88236e55f.zip |
Allow logout screen to use compositing for fadeout in background if available
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1246376 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksmserver/shutdowndlg.cpp')
-rw-r--r-- | ksmserver/shutdowndlg.cpp | 441 |
1 files changed, 333 insertions, 108 deletions
diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp index 261793dcf..d8741da4b 100644 --- a/ksmserver/shutdowndlg.cpp +++ b/ksmserver/shutdowndlg.cpp @@ -78,8 +78,18 @@ KSMShutdownFeedback::KSMShutdownFeedback() m_greyImageCreated( FALSE ) { - DCOPRef("kicker", "KMenu").call("hideMenu"); // Make sure the K Menu is completely removed from the screen before taking a snapshot... - m_grayImage = TQPixmap(TQPixmap::grabWindow(qt_xrootwin(), 0, 0, TQApplication::desktop()->width(), TQApplication::desktop()->height())).convertToImage(); + if (kapp->isX11CompositionAvailable()) { + m_grayImage = TQImage( TQApplication::desktop()->width(), TQApplication::desktop()->height(), 32 ); + m_grayImage = m_grayImage.convertDepth(32); + m_grayImage.setAlphaBuffer(false); + m_grayImage.fill(0); // Set the alpha buffer to 0 (fully transparent) + m_grayImage.setAlphaBuffer(true); + } + else { + // The hacks below aren't needed any more because Qt3 supports true transparency for the fading logout screen when composition is available + DCOPRef("kicker", "KMenu").call("hideMenu"); // Make sure the K Menu is completely removed from the screen before taking a snapshot... + m_grayImage = TQPixmap(TQPixmap::grabWindow(qt_xrootwin(), 0, 0, TQApplication::desktop()->width(), TQApplication::desktop()->height())).convertToImage(); + } m_unfadedImage = m_grayImage; resize(0, 0); setShown(true); @@ -102,7 +112,7 @@ void KSMShutdownFeedback::fadeBack( void ) void KSMShutdownFeedback::slotPaintEffect() { // determine which fade to use - if (KConfigGroup(KGlobal::config(), "Logout").readBoolEntry("doFancyLogout", true)) + if (KConfigGroup(KGlobal::config(), "Logout").readBoolEntry("doFancyLogout", true)) { float doFancyLogoutAdditionalDarkness = (float)KConfigGroup(KGlobal::config(), "Logout").readDoubleNumEntry("doFancyLogoutAdditionalDarkness", 0.6); @@ -110,134 +120,348 @@ void KSMShutdownFeedback::slotPaintEffect() float doFancyLogoutFadeTime = (float)KConfigGroup(KGlobal::config(), "Logout").readDoubleNumEntry("doFancyLogoutFadeTime", 4000); float doFancyLogoutFadeBackTime = (float)KConfigGroup(KGlobal::config(), "Logout").readDoubleNumEntry("doFancyLogoutFadeBackTime", 1000); + + if (kapp->isX11CompositionAvailable()) { + // We can do this in a different (simpler) manner because we have compositing support! + // if slotPaintEffect() is called first time, we have to initialize the gray image + // we also could do that in the constructor, but then the displaying of the + // logout-UI would be too much delayed... + if ( m_greyImageCreated == false ) + { + m_greyImageCreated = true; + setBackgroundMode( TQWidget::NoBackground ); + setGeometry( TQApplication::desktop()->geometry() ); + m_root.resize( width(), height() ); // for the default logout - // if slotPaintEffect() is called first time, we have to initialize the gray image - // we also could do that in the constructor, but then the displaying of the - // logout-UI would be too much delayed... - if ( m_greyImageCreated == false ) - { - m_greyImageCreated = true; - setBackgroundMode( TQWidget::NoBackground ); - setGeometry( TQApplication::desktop()->geometry() ); - m_root.resize( width(), height() ); // for the default logout - - m_unfadedImage = m_grayImage.copy(); - register uchar * r = m_grayImage.bits(); - register uchar * g = m_grayImage.bits() + 1; - register uchar * b = m_grayImage.bits() + 2; - uchar * end = m_grayImage.bits() + m_grayImage.numBytes(); - - while ( r != end ) { - *r = *g = *b = (uchar) ( ( (*r)*11 + ((*g)<<4) + (*b)*5 ) * doFancyLogoutAdditionalDarkness / 32.0f ); - r += 4; - g += 4; - b += 4; - } - // start timer which is used for cpu-speed-independent fading - m_fadeTime.start(); - m_rowsDone = 0; - } + m_unfadedImage = m_grayImage.copy(); - // return if fading is completely done... - if ( ( m_grayOpacity >= 1.0f && m_fadeBackwards == FALSE ) || ( m_grayOpacity <= 0.0f && m_fadeBackwards == TRUE ) ) - return; + register uchar * r = m_grayImage.bits(); + uchar * end = m_grayImage.bits() + m_grayImage.numBytes(); + + while ( r != end ) { + *reinterpret_cast<TQRgb*>(r) = qRgba(0, 0, 0, 128); + r += 4; + } + // start timer which is used for cpu-speed-independent fading + m_fadeTime.start(); + m_rowsDone = 0; + } + + // return if fading is completely done... + if ( ( m_grayOpacity >= 1.0f && m_fadeBackwards == FALSE ) || ( m_grayOpacity <= 0.0f && m_fadeBackwards == TRUE ) ) + return; + + + if ( m_fadeBackwards == FALSE ) + { + m_grayOpacity = m_fadeTime.elapsed() / doFancyLogoutFadeTime; + if ( m_grayOpacity > 1.0f ) + m_grayOpacity = 1.0f; + } + else + { + m_grayOpacity = 1.0f - m_fadeTime.elapsed() / doFancyLogoutFadeBackTime - m_compensation; + if ( m_grayOpacity < 0.0f ) + m_grayOpacity = 0.0f; + } + + const int imgWidth = m_unfadedImage.width(); + int imgHeight = m_unfadedImage.height(); + int heightUnit = imgHeight / 3; + if( heightUnit < 1 ) + heightUnit = 1; - if ( m_fadeBackwards == FALSE ) - { - m_grayOpacity = m_fadeTime.elapsed() / doFancyLogoutFadeTime; - if ( m_grayOpacity > 1.0f ) - m_grayOpacity = 1.0f; - } - else - { - m_grayOpacity = 1.0f - m_fadeTime.elapsed() / doFancyLogoutFadeBackTime - m_compensation; - if ( m_grayOpacity < 0.0f ) - m_grayOpacity = 0.0f; + int y1 = static_cast<int>( imgHeight*m_grayOpacity - heightUnit + m_grayOpacity*heightUnit*2.0f ); + if( y1 > imgHeight ) + y1 = imgHeight; + + int y2 = y1+heightUnit; + if( y2 > imgHeight ) + y2 = imgHeight; + + if( m_fadeBackwards == FALSE ) + { + if( y1 > 0 && y1 < imgHeight && y1-m_rowsDone > 0 && m_rowsDone < imgHeight ) + { + TQImage img( imgWidth, y1-m_rowsDone, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( m_rowsDone ), imgWidth*(y1-m_rowsDone)*4 ); + bitBlt( this, 0, m_rowsDone, &img ); + m_rowsDone = y1; + } + } + else + { + // when fading back we have to blit area which isnt gray anymore to unfaded image + if( y2 > 0 && y2 < imgHeight && m_rowsDone > y2 ) + { + TQImage img( imgWidth, m_rowsDone-y2, 32 ); + memcpy( img.bits(), m_unfadedImage.scanLine( y2 ), imgWidth*(m_rowsDone-y2)*4 ); + bitBlt( this, 0, y2, &img ); + m_rowsDone = y2; + } + } + + int start_y1 = y1; + if( start_y1 < 0 ) + start_y1 = 0; + if( y2 > start_y1 ) + { + TQImage img( imgWidth, y2-start_y1, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 ); + register uchar * rs = m_unfadedImage.scanLine( start_y1 ); + register uchar * rd = img.bits(); + for( int y = start_y1; y < y2; ++y ) + { + // linear gradients look bad, so use cos-function + short int opac = static_cast<short int>( 128 - cosf( M_PI*(y-y1)/heightUnit )*128.0f ); + for( short int x = 0; x < imgWidth; ++x ) + { + *reinterpret_cast<TQRgb*>(rd) = qRgba(0, 0, 0, ((255.0-opac)/(255.0/127.0))); + rs += 4; rd += 4; + } + } + bitBlt( this, 0, start_y1, &img ); + } + + TQTimer::singleShot( 5, this, TQT_SLOT( slotPaintEffect() ) ); } + else { + // if slotPaintEffect() is called first time, we have to initialize the gray image + // we also could do that in the constructor, but then the displaying of the + // logout-UI would be too much delayed... + if ( m_greyImageCreated == false ) + { + m_greyImageCreated = true; + setBackgroundMode( TQWidget::NoBackground ); + setGeometry( TQApplication::desktop()->geometry() ); + m_root.resize( width(), height() ); // for the default logout - const int imgWidth = m_unfadedImage.width(); - int imgHeight = m_unfadedImage.height(); - int heightUnit = imgHeight / 3; - if( heightUnit < 1 ) - heightUnit = 1; - - int y1 = static_cast<int>( imgHeight*m_grayOpacity - heightUnit + m_grayOpacity*heightUnit*2.0f ); - if( y1 > imgHeight ) - y1 = imgHeight; + m_unfadedImage = m_grayImage.copy(); - int y2 = y1+heightUnit; - if( y2 > imgHeight ) - y2 = imgHeight; + register uchar * r = m_grayImage.bits(); + register uchar * g = m_grayImage.bits() + 1; + register uchar * b = m_grayImage.bits() + 2; + uchar * end = m_grayImage.bits() + m_grayImage.numBytes(); + + while ( r != end ) { + *r = *g = *b = (uchar) ( ( (*r)*11 + ((*g)<<4) + (*b)*5 ) * doFancyLogoutAdditionalDarkness / 32.0f ); + r += 4; + g += 4; + b += 4; + } - if( m_fadeBackwards == FALSE ) - { - if( y1 > 0 && y1 < imgHeight && y1-m_rowsDone > 0 && m_rowsDone < imgHeight ) + // start timer which is used for cpu-speed-independent fading + m_fadeTime.start(); + m_rowsDone = 0; + } + + // return if fading is completely done... + if ( ( m_grayOpacity >= 1.0f && m_fadeBackwards == FALSE ) || ( m_grayOpacity <= 0.0f && m_fadeBackwards == TRUE ) ) + return; + + + if ( m_fadeBackwards == FALSE ) { - TQImage img( imgWidth, y1-m_rowsDone, 32 ); - memcpy( img.bits(), m_grayImage.scanLine( m_rowsDone ), imgWidth*(y1-m_rowsDone)*4 ); - // conversion is slow as hell if desktop-depth != 24bpp... - //Pixmap pm = m_pmio.convertToPixmap( img ); - //bitBlt( this, 0, m_rowsDone, &pm ); -// TQImage pm = m_pmio.convertToImage( img ); - bitBlt( this, 0, m_rowsDone, &img ); - m_rowsDone = y1; + m_grayOpacity = m_fadeTime.elapsed() / doFancyLogoutFadeTime; + if ( m_grayOpacity > 1.0f ) + m_grayOpacity = 1.0f; } - } - else - { - // when fading back we have to blit area which isnt gray anymore to unfaded image - if( y2 > 0 && y2 < imgHeight && m_rowsDone > y2 ) + else { - TQImage img( imgWidth, m_rowsDone-y2, 32 ); - memcpy( img.bits(), m_unfadedImage.scanLine( y2 ), imgWidth*(m_rowsDone-y2)*4 ); - // conversion is slow as hell if desktop-depth != 24bpp... - //TQPixmap pm = m_pmio.convertToPixmap( img ); - //bitBlt( this, 0, y2, &pm ); - bitBlt( this, 0, y2, &img ); - m_rowsDone = y2; + m_grayOpacity = 1.0f - m_fadeTime.elapsed() / doFancyLogoutFadeBackTime - m_compensation; + if ( m_grayOpacity < 0.0f ) + m_grayOpacity = 0.0f; } - } + + const int imgWidth = m_unfadedImage.width(); + int imgHeight = m_unfadedImage.height(); + int heightUnit = imgHeight / 3; + if( heightUnit < 1 ) + heightUnit = 1; - int start_y1 = y1; - if( start_y1 < 0 ) - start_y1 = 0; - if( y2 > start_y1 ) - { - TQImage img( imgWidth, y2-start_y1, 32 ); - memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 ); - register uchar * rs = m_unfadedImage.scanLine( start_y1 ); - register uchar * gs = rs + 1; - register uchar * bs = gs + 1; - register uchar * rd = img.bits(); - register uchar * gd = rd + 1; - register uchar * bd = gd + 1; - for( int y = start_y1; y < y2; ++y ) + int y1 = static_cast<int>( imgHeight*m_grayOpacity - heightUnit + m_grayOpacity*heightUnit*2.0f ); + if( y1 > imgHeight ) + y1 = imgHeight; + + int y2 = y1+heightUnit; + if( y2 > imgHeight ) + y2 = imgHeight; + + if( m_fadeBackwards == FALSE ) { - // linear gradients look bad, so use cos-function - short int opac = static_cast<short int>( 128 - cosf( M_PI*(y-y1)/heightUnit )*128.0f ); - for( short int x = 0; x < imgWidth; ++x ) + if( y1 > 0 && y1 < imgHeight && y1-m_rowsDone > 0 && m_rowsDone < imgHeight ) + { + TQImage img( imgWidth, y1-m_rowsDone, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( m_rowsDone ), imgWidth*(y1-m_rowsDone)*4 ); + // conversion is slow as hell if desktop-depth != 24bpp... + //Pixmap pm = m_pmio.convertToPixmap( img ); + //bitBlt( this, 0, m_rowsDone, &pm ); + //TQImage pm = m_pmio.convertToImage( img ); + bitBlt( this, 0, m_rowsDone, &img ); + m_rowsDone = y1; + } + } + else { - *rd += ( ( ( *rs - *rd ) * opac ) >> 8 ); - rs += 4; rd += 4; - *gd += ( ( ( *gs - *gd ) * opac ) >> 8 ); - gs += 4; gd += 4; - *bd += ( ( ( *bs - *bd ) * opac ) >> 8 ); - bs += 4; bd += 4; + // when fading back we have to blit area which isnt gray anymore to unfaded image + if( y2 > 0 && y2 < imgHeight && m_rowsDone > y2 ) + { + TQImage img( imgWidth, m_rowsDone-y2, 32 ); + memcpy( img.bits(), m_unfadedImage.scanLine( y2 ), imgWidth*(m_rowsDone-y2)*4 ); + // conversion is slow as hell if desktop-depth != 24bpp... + //TQPixmap pm = m_pmio.convertToPixmap( img ); + //bitBlt( this, 0, y2, &pm ); + bitBlt( this, 0, y2, &img ); + m_rowsDone = y2; + } } + + int start_y1 = y1; + if( start_y1 < 0 ) + start_y1 = 0; + if( y2 > start_y1 ) + { + TQImage img( imgWidth, y2-start_y1, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 ); + register uchar * rs = m_unfadedImage.scanLine( start_y1 ); + register uchar * gs = rs + 1; + register uchar * bs = gs + 1; + register uchar * rd = img.bits(); + register uchar * gd = rd + 1; + register uchar * bd = gd + 1; + for( int y = start_y1; y < y2; ++y ) + { + // linear gradients look bad, so use cos-function + short int opac = static_cast<short int>( 128 - cosf( M_PI*(y-y1)/heightUnit )*128.0f ); + for( short int x = 0; x < imgWidth; ++x ) + { + *rd += ( ( ( *rs - *rd ) * opac ) >> 8 ); + rs += 4; rd += 4; + *gd += ( ( ( *gs - *gd ) * opac ) >> 8 ); + gs += 4; gd += 4; + *bd += ( ( ( *bs - *bd ) * opac ) >> 8 ); + bs += 4; bd += 4; + } + } + // conversion is slow as hell if desktop-depth != 24bpp... + //TQPixmap pm = m_pmio.convertToPixmap( img ); + //bitBlt( this, 0, start_y1, &pm ); + bitBlt( this, 0, start_y1, &img ); } - // conversion is slow as hell if desktop-depth != 24bpp... - //TQPixmap pm = m_pmio.convertToPixmap( img ); - //bitBlt( this, 0, start_y1, &pm ); - bitBlt( this, 0, start_y1, &img ); + + TQTimer::singleShot( 5, this, TQT_SLOT( slotPaintEffect() ) ); } - - TQTimer::singleShot( 5, this, TQT_SLOT( slotPaintEffect() ) ); } // standard logout fade else { + if (kapp->isX11CompositionAvailable()) { + // We can do this in a different (simpler) manner because we have compositing support! + // The end effect will be very similar to the old style logout + float doFancyLogoutFadeTime = 1000; + float doFancyLogoutFadeBackTime = 0; + if ( m_greyImageCreated == false ) + { + m_greyImageCreated = true; + setBackgroundMode( TQWidget::NoBackground ); + setGeometry( TQApplication::desktop()->geometry() ); + m_root.resize( width(), height() ); // for the default logout + + m_unfadedImage = m_grayImage.copy(); + + register uchar * r = m_grayImage.bits(); + uchar * end = m_grayImage.bits() + m_grayImage.numBytes(); + + while ( r != end ) { + *reinterpret_cast<TQRgb*>(r) = qRgba(0, 0, 0, 107); + r += 4; + } + + // start timer which is used for cpu-speed-independent fading + m_fadeTime.start(); + m_rowsDone = 0; + } + + // return if fading is completely done... + if ( ( m_grayOpacity >= 1.0f && m_fadeBackwards == FALSE ) || ( m_grayOpacity <= 0.0f && m_fadeBackwards == TRUE ) ) + return; + + + if ( m_fadeBackwards == FALSE ) + { + m_grayOpacity = m_fadeTime.elapsed() / doFancyLogoutFadeTime; + if ( m_grayOpacity > 1.0f ) + m_grayOpacity = 1.0f; + } + else + { + m_grayOpacity = 1.0f - m_fadeTime.elapsed() / doFancyLogoutFadeBackTime - m_compensation; + if ( m_grayOpacity < 0.0f ) + m_grayOpacity = 0.0f; + } + + const int imgWidth = m_unfadedImage.width(); + int imgHeight = m_unfadedImage.height(); + int heightUnit = imgHeight / 3; + if( heightUnit < 1 ) + heightUnit = 1; + + int y1 = static_cast<int>( imgHeight*m_grayOpacity - heightUnit + m_grayOpacity*heightUnit*2.0f ); + if( y1 > imgHeight ) + y1 = imgHeight; + + int y2 = y1+heightUnit; + if( y2 > imgHeight ) + y2 = imgHeight; + + if( m_fadeBackwards == FALSE ) + { + if( y1 > 0 && y1 < imgHeight && y1-m_rowsDone > 0 && m_rowsDone < imgHeight ) + { + TQImage img( imgWidth, y1-m_rowsDone, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( m_rowsDone ), imgWidth*(y1-m_rowsDone)*4 ); + bitBlt( this, 0, m_rowsDone, &img ); + m_rowsDone = y1; + } + } + else + { + // when fading back we have to blit area which isnt gray anymore to unfaded image + if( y2 > 0 && y2 < imgHeight && m_rowsDone > y2 ) + { + TQImage img( imgWidth, m_rowsDone-y2, 32 ); + memcpy( img.bits(), m_unfadedImage.scanLine( y2 ), imgWidth*(m_rowsDone-y2)*4 ); + bitBlt( this, 0, y2, &img ); + m_rowsDone = y2; + } + } + + int start_y1 = y1; + if( start_y1 < 0 ) + start_y1 = 0; + if( y2 > start_y1 ) + { + TQImage img( imgWidth, y2-start_y1, 32 ); + memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 ); + register uchar * rs = m_unfadedImage.scanLine( start_y1 ); + register uchar * rd = img.bits(); + for( int y = start_y1; y < y2; ++y ) + { + // linear gradients look bad, so use cos-function + for( short int x = 0; x < imgWidth; ++x ) + { + *reinterpret_cast<TQRgb*>(rd) = qRgba(0, 0, 0, 107); + rs += 4; rd += 4; + } + } + bitBlt( this, 0, start_y1, &img ); + } + + TQTimer::singleShot( 1, this, TQT_SLOT( slotPaintEffect() ) ); + } + else { if ( m_currentY >= height() ) { if ( backgroundMode() == TQWidget::NoBackground ) { setBackgroundMode( TQWidget::NoBackground ); @@ -256,6 +480,7 @@ void KSMShutdownFeedback::slotPaintEffect() bitBlt( &m_root, 0, m_currentY, &pixmap ); m_currentY += 10; TQTimer::singleShot( 1, this, TQT_SLOT( slotPaintEffect() ) ); + } } } |