Twin view support for cube. Cube is painted on one screen and scaled so that both screens fit on it. Projection matrix has unfortunatelly to be changed in twin view mode.
svn path=/trunk/KDE/kdebase/workspace/; revision=842026
This commit is contained in:
parent
7f8b7e78f6
commit
d719718780
2 changed files with 140 additions and 29 deletions
166
effects/cube.cpp
166
effects/cube.cpp
|
@ -69,6 +69,7 @@ CubeEffect::CubeEffect()
|
|||
, reflectionPainting( false )
|
||||
, slide( false )
|
||||
, oldDesktop( 0 )
|
||||
, activeScreen( 0 )
|
||||
{
|
||||
KConfigGroup conf = effects->effectConfig( "Cube" );
|
||||
borderActivate = (ElectricBorder)conf.readEntry( "BorderActivate", (int)ElectricNone );
|
||||
|
@ -155,7 +156,8 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
if( activated )
|
||||
{
|
||||
//kDebug();
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), effects->currentDesktop());
|
||||
QRect rect = effects->clientArea( FullScreenArea, activeScreen, effects->currentDesktop());
|
||||
QRect fullRect = effects->clientArea( FullArea, activeScreen, effects->currentDesktop() );
|
||||
|
||||
// background
|
||||
float clearColor[4];
|
||||
|
@ -165,7 +167,7 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
glClearColor( clearColor[0], clearColor[1], clearColor[2], clearColor[3] );
|
||||
|
||||
// wallpaper
|
||||
if( wallpaper )
|
||||
if( wallpaper && !slide )
|
||||
{
|
||||
wallpaper->bind();
|
||||
wallpaper->render( region, rect );
|
||||
|
@ -176,11 +178,66 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
if( effects->numScreens() > 1 )
|
||||
{
|
||||
windowsOnOtherScreens.clear();
|
||||
// unfortunatelly we have to change the projection matrix in dual screen mode
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
float fovy = 60.0f;
|
||||
float aspect = 1.0f;
|
||||
float zNear = 0.1f;
|
||||
float zFar = 100.0f;
|
||||
float ymax = zNear * tan( fovy * M_PI / 360.0f );
|
||||
float ymin = -ymax;
|
||||
float xmin = ymin * aspect;
|
||||
float xmax = ymax * aspect;
|
||||
float xTranslate = 0.0;
|
||||
float yTranslate = 0.0;
|
||||
bool projectionSet = false;
|
||||
if( rect.x() == 0 && rect.width() != fullRect.width() )
|
||||
{
|
||||
// horizontal layout: left screen
|
||||
glFrustum( xmin*0.5, xmax*1.5, ymin, ymax, zNear, zFar );
|
||||
xTranslate = rect.width()*0.5;
|
||||
projectionSet = true;
|
||||
}
|
||||
if( rect.x() != 0 && rect.width() != fullRect.width() )
|
||||
{
|
||||
// horizontal layout: right screen
|
||||
glFrustum( xmin*1.5, xmax*0.5, ymin, ymax, zNear, zFar );
|
||||
xTranslate = rect.width()*0.5;
|
||||
projectionSet = true;
|
||||
}
|
||||
if( rect.y() == 0 && rect.height() != fullRect.height() )
|
||||
{
|
||||
glFrustum( xmin, xmax, ymin*1.5, ymax*0.5, zNear, zFar );
|
||||
yTranslate = rect.height()*0.5;
|
||||
projectionSet = true;
|
||||
}
|
||||
if( rect.y() != 0 && rect.height() != fullRect.height() )
|
||||
{
|
||||
glFrustum( xmin, xmax, ymin*0.5, ymax*1.5, zNear, zFar );
|
||||
yTranslate = rect.height()*0.5;
|
||||
projectionSet = true;
|
||||
}
|
||||
if( !projectionSet )
|
||||
{
|
||||
// this should never happen; nevertheless reset the projection to the default
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
}
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPushMatrix();
|
||||
glTranslatef( xTranslate, yTranslate, 0.0 );
|
||||
}
|
||||
|
||||
// reflection
|
||||
if( reflection && (!slide) )
|
||||
{
|
||||
glPushMatrix();
|
||||
float scaleFactor = 6100 * tan( 60.0 * M_PI / 360.0f )/rect.height();
|
||||
float scaleFactor = 10000 * tan( 60.0 * M_PI / 360.0f )/rect.height();
|
||||
glScalef( 1.0, -1.0, 1.0 );
|
||||
glTranslatef( 0.0, -rect.height()*2, 0.0 );
|
||||
|
||||
|
@ -193,11 +250,16 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef( 0.0, rect.height(), 0.0 );
|
||||
if( effects->numScreens() > 1 && rect.width() != fullRect.width() )
|
||||
{
|
||||
// have to change the reflection area in horizontal layout and right screen
|
||||
glTranslatef( -rect.width(), 0.0, 0.0 );
|
||||
}
|
||||
float vertices[] = {
|
||||
0.0, 0.0, 0.0,
|
||||
rect.width(), 0.0, 0.0,
|
||||
rect.width()*scaleFactor, 0.0, -5000,
|
||||
-rect.width()*scaleFactor, 0.0, -5000 };
|
||||
rect.x(), 0.0, 0.0,
|
||||
rect.x()+rect.width(), 0.0, 0.0,
|
||||
(rect.x()+rect.width())*scaleFactor, 0.0, -5000,
|
||||
(-rect.x()-rect.width())*scaleFactor, 0.0, -5000 };
|
||||
// foreground
|
||||
float alpha = 0.7;
|
||||
if( start )
|
||||
|
@ -220,6 +282,15 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
paintScene( mask, region, data );
|
||||
glPopMatrix();
|
||||
|
||||
if( effects->numScreens() > 1 )
|
||||
{
|
||||
glPopMatrix();
|
||||
// revert change of projection matrix
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPopMatrix();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
}
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glPopAttrib();
|
||||
|
||||
|
@ -262,6 +333,18 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
{
|
||||
effects->paintScreen( mask, region, data );
|
||||
}
|
||||
if( effects->numScreens() > 1 )
|
||||
{
|
||||
foreach( EffectWindow* w, windowsOnOtherScreens )
|
||||
{
|
||||
WindowPaintData wData( w );
|
||||
if( start && !w->isDesktop() && !w->isDock() )
|
||||
wData.opacity *= (1.0 - timeLine.value());
|
||||
if( stop && !w->isDesktop() && !w->isDock() )
|
||||
wData.opacity *= timeLine.value();
|
||||
effects->paintWindow( w, 0, QRegion( w->x(), w->y(), w->width(), w->height() ), wData );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -271,7 +354,35 @@ void CubeEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|||
|
||||
void CubeEffect::paintScene( int mask, QRegion region, ScreenPaintData& data )
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), effects->currentDesktop());
|
||||
QRect rect = effects->clientArea( FullScreenArea, activeScreen, effects->currentDesktop());
|
||||
float xScale = 1.0;
|
||||
float yScale = 1.0;
|
||||
if( effects->numScreens() > 1 )
|
||||
{
|
||||
QRect fullRect = effects->clientArea( FullArea, activeScreen, effects->currentDesktop() );
|
||||
xScale = (float)rect.width()/(float)fullRect.width();
|
||||
yScale = (float)rect.height()/(float)fullRect.height();
|
||||
if( start )
|
||||
{
|
||||
xScale = xScale + (1.0 - xScale) * (1.0 - timeLine.value());
|
||||
yScale = yScale + (1.0 - yScale) * (1.0 - timeLine.value());
|
||||
if( rect.x() > 0 )
|
||||
glTranslatef( -rect.x()*(1.0 - timeLine.value()), 0.0, 0.0 );
|
||||
if( rect.y() > 0 )
|
||||
glTranslatef( 0.0, -rect.y()*(1.0 - timeLine.value()), 0.0 );
|
||||
}
|
||||
if( stop )
|
||||
{
|
||||
xScale = xScale + (1.0 - xScale) * timeLine.value();
|
||||
yScale = yScale + (1.0 - yScale) * timeLine.value();
|
||||
if( rect.x() > 0 )
|
||||
glTranslatef( -rect.x()*timeLine.value(), 0.0, 0.0 );
|
||||
if( rect.y() > 0 )
|
||||
glTranslatef( 0.0, -rect.y()*timeLine.value(), 0.0 );
|
||||
}
|
||||
glScalef( xScale, yScale, 1.0 );
|
||||
rect = fullRect;
|
||||
}
|
||||
int rightSteps = effects->numberOfDesktops()/2;
|
||||
int leftSteps = rightSteps+1;
|
||||
int rightSideCounter = 0;
|
||||
|
@ -576,7 +687,7 @@ void CubeEffect::paintScene( int mask, QRegion region, ScreenPaintData& data )
|
|||
|
||||
void CubeEffect::paintCap( float z, float zTexture )
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), effects->currentDesktop());
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, effects->currentDesktop());
|
||||
if( ( !paintCaps ) || effects->numberOfDesktops() <= 2 )
|
||||
return;
|
||||
float opacity = cubeOpacity;
|
||||
|
@ -795,9 +906,18 @@ void CubeEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int
|
|||
//kDebug();
|
||||
if( cube_painting )
|
||||
{
|
||||
if( ( w->isDesktop() || w->isDock() ) && w->screen() != activeScreen && w->isOnDesktop( effects->currentDesktop() ) )
|
||||
{
|
||||
windowsOnOtherScreens.append( w );
|
||||
}
|
||||
if( (start || stop) && w->screen() != activeScreen && w->isOnDesktop( effects->currentDesktop() )
|
||||
&& !w->isDesktop() && !w->isDock() )
|
||||
{
|
||||
windowsOnOtherScreens.append( w );
|
||||
}
|
||||
if( w->isOnDesktop( painting_desktop ))
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), painting_desktop );
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, painting_desktop );
|
||||
if( w->x() < rect.x() )
|
||||
{
|
||||
data.quads = data.quads.splitAtX( -w->x() );
|
||||
|
@ -824,7 +944,7 @@ void CubeEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int
|
|||
prev_desktop = effects->numberOfDesktops();
|
||||
if( w->isOnDesktop( prev_desktop ) )
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), prev_desktop);
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, prev_desktop);
|
||||
if( w->x()+w->width() > rect.x() + rect.width() )
|
||||
{
|
||||
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
||||
|
@ -848,7 +968,7 @@ void CubeEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int
|
|||
next_desktop = 1;
|
||||
if( w->isOnDesktop( next_desktop ) )
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), next_desktop);
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, next_desktop);
|
||||
if( w->x() < rect.x() )
|
||||
{
|
||||
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
||||
|
@ -919,7 +1039,7 @@ void CubeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowP
|
|||
next_desktop = 1;
|
||||
if( w->isOnDesktop( prev_desktop ) && ( mask & PAINT_WINDOW_TRANSFORMED ) )
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), prev_desktop);
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, prev_desktop);
|
||||
data.xTranslate = -rect.width();
|
||||
WindowQuadList new_quads;
|
||||
foreach( WindowQuad quad, data.quads )
|
||||
|
@ -933,7 +1053,7 @@ void CubeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowP
|
|||
}
|
||||
if( w->isOnDesktop( next_desktop ) && ( mask & PAINT_WINDOW_TRANSFORMED ) )
|
||||
{
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), next_desktop);
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, next_desktop);
|
||||
data.xTranslate = rect.width();
|
||||
WindowQuadList new_quads;
|
||||
foreach( WindowQuad quad, data.quads )
|
||||
|
@ -945,7 +1065,7 @@ void CubeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowP
|
|||
}
|
||||
data.quads = new_quads;
|
||||
}
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), painting_desktop );
|
||||
QRect rect = effects->clientArea( FullArea, activeScreen, painting_desktop );
|
||||
|
||||
if( start || stop )
|
||||
{
|
||||
|
@ -1020,17 +1140,6 @@ void CubeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowP
|
|||
effects->paintWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
void CubeEffect::postPaintWindow( EffectWindow* w )
|
||||
{
|
||||
if( activated && !cube_painting )
|
||||
{
|
||||
// a window was updated which has not been handled by cube_painting.
|
||||
// trigger full repaint, so that this window will be updated
|
||||
//effects->addRepaintFull();
|
||||
}
|
||||
effects->postPaintWindow( w );
|
||||
}
|
||||
|
||||
bool CubeEffect::borderActivated( ElectricBorder border )
|
||||
{
|
||||
if( effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this )
|
||||
|
@ -1246,6 +1355,7 @@ void CubeEffect::setActive( bool active )
|
|||
if( active )
|
||||
{
|
||||
activated = true;
|
||||
activeScreen = effects->activeScreen();
|
||||
if( !slide )
|
||||
{
|
||||
keyboard_grab = effects->grabKeyboard( this );
|
||||
|
@ -1265,7 +1375,7 @@ void CubeEffect::setActive( bool active )
|
|||
// clip parts above the reflection area
|
||||
double eqn[4] = {0.0, 1.0, 0.0, 0.0};
|
||||
glPushMatrix();
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), effects->currentDesktop());
|
||||
QRect rect = effects->clientArea( FullScreenArea, activeScreen, effects->currentDesktop());
|
||||
glTranslatef( 0.0, rect.height(), 0.0 );
|
||||
glClipPlane( GL_CLIP_PLANE0, eqn );
|
||||
glPopMatrix();
|
||||
|
@ -1287,7 +1397,7 @@ void CubeEffect::mouseChanged( const QPoint& pos, const QPoint& oldpos, Qt::Mous
|
|||
return;
|
||||
if( stop || slide )
|
||||
return;
|
||||
QRect rect = effects->clientArea( FullArea, effects->activeScreen(), effects->currentDesktop());
|
||||
QRect rect = effects->clientArea( FullScreenArea, activeScreen, effects->currentDesktop());
|
||||
if( buttons.testFlag( Qt::LeftButton ) )
|
||||
{
|
||||
bool repaint = false;
|
||||
|
|
|
@ -41,7 +41,6 @@ class CubeEffect
|
|||
virtual void postPaintScreen();
|
||||
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w);
|
||||
virtual bool borderActivated( ElectricBorder border );
|
||||
virtual void grabbedKeyboardEvent( QKeyEvent* e );
|
||||
virtual void mouseChanged( const QPoint& pos, const QPoint& oldpos, Qt::MouseButtons buttons,
|
||||
|
@ -103,6 +102,8 @@ class CubeEffect
|
|||
bool slide;
|
||||
int oldDesktop;
|
||||
int rotationDuration;
|
||||
QList<EffectWindow*> windowsOnOtherScreens;
|
||||
int activeScreen;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in a new issue