diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a1305526e..be2a18cb0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ set(kwin_KDEINIT_SRCS effects/boxswitch.cpp effects/fallapart.cpp effects/drunken.cpp + effects/flame.cpp effects/test_input.cpp effects/test_thumbnail.cpp ) diff --git a/effects.cpp b/effects.cpp index 47ac3f1a61..2d50ca7077 100644 --- a/effects.cpp +++ b/effects.cpp @@ -33,6 +33,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "effects/videorecord.h" #endif #ifdef HAVE_OPENGL +#include "effects/flame.h" #include "effects/fallapart.h" #include "effects/wavywindows.h" #endif @@ -194,6 +195,7 @@ EffectsHandler::EffectsHandler() registerEffect("Fade", new GenericEffectFactory); registerEffect("ScaleIn", new GenericEffectFactory); registerEffect("FallApart", new GenericEffectFactory); + registerEffect("Flame", new GenericEffectFactory); registerEffect("DialogParent", new GenericEffectFactory); registerEffect("DesktopChangeSlide", new GenericEffectFactory); registerEffect("BoxSwitch", new GenericEffectFactory); diff --git a/effects/flame.cpp b/effects/flame.cpp new file mode 100644 index 0000000000..6920ddad0a --- /dev/null +++ b/effects/flame.cpp @@ -0,0 +1,109 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#include "flame.h" + +#include +#include + +namespace KWinInternal +{ + +void FlameEffect::prePaintScreen( int* mask, QRegion* region, int time ) + { + if( !windows.isEmpty()) + *mask |= Scene::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen(mask, region, time); + } + +void FlameEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time ) + { + if( windows.contains( w )) + { + SceneOpenGL::Window* glwin = dynamic_cast< SceneOpenGL::Window* >( w->sceneWindow()); + if( glwin ) + { + if( windows[ w ] < 1 ) + { + windows[ w ] += time / 500.; + *mask |= Scene::PAINT_WINDOW_TRANSFORMED; + glwin->enablePainting( Scene::Window::PAINT_DISABLED_BY_DELETE ); + // Request the window to be divided into cells + glwin->requestVertexGrid( qMax( glwin->height() / 50, 5 )); + } + else + { + windows.remove( w ); + static_cast< Deleted* >( w->window())->unrefWindow(); + } + } + } + effects->prePaintWindow( w, mask, region, time ); + } + +void FlameEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) + { + if( windows.contains( w )) + { + SceneOpenGL::Window* glwin = dynamic_cast< SceneOpenGL::Window* >( w->sceneWindow() ); + if( glwin ) + { + QVector< SceneOpenGL::Window::Vertex >& vertices = glwin->vertices(); + QVector< SceneOpenGL::Window::Vertex > new_vertices; + double ylimit = windows[ w ] * w->height(); // parts above this are already away + assert( vertices.count() % 4 == 0 ); + for( int i = 0; + i < vertices.count(); + i += 4 ) + { + bool is_in = false; + for( int j = 0; + j < 4; + ++j ) + if( vertices[ i + j ].pos[ 1 ] >= ylimit ) + is_in = true; + if( !is_in ) + continue; + for( int j = 0; + j < 4; + ++j ) + { + SceneOpenGL::Window::Vertex vertex = vertices[ i + j ]; + new_vertices.append( vertex ); + } + } + if( new_vertices.isEmpty()) + return; // nothing to paint + glwin->vertices() = new_vertices; + glwin->markVerticesDirty(); + } + } + effects->paintWindow( w, mask, region, data ); + } + +void FlameEffect::postPaintWindow( EffectWindow* w ) + { + if( windows.contains( w )) + workspace()->addRepaint( w->geometry()); // workspace, since the window under it will need painting too + effects->postPaintScreen(); + } + +void FlameEffect::windowClosed( EffectWindow* c ) + { + windows[ c ] = 0; + static_cast< Deleted* >( c->window())->refWindow(); + } + +void FlameEffect::windowDeleted( EffectWindow* c ) + { + windows.remove( c ); + } + +} // namespace diff --git a/effects/flame.h b/effects/flame.h new file mode 100644 index 0000000000..03c9fa8e15 --- /dev/null +++ b/effects/flame.h @@ -0,0 +1,35 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Lubos Lunak + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_FLAME_H +#define KWIN_FLAME_H + +#include + +namespace KWinInternal +{ + +class FlameEffect + : public Effect + { + public: + virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time ); + virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); + virtual void postPaintWindow( EffectWindow* w ); + virtual void windowClosed( EffectWindow* c ); + virtual void windowDeleted( EffectWindow* c ); + private: + QHash< const EffectWindow*, double > windows; + }; + +} // namespace + +#endif