diff --git a/scene_opengl.h b/scene_opengl.h --- a/scene_opengl.h +++ b/scene_opengl.h @@ -100,6 +100,7 @@ virtual void doPaintBackground(const QVector &vertices) = 0; virtual void updateProjectionMatrix() = 0; + virtual void paintCursor(); Q_SIGNALS: void resetCompositing(); @@ -137,6 +138,7 @@ virtual Scene::Window *createWindow(Toplevel *t); virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); virtual void updateProjectionMatrix() override; + virtual void paintCursor() override; private Q_SLOTS: void resetLanczosFilter(); diff --git a/scene_opengl.cpp b/scene_opengl.cpp --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -42,6 +42,7 @@ #include "main.h" #include "overlaywindow.h" #include "screens.h" +#include "cursor.h" #include "decorations/decoratedclient.h" #include @@ -678,6 +679,48 @@ } } +void SceneOpenGL::paintCursor() +{ + +} + +void SceneOpenGL2::paintCursor() +{ + // don't paint if we use hardware cursor + if (!kwinApp()->platform()->usesSoftwareCursor()) { + return; + } + + // don't paint if no image for cursor is set + const QImage img = kwinApp()->platform()->softwareCursor(); + if (img.isNull()) { + return; + } + + const QPoint cursorPos = Cursor::pos(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + GLVertexBuffer* vbo = GLVertexBuffer::streamingBuffer(); + vbo->reset(); + vbo->setUseColor(true); + + QScopedPointer cursorTex; + cursorTex.reset(new GLTexture(img)); + cursorTex->bind(); + ShaderBinder binder(ShaderTrait::MapTexture); + QMatrix4x4 mvp = m_projectionMatrix; + mvp.translate(cursorPos.x(), cursorPos.y()); + binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, mvp); + cursorTex->render(QRegion(img.rect()), img.rect()); + cursorTex->unbind(); + + kwinApp()->platform()->markCursorAsRendered(); + + glDisable(GL_BLEND); +} + qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) { // actually paint the frame, flushed with the NEXT frame @@ -711,6 +754,7 @@ int mask = 0; updateProjectionMatrix(); paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid, projectionMatrix(), geo); // call generic implementation + paintCursor(); GLVertexBuffer::streamingBuffer()->endOfFrame();