~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kwin/effects/resize/resize.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 KWin - the KDE window manager
 
3
 This file is part of the KDE project.
 
4
 
 
5
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
 
6
 
 
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.
 
11
 
 
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.
 
16
 
 
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
*********************************************************************/
 
20
 
 
21
#include "resize.h"
 
22
 
 
23
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
 
24
#include <kwinglutils.h>
 
25
#endif
 
26
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
 
27
#include <X11/Xlib.h>
 
28
#include <X11/extensions/Xrender.h>
 
29
#endif
 
30
 
 
31
#include <KColorScheme>
 
32
#include <KDE/KConfigGroup>
 
33
 
 
34
namespace KWin
 
35
{
 
36
 
 
37
KWIN_EFFECT(resize, ResizeEffect)
 
38
 
 
39
ResizeEffect::ResizeEffect()
 
40
    : m_active(false)
 
41
    , m_resizeWindow(0)
 
42
{
 
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*)));
 
47
}
 
48
 
 
49
ResizeEffect::~ResizeEffect()
 
50
{
 
51
}
 
52
 
 
53
void ResizeEffect::prePaintScreen(ScreenPrePaintData& data, int time)
 
54
{
 
55
    if (m_active) {
 
56
        data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
 
57
    }
 
58
    effects->prePaintScreen(data, time);
 
59
}
 
60
 
 
61
void ResizeEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
 
62
{
 
63
    if (m_active && w == m_resizeWindow)
 
64
        data.mask |= PAINT_WINDOW_TRANSFORMED;
 
65
    effects->prePaintWindow(w, data, time);
 
66
}
 
67
 
 
68
void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
 
69
{
 
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();
 
78
        }
 
79
        effects->paintWindow(w, mask, region, data);
 
80
 
 
81
        if (m_features & Outline) {
 
82
            QRegion intersection = m_originalGeometry.intersected(m_currentGeometry);
 
83
            QRegion paintRegion = QRegion(m_originalGeometry).united(m_currentGeometry).subtracted(intersection);
 
84
            float alpha = 0.8f;
 
85
            QColor color = KColorScheme(QPalette::Normal, KColorScheme::Selection).background().color();
 
86
 
 
87
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
 
88
            if (effects->compositingType() == OpenGLCompositing) {
 
89
#ifndef KWIN_HAVE_OPENGLES
 
90
                glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
 
91
#endif
 
92
                GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
 
93
                vbo->reset();
 
94
                vbo->setUseColor(true);
 
95
                if (ShaderManager::instance()->isValid()) {
 
96
                    ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
 
97
                }
 
98
                glEnable(GL_BLEND);
 
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();
 
111
                }
 
112
                vbo->setData(verts.count() / 2, 2, verts.data(), NULL);
 
113
                vbo->render(GL_TRIANGLES);
 
114
                if (ShaderManager::instance()->isValid()) {
 
115
                    ShaderManager::instance()->popShader();
 
116
                }
 
117
                glDisable(GL_BLEND);
 
118
#ifndef KWIN_HAVE_OPENGLES
 
119
                glPopAttrib();
 
120
#endif
 
121
            }
 
122
#endif
 
123
 
 
124
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
 
125
            if (effects->compositingType() == XRenderCompositing) {
 
126
                XRenderColor col;
 
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());
 
134
            }
 
135
#endif
 
136
        }
 
137
    } else
 
138
        effects->paintWindow(w, mask, region, data);
 
139
}
 
140
 
 
141
void ResizeEffect::reconfigure(ReconfigureFlags)
 
142
{
 
143
    KConfigGroup conf = effects->effectConfig("Resize");
 
144
    m_features = 0;
 
145
    if (conf.readEntry("TextureScale", true))
 
146
        m_features |= TextureScale;
 
147
    if (conf.readEntry("Outline", false))
 
148
        m_features |= Outline;
 
149
}
 
150
 
 
151
void ResizeEffect::slotWindowStartUserMovedResized(EffectWindow *w)
 
152
{
 
153
    if (w->isUserResize() && !w->isUserMove()) {
 
154
        m_active = true;
 
155
        m_resizeWindow = w;
 
156
        m_originalGeometry = w->geometry();
 
157
        m_currentGeometry = w->geometry();
 
158
        w->addRepaintFull();
 
159
    }
 
160
}
 
161
 
 
162
void ResizeEffect::slotWindowFinishUserMovedResized(EffectWindow *w)
 
163
{
 
164
    if (m_active && w == m_resizeWindow) {
 
165
        m_active = false;
 
166
        m_resizeWindow = NULL;
 
167
        effects->addRepaintFull();
 
168
    }
 
169
}
 
170
 
 
171
void ResizeEffect::slotWindowStepUserMovedResized(EffectWindow *w, const QRect &geometry)
 
172
{
 
173
    if (m_active && w == m_resizeWindow) {
 
174
        m_currentGeometry = geometry;
 
175
        effects->addRepaintFull();
 
176
    }
 
177
}
 
178
 
 
179
} // namespace