Add XRender support to BoxSwitch.
This includes icon support for XRender. svn path=/branches/work/kwin_composite/; revision=640729
This commit is contained in:
parent
04d80e9d05
commit
04e488b0a7
2 changed files with 180 additions and 73 deletions
|
@ -10,12 +10,11 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "boxswitch.h"
|
||||
|
||||
#include "tabbox.h"
|
||||
#include "client.h"
|
||||
#include "scene_opengl.h"
|
||||
#include <tabbox.h>
|
||||
#include <client.h>
|
||||
#include <scene_xrender.h>
|
||||
#include <scene_opengl.h>
|
||||
#include <QSize>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#include <GL/gl.h>
|
||||
|
@ -31,6 +30,9 @@ BoxSwitchEffect::BoxSwitchEffect()
|
|||
{
|
||||
frame_margin = 10;
|
||||
highlight_margin = 5;
|
||||
#ifdef HAVE_XRENDER
|
||||
alphaFormat = XRenderFindStandardFormat( display(), PictStandardARGB32 );
|
||||
#endif
|
||||
}
|
||||
|
||||
BoxSwitchEffect::~BoxSwitchEffect()
|
||||
|
@ -85,6 +87,7 @@ void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
|
|||
static_cast< Client* >( w->window())->caption());
|
||||
}
|
||||
paintWindowThumbnail( w );
|
||||
paintWindowIcon( w );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -309,6 +312,20 @@ void BoxSwitchEffect::setActive()
|
|||
{
|
||||
if( w != selected_window )
|
||||
w->window()->addRepaintFull();
|
||||
#ifdef HAVE_OPENGL
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
// windows[ w ].iconTexture.discard();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_XRENDER
|
||||
if( windows[ w ].iconPicture != None )
|
||||
XRenderFreePicture( display(), windows[ w ].iconPicture );
|
||||
windows[ w ].iconPicture = None;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,6 +344,20 @@ void BoxSwitchEffect::setInactive()
|
|||
{
|
||||
if( w != selected_window )
|
||||
w->window()->addRepaintFull();
|
||||
#ifdef HAVE_OPENGL
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
// windows[ w ].iconTexture.discard();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_XRENDER
|
||||
if( windows[ w ].iconPicture != None )
|
||||
XRenderFreePicture( display(), windows[ w ].iconPicture );
|
||||
windows[ w ].iconPicture = None;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
workspace()->addRepaint( frame_area );
|
||||
|
@ -380,11 +411,6 @@ void BoxSwitchEffect::calculateItemSizes()
|
|||
frame_area.y() + frame_margin,
|
||||
item_max_size.width(), item_max_size.height());
|
||||
windows[ w ].clickable = windows[ w ].area;
|
||||
windows[ w ].icon = static_cast< Client* >( w->window())->icon();
|
||||
/* #ifdef HAVE_OPENGL
|
||||
windows[ w ].glIcon.bindPixmap( windows[ w ].icon.handle(), windows[ w ].icon.width(), windows[ w ].icon.height(), windows[ w ].icon.depth());
|
||||
windows[ w ].glIcon.glFilter = GL_LINEAR;
|
||||
#endif */
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -409,36 +435,84 @@ void BoxSwitchEffect::calculateItemSizes()
|
|||
|
||||
void BoxSwitchEffect::paintFrame()
|
||||
{
|
||||
double alpha = 0.75;
|
||||
#ifdef HAVE_OPENGL
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 0, 0, 0, 0.75 );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( frame_area.x(), frame_area.y());
|
||||
glVertex2i( frame_area.x() + frame_area.width(), frame_area.y());
|
||||
glVertex2i( frame_area.x() + frame_area.width(), frame_area.y() + frame_area.height());
|
||||
glVertex2i( frame_area.x(), frame_area.y() + frame_area.height());
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 0, 0, 0, alpha );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( frame_area.x(), frame_area.y());
|
||||
glVertex2i( frame_area.x() + frame_area.width(), frame_area.y());
|
||||
glVertex2i( frame_area.x() + frame_area.width(), frame_area.y() + frame_area.height());
|
||||
glVertex2i( frame_area.x(), frame_area.y() + frame_area.height());
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_XRENDER
|
||||
Pixmap pixmap = XCreatePixmap( display(), rootWindow(),
|
||||
frame_area.width(), frame_area.height(), 32 );
|
||||
Picture pic = XRenderCreatePicture( display(), pixmap, alphaFormat, 0, NULL );
|
||||
XFreePixmap( display(), pixmap );
|
||||
XRenderColor col;
|
||||
col.alpha = int( alpha * 0xffff );
|
||||
col.red = 0;
|
||||
col.green = 0;
|
||||
col.blue = 0;
|
||||
XRenderFillRectangle( display(), PictOpSrc, pic, &col, 0, 0,
|
||||
frame_area.width(), frame_area.height());
|
||||
XRenderComposite( display(), alpha != 1.0 ? PictOpOver : PictOpSrc,
|
||||
pic, None, static_cast< SceneXrender* >( scene )->bufferPicture(),
|
||||
0, 0, 0, 0, frame_area.x(), frame_area.y(), frame_area.width(), frame_area.height());
|
||||
XRenderFreePicture( display(), pic );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void BoxSwitchEffect::paintHighlight( QRect area, QString text )
|
||||
{
|
||||
double alpha = 0.75;
|
||||
#ifdef HAVE_OPENGL
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 1, 1, 1, 0.75 );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( area.x(), area.y());
|
||||
glVertex2i( area.x() + area.width(), area.y());
|
||||
glVertex2i( area.x() + area.width(), area.y() + area.height());
|
||||
glVertex2i( area.x(), area.y() + area.height());
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glColor4f( 1, 1, 1, alpha );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( area.x(), area.y());
|
||||
glVertex2i( area.x() + area.width(), area.y());
|
||||
glVertex2i( area.x() + area.width(), area.y() + area.height());
|
||||
glVertex2i( area.x(), area.y() + area.height());
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_XRENDER
|
||||
Pixmap pixmap = XCreatePixmap( display(), rootWindow(),
|
||||
area.width(), area.height(), 32 );
|
||||
Picture pic = XRenderCreatePicture( display(), pixmap, alphaFormat, 0, NULL );
|
||||
XFreePixmap( display(), pixmap );
|
||||
XRenderColor col;
|
||||
col.alpha = int( alpha * 0xffff );
|
||||
col.red = int( alpha * 0xffff );
|
||||
col.green = int( alpha * 0xffff );
|
||||
col.blue = int( alpha * 0xffff );
|
||||
XRenderFillRectangle( display(), PictOpSrc, pic, &col, 0, 0,
|
||||
area.width(), area.height());
|
||||
XRenderComposite( display(), alpha != 1.0 ? PictOpOver : PictOpSrc,
|
||||
pic, None, static_cast< SceneXrender* >( scene )->bufferPicture(),
|
||||
0, 0, 0, 0, area.x(), area.y(), area.width(), area.height());
|
||||
XRenderFreePicture( display(), pic );
|
||||
#endif
|
||||
}
|
||||
// kDebug() << text << endl; // TODO draw this nicely on screen
|
||||
}
|
||||
|
||||
|
@ -488,45 +562,68 @@ void BoxSwitchEffect::paintWindowIcon( EffectWindow* w )
|
|||
{
|
||||
if( !windows.contains( w ))
|
||||
return;
|
||||
/* if( windows[ w ].icon.serialNumber()
|
||||
if( windows[ w ].icon.serialNumber()
|
||||
!= static_cast< Client* >( w->window())->icon().serialNumber())
|
||||
{ // icon changed
|
||||
{ // make sure windows[ w ].icon is the right QPixmap, and rebind
|
||||
windows[ w ].icon = static_cast< Client* >( w->window())->icon();
|
||||
#ifdef HAVE_OPENGL
|
||||
windows[ w ].glIcon.bindPixmap( windows[ w ].icon.handle(),
|
||||
windows[ w ].icon.width(), windows[ w ].icon.height(),
|
||||
windows[ w ].icon.depth(), windows[ w ].icon.rect());
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
// windows[ w ].iconTexture.bindPixmap( windows[ w ].icon.handle(),
|
||||
// windows[ w ].icon.width(), windows[ w ].icon.height(),
|
||||
// windows[ w ].icon.depth(), windows[ w ].icon.rect());
|
||||
// windows[ w ].iconTexture.setFilter( GL_LINEAR );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_XRENDER
|
||||
if( windows[ w ].iconPicture != None )
|
||||
XRenderFreePicture( display(), windows[ w ].iconPicture );
|
||||
windows[ w ].iconPicture = XRenderCreatePicture( display(),
|
||||
windows[ w ].icon.handle(), alphaFormat, 0, NULL );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
int x = windows[ w ].area.x() + ( windows[ w ].area.width() - windows[ w ].icon.width()) / 2;
|
||||
int y = windows[ w ].area.y() + ( windows[ w ].area.height() - windows[ w ].icon.height()) / 2;
|
||||
int width = windows[ w ].icon.width();
|
||||
int height = windows[ w ].icon.height();
|
||||
#ifdef HAVE_OPENGL
|
||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||
{
|
||||
// glPushMatrix();
|
||||
// glPushAttrib( GL_ENABLE_BIT );
|
||||
// glEnable( GL_BLEND );
|
||||
// glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
// windows[ w ].iconTexture.enable();
|
||||
// windows[ w ].iconTexture.preparePaint();
|
||||
// glBegin( GL_QUADS );
|
||||
// glTexCoord2i( 0, 0 );
|
||||
// glVertex2i( x, y );
|
||||
// glTexCoord2i( windows[ w ].icon.width(), 0 );
|
||||
// glVertex2i( x + width, y );
|
||||
// glTexCoord2i( windows[ w ].icon.width(), windows[ w ].icon.height());
|
||||
// glVertex2i( x + width, y + height );
|
||||
// glTexCoord2i( 0, windows[ w ].icon.height());
|
||||
// glVertex2i( x, y + height );
|
||||
// glEnd();
|
||||
// windows[ w ].iconTexture.finishPaint();
|
||||
// glPopMatrix();
|
||||
// glPopAttrib();
|
||||
// windows[ w ].iconTexture.disable();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_XRENDER
|
||||
XRenderComposite( display(),
|
||||
windows[ w ].icon.depth() == 32 ? PictOpOver : PictOpSrc,
|
||||
windows[ w ].iconPicture, None,
|
||||
static_cast< SceneXrender* >( scene )->bufferPicture(),
|
||||
0, 0, 0, 0, x, y, width, height );
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_OPENGL
|
||||
glPushMatrix();
|
||||
glPushAttrib( GL_ENABLE_BIT );
|
||||
windows[ w ].glIcon.enable();
|
||||
windows[ w ].glIcon.preparePaint();
|
||||
int x = windows[ w ].area.x() + ( windows[ w ].area.width() - windows[ w ].icon.width()) / 2
|
||||
int y = windows[ w ].area.y() + ( windows[ w ].area.height() - windows[ w ].icon.height()) / 2
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2i( 0, 0 );
|
||||
glVertex2i( x, y );
|
||||
glTexCoord2i( windows[ w ].icon.width(), 0 );
|
||||
glVertex2i( x + windows[ w ].icon.width(), y );
|
||||
glTexCoord2i( windows[ w ].icon.width(), windows[ w ].icon.height());
|
||||
glVertex2i( x + windows[ w ].icon.width(), y + windows[ w ].icon.height());
|
||||
glTexCoord2i( 0, windows[ w ].icon.height());
|
||||
glVertex2i( x, y + windows[ w ].icon.height());
|
||||
glEnd();
|
||||
windows[ w ].glIcon.finishPaint();
|
||||
glPopAttrib();
|
||||
glPopMatrix();
|
||||
windows[ w ].glIcon.disable();
|
||||
#endif */
|
||||
}
|
||||
|
||||
BoxSwitchEffect::ItemInfo::~ItemInfo()
|
||||
{
|
||||
/* #ifdef HAVE_OPENGL
|
||||
glIcon.discard();
|
||||
#endif */
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -11,11 +11,15 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#ifndef KWIN_BOXSWITCH_H
|
||||
#define KWIN_BOXSWITCH_H
|
||||
|
||||
#include "effects.h"
|
||||
#include "scene_opengl.h"
|
||||
#include <effects.h>
|
||||
#include <scene_xrender.h>
|
||||
#include <scene_opengl.h>
|
||||
|
||||
#include <QPoint>
|
||||
#include <QMap>
|
||||
#include <QPixmap>
|
||||
#include <QRect>
|
||||
#include <QRegion>
|
||||
#include <QSize>
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
@ -70,19 +74,25 @@ class BoxSwitchEffect
|
|||
EffectWindow* selected_window;
|
||||
|
||||
int painting_desktop;
|
||||
|
||||
#ifdef HAVE_XRENDER
|
||||
XRenderPictFormat* alphaFormat;
|
||||
#endif
|
||||
};
|
||||
|
||||
class BoxSwitchEffect::ItemInfo
|
||||
{
|
||||
public:
|
||||
~ItemInfo();
|
||||
QRect area; // maximal painting area, including any frames/highlights/etc.
|
||||
QRegion clickable;
|
||||
QRect thumbnail;
|
||||
QPixmap icon;
|
||||
/* #ifdef HAVE_OPENGL
|
||||
SceneOpenGL::Texture glIcon;
|
||||
#endif */
|
||||
#ifdef HAVE_OPENGL
|
||||
// SceneOpenGL::Texture iconTexture;
|
||||
#endif
|
||||
#ifdef HAVE_XRENDER
|
||||
Picture iconPicture;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in a new issue