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

« back to all changes in this revision

Viewing changes to kwin/effects/invert/invert.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) 2007 Rivo Laks <rivolaks@hot.ee>
 
6
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
 
7
 
 
8
This program is free software; you can redistribute it and/or modify
 
9
it under the terms of the GNU General Public License as published by
 
10
the Free Software Foundation; either version 2 of the License, or
 
11
(at your option) any later version.
 
12
 
 
13
This program is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*********************************************************************/
 
21
 
 
22
#include "invert.h"
 
23
 
 
24
#include <kwinglutils.h>
 
25
#include <kwinglplatform.h>
 
26
#include <kactioncollection.h>
 
27
#include <kaction.h>
 
28
#include <klocale.h>
 
29
#include <kdebug.h>
 
30
#include <KStandardDirs>
 
31
 
 
32
#include <QMatrix4x4>
 
33
 
 
34
namespace KWin
 
35
{
 
36
 
 
37
KWIN_EFFECT(invert, InvertEffect)
 
38
KWIN_EFFECT_SUPPORTED(invert, InvertEffect::supported())
 
39
 
 
40
InvertEffect::InvertEffect()
 
41
    :   m_inited(false),
 
42
        m_valid(true),
 
43
        m_shader(NULL),
 
44
        m_allWindows(false)
 
45
{
 
46
    KActionCollection* actionCollection = new KActionCollection(this);
 
47
 
 
48
    KAction* a = (KAction*)actionCollection->addAction("Invert");
 
49
    a->setText(i18n("Toggle Invert Effect"));
 
50
    a->setGlobalShortcut(KShortcut(Qt::CTRL + Qt::META + Qt::Key_I));
 
51
    connect(a, SIGNAL(triggered(bool)), this, SLOT(toggle()));
 
52
 
 
53
    KAction* b = (KAction*)actionCollection->addAction("InvertWindow");
 
54
    b->setText(i18n("Toggle Invert Effect on Window"));
 
55
    b->setGlobalShortcut(KShortcut(Qt::CTRL + Qt::META + Qt::Key_U));
 
56
    connect(b, SIGNAL(triggered(bool)), this, SLOT(toggleWindow()));
 
57
    connect(effects, SIGNAL(windowClosed(EffectWindow*)), this, SLOT(slotWindowClosed(EffectWindow*)));
 
58
}
 
59
 
 
60
InvertEffect::~InvertEffect()
 
61
{
 
62
    delete m_shader;
 
63
}
 
64
 
 
65
bool InvertEffect::supported()
 
66
{
 
67
    return GLPlatform::instance()->supports(GLSL) &&
 
68
           (effects->compositingType() == OpenGLCompositing);
 
69
}
 
70
 
 
71
bool InvertEffect::loadData()
 
72
{
 
73
    m_inited = true;
 
74
    if (!ShaderManager::instance()->isValid()) {
 
75
        return false;
 
76
    }
 
77
 
 
78
    const QString fragmentshader =  KGlobal::dirs()->findResource("data", "kwin/invert.frag");
 
79
 
 
80
    m_shader = ShaderManager::instance()->loadFragmentShader(ShaderManager::GenericShader, fragmentshader);
 
81
    if (!m_shader->isValid()) {
 
82
        kError(1212) << "The shader failed to load!" << endl;
 
83
        return false;
 
84
    }
 
85
 
 
86
    return true;
 
87
}
 
88
 
 
89
void InvertEffect::prePaintScreen(ScreenPrePaintData &data, int time)
 
90
{
 
91
    if (m_valid && (m_allWindows || !m_windows.isEmpty())) {
 
92
        data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS;
 
93
    }
 
94
    effects->prePaintScreen(data, time);
 
95
}
 
96
 
 
97
void InvertEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
 
98
{
 
99
    if (m_valid && (m_allWindows != m_windows.contains(w))) {
 
100
        data.mask |= PAINT_WINDOW_TRANSFORMED;
 
101
    }
 
102
    effects->prePaintWindow(w, data, time);
 
103
}
 
104
 
 
105
void InvertEffect::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
 
106
{
 
107
    // Load if we haven't already
 
108
    if (m_valid && !m_inited)
 
109
        m_valid = loadData();
 
110
 
 
111
    bool useShader = m_valid && (m_allWindows != m_windows.contains(w));
 
112
    if (useShader) {
 
113
        ShaderManager *shaderManager = ShaderManager::instance();
 
114
        GLShader *genericShader = shaderManager->pushShader(ShaderManager::GenericShader);
 
115
        QMatrix4x4 screenTransformation = genericShader->getUniformMatrix4x4("screenTransformation");
 
116
        shaderManager->popShader();
 
117
        shaderManager->pushShader(m_shader);
 
118
        m_shader->setUniform("screenTransformation", screenTransformation);
 
119
 
 
120
        data.shader = m_shader;
 
121
    }
 
122
 
 
123
    effects->drawWindow(w, mask, region, data);
 
124
 
 
125
    if (useShader) {
 
126
        ShaderManager::instance()->popShader();
 
127
    }
 
128
}
 
129
 
 
130
void InvertEffect::paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity)
 
131
{
 
132
    if (m_valid && m_allWindows) {
 
133
        frame->setShader(m_shader);
 
134
        ShaderManager::instance()->pushShader(m_shader);
 
135
        m_shader->setUniform("screenTransformation", QMatrix4x4());
 
136
        m_shader->setUniform("windowTransformation", QMatrix4x4());
 
137
        effects->paintEffectFrame(frame, region, opacity, frameOpacity);
 
138
        ShaderManager::instance()->popShader();
 
139
    } else {
 
140
        effects->paintEffectFrame(frame, region, opacity, frameOpacity);
 
141
    }
 
142
}
 
143
 
 
144
void InvertEffect::slotWindowClosed(EffectWindow* w)
 
145
{
 
146
    m_windows.removeOne(w);
 
147
}
 
148
 
 
149
void InvertEffect::toggle()
 
150
{
 
151
    m_allWindows = !m_allWindows;
 
152
    effects->addRepaintFull();
 
153
}
 
154
 
 
155
void InvertEffect::toggleWindow()
 
156
{
 
157
    if (!m_windows.contains(effects->activeWindow()))
 
158
        m_windows.append(effects->activeWindow());
 
159
    else
 
160
        m_windows.removeOne(effects->activeWindow());
 
161
    effects->activeWindow()->addRepaintFull();
 
162
}
 
163
 
 
164
} // namespace
 
165
 
 
166
#include "invert.moc"