1
/********************************************************************
2
KWin - the KDE window manager
3
This file is part of the KDE project.
5
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program. If not, see <http://www.gnu.org/licenses/>.
19
*********************************************************************/
23
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
24
#include <kwinglutils.h>
26
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
28
#include <X11/extensions/Xrender.h>
31
#include <KColorScheme>
32
#include <KDE/KConfigGroup>
37
KWIN_EFFECT(resize, ResizeEffect)
39
ResizeEffect::ResizeEffect()
43
reconfigure(ReconfigureAll);
44
connect(effects, SIGNAL(windowStartUserMovedResized(EffectWindow*)), this, SLOT(slotWindowStartUserMovedResized(EffectWindow*)));
45
connect(effects, SIGNAL(windowStepUserMovedResized(EffectWindow*,QRect)), this, SLOT(slotWindowStepUserMovedResized(EffectWindow*,QRect)));
46
connect(effects, SIGNAL(windowFinishUserMovedResized(EffectWindow*)), this, SLOT(slotWindowFinishUserMovedResized(EffectWindow*)));
49
ResizeEffect::~ResizeEffect()
53
void ResizeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
56
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
58
effects->prePaintScreen(data, time);
61
void ResizeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
63
if (m_active && w == m_resizeWindow)
64
data.mask |= PAINT_WINDOW_TRANSFORMED;
65
effects->prePaintWindow(w, data, time);
68
void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
70
if (m_active && w == m_resizeWindow) {
71
if (m_features & TextureScale) {
72
data.xTranslate += m_currentGeometry.x() - m_originalGeometry.x();
73
data.xScale *= m_currentGeometry.width();
74
data.xScale /= m_originalGeometry.width();
75
data.yTranslate += m_currentGeometry.y() - m_originalGeometry.y();
76
data.yScale *= m_currentGeometry.height();
77
data.yScale /= m_originalGeometry.height();
79
effects->paintWindow(w, mask, region, data);
81
if (m_features & Outline) {
82
QRegion intersection = m_originalGeometry.intersected(m_currentGeometry);
83
QRegion paintRegion = QRegion(m_originalGeometry).united(m_currentGeometry).subtracted(intersection);
85
QColor color = KColorScheme(QPalette::Normal, KColorScheme::Selection).background().color();
87
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
88
if (effects->compositingType() == OpenGLCompositing) {
89
#ifndef KWIN_HAVE_OPENGLES
90
glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
92
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
94
vbo->setUseColor(true);
95
if (ShaderManager::instance()->isValid()) {
96
ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
99
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
100
color.setAlphaF(alpha);
101
vbo->setColor(color);
102
QVector<float> verts;
103
verts.reserve(paintRegion.rects().count() * 12);
104
foreach (const QRect & r, paintRegion.rects()) {
105
verts << r.x() + r.width() << r.y();
106
verts << r.x() << r.y();
107
verts << r.x() << r.y() + r.height();
108
verts << r.x() << r.y() + r.height();
109
verts << r.x() + r.width() << r.y() + r.height();
110
verts << r.x() + r.width() << r.y();
112
vbo->setData(verts.count() / 2, 2, verts.data(), NULL);
113
vbo->render(GL_TRIANGLES);
114
if (ShaderManager::instance()->isValid()) {
115
ShaderManager::instance()->popShader();
118
#ifndef KWIN_HAVE_OPENGLES
124
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
125
if (effects->compositingType() == XRenderCompositing) {
127
col.alpha = int(alpha * 0xffff);
128
col.red = int(alpha * 0xffff * color.red() / 255);
129
col.green = int(alpha * 0xffff * color.green() / 255);
130
col.blue = int(alpha * 0xffff * color.blue() / 255);
131
foreach (const QRect & r, paintRegion.rects())
132
XRenderFillRectangle(display(), PictOpOver, effects->xrenderBufferPicture(),
133
&col, r.x(), r.y(), r.width(), r.height());
138
effects->paintWindow(w, mask, region, data);
141
void ResizeEffect::reconfigure(ReconfigureFlags)
143
KConfigGroup conf = effects->effectConfig("Resize");
145
if (conf.readEntry("TextureScale", true))
146
m_features |= TextureScale;
147
if (conf.readEntry("Outline", false))
148
m_features |= Outline;
151
void ResizeEffect::slotWindowStartUserMovedResized(EffectWindow *w)
153
if (w->isUserResize() && !w->isUserMove()) {
156
m_originalGeometry = w->geometry();
157
m_currentGeometry = w->geometry();
162
void ResizeEffect::slotWindowFinishUserMovedResized(EffectWindow *w)
164
if (m_active && w == m_resizeWindow) {
166
m_resizeWindow = NULL;
167
effects->addRepaintFull();
171
void ResizeEffect::slotWindowStepUserMovedResized(EffectWindow *w, const QRect &geometry)
173
if (m_active && w == m_resizeWindow) {
174
m_currentGeometry = geometry;
175
effects->addRepaintFull();