1
/********************************************************************
2
KWin - the KDE window manager
3
This file is part of the KDE project.
5
Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
6
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
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.
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.
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
*********************************************************************/
24
#include <kwinglutils.h>
25
#include <kwinglplatform.h>
26
#include <kactioncollection.h>
30
#include <KStandardDirs>
37
KWIN_EFFECT(invert, InvertEffect)
38
KWIN_EFFECT_SUPPORTED(invert, InvertEffect::supported())
40
InvertEffect::InvertEffect()
46
KActionCollection* actionCollection = new KActionCollection(this);
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()));
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*)));
60
InvertEffect::~InvertEffect()
65
bool InvertEffect::supported()
67
return GLPlatform::instance()->supports(GLSL) &&
68
(effects->compositingType() == OpenGLCompositing);
71
bool InvertEffect::loadData()
74
if (!ShaderManager::instance()->isValid()) {
78
const QString fragmentshader = KGlobal::dirs()->findResource("data", "kwin/invert.frag");
80
m_shader = ShaderManager::instance()->loadFragmentShader(ShaderManager::GenericShader, fragmentshader);
81
if (!m_shader->isValid()) {
82
kError(1212) << "The shader failed to load!" << endl;
89
void InvertEffect::prePaintScreen(ScreenPrePaintData &data, int time)
91
if (m_valid && (m_allWindows || !m_windows.isEmpty())) {
92
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS;
94
effects->prePaintScreen(data, time);
97
void InvertEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
99
if (m_valid && (m_allWindows != m_windows.contains(w))) {
100
data.mask |= PAINT_WINDOW_TRANSFORMED;
102
effects->prePaintWindow(w, data, time);
105
void InvertEffect::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
107
// Load if we haven't already
108
if (m_valid && !m_inited)
109
m_valid = loadData();
111
bool useShader = m_valid && (m_allWindows != m_windows.contains(w));
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);
120
data.shader = m_shader;
123
effects->drawWindow(w, mask, region, data);
126
ShaderManager::instance()->popShader();
130
void InvertEffect::paintEffectFrame(KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity)
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();
140
effects->paintEffectFrame(frame, region, opacity, frameOpacity);
144
void InvertEffect::slotWindowClosed(EffectWindow* w)
146
m_windows.removeOne(w);
149
void InvertEffect::toggle()
151
m_allWindows = !m_allWindows;
152
effects->addRepaintFull();
155
void InvertEffect::toggleWindow()
157
if (!m_windows.contains(effects->activeWindow()))
158
m_windows.append(effects->activeWindow());
160
m_windows.removeOne(effects->activeWindow());
161
effects->activeWindow()->addRepaintFull();
166
#include "invert.moc"