diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt
index 17e3d7bfbd..5734b289fa 100644
--- a/effects/CMakeLists.txt
+++ b/effects/CMakeLists.txt
@@ -125,8 +125,7 @@ if( NOT KWIN_MOBILE_EFFECTS )
include( glide/CMakeLists.txt )
include( invert/CMakeLists.txt )
include( lookingglass/CMakeLists.txt )
-# Magnifier currently broken due to removed PaintClipper
-# include( magnifier/CMakeLists.txt )
+ include( magnifier/CMakeLists.txt )
include( mousemark/CMakeLists.txt )
include( sheet/CMakeLists.txt )
include( snaphelper/CMakeLists.txt )
diff --git a/effects/configs_builtins.cpp b/effects/configs_builtins.cpp
index 85db0c8010..b291e388ad 100644
--- a/effects/configs_builtins.cpp
+++ b/effects/configs_builtins.cpp
@@ -45,10 +45,7 @@ along with this program. If not, see .
#include "glide/glide_config.h"
#include "invert/invert_config.h"
#include "lookingglass/lookingglass_config.h"
-#if 0
-// Magnifier currently broken due to removed PaintClipper
#include "magnifier/magnifier_config.h"
-#endif
#include "mousemark/mousemark_config.h"
#include "trackmouse/trackmouse_config.h"
#include "wobblywindows/wobblywindows_config.h"
@@ -85,9 +82,7 @@ KWIN_EFFECT_CONFIG_MULTIPLE(builtins,
KWIN_EFFECT_CONFIG_SINGLE(glide, GlideEffectConfig)
KWIN_EFFECT_CONFIG_SINGLE(invert, InvertEffectConfig)
KWIN_EFFECT_CONFIG_SINGLE(lookingglass, LookingGlassEffectConfig)
-#if 0
KWIN_EFFECT_CONFIG_SINGLE(magnifier, MagnifierEffectConfig)
-#endif
KWIN_EFFECT_CONFIG_SINGLE(mousemark, MouseMarkEffectConfig)
KWIN_EFFECT_CONFIG_SINGLE(trackmouse, TrackMouseEffectConfig)
KWIN_EFFECT_CONFIG_SINGLE(wobblywindows, WobblyWindowsEffectConfig)
diff --git a/effects/magnifier/magnifier.cpp b/effects/magnifier/magnifier.cpp
index 5fea59c10d..3e216f6736 100644
--- a/effects/magnifier/magnifier.cpp
+++ b/effects/magnifier/magnifier.cpp
@@ -4,6 +4,7 @@
Copyright (C) 2007 Lubos Lunak
Copyright (C) 2007 Christian Nitschkowski
+Copyright (C) 2011 Martin Gräßlin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,6 +43,8 @@ MagnifierEffect::MagnifierEffect()
: zoom(1)
, target_zoom(1)
, polling(false)
+ , m_texture(0)
+ , m_fbo(0)
{
KActionCollection* actionCollection = new KActionCollection(this);
KAction* a;
@@ -56,9 +59,15 @@ MagnifierEffect::MagnifierEffect()
reconfigure(ReconfigureAll);
}
+MagnifierEffect::~MagnifierEffect()
+{
+ delete m_fbo;
+ delete m_texture;
+}
+
bool MagnifierEffect::supported()
{
- return effects->compositingType() == OpenGLCompositing;
+ return effects->compositingType() == OpenGLCompositing && GLRenderTarget::blitSupported();
}
void MagnifierEffect::reconfigure(ReconfigureFlags)
@@ -86,21 +95,17 @@ void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, int time)
void MagnifierEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
- ScreenPaintData data2 = data;
effects->paintScreen(mask, region, data); // paint normal screen
if (zoom != 1.0) {
+ // get the right area from the current rendered screen
+ const QRect area = magnifierArea();
+ const QPoint cursor = cursorPos();
+ m_fbo->blitFromFramebuffer(QRect(cursor.x() - (double)area.width() / (zoom*2), cursor.y() - (double)area.height() / (zoom*2),
+ (double)area.width() / zoom, (double)area.height() / zoom));
// paint magnifier
- QRect area = magnifierArea();
- PaintClipper::push(area); // don't allow any painting outside of the area
- mask |= PAINT_SCREEN_TRANSFORMED;
- data2.xScale *= zoom;
- data2.yScale *= zoom;
- QPoint cursor = cursorPos();
- // set the position so that the cursor is in the same position in the scaled view
- data2.xTranslate = - int(cursor.x() * (zoom - 1));
- data2.yTranslate = - int(cursor.y() * (zoom - 1));
- effects->paintScreen(mask, region, data2);
- PaintClipper::pop(area);
+ m_texture->bind();
+ m_texture->render(infiniteRegion(), area);
+ m_texture->unbind();
QVector verts;
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
vbo->reset();
@@ -166,6 +171,11 @@ void MagnifierEffect::zoomIn()
polling = true;
effects->startMousePolling();
}
+ if (!m_texture) {
+ m_texture = new GLTexture(magnifier_size);
+ m_texture->setYInverted(false);
+ m_fbo = new GLRenderTarget(m_texture);
+ }
effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH));
}
@@ -178,6 +188,10 @@ void MagnifierEffect::zoomOut()
polling = false;
effects->stopMousePolling();
}
+ delete m_fbo;
+ delete m_texture;
+ m_fbo = NULL;
+ m_texture = NULL;
}
effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH));
}
@@ -190,12 +204,21 @@ void MagnifierEffect::toggle()
polling = true;
effects->startMousePolling();
}
+ if (!m_texture) {
+ m_texture = new GLTexture(magnifier_size);
+ m_texture->setYInverted(false);
+ m_fbo = new GLRenderTarget(m_texture);
+ }
} else {
target_zoom = 1;
if (polling) {
polling = false;
effects->stopMousePolling();
}
+ delete m_fbo;
+ delete m_texture;
+ m_fbo = NULL;
+ m_texture = NULL;
}
effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH));
}
diff --git a/effects/magnifier/magnifier.h b/effects/magnifier/magnifier.h
index 0ea3adabae..0e4e6750d2 100644
--- a/effects/magnifier/magnifier.h
+++ b/effects/magnifier/magnifier.h
@@ -3,6 +3,7 @@
This file is part of the KDE project.
Copyright (C) 2007 Lubos Lunak
+Copyright (C) 2011 Martin Gräßlin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,12 +27,16 @@ along with this program. If not, see .
namespace KWin
{
+class GLRenderTarget;
+class GLTexture;
+
class MagnifierEffect
: public Effect
{
Q_OBJECT
public:
MagnifierEffect();
+ virtual ~MagnifierEffect();
virtual void reconfigure(ReconfigureFlags);
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data);
@@ -50,6 +55,8 @@ private:
double target_zoom;
bool polling; // Mouse polling
QSize magnifier_size;
+ GLTexture *m_texture;
+ GLRenderTarget *m_fbo;
};
} // namespace