Support for effects that affect opacity.

svn path=/branches/work/kwin_composite/; revision=558921
This commit is contained in:
Luboš Luňák 2006-07-06 09:55:10 +00:00
parent a67e2c7f07
commit 391bb6b28d
4 changed files with 50 additions and 3 deletions

View file

@ -65,6 +65,24 @@ void Effect::paintWorkspace( Workspace*, EffectData& )
// EffectsHandler // 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* ) 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& ) void EffectsHandler::paintWorkspace( Workspace*, EffectData& )

View file

@ -46,6 +46,7 @@ class Effect
class EffectsHandler class EffectsHandler
{ {
public: public:
EffectsHandler();
void windowUserMoved( Toplevel* c ); void windowUserMoved( Toplevel* c );
void windowUserResized( Toplevel* c ); void windowUserResized( Toplevel* c );
void paintWindow( Toplevel* c, EffectData& data ); void paintWindow( Toplevel* c, EffectData& data );

View file

@ -13,6 +13,7 @@ License. See the file "COPYING" for the exact licensing terms.
#ifdef HAVE_XRENDER #ifdef HAVE_XRENDER
#include "toplevel.h" #include "toplevel.h"
#include "effects.h"
namespace KWinInternal namespace KWinInternal
{ {
@ -43,6 +44,14 @@ SceneXrender::~SceneXrender()
void SceneXrender::paint( XserverRegion damage ) 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 // Use the damage region as the clip region for the root window
XFixesSetPictureClipRegion( display(), front, 0, 0, damage ); XFixesSetPictureClipRegion( display(), front, 0, 0, damage );
// Client list for clients that are either translucent or have a shadow // 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 ]; Toplevel* c = windows[ i ];
checkWindowData( c ); checkWindowData( c );
effects->paintWindow( c, window_data[ c ].effect );
if( isOpaque( c )) if( isOpaque( c ))
{ {
Picture picture = windowPicture( c ); Picture picture = windowPicture( c );
@ -91,9 +101,11 @@ void SceneXrender::paint( XserverRegion damage )
Picture picture = windowPicture( c ); Picture picture = windowPicture( c );
Picture alpha = windowAlphaMask( c ); Picture alpha = windowAlphaMask( c );
if( picture != None ) if( picture != None )
{
// TODO clip also using shape? also above? // TODO clip also using shape? also above?
XRenderComposite( display(), PictOpOver, picture, alpha, buffer, 0, 0, 0, 0, XRenderComposite( display(), PictOpOver, picture, alpha, buffer, 0, 0, 0, 0,
c->x(), c->y(), c->width(), c->height()); c->x(), c->y(), c->width(), c->height());
}
} }
XFixesDestroyRegion( display(), r ); XFixesDestroyRegion( display(), r );
} }
@ -110,6 +122,9 @@ void SceneXrender::checkWindowData( Toplevel* c )
window_data[ c ] = WindowData(); window_data[ c ] = WindowData();
window_data[ c ].format = XRenderFindVisualFormat( display(), c->visual()); 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 ) void SceneXrender::windowGeometryShapeChanged( Toplevel* c )
@ -174,7 +189,7 @@ bool SceneXrender::isOpaque( Toplevel* c ) const
const WindowData& data = window_data[ c ]; const WindowData& data = window_data[ c ];
if( data.format->type == PictTypeDirect && data.format->direct.alphaMask ) if( data.format->type == PictTypeDirect && data.format->direct.alphaMask )
return false; return false;
if( c->opacity() != 1.0 ) if( data.effect.opacity != 1.0 )
return false; return false;
return true; return true;
} }
@ -184,6 +199,12 @@ Picture SceneXrender::windowAlphaMask( Toplevel* c )
if( isOpaque( c )) if( isOpaque( c ))
return None; return None;
WindowData& data = window_data[ c ]; 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 ) if( data.alpha != None )
return data.alpha; return data.alpha;
Pixmap pixmap = XCreatePixmap( display(), rootWindow(), 1, 1, 8 ); 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 ); data.alpha = XRenderCreatePicture( display(), pixmap, format, CPRepeat, &pa );
XFreePixmap( display(), pixmap ); XFreePixmap( display(), pixmap );
XRenderColor col; 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 ); XRenderFillRectangle( display(), PictOpSrc, data.alpha, &col, 0, 0, 1, 1 );
return data.alpha; return data.alpha;
} }

View file

@ -17,10 +17,13 @@ License. See the file "COPYING" for the exact licensing terms.
#include <X11/extensions/Xrender.h> #include <X11/extensions/Xrender.h>
#include "scene.h" #include "scene.h"
#include "effects.h"
namespace KWinInternal namespace KWinInternal
{ {
class Matrix;
class SceneXrender class SceneXrender
: public Scene : public Scene
{ {
@ -51,7 +54,9 @@ class SceneXrender
XRenderPictFormat* format; XRenderPictFormat* format;
XserverRegion saved_clip_region; XserverRegion saved_clip_region;
Picture alpha; Picture alpha;
double alpha_cached_opacity;
XserverRegion shape; XserverRegion shape;
EffectData effect;
}; };
QMap< Toplevel*, WindowData > window_data; QMap< Toplevel*, WindowData > window_data;
}; };