zoom effect: fix xcursor loading, implement cursor scaling for XRender
This commit is contained in:
parent
3259ff612a
commit
c2e06221ca
1 changed files with 38 additions and 24 deletions
|
@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QtDebug>
|
||||||
#include <QtGui/QX11Info>
|
#include <QtGui/QX11Info>
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
#include <QtGui/QStyle>
|
#include <QtGui/QStyle>
|
||||||
|
@ -168,27 +169,17 @@ void ZoomEffect::recreateTexture()
|
||||||
QString theme = mousecfg.readEntry("cursorTheme", QString());
|
QString theme = mousecfg.readEntry("cursorTheme", QString());
|
||||||
QString size = mousecfg.readEntry("cursorSize", 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
|
// fetch a reasonable size for the cursor-theme image
|
||||||
bool ok;
|
bool ok;
|
||||||
int iconSize = size.toInt(&ok);
|
int iconSize = size.toInt(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
iconSize = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
|
iconSize = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
|
||||||
|
iconSize = nominalCursorSize(iconSize);
|
||||||
|
|
||||||
// load the cursor-theme image from the Xcursor-library
|
// 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) {
|
if (ximg) {
|
||||||
// turn the XcursorImage into a QImage that will be used to create the GLTexture/XRenderPicture.
|
// turn the XcursorImage into a QImage that will be used to create the GLTexture/XRenderPicture.
|
||||||
imageWidth = ximg->width;
|
imageWidth = ximg->width;
|
||||||
|
@ -204,6 +195,10 @@ void ZoomEffect::recreateTexture()
|
||||||
#endif
|
#endif
|
||||||
XcursorImageDestroy(ximg);
|
XcursorImageDestroy(ximg);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
qDebug() << "Loading cursor image (" << theme << ") FAILED -> falling back to proportional mouse tracking!";
|
||||||
|
mouseTracking = MouseTrackingProportional;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoomEffect::reconfigure(ReconfigureFlags)
|
void ZoomEffect::reconfigure(ReconfigureFlags)
|
||||||
|
@ -254,6 +249,15 @@ void ZoomEffect::prePaintScreen(ScreenPrePaintData& data, int time)
|
||||||
effects->prePaintScreen(data, 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)
|
void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
|
||||||
{
|
{
|
||||||
if (zoom != 1.0) {
|
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
|
// 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
|
// 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.
|
// 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
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
if (texture) {
|
if (texture) {
|
||||||
#ifndef KWIN_HAVE_OPENGLES
|
#ifndef KWIN_HAVE_OPENGLES
|
||||||
|
@ -331,14 +344,6 @@ void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
|
||||||
texture->bind();
|
texture->bind();
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
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->render(region, rect);
|
||||||
texture->unbind();
|
texture->unbind();
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
@ -349,9 +354,18 @@ void ZoomEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
|
||||||
#endif
|
#endif
|
||||||
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
if (xrenderPicture) {
|
if (xrenderPicture) {
|
||||||
QPoint p = QCursor::pos();
|
if (mousePointer == MousePointerScale) {
|
||||||
QRect rect(p.x() * zoom + data.xTranslate, p.y() * zoom + data.yTranslate, imageWidth, imageHeight);
|
XRenderSetPictureFilter(display(), *xrenderPicture, const_cast<char*>("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());
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue