From 391bb6b28d5103ac641f0b6471940919db0801f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Thu, 6 Jul 2006 09:55:10 +0000 Subject: [PATCH] Support for effects that affect opacity. svn path=/branches/work/kwin_composite/; revision=558921 --- effects.cpp | 21 ++++++++++++++++++++- effects.h | 1 + scene_xrender.cpp | 26 ++++++++++++++++++++++++-- scene_xrender.h | 5 +++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/effects.cpp b/effects.cpp index c12b9ba93a..d551f8a446 100644 --- a/effects.cpp +++ b/effects.cpp @@ -65,6 +65,24 @@ void Effect::paintWorkspace( Workspace*, EffectData& ) // EffectsHandler //**************************************** +class MakeHalfTransparent + : public Effect + { + public: + virtual void paintWindow( Toplevel* c, EffectData& data ); + }; + +void MakeHalfTransparent::paintWindow( Toplevel*, EffectData& data ) + { + data.opacity *= 0.8; + } + +static MakeHalfTransparent* mht; +EffectsHandler::EffectsHandler() + { + mht = new MakeHalfTransparent; + } + void EffectsHandler::windowUserMoved( Toplevel* ) { } @@ -73,8 +91,9 @@ void EffectsHandler::windowUserResized( Toplevel* ) { } -void EffectsHandler::paintWindow( Toplevel*, EffectData& ) +void EffectsHandler::paintWindow( Toplevel* c, EffectData& data ) { + mht->paintWindow( c, data ); } void EffectsHandler::paintWorkspace( Workspace*, EffectData& ) diff --git a/effects.h b/effects.h index 66d8ace60a..775ffe58e8 100644 --- a/effects.h +++ b/effects.h @@ -46,6 +46,7 @@ class Effect class EffectsHandler { public: + EffectsHandler(); void windowUserMoved( Toplevel* c ); void windowUserResized( Toplevel* c ); void paintWindow( Toplevel* c, EffectData& data ); diff --git a/scene_xrender.cpp b/scene_xrender.cpp index 99f6088463..5653e15810 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -13,6 +13,7 @@ License. See the file "COPYING" for the exact licensing terms. #ifdef HAVE_XRENDER #include "toplevel.h" +#include "effects.h" namespace KWinInternal { @@ -43,6 +44,14 @@ SceneXrender::~SceneXrender() void SceneXrender::paint( XserverRegion damage ) { +#if 0 + XRectangle r; + r.x = 0; + r.y = 0; + r.width = displayWidth(); + r.height = displayHeight(); + XFixesSetRegion( display(), damage, &r, 1 ); +#endif // Use the damage region as the clip region for the root window XFixesSetPictureClipRegion( display(), front, 0, 0, damage ); // Client list for clients that are either translucent or have a shadow @@ -55,6 +64,7 @@ void SceneXrender::paint( XserverRegion damage ) { Toplevel* c = windows[ i ]; checkWindowData( c ); + effects->paintWindow( c, window_data[ c ].effect ); if( isOpaque( c )) { Picture picture = windowPicture( c ); @@ -91,9 +101,11 @@ void SceneXrender::paint( XserverRegion damage ) Picture picture = windowPicture( c ); Picture alpha = windowAlphaMask( c ); if( picture != None ) + { // TODO clip also using shape? also above? XRenderComposite( display(), PictOpOver, picture, alpha, buffer, 0, 0, 0, 0, c->x(), c->y(), c->width(), c->height()); + } } XFixesDestroyRegion( display(), r ); } @@ -110,6 +122,9 @@ void SceneXrender::checkWindowData( Toplevel* c ) window_data[ c ] = WindowData(); window_data[ c ].format = XRenderFindVisualFormat( display(), c->visual()); } + WindowData& data = window_data[ c ]; + data.effect.matrix = Matrix(); + data.effect.opacity = c->opacity(); } void SceneXrender::windowGeometryShapeChanged( Toplevel* c ) @@ -174,7 +189,7 @@ bool SceneXrender::isOpaque( Toplevel* c ) const const WindowData& data = window_data[ c ]; if( data.format->type == PictTypeDirect && data.format->direct.alphaMask ) return false; - if( c->opacity() != 1.0 ) + if( data.effect.opacity != 1.0 ) return false; return true; } @@ -184,6 +199,12 @@ Picture SceneXrender::windowAlphaMask( Toplevel* c ) if( isOpaque( c )) return None; WindowData& data = window_data[ c ]; + if( data.alpha != None && data.alpha_cached_opacity != data.effect.opacity ) + { + if( data.alpha != None ) + XRenderFreePicture( display(), data.alpha ); + data.alpha = None; + } if( data.alpha != None ) return data.alpha; Pixmap pixmap = XCreatePixmap( display(), rootWindow(), 1, 1, 8 ); @@ -193,7 +214,8 @@ Picture SceneXrender::windowAlphaMask( Toplevel* c ) data.alpha = XRenderCreatePicture( display(), pixmap, format, CPRepeat, &pa ); XFreePixmap( display(), pixmap ); XRenderColor col; - col.alpha = int( c->opacity() * 0xffff ); + col.alpha = int( data.effect.opacity * 0xffff ); + data.alpha_cached_opacity = data.effect.opacity; XRenderFillRectangle( display(), PictOpSrc, data.alpha, &col, 0, 0, 1, 1 ); return data.alpha; } diff --git a/scene_xrender.h b/scene_xrender.h index e50b529fed..ec62de0292 100644 --- a/scene_xrender.h +++ b/scene_xrender.h @@ -17,10 +17,13 @@ License. See the file "COPYING" for the exact licensing terms. #include #include "scene.h" +#include "effects.h" namespace KWinInternal { +class Matrix; + class SceneXrender : public Scene { @@ -51,7 +54,9 @@ class SceneXrender XRenderPictFormat* format; XserverRegion saved_clip_region; Picture alpha; + double alpha_cached_opacity; XserverRegion shape; + EffectData effect; }; QMap< Toplevel*, WindowData > window_data; };