From c2e06221ca2fd3c142fa5d05a7fc0a97bf3f552d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Thu, 30 Jun 2011 21:06:17 +0200 Subject: [PATCH] zoom effect: fix xcursor loading, implement cursor scaling for XRender --- effects/zoom/zoom.cpp | 62 ++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/effects/zoom/zoom.cpp b/effects/zoom/zoom.cpp index 33b54dc4da..99ae23ff32 100644 --- a/effects/zoom/zoom.cpp +++ b/effects/zoom/zoom.cpp @@ -24,6 +24,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -168,27 +169,17 @@ void ZoomEffect::recreateTexture() QString theme = mousecfg.readEntry("cursorTheme", QString()); QString size = mousecfg.readEntry("cursorSize", QString()); - // try to find the to the theme-name matching cursor-directory. - QByteArray themePath; - foreach (const QString & baseDir, QString(XcursorLibraryPath()).split(':', QString::SkipEmptyParts)) { - QDir dir(baseDir); - if (!dir.exists()) continue; - if (!theme.isEmpty() && dir.cd(theme)) { - themePath = QFile::encodeName(dir.absolutePath()); - break; // theme found, job is done and we can abort the search now - } - if (dir.cd("default")) // default is better then nothing, so keep it as backup - themePath = QFile::encodeName(dir.absolutePath()); - } - // fetch a reasonable size for the cursor-theme image bool ok; int iconSize = size.toInt(&ok); if (!ok) iconSize = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize); + iconSize = nominalCursorSize(iconSize); // load the cursor-theme image from the Xcursor-library - XcursorImage *ximg = XcursorLibraryLoadImage("left_ptr", themePath, nominalCursorSize(iconSize)); + XcursorImage *ximg = XcursorLibraryLoadImage("left_ptr", theme.toLocal8Bit(), iconSize); + if (!ximg) // default is better then nothing, so keep it as backup + ximg = XcursorLibraryLoadImage("left_ptr", "default", iconSize); if (ximg) { // turn the XcursorImage into a QImage that will be used to create the GLTexture/XRenderPicture. imageWidth = ximg->width; @@ -204,6 +195,10 @@ void ZoomEffect::recreateTexture() #endif XcursorImageDestroy(ximg); } + else { + qDebug() << "Loading cursor image (" << theme << ") FAILED -> falling back to proportional mouse tracking!"; + mouseTracking = MouseTrackingProportional; + } } void ZoomEffect::reconfigure(ReconfigureFlags) @@ -254,6 +249,15 @@ void ZoomEffect::prePaintScreen(ScreenPrePaintData& data, int time) effects->prePaintScreen(data, time); } + +#ifdef KWIN_HAVE_XRENDER_COMPOSITING +static XTransform xrenderIdentity = {{ + { XDoubleToFixed( 1.0 ), XDoubleToFixed( 0.0 ), XDoubleToFixed( 0.0 ) }, + { XDoubleToFixed( 0.0 ), XDoubleToFixed( 1.0 ), XDoubleToFixed( 0.0 ) }, + { XDoubleToFixed( 0.0 ), XDoubleToFixed( 0.0 ), XDoubleToFixed( 1.0 ) } +}}; +#endif + void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { if (zoom != 1.0) { @@ -323,6 +327,15 @@ void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) // Draw the mouse-texture at the position matching to zoomed-in image of the desktop. Hiding the // previous mouse-cursor and drawing our own fake mouse-cursor is needed to be able to scale the // mouse-cursor up and to re-position those mouse-cursor to match to the chosen zoom-level. + int w = imageWidth; + int h = imageHeight; + if (mousePointer == MousePointerScale) { + w *= zoom; + h *= zoom; + } + QPoint p = QCursor::pos(); + QRect rect(p.x() * zoom + data.xTranslate, p.y() * zoom + data.yTranslate, w, h); + #ifdef KWIN_HAVE_OPENGL_COMPOSITING if (texture) { #ifndef KWIN_HAVE_OPENGLES @@ -331,14 +344,6 @@ void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) texture->bind(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - int w = imageWidth; - int h = imageHeight; - if (mousePointer == MousePointerScale) { - w *= zoom; - h *= zoom; - } - QPoint p = QCursor::pos(); - QRect rect(p.x() * zoom + data.xTranslate, p.y() * zoom + data.yTranslate, w, h); texture->render(region, rect); texture->unbind(); glDisable(GL_BLEND); @@ -349,9 +354,18 @@ void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) #endif #ifdef KWIN_HAVE_XRENDER_COMPOSITING if (xrenderPicture) { - QPoint p = QCursor::pos(); - QRect rect(p.x() * zoom + data.xTranslate, p.y() * zoom + data.yTranslate, imageWidth, imageHeight); + if (mousePointer == MousePointerScale) { + XRenderSetPictureFilter(display(), *xrenderPicture, const_cast("good"), NULL, 0); + XTransform xform = {{ + { XDoubleToFixed( 1.0 / zoom ), XDoubleToFixed( 0.0 ), XDoubleToFixed( 0.0 ) }, + { XDoubleToFixed( 0.0 ), XDoubleToFixed( 1.0 / zoom ), XDoubleToFixed( 0.0 ) }, + { XDoubleToFixed( 0.0 ), XDoubleToFixed( 0.0 ), XDoubleToFixed( 1.0 ) } + }}; + XRenderSetPictureTransform( display(), *xrenderPicture, &xform ); + } XRenderComposite(display(), PictOpOver, *xrenderPicture, None, effects->xrenderBufferPicture(), 0, 0, 0, 0, rect.x(), rect.y(), rect.width(), rect.height()); + if (mousePointer == MousePointerScale) + XRenderSetPictureTransform( display(), *xrenderPicture, &xrenderIdentity ); } #endif }