summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/accessibility/accessibility.pri9
-rw-r--r--src/platformsupport/accessibility/qaccessiblebridgeutils.cpp119
-rw-r--r--src/platformsupport/accessibility/qaccessiblebridgeutils_p.h61
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri11
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor.cpp54
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp26
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h5
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp99
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h7
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor.cpp3
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor_p.h5
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp82
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration_p.h11
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow.cpp8
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow_p.h1
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp9
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen_p.h2
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp3
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp144
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp2
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h4
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm43
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm2
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h2
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience.cpp39
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience_p.h3
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp76
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h9
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp26
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h3
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp75
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h10
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp19
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h2
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouch.cpp12
-rw-r--r--src/platformsupport/linuxaccessibility/application.cpp43
-rw-r--r--src/platformsupport/linuxaccessibility/application_p.h3
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp106
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor_p.h9
-rw-r--r--src/platformsupport/linuxaccessibility/bridge.cpp24
-rw-r--r--src/platformsupport/linuxaccessibility/bridge_p.h2
-rw-r--r--src/platformsupport/linuxaccessibility/cache.cpp2
-rw-r--r--src/platformsupport/linuxaccessibility/cache_p.h2
-rw-r--r--src/platformsupport/linuxaccessibility/constant_mappings.cpp2
-rw-r--r--src/platformsupport/linuxaccessibility/constant_mappings_p.h2
-rw-r--r--src/platformsupport/linuxaccessibility/dbusconnection.cpp10
-rw-r--r--src/platformsupport/linuxaccessibility/dbusconnection_p.h2
-rw-r--r--src/platformsupport/linuxaccessibility/linuxaccessibility.pri1
-rw-r--r--src/platformsupport/linuxaccessibility/struct_marshallers.cpp2
-rw-r--r--src/platformsupport/linuxaccessibility/struct_marshallers_p.h2
-rw-r--r--src/platformsupport/platformsupport.pro1
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp194
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes_p.h4
53 files changed, 1112 insertions, 285 deletions
diff --git a/src/platformsupport/accessibility/accessibility.pri b/src/platformsupport/accessibility/accessibility.pri
new file mode 100644
index 0000000000..fb56edbf1a
--- /dev/null
+++ b/src/platformsupport/accessibility/accessibility.pri
@@ -0,0 +1,9 @@
+contains(QT_CONFIG, accessibility) {
+ INCLUDEPATH += $$PWD
+
+ HEADERS += \
+ $$PWD/qaccessiblebridgeutils_p.h
+
+ SOURCES += \
+ $$PWD/qaccessiblebridgeutils.cpp
+}
diff --git a/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp b/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp
new file mode 100644
index 0000000000..7140bb6e2d
--- /dev/null
+++ b/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qaccessiblebridgeutils_p.h"
+#include <QtCore/qmath.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+namespace QAccessibleBridgeUtils {
+
+static bool performAction(QAccessibleInterface *iface, const QString &actionName)
+{
+ if (QAccessibleActionInterface *actionIface = iface->actionInterface()) {
+ if (actionIface->actionNames().contains(actionName)) {
+ actionIface->doAction(actionName);
+ return true;
+ }
+ }
+ return false;
+}
+
+QStringList effectiveActionNames(QAccessibleInterface *iface)
+{
+ QStringList actions;
+ if (QAccessibleActionInterface *actionIface = iface->actionInterface())
+ actions = actionIface->actionNames();
+
+ if (iface->valueInterface()) {
+ if (!actions.contains(QAccessibleActionInterface::increaseAction()))
+ actions << QAccessibleActionInterface::increaseAction();
+ if (!actions.contains(QAccessibleActionInterface::decreaseAction()))
+ actions << QAccessibleActionInterface::decreaseAction();
+ }
+ return actions;
+}
+
+bool performEffectiveAction(QAccessibleInterface *iface, const QString &actionName)
+{
+ if (!iface)
+ return false;
+ if (performAction(iface, actionName))
+ return true;
+ if (actionName != QAccessibleActionInterface::increaseAction()
+ && actionName != QAccessibleActionInterface::decreaseAction())
+ return false;
+
+ QAccessibleValueInterface *valueIface = iface->valueInterface();
+ if (!valueIface)
+ return false;
+ bool success;
+ const QVariant currentVariant = valueIface->currentValue();
+ double stepSize = valueIface->minimumStepSize().toDouble(&success);
+ if (!success || qFuzzyIsNull(stepSize)) {
+ const double min = valueIface->minimumValue().toDouble(&success);
+ if (!success)
+ return false;
+ const double max = valueIface->maximumValue().toDouble(&success);
+ if (!success)
+ return false;
+ stepSize = (max - min) / 10; // this is pretty arbitrary, we just need to provide something
+ const int typ = currentVariant.type();
+ if (typ != QMetaType::Float && typ != QMetaType::Double) {
+ // currentValue is an integer. Round it up to ensure stepping in case it was below 1
+ stepSize = qCeil(stepSize);
+ }
+ }
+ const double current = currentVariant.toDouble(&success);
+ if (!success)
+ return false;
+ if (actionName == QAccessibleActionInterface::decreaseAction())
+ stepSize = -stepSize;
+ valueIface->setCurrentValue(current + stepSize);
+ return true;
+}
+
+} //namespace
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h b/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h
new file mode 100644
index 0000000000..d05934b844
--- /dev/null
+++ b/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEBRIDGEUTILS_H
+#define QACCESSIBLEBRIDGEUTILS_H
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#include <QtCore/qstringlist.h>
+#include <QtGui/qaccessible.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QAccessibleBridgeUtils {
+ QStringList effectiveActionNames(QAccessibleInterface *iface);
+ bool performEffectiveAction(QAccessibleInterface *iface, const QString &actionName);
+}
+
+QT_END_NAMESPACE
+
+#endif
+
+#endif //QACCESSIBLEBRIDGEUTILS_H
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index 7600cc952b..8ada53d2c1 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -40,15 +40,4 @@ contains(QT_CONFIG,egl) {
$$PWD/qxlibeglintegration.cpp
}
CONFIG += egl
-
-} else: contains(QT_CONFIG,dynamicgl) {
- HEADERS += \
- $$PWD/qeglconvenience_p.h \
- $$PWD/qeglplatformcontext_p.h \
- $$PWD/qeglpbuffer_p.h
-
- SOURCES += \
- $$PWD/qeglconvenience.cpp \
- $$PWD/qeglplatformcontext.cpp \
- $$PWD/qeglpbuffer.cpp
}
diff --git a/src/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp
index 0e0a2d9375..0deb8d3c39 100644
--- a/src/platformsupport/eglconvenience/qeglcompositor.cpp
+++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp
@@ -105,6 +105,29 @@ void QEGLCompositor::renderAll()
windows.at(i)->composited();
}
+struct BlendStateBinder
+{
+ BlendStateBinder() : m_blend(false) {
+ glDisable(GL_BLEND);
+ }
+ void set(bool blend) {
+ if (blend != m_blend) {
+ if (blend) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glDisable(GL_BLEND);
+ }
+ m_blend = blend;
+ }
+ }
+ ~BlendStateBinder() {
+ if (m_blend)
+ glDisable(GL_BLEND);
+ }
+ bool m_blend;
+};
+
void QEGLCompositor::render(QEGLPlatformWindow *window)
{
const QPlatformTextureList *textures = window->textures();
@@ -114,29 +137,44 @@ void QEGLCompositor::render(QEGLPlatformWindow *window)
const QRect targetWindowRect(QPoint(0, 0), window->screen()->geometry().size());
glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
+ float currentOpacity = 1.0f;
+ BlendStateBinder blend;
+
for (int i = 0; i < textures->count(); ++i) {
uint textureId = textures->textureId(i);
- glBindTexture(GL_TEXTURE_2D, textureId);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i),
targetWindowRect);
+ const float opacity = window->window()->opacity();
+ if (opacity != currentOpacity) {
+ currentOpacity = opacity;
+ m_blitter->setOpacity(currentOpacity);
+ }
if (textures->count() > 1 && i == textures->count() - 1) {
// Backingstore for a widget with QOpenGLWidget subwidgets
- m_blitter->setSwizzleRB(true);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ blend.set(true);
m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
- glDisable(GL_BLEND);
} else if (textures->count() == 1) {
// A regular QWidget window
- m_blitter->setSwizzleRB(true);
+ const bool translucent = window->window()->requestedFormat().alphaBufferSize() > 0;
+ blend.set(translucent);
m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
- } else {
+ } else if (!textures->stacksOnTop(i)) {
// Texture from an FBO belonging to a QOpenGLWidget
- m_blitter->setSwizzleRB(false);
+ blend.set(false);
m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
}
}
+
+ for (int i = 0; i < textures->count(); ++i) {
+ if (textures->stacksOnTop(i)) {
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
+ blend.set(true);
+ m_blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
+ }
+
+ m_blitter->setOpacity(1.0f);
}
QEGLCompositor *QEGLCompositor::instance()
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
index ab92bac37d..7923ef1cab 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
@@ -41,6 +41,7 @@
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QPainter>
#include "qeglplatformbackingstore_p.h"
#include "qeglcompositor_p.h"
@@ -164,13 +165,15 @@ void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, con
}
void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
- QPlatformTextureList *textures, QOpenGLContext *context)
+ QPlatformTextureList *textures, QOpenGLContext *context,
+ bool translucentBackground)
{
// QOpenGLWidget content provided as textures. The raster content should go on top.
Q_UNUSED(region);
Q_UNUSED(offset);
Q_UNUSED(context);
+ Q_UNUSED(translucentBackground);
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
QEGLPlatformWindow *dstWin = screen->compositingWindow();
@@ -180,11 +183,8 @@ void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &r
screen->compositingContext()->makeCurrent(dstWin->window());
m_textures->clear();
- for (int i = 0; i < textures->count(); ++i) {
- uint textureId = textures->textureId(i);
- QRect geom = textures->geometry(i);
- m_textures->appendTexture(textureId, geom);
- }
+ for (int i = 0; i < textures->count(); ++i)
+ m_textures->appendTexture(textures->textureId(i), textures->geometry(i), textures->stacksOnTop(i));
updateTexture();
m_textures->appendTexture(m_bsTexture, window->geometry());
@@ -209,9 +209,16 @@ void QEGLPlatformBackingStore::composited()
}
}
-void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn)
+void QEGLPlatformBackingStore::beginPaint(const QRegion &region)
{
- m_dirty |= rgn;
+ m_dirty |= region;
+
+ if (m_image.hasAlphaChannel()) {
+ QPainter p(&m_image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ foreach (const QRect &r, region.rects())
+ p.fillRect(r, Qt::transparent);
+ }
}
void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
@@ -223,7 +230,8 @@ void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticCo
if (!dstWin || (!dstWin->isRaster() && dstWin->window()->surfaceType() != QSurface::RasterGLSurface))
return;
- m_image = QImage(size, QImage::Format_RGB32);
+ m_image = QImage(size, QImage::Format_RGBA8888);
+
m_window->create();
screen->compositingContext()->makeCurrent(dstWin->window());
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
index 57c632a4c5..664e637193 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
@@ -72,14 +72,15 @@ public:
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
+ void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
QImage toImage() const Q_DECL_OVERRIDE;
void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
- QPlatformTextureList *textures, QOpenGLContext *context) Q_DECL_OVERRIDE;
+ QPlatformTextureList *textures, QOpenGLContext *context,
+ bool translucentBackground) Q_DECL_OVERRIDE;
const QPlatformTextureList *textures() const { return m_textures; }
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index eec6463c21..dce8bd888c 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -44,6 +44,7 @@
#include "qeglpbuffer_p.h"
#include <qpa/qplatformwindow.h>
#include <QOpenGLContext>
+#include <QtPlatformHeaders/QEGLNativeContext>
#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -108,25 +109,21 @@ QT_BEGIN_NAMESPACE
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#endif
-QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
- : m_eglDisplay(display)
- , m_eglConfig(q_configFromGLFormat(display, format))
- , m_swapInterval(-1)
- , m_swapIntervalEnvChecked(false)
- , m_swapIntervalFromEnv(-1)
-{
- init(format, share);
-}
-
QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
- EGLConfig config)
+ EGLConfig *config, const QVariant &nativeHandle)
: m_eglDisplay(display)
- , m_eglConfig(config)
, m_swapInterval(-1)
, m_swapIntervalEnvChecked(false)
, m_swapIntervalFromEnv(-1)
{
- init(format, share);
+ if (nativeHandle.isNull()) {
+ m_eglConfig = config ? *config : q_configFromGLFormat(display, format);
+ m_ownsContext = true;
+ init(format, share);
+ } else {
+ m_ownsContext = false;
+ adopt(nativeHandle, share);
+ }
}
void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
@@ -198,7 +195,69 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
q_printEglConfig(m_eglDisplay, m_eglConfig);
}
+ updateFormatFromGL();
+}
+
+void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share)
+{
+ if (!nativeHandle.canConvert<QEGLNativeContext>()) {
+ qWarning("QEGLPlatformContext: Requires a QEGLNativeContext");
+ return;
+ }
+ QEGLNativeContext handle = nativeHandle.value<QEGLNativeContext>();
+ EGLContext context = handle.context();
+ if (!context) {
+ qWarning("QEGLPlatformContext: No EGLContext given");
+ return;
+ }
+
+ // A context belonging to a given EGLDisplay cannot be used with another one.
+ if (handle.display() != m_eglDisplay) {
+ qWarning("QEGLPlatformContext: Cannot adopt context from different display");
+ return;
+ }
+
+ // Figure out the EGLConfig.
+ EGLint value = 0;
+ eglQueryContext(m_eglDisplay, context, EGL_CONFIG_ID, &value);
+ EGLint n = 0;
+ EGLConfig cfg;
+ const EGLint attribs[] = { EGL_CONFIG_ID, value, EGL_NONE };
+ if (eglChooseConfig(m_eglDisplay, attribs, &cfg, 1, &n) && n == 1) {
+ m_eglConfig = cfg;
+ m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig);
+ } else {
+ qWarning("QEGLPlatformContext: Failed to get framebuffer configuration for context");
+ }
+
+ // Fetch client API type.
+ value = 0;
+ eglQueryContext(m_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value);
+ if (value == EGL_OPENGL_API || value == EGL_OPENGL_ES_API) {
+ m_api = value;
+ eglBindAPI(m_api);
+ } else {
+ qWarning("QEGLPlatformContext: Failed to get client API type");
+ m_api = EGL_OPENGL_ES_API;
+ }
+
+ m_eglContext = context;
+ m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0;
+ updateFormatFromGL();
+}
+
+void QEGLPlatformContext::updateFormatFromGL()
+{
#ifndef QT_NO_OPENGL
+ // Have to save & restore to prevent QOpenGLContext::currentContext() from becoming
+ // inconsistent after QOpenGLContext::create().
+ EGLDisplay prevDisplay = eglGetCurrentDisplay();
+ if (prevDisplay == EGL_NO_DISPLAY) // when no context is current
+ prevDisplay = m_eglDisplay;
+ EGLContext prevContext = eglGetCurrentContext();
+ EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW);
+ EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ);
+
// Make the context current to ensure the GL version query works. This needs a surface too.
const EGLint pbufferAttributes[] = {
EGL_WIDTH, 1,
@@ -206,7 +265,11 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
EGL_LARGEST_PBUFFER, EGL_FALSE,
EGL_NONE
};
- EGLSurface pbuffer = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttributes);
+ // Cannot just pass m_eglConfig because it may not be suitable for pbuffers. Instead,
+ // do what QEGLPbuffer would do: request a config with the same attributes but with
+ // PBUFFER_BIT set.
+ EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT);
+ EGLSurface pbuffer = eglCreatePbufferSurface(m_eglDisplay, config, pbufferAttributes);
if (pbuffer == EGL_NO_SURFACE)
return;
@@ -246,7 +309,7 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
}
}
}
- eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext);
}
eglDestroySurface(m_eglDisplay, pbuffer);
#endif // QT_NO_OPENGL
@@ -296,10 +359,10 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
QEGLPlatformContext::~QEGLPlatformContext()
{
- if (m_eglContext != EGL_NO_CONTEXT) {
+ if (m_ownsContext && m_eglContext != EGL_NO_CONTEXT)
eglDestroyContext(m_eglDisplay, m_eglContext);
- m_eglContext = EGL_NO_CONTEXT;
- }
+
+ m_eglContext = EGL_NO_CONTEXT;
}
void QEGLPlatformContext::doneCurrent()
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
index 8fbd573e33..369359fc50 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
@@ -55,6 +55,7 @@
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformopenglcontext.h>
+#include <QtCore/QVariant>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -62,9 +63,8 @@ QT_BEGIN_NAMESPACE
class QEGLPlatformContext : public QPlatformOpenGLContext
{
public:
- QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
- EGLConfig config);
+ EGLConfig *config = 0, const QVariant &nativeHandle = QVariant());
~QEGLPlatformContext();
bool makeCurrent(QPlatformSurface *surface);
@@ -85,6 +85,8 @@ protected:
private:
void init(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
+ void adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share);
+ void updateFormatFromGL();
EGLContext m_eglContext;
EGLContext m_shareContext;
@@ -95,6 +97,7 @@ private:
int m_swapInterval;
bool m_swapIntervalEnvChecked;
int m_swapIntervalFromEnv;
+ bool m_ownsContext;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
index b6293e60ec..7198d7c6fb 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
@@ -343,6 +343,8 @@ void QEGLPlatformCursor::draw(const QRectF &r)
{
if (!m_program) {
// one time initialization
+ initializeOpenGLFunctions();
+
createShaderPrograms();
if (!m_cursorAtlas.texture) {
@@ -387,6 +389,7 @@ void QEGLPlatformCursor::draw(const QRectF &r)
};
glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
m_program->enableAttributeArray(m_vertexCoordEntry);
m_program->enableAttributeArray(m_textureCoordEntry);
diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
index be2ec56787..55c87859be 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
@@ -55,6 +55,7 @@
#include <qpa/qplatformcursor.h>
#include <qpa/qplatformscreen.h>
+#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE
@@ -97,7 +98,7 @@ private:
bool m_active;
};
-class QEGLPlatformCursor : public QPlatformCursor
+class QEGLPlatformCursor : public QPlatformCursor, protected QOpenGLFunctions
{
public:
QEGLPlatformCursor(QPlatformScreen *screen);
@@ -124,7 +125,7 @@ private:
void draw(const QRectF &rect);
void update(const QRegion &region);
void createShaderPrograms();
- static void createCursorTexture(uint *texture, const QImage &image);
+ void createCursorTexture(uint *texture, const QImage &image);
void initCursorAtlas();
// current cursor information
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
index b48f993436..67064f63b5 100644
--- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
@@ -43,6 +43,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOffscreenSurface>
#include <QtGui/QGuiApplication>
+#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontextfactory_p.h>
@@ -57,6 +58,8 @@
#include <QtPlatformSupport/private/qevdevtouch_p.h>
#endif
+#include <QtPlatformHeaders/qeglfsfunctions.h>
+
#include "qeglplatformintegration_p.h"
#include "qeglplatformcontext_p.h"
#include "qeglplatformwindow_p.h"
@@ -93,7 +96,8 @@ QEGLPlatformIntegration::QEGLPlatformIntegration()
m_display(EGL_NO_DISPLAY),
m_inputContext(0),
m_fontDb(new QGenericUnixFontDatabase),
- m_services(new QGenericUnixServices)
+ m_services(new QGenericUnixServices),
+ m_kbdMgr(0)
{
}
@@ -158,9 +162,14 @@ QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOp
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
QOpenGLContext *compositingContext = screen ? screen->compositingContext() : 0;
- return createContext(context->format(),
- compositingContext ? compositingContext->handle() : context->shareHandle(),
- display());
+ QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle();
+ QVariant nativeHandle = context->nativeHandle();
+ QPlatformOpenGLContext *platformContext = createContext(context->format(),
+ share,
+ display(),
+ &nativeHandle);
+ context->setNativeHandle(nativeHandle);
+ return platformContext;
}
QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
@@ -189,7 +198,10 @@ QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const
enum ResourceType {
EglDisplay,
EglWindow,
- EglContext
+ EglContext,
+ EglConfig,
+ NativeDisplay,
+ Display
};
static int resourceType(const QByteArray &key)
@@ -197,7 +209,10 @@ static int resourceType(const QByteArray &key)
static const QByteArray names[] = { // match ResourceType
QByteArrayLiteral("egldisplay"),
QByteArrayLiteral("eglwindow"),
- QByteArrayLiteral("eglcontext")
+ QByteArrayLiteral("eglcontext"),
+ QByteArrayLiteral("eglconfig"),
+ QByteArrayLiteral("nativedisplay"),
+ QByteArrayLiteral("display")
};
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
const QByteArray *result = std::find(names, end, key);
@@ -214,6 +229,26 @@ void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &re
case EglDisplay:
result = m_screen->display();
break;
+ case NativeDisplay:
+ result = reinterpret_cast<void*>(nativeDisplay());
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEGLPlatformIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case Display:
+ // Play nice when using the x11 hooks: Be compatible with xcb that allows querying
+ // the X Display pointer, which is nothing but our native display.
+ result = reinterpret_cast<void*>(nativeDisplay());
+ break;
default:
break;
}
@@ -252,6 +287,14 @@ void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resour
if (context->handle())
result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
break;
+ case EglConfig:
+ if (context->handle())
+ result = static_cast<QEGLPlatformContext *>(context->handle())->eglConfig();
+ break;
+ case EglDisplay:
+ if (context->handle())
+ result = static_cast<QEGLPlatformContext *>(context->handle())->eglDisplay();
+ break;
default:
break;
}
@@ -279,10 +322,35 @@ QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegrati
return 0;
}
+QFunctionPointer QEGLPlatformIntegration::platformFunction(const QByteArray &function) const
+{
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ if (function == QEglFSFunctions::loadKeymapTypeIdentifier())
+ return QFunctionPointer(loadKeymapStatic);
+#else
+ Q_UNUSED(function)
+#endif
+
+ return 0;
+}
+
+void QEGLPlatformIntegration::loadKeymapStatic(const QString &filename)
+{
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ QEGLPlatformIntegration *self = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration());
+ if (self->m_kbdMgr)
+ self->m_kbdMgr->loadKeymap(filename);
+ else
+ qWarning("QEGLPlatformIntegration: Cannot load keymap, no keyboard handler found");
+#else
+ Q_UNUSED(filename);
+#endif
+}
+
void QEGLPlatformIntegration::createInputHandlers()
{
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
+ m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
QEvdevMouseManager *mouseMgr = new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
Q_FOREACH (QScreen *screen, QGuiApplication::screens()) {
QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->handle()->cursor());
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
index cc10f3ed77..b0c3865b25 100644
--- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
@@ -55,6 +55,7 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
+#include <QtCore/QVariant>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -63,6 +64,7 @@ class QEGLPlatformScreen;
class QEGLPlatformWindow;
class QEGLPlatformContext;
class QFbVtHandler;
+class QEvdevKeyboardManager;
class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
{
@@ -90,16 +92,20 @@ public:
QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
// QPlatformNativeInterface
void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
+ void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE;
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+ QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+
protected:
virtual QEGLPlatformScreen *createScreen() const = 0;
virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0;
virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format,
QPlatformOpenGLContext *shareContext,
- EGLDisplay display) const = 0;
+ EGLDisplay display,
+ QVariant *nativeHandle) const = 0;
virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
const QSurfaceFormat &format,
QOffscreenSurface *surface) const = 0;
@@ -109,12 +115,15 @@ protected:
void createInputHandlers();
private:
+ static void loadKeymapStatic(const QString &filename);
+
QEGLPlatformScreen *m_screen;
EGLDisplay m_display;
QPlatformInputContext *m_inputContext;
QScopedPointer<QPlatformFontDatabase> m_fontDb;
QScopedPointer<QPlatformServices> m_services;
QScopedPointer<QFbVtHandler> m_vtHandler;
+ QEvdevKeyboardManager *m_kbdMgr;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
index e9b79512ba..a83dd80391 100644
--- a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
@@ -127,4 +127,12 @@ WId QEGLPlatformWindow::winId() const
return m_winId;
}
+void QEGLPlatformWindow::setOpacity(qreal)
+{
+ if (!isRaster())
+ qWarning("eglfs: Cannot set opacity for non-raster windows");
+
+ // Nothing to do here. The opacity is stored in the QWindow.
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
index 86d6eee57a..536b97e419 100644
--- a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
@@ -75,6 +75,7 @@ public:
bool isRaster() const;
WId winId() const Q_DECL_OVERRIDE;
+ void setOpacity(qreal opacity) Q_DECL_OVERRIDE;
virtual EGLNativeWindowType eglWindow() const = 0;
diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp
index 37d16ddeb6..f4fb41c5a7 100644
--- a/src/platformsupport/fbconvenience/qfbscreen.cpp
+++ b/src/platformsupport/fbconvenience/qfbscreen.cpp
@@ -171,8 +171,7 @@ void QFbScreen::setGeometry(const QRect &rect)
mGeometry = rect;
mScreenImage = new QImage(mGeometry.size(), mFormat);
invalidateRectCache();
- QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
- QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
+ QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry());
resizeMaximizedWindows();
}
@@ -196,13 +195,13 @@ void QFbScreen::generateRects()
remainingScreen -= localGeometry;
QRegion windowRegion(localGeometry);
windowRegion -= remainingScreen;
- foreach (QRect rect, windowRegion.rects()) {
+ foreach (const QRect &rect, windowRegion.rects()) {
mCachedRects += QPair<QRect, int>(rect, i);
}
}
#endif
}
- foreach (QRect rect, remainingScreen.rects())
+ foreach (const QRect &rect, remainingScreen.rects())
mCachedRects += QPair<QRect, int>(rect, -1);
mIsUpToDate = true;
return;
@@ -242,7 +241,7 @@ QRegion QFbScreen::doRedraw()
rectRegion -= intersect;
// we only expect one rectangle, but defensive coding...
- foreach (QRect rect, intersect.rects()) {
+ foreach (const QRect &rect, intersect.rects()) {
bool firstLayer = true;
if (layer == -1) {
mCompositePainter->fillRect(rect, Qt::black);
diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h
index db93304fc7..874702fd47 100644
--- a/src/platformsupport/fbconvenience/qfbscreen_p.h
+++ b/src/platformsupport/fbconvenience/qfbscreen_p.h
@@ -119,7 +119,7 @@ private:
void generateRects();
QPainter *mCompositePainter;
- QList<QPair<QRect, int> > mCachedRects;
+ QVector<QPair<QRect, int> > mCachedRects;
QList <QFbBackingStore*> mBackingStores;
friend class QFbWindow;
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 26ae0eb724..75359fbaa3 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -96,8 +96,9 @@ void QBasicFontDatabase::populateFontDatabase()
QString fontpath = fontDir();
if(!QFile::exists(fontpath)) {
- qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
+ qWarning("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
qPrintable(fontpath));
+ return;
}
QDir dir(fontpath);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index b8da9726d5..13a4c13099 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -51,7 +51,6 @@
#include <qpa/qplatformservices.h>
#include <QtGui/private/qfontengine_ft_p.h>
-#include <QtGui/private/qfontengine_qpa_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qguiapplication.h>
@@ -517,21 +516,20 @@ QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
}
namespace {
-QFontEngineFT::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match)
+QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match, bool useXftConf)
{
switch (hintingPreference) {
case QFont::PreferNoHinting:
- return QFontEngineFT::HintNone;
+ return QFontEngine::HintNone;
case QFont::PreferVerticalHinting:
- return QFontEngineFT::HintLight;
+ return QFontEngine::HintLight;
case QFont::PreferFullHinting:
- return QFontEngineFT::HintFull;
+ return QFontEngine::HintFull;
case QFont::PreferDefaultHinting:
break;
}
- const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
- if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
+ if (useXftConf) {
void *hintStyleResource =
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
QGuiApplication::primaryScreen());
@@ -545,42 +543,51 @@ QFontEngineFT::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hint
hint_style = FC_HINT_FULL;
switch (hint_style) {
case FC_HINT_NONE:
- return QFontEngineFT::HintNone;
+ return QFontEngine::HintNone;
case FC_HINT_SLIGHT:
- return QFontEngineFT::HintLight;
+ return QFontEngine::HintLight;
case FC_HINT_MEDIUM:
- return QFontEngineFT::HintMedium;
+ return QFontEngine::HintMedium;
case FC_HINT_FULL:
- return QFontEngineFT::HintFull;
+ return QFontEngine::HintFull;
default:
Q_UNREACHABLE();
break;
}
- return QFontEngineFT::HintFull;
+ return QFontEngine::HintFull;
}
-QFontEngineFT::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match)
+QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bool useXftConf)
{
+ if (useXftConf) {
+ void *subpixelTypeResource =
+ QGuiApplication::platformNativeInterface()->nativeResourceForScreen("subpixeltype",
+ QGuiApplication::primaryScreen());
+ int subpixelType = int(reinterpret_cast<qintptr>(subpixelTypeResource));
+ if (subpixelType > 0)
+ return QFontEngine::SubpixelAntialiasingType(subpixelType - 1);
+ }
+
int subpixel = FC_RGBA_UNKNOWN;
FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
switch (subpixel) {
case FC_RGBA_UNKNOWN:
case FC_RGBA_NONE:
- return QFontEngineFT::Subpixel_None;
+ return QFontEngine::Subpixel_None;
case FC_RGBA_RGB:
- return QFontEngineFT::Subpixel_RGB;
+ return QFontEngine::Subpixel_RGB;
case FC_RGBA_BGR:
- return QFontEngineFT::Subpixel_BGR;
+ return QFontEngine::Subpixel_BGR;
case FC_RGBA_VRGB:
- return QFontEngineFT::Subpixel_VRGB;
+ return QFontEngine::Subpixel_VRGB;
case FC_RGBA_VBGR:
- return QFontEngineFT::Subpixel_VBGR;
+ return QFontEngine::Subpixel_VBGR;
default:
Q_UNREACHABLE();
break;
}
- return QFontEngineFT::Subpixel_None;
+ return QFontEngine::Subpixel_None;
}
} // namespace
@@ -597,9 +604,23 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
fid.index = fontfile->indexValue;
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ bool forcedAntialiasSetting = !antialias;
engine = new QFontEngineFT(fontDef);
- QFontEngineFT::GlyphFormat format;
+ const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
+ bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY"));
+ if (useXftConf) {
+ void *antialiasResource =
+ QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
+ QGuiApplication::primaryScreen());
+ int antialiasingEnabled = int(reinterpret_cast<qintptr>(antialiasResource));
+ if (antialiasingEnabled > 0) {
+ antialias = antialiasingEnabled - 1;
+ forcedAntialiasSetting = true;
+ }
+ }
+
+ QFontEngine::GlyphFormat format;
// try and get the pattern
FcPattern *pattern = FcPatternCreate();
@@ -623,29 +644,39 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
FcPattern *match = FcFontMatch(0, pattern, &result);
if (match) {
- engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match));
+ engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match, useXftConf));
- if (antialias) {
- // If antialiasing is not fully disabled, fontconfig may still disable it on a font match basis.
+ FcBool fc_autohint;
+ if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
+ engine->forceAutoHint = fc_autohint;
+
+#if defined(FT_LCD_FILTER_H)
+ int lcdFilter;
+ if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch)
+ engine->lcdFilterType = lcdFilter;
+#endif
+
+ if (!forcedAntialiasSetting) {
FcBool fc_antialias;
- if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
- fc_antialias = true;
- antialias = fc_antialias;
+ if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
+ antialias = fc_antialias;
}
if (antialias) {
- QFontEngineFT::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
+ QFontEngine::SubpixelAntialiasingType subpixelType = QFontEngine::Subpixel_None;
+ if (!(f.styleStrategy & QFont::NoSubpixelAntialias))
+ subpixelType = subpixelTypeFromMatch(match, useXftConf);
engine->subpixelType = subpixelType;
- format = (subpixelType == QFontEngineFT::Subpixel_None)
- ? QFontEngineFT::Format_A8
- : QFontEngineFT::Format_A32;
+ format = (subpixelType == QFontEngine::Subpixel_None)
+ ? QFontEngine::Format_A8
+ : QFontEngine::Format_A32;
} else
- format = QFontEngineFT::Format_Mono;
+ format = QFontEngine::Format_Mono;
FcPatternDestroy(match);
} else
- format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ format = antialias ? QFontEngine::Format_A8 : QFontEngine::Format_Mono;
FcPatternDestroy(pattern);
@@ -665,7 +696,21 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p
QFontDef fontDef = engine->fontDef;
- QFontEngineFT::GlyphFormat format;
+ bool forcedAntialiasSetting = false;
+ const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
+ bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY"));
+ if (useXftConf) {
+ void *antialiasResource =
+ QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
+ QGuiApplication::primaryScreen());
+ int antialiasingEnabled = int(reinterpret_cast<qintptr>(antialiasResource));
+ if (antialiasingEnabled > 0) {
+ engine->antialias = antialiasingEnabled - 1;
+ forcedAntialiasSetting = true;
+ }
+ }
+
+ QFontEngine::GlyphFormat format;
// try and get the pattern
FcPattern *pattern = FcPatternCreate();
@@ -682,25 +727,36 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p
FcPattern *match = FcFontMatch(0, pattern, &result);
if (match) {
- engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match));
+ engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match, useXftConf));
- FcBool fc_antialias;
- if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
- fc_antialias = true;
- engine->antialias = fc_antialias;
+ FcBool fc_autohint;
+ if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
+ engine->forceAutoHint = fc_autohint;
+
+#if defined(FT_LCD_FILTER_H)
+ int lcdFilter;
+ if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch)
+ engine->lcdFilterType = lcdFilter;
+#endif
+
+ if (!forcedAntialiasSetting) {
+ FcBool fc_antialias;
+ if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
+ engine->antialias = fc_antialias;
+ }
if (engine->antialias) {
- QFontEngineFT::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
+ QFontEngine::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match, useXftConf);
engine->subpixelType = subpixelType;
- format = subpixelType == QFontEngineFT::Subpixel_None
- ? QFontEngineFT::Format_A8
- : QFontEngineFT::Format_A32;
+ format = subpixelType == QFontEngine::Subpixel_None
+ ? QFontEngine::Format_A8
+ : QFontEngine::Format_A32;
} else
- format = QFontEngineFT::Format_Mono;
+ format = QFontEngine::Format_Mono;
FcPatternDestroy(match);
} else
- format = QFontEngineFT::Format_A8;
+ format = QFontEngine::Format_A8;
FcPatternDestroy(pattern);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
index fec489ba60..20cdab6de1 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
QFontEngineMultiFontConfig::QFontEngineMultiFontConfig(QFontEngine *fe, int script)
- : QFontEngineMultiQPA(fe, script)
+ : QFontEngineMultiBasicImpl(fe, script)
{
}
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h
index 3c2be10be6..e6fdef37b0 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h
@@ -53,12 +53,12 @@
// We mean it.
//
-#include <QtGui/private/qfontengine_qpa_p.h>
+#include <QtGui/private/qfontengine_p.h>
#include <fontconfig/fontconfig.h>
QT_BEGIN_NAMESPACE
-class QFontEngineMultiFontConfig : public QFontEngineMultiQPA
+class QFontEngineMultiFontConfig : public QFontEngineMultiBasicImpl
{
public:
explicit QFontEngineMultiFontConfig(QFontEngine *fe, int script);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 063d20dbd4..f213f6b04c 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -52,6 +52,7 @@
#include "qfontengine_coretext_p.h"
#include <QtCore/QSettings>
#include <QtGui/QGuiApplication>
+#include <QtCore/QtEndian>
QT_BEGIN_NAMESPACE
@@ -262,6 +263,27 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
fd->stretch = QFont::Unstretched;
fd->fixedPitch = false;
+ if (QCFType<CTFontRef> tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) {
+ uint length = 0;
+ uint tag = MAKE_TAG('O', 'S', '/', '2');
+ CTFontRef tempFontRef = tempFont;
+ void *userData = reinterpret_cast<void *>(&tempFontRef);
+ if (QCoreTextFontEngine::ct_getSfntTable(userData, tag, 0, &length)) {
+ QVarLengthArray<uchar> os2Table(length);
+ if (length >= 86 && QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length)) {
+ quint32 unicodeRange[4] = {
+ qFromBigEndian<quint32>(os2Table.data() + 42),
+ qFromBigEndian<quint32>(os2Table.data() + 46),
+ qFromBigEndian<quint32>(os2Table.data() + 50),
+ qFromBigEndian<quint32>(os2Table.data() + 54)
+ };
+ quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78),
+ qFromBigEndian<quint32>(os2Table.data() + 82) };
+ fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ }
+ }
+ }
+
if (styles) {
if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
double normalizedWeight;
@@ -384,7 +406,7 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal
QFontEngine *fontEngine = NULL;
if (cgFont == NULL) {
- qWarning("QRawFont::platformLoadFromData: CGFontCreateWithDataProvider failed");
+ qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed");
} else {
QFontDef def;
def.pixelSize = pixelSize;
@@ -459,6 +481,17 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
QCFString fallbackFamilyName = (CFStringRef) CTFontDescriptorCopyAttribute(fontFallback, kCTFontFamilyNameAttribute);
fallbackList.append(QCFString::toQString(fallbackFamilyName));
}
+
+#if defined(Q_OS_OSX)
+ // Since we are only returning a list of default fonts for the current language, we do not
+ // cover all unicode completely. This was especially an issue for some of the common script
+ // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
+ // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
+ // of Unicode 2.1.
+ if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
+ fallbackList.append(QStringLiteral("Arial Unicode MS"));
+#endif
+
fallbackLists[family] = fallbackList;
}
}
@@ -502,6 +535,14 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
if (QCoreTextFontEngine::supportsColorGlyphs())
fallbackList.append(QLatin1String("Apple Color Emoji"));
+ // Since we are only returning a list of default fonts for the current language, we do not
+ // cover all unicode completely. This was especially an issue for some of the common script
+ // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
+ // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
+ // of Unicode 2.1.
+ if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
+ fallbackList.append(QStringLiteral("Arial Unicode MS"));
+
fallbackLists[styleLookupKey.arg(fallbackStyleHint)] = fallbackList;
}
#else
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 6e2c8a2a9a..f96163fc5b 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
-static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
+bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
{
CTFontRef ctfont = *(CTFontRef *)user_data;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index 8157742219..380b3a711d 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -129,6 +129,8 @@ public:
#endif
}
+ static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length);
+
static int antialiasingThreshold;
static QFontEngine::GlyphFormat defaultGlyphFormat;
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp
index 4630b12a57..851ad37a6a 100644
--- a/src/platformsupport/glxconvenience/qglxconvenience.cpp
+++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp
@@ -250,7 +250,7 @@ XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *f
return visualInfo;
}
-void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config, GLXContext)
+void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config)
{
int redSize = 0;
int greenSize = 0;
@@ -262,8 +262,6 @@ void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display,
int sampleCount = 0;
int stereo = 0;
- XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
- XFree(vi);
glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
@@ -287,6 +285,41 @@ void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display,
format->setStereo(stereo);
}
+void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo)
+{
+ int redSize = 0;
+ int greenSize = 0;
+ int blueSize = 0;
+ int alphaSize = 0;
+ int depthSize = 0;
+ int stencilSize = 0;
+ int sampleBuffers = 0;
+ int sampleCount = 0;
+ int stereo = 0;
+
+ glXGetConfig(display, visualInfo, GLX_RED_SIZE, &redSize);
+ glXGetConfig(display, visualInfo, GLX_GREEN_SIZE, &greenSize);
+ glXGetConfig(display, visualInfo, GLX_BLUE_SIZE, &blueSize);
+ glXGetConfig(display, visualInfo, GLX_ALPHA_SIZE, &alphaSize);
+ glXGetConfig(display, visualInfo, GLX_DEPTH_SIZE, &depthSize);
+ glXGetConfig(display, visualInfo, GLX_STENCIL_SIZE, &stencilSize);
+ glXGetConfig(display, visualInfo, GLX_SAMPLES_ARB, &sampleBuffers);
+ glXGetConfig(display, visualInfo, GLX_STEREO, &stereo);
+
+ format->setRedBufferSize(redSize);
+ format->setGreenBufferSize(greenSize);
+ format->setBlueBufferSize(blueSize);
+ format->setAlphaBufferSize(alphaSize);
+ format->setDepthBufferSize(depthSize);
+ format->setStencilBufferSize(stencilSize);
+ if (sampleBuffers) {
+ glXGetConfig(display, visualInfo, GLX_SAMPLES_ARB, &sampleCount);
+ format->setSamples(sampleCount);
+ }
+
+ format->setStereo(stereo);
+}
+
QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced)
{
QSurfaceFormat retFormat = format;
diff --git a/src/platformsupport/glxconvenience/qglxconvenience_p.h b/src/platformsupport/glxconvenience/qglxconvenience_p.h
index 0477589d6c..bba177b14b 100644
--- a/src/platformsupport/glxconvenience/qglxconvenience_p.h
+++ b/src/platformsupport/glxconvenience/qglxconvenience_p.h
@@ -61,7 +61,8 @@
XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format);
GLXFBConfig qglx_findConfig(Display *display, int screen, const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT);
-void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config, GLXContext context = 0);
+void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config);
+void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo);
QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT);
QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced);
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
index 0841544208..9c44283b0e 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -93,13 +93,15 @@ QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
qt_safe_close(m_fd);
}
-QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, const QString &specification)
+QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
+ const QString &specification,
+ const QString &defaultKeymapFile)
{
#ifdef QT_QPA_KEYMAP_DEBUG
qWarning() << "Try to create keyboard handler for" << device << specification;
#endif
- QString keymapFile;
+ QString keymapFile = defaultKeymapFile;
int repeatDelay = 400;
int repeatRate = 80;
bool disableZap = false;
@@ -406,6 +408,53 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint
#ifdef QT_QPA_KEYMAP_DEBUG
qWarning("Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask));
#endif
+ //If NumLockOff and keypad key pressed remap event sent
+ if (!m_locks[1] &&
+ (qtcode & Qt::KeypadModifier) &&
+ keycode >= 71 &&
+ keycode <= 83 &&
+ keycode != 74 &&
+ keycode != 78) {
+
+ unicode = 0xffff;
+ int oldMask = (qtcode & modmask);
+ switch (keycode) {
+ case 71: //7 --> Home
+ qtcode = Qt::Key_Home;
+ break;
+ case 72: //8 --> Up
+ qtcode = Qt::Key_Up;
+ break;
+ case 73: //9 --> PgUp
+ qtcode = Qt::Key_PageUp;
+ break;
+ case 75: //4 --> Left
+ qtcode = Qt::Key_Left;
+ break;
+ case 76: //5 --> Clear
+ qtcode = Qt::Key_Clear;
+ break;
+ case 77: //6 --> right
+ qtcode = Qt::Key_Right;
+ break;
+ case 79: //1 --> End
+ qtcode = Qt::Key_End;
+ break;
+ case 80: //2 --> Down
+ qtcode = Qt::Key_Down;
+ break;
+ case 81: //3 --> PgDn
+ qtcode = Qt::Key_PageDown;
+ break;
+ case 82: //0 --> Ins
+ qtcode = Qt::Key_Insert;
+ break;
+ case 83: //, --> Del
+ qtcode = Qt::Key_Delete;
+ break;
+ }
+ qtcode ^= oldMask;
+ }
// send the result to the server
processKeyEvent(keycode, unicode, qtcode & ~modmask, Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat);
@@ -435,6 +484,29 @@ void QEvdevKeyboardHandler::unloadKeymap()
memset(m_locks, 0, sizeof(m_locks));
m_composing = 0;
m_dead_unicode = 0xffff;
+
+ //Set locks according to keyboard leds
+ quint16 ledbits[1];
+ memset(ledbits, 0, sizeof(ledbits));
+ if (::ioctl(m_fd, EVIOCGLED(sizeof(ledbits)), ledbits) < 0) {
+ qWarning("Failed to query led states. Settings numlock & capslock off");
+ switchLed(LED_NUML,false);
+ switchLed(LED_CAPSL, false);
+ switchLed(LED_SCROLLL,false);
+ } else {
+ //Capslock
+ if ((ledbits[0]&0x02) > 0)
+ m_locks[0] = 1;
+ //Numlock
+ if ((ledbits[0]&0x01) > 0)
+ m_locks[1] = 1;
+ //Scrollock
+ if ((ledbits[0]&0x04) > 0)
+ m_locks[2] = 1;
+#ifdef QT_QPA_KEYMAP_DEBUG
+ qWarning("numlock=%d , capslock=%d, scrolllock=%d",m_locks[1],m_locks[0],m_locks[2]);
+#endif
+ }
}
bool QEvdevKeyboardHandler::loadKeymap(const QString &file)
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
index 81bc2f6154..06b7818135 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
@@ -156,7 +156,9 @@ public:
SwitchConsoleMask = 0x0000007f
};
- static QEvdevKeyboardHandler *create(const QString &device, const QString &specification);
+ static QEvdevKeyboardHandler *create(const QString &device,
+ const QString &specification,
+ const QString &defaultKeymapFile = QString());
static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
{
@@ -172,13 +174,14 @@ public:
return qtmod;
}
+ bool loadKeymap(const QString &file);
+ void unloadKeymap();
+
private slots:
void readKeycode();
KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat);
private:
- void unloadKeymap();
- bool loadKeymap(const QString &file);
void processKeyEvent(int nativecode, int unicode, int qtcode,
Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat);
void switchLed(int, bool);
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp
index 4932087c5f..4ceaf98055 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp
@@ -113,7 +113,7 @@ void QEvdevKeyboardManager::addKeyboard(const QString &deviceNode)
#endif
QEvdevKeyboardHandler *keyboard;
- keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec);
+ keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec, m_defaultKeymapFile);
if (keyboard)
m_keyboards.insert(deviceNode, keyboard);
else
@@ -132,4 +132,28 @@ void QEvdevKeyboardManager::removeKeyboard(const QString &deviceNode)
}
}
+void QEvdevKeyboardManager::loadKeymap(const QString &file)
+{
+ m_defaultKeymapFile = file;
+
+ if (file.isEmpty()) {
+ // Restore the default, which is either the built-in keymap or
+ // the one given in the plugin spec.
+ QString keymapFromSpec;
+ foreach (const QString &arg, m_spec.split(QLatin1Char(':'))) {
+ if (arg.startsWith(QLatin1String("keymap=")))
+ keymapFromSpec = arg.mid(7);
+ }
+ foreach (QEvdevKeyboardHandler *handler, m_keyboards) {
+ if (keymapFromSpec.isEmpty())
+ handler->unloadKeymap();
+ else
+ handler->loadKeymap(keymapFromSpec);
+ }
+ } else {
+ foreach (QEvdevKeyboardHandler *handler, m_keyboards)
+ handler->loadKeymap(file);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h
index 0b1ccc23ab..c59de3ca09 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h
@@ -70,6 +70,8 @@ public:
QEvdevKeyboardManager(const QString &key, const QString &specification, QObject *parent = 0);
~QEvdevKeyboardManager();
+ void loadKeymap(const QString &file);
+
private slots:
void addKeyboard(const QString &deviceNode = QString());
void removeKeyboard(const QString &deviceNode);
@@ -78,6 +80,7 @@ private:
QString m_spec;
QHash<QString,QEvdevKeyboardHandler*> m_keyboards;
QDeviceDiscovery *m_deviceDiscovery;
+ QString m_defaultKeymapFile;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
index 92f807095f..611a7f9d6d 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
@@ -60,6 +60,8 @@
//#define QT_QPA_MOUSE_HANDLER_DEBUG
+#define TEST_BIT(array, bit) (array[bit/8] & (1<<(bit%8)))
+
QT_BEGIN_NAMESPACE
QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QString &specification)
@@ -71,6 +73,7 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
bool compression = true;
int jitterLimit = 0;
int grab = 0;
+ bool abs = false;
QStringList args = specification.split(QLatin1Char(':'));
foreach (const QString &arg, args) {
@@ -80,27 +83,37 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
jitterLimit = arg.mid(9).toInt();
else if (arg.startsWith(QLatin1String("grab=")))
grab = arg.mid(5).toInt();
+ else if (arg == QLatin1String("abs"))
+ abs = true;
}
int fd;
fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if (fd >= 0) {
::ioctl(fd, EVIOCGRAB, grab);
- return new QEvdevMouseHandler(device, fd, compression, jitterLimit);
+ return new QEvdevMouseHandler(device, fd, abs, compression, jitterLimit);
} else {
qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno));
return 0;
}
}
-QEvdevMouseHandler::QEvdevMouseHandler(const QString &device, int fd, bool compression, int jitterLimit)
+QEvdevMouseHandler::QEvdevMouseHandler(const QString &device, int fd, bool abs, bool compression, int jitterLimit)
: m_device(device), m_fd(fd), m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0),
- m_compression(compression), m_buttons(0), m_prevInvalid(true)
+ m_abs(abs), m_compression(compression), m_buttons(0), m_prevInvalid(true)
{
setObjectName(QLatin1String("Evdev Mouse Handler"));
m_jitterLimitSquared = jitterLimit * jitterLimit;
+ // Some touch screens present as mice with absolute coordinates.
+ // These can not be differentiated from touchpads, so supplying abs to QT_QPA_EVDEV_MOUSE_PARAMETERS
+ // will force qevdevmousehandler to treat the coordinates as absolute, scaled to the hardware maximums.
+ // Turning this on will not affect mice as these do not report in absolute coordinates
+ // but will make touchpads act like touch screens
+ if (m_abs)
+ m_abs = getHardwareMaximum();
+
// socket notifier for events on the mouse device
QSocketNotifier *notifier;
notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
@@ -113,16 +126,66 @@ QEvdevMouseHandler::~QEvdevMouseHandler()
qt_safe_close(m_fd);
}
+// Ask touch screen hardware for information on coordinate maximums
+// If any ioctls fail, revert to non abs mode
+bool QEvdevMouseHandler::getHardwareMaximum()
+{
+ unsigned char absFeatures[(ABS_MAX / 8) + 1];
+ memset(absFeatures, '\0', sizeof (absFeatures));
+
+ // test if ABS_X, ABS_Y are available
+ if (ioctl(m_fd, EVIOCGBIT(EV_ABS, sizeof (absFeatures)), absFeatures) == -1)
+ return false;
+
+ if ((!TEST_BIT(absFeatures, ABS_X)) || (!TEST_BIT(absFeatures, ABS_Y)))
+ return false;
+
+ // ask hardware for minimum and maximum values
+ struct input_absinfo absInfo;
+ if (ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) == -1)
+ return false;
+
+ m_hardwareWidth = absInfo.maximum - absInfo.minimum;
+
+ if (ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) == -1)
+ return false;
+
+ m_hardwareHeight = absInfo.maximum - absInfo.minimum;
+
+ QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ m_hardwareScalerX = static_cast<qreal>(m_hardwareWidth) / (g.right() - g.left());
+ m_hardwareScalerY = static_cast<qreal>(m_hardwareHeight) / (g.bottom() - g.top());
+
+#ifdef QT_QPA_MOUSE_HANDLER_DEBUG
+ qDebug() << "Absolute pointing device";
+ qDebug() << "hardware max x" << m_hardwareWidth;
+ qDebug() << "hardware max y" << m_hardwareHeight;
+ qDebug() << "hardware scalers x" << m_hardwareScalerX << "y" << m_hardwareScalerY;
+#endif
+
+ return true;
+}
+
void QEvdevMouseHandler::sendMouseEvent()
{
- int x = m_x - m_prevx;
- int y = m_y - m_prevy;
+ int x;
+ int y;
+
+ if (!m_abs) {
+ x = m_x - m_prevx;
+ y = m_y - m_prevy;
+ }
+ else {
+ x = m_x / m_hardwareScalerX;
+ y = m_y / m_hardwareScalerY;
+ }
+
if (m_prevInvalid) {
x = y = 0;
m_prevInvalid = false;
}
- emit handleMouseEvent(x, y, m_buttons);
+ emit handleMouseEvent(x, y, m_abs, m_buttons);
m_prevx = m_x;
m_prevy = m_y;
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h b/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h
index 5d8a536ee1..ee284bd7ed 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h
+++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h
@@ -68,26 +68,32 @@ public:
~QEvdevMouseHandler();
signals:
- void handleMouseEvent(int x, int y, Qt::MouseButtons buttons);
+ void handleMouseEvent(int x, int y, bool abs, Qt::MouseButtons buttons);
void handleWheelEvent(int delta, Qt::Orientation orientation);
private slots:
void readMouseData();
private:
- QEvdevMouseHandler(const QString &device, int fd, bool compression, int jitterLimit);
+ QEvdevMouseHandler(const QString &device, int fd, bool abs, bool compression, int jitterLimit);
void sendMouseEvent();
+ bool getHardwareMaximum();
QString m_device;
int m_fd;
QSocketNotifier *m_notify;
int m_x, m_y;
int m_prevx, m_prevy;
+ bool m_abs;
bool m_compression;
Qt::MouseButtons m_buttons;
int m_jitterLimitSquared;
bool m_prevInvalid;
+ int m_hardwareWidth;
+ int m_hardwareHeight;
+ qreal m_hardwareScalerY;
+ qreal m_hardwareScalerX;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
index 6c430091c1..87f3a4c9a0 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
@@ -111,11 +111,16 @@ QEvdevMouseManager::~QEvdevMouseManager()
m_mice.clear();
}
-void QEvdevMouseManager::handleMouseEvent(int x, int y, Qt::MouseButtons buttons)
+void QEvdevMouseManager::handleMouseEvent(int x, int y, bool abs, Qt::MouseButtons buttons)
{
// update current absolute coordinates
- m_x += x;
- m_y += y;
+ if (!abs) {
+ m_x += x;
+ m_y += y;
+ } else {
+ m_x = x;
+ m_y = y;
+ }
// clamp to screen geometry
QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
@@ -130,7 +135,9 @@ void QEvdevMouseManager::handleMouseEvent(int x, int y, Qt::MouseButtons buttons
m_y = g.bottom() - m_yoffset;
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
- QWindowSystemInterface::handleMouseEvent(0, pos, pos, buttons);
+ // Cannot track the keyboard modifiers ourselves here. Instead, report the
+ // modifiers from the last key event that has been seen by QGuiApplication.
+ QWindowSystemInterface::handleMouseEvent(0, pos, pos, buttons, QGuiApplication::keyboardModifiers());
#ifdef QT_QPA_MOUSEMANAGER_DEBUG
qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(buttons));
@@ -140,7 +147,7 @@ void QEvdevMouseManager::handleMouseEvent(int x, int y, Qt::MouseButtons buttons
void QEvdevMouseManager::handleWheelEvent(int delta, Qt::Orientation orientation)
{
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
- QWindowSystemInterface::handleWheelEvent(0, pos, pos, delta, orientation);
+ QWindowSystemInterface::handleWheelEvent(0, pos, pos, delta, orientation, QGuiApplication::keyboardModifiers());
#ifdef QT_QPA_MOUSEMANAGER_DEBUG
qDebug("mouse wheel event %dx%d %d %d", pos.x(), pos.y(), delta, int(orientation));
@@ -156,7 +163,7 @@ void QEvdevMouseManager::addMouse(const QString &deviceNode)
QEvdevMouseHandler *handler;
handler = QEvdevMouseHandler::create(deviceNode, m_spec);
if (handler) {
- connect(handler, SIGNAL(handleMouseEvent(int,int,Qt::MouseButtons)), this, SLOT(handleMouseEvent(int,int,Qt::MouseButtons)));
+ connect(handler, SIGNAL(handleMouseEvent(int,int,bool,Qt::MouseButtons)), this, SLOT(handleMouseEvent(int,int,bool,Qt::MouseButtons)));
connect(handler, SIGNAL(handleWheelEvent(int,Qt::Orientation)), this, SLOT(handleWheelEvent(int,Qt::Orientation)));
m_mice.insert(deviceNode, handler);
} else {
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h
index 662b216b11..83d8b314aa 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h
+++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h
@@ -73,7 +73,7 @@ public:
QDeviceDiscovery *deviceDiscovery() { return m_deviceDiscovery; }
public slots:
- void handleMouseEvent(int x, int y, Qt::MouseButtons buttons);
+ void handleMouseEvent(int x, int y, bool abs, Qt::MouseButtons buttons);
void handleWheelEvent(int delta, Qt::Orientation orientation);
private slots:
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
index 563edf4fd7..6ed4abaeee 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
@@ -184,6 +184,8 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
QString dev;
int rotationAngle = 0;
+ bool invertx = false;
+ bool inverty = false;
for (int i = 0; i < args.count(); ++i) {
if (args.at(i).startsWith(QLatin1String("/dev/")) && dev.isEmpty()) {
dev = args.at(i);
@@ -201,6 +203,10 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
break;
}
}
+ } else if (args.at(i) == QLatin1String("invertx")) {
+ invertx = true;
+ } else if (args.at(i) == QLatin1String("inverty")) {
+ inverty = true;
}
}
@@ -326,6 +332,12 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
if (rotationAngle)
d->m_rotate = QTransform::fromTranslate(0.5, 0.5).rotate(rotationAngle).translate(-0.5, -0.5);
+ if (invertx)
+ d->m_rotate *= QTransform::fromTranslate(0.5, 0.5).scale(-1.0, 1.0).translate(-0.5, -0.5);
+
+ if (inverty)
+ d->m_rotate *= QTransform::fromTranslate(0.5, 0.5).scale(1.0, -1.0).translate(-0.5, -0.5);
+
d->registerDevice();
}
diff --git a/src/platformsupport/linuxaccessibility/application.cpp b/src/platformsupport/linuxaccessibility/application.cpp
index ae52ab3b57..c651d604ae 100644
--- a/src/platformsupport/linuxaccessibility/application.cpp
+++ b/src/platformsupport/linuxaccessibility/application.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -47,6 +47,7 @@
#include <qdebug.h>
#include "deviceeventcontroller_adaptor.h"
+#include "atspi/atspi-constants.h"
//#define KEYBOARD_DEBUG
@@ -62,7 +63,7 @@ QT_BEGIN_NAMESPACE
*/
QSpiApplicationAdaptor::QSpiApplicationAdaptor(const QDBusConnection &connection, QObject *parent)
- : QObject(parent), dbusConnection(connection)
+ : QObject(parent), dbusConnection(connection), inCapsLock(false)
{
}
@@ -107,13 +108,14 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
de.id = keyEvent->nativeVirtualKey();
de.hardwareCode = keyEvent->nativeScanCode();
- de.modifiers = keyEvent->nativeModifiers();
de.timestamp = QDateTime::currentMSecsSinceEpoch();
if (keyEvent->key() == Qt::Key_Tab)
de.text = QStringLiteral("Tab");
else if (keyEvent->key() == Qt::Key_Backtab)
de.text = QStringLiteral("Backtab");
+ else if (keyEvent->key() == Qt::Key_Control)
+ de.text = QStringLiteral("Control_L");
else if (keyEvent->key() == Qt::Key_Left)
de.text = (keyEvent->modifiers() & Qt::KeypadModifier) ? QStringLiteral("KP_Left") : QStringLiteral("Left");
else if (keyEvent->key() == Qt::Key_Right)
@@ -142,9 +144,13 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
de.text = QStringLiteral("Escape");
else if (keyEvent->key() == Qt::Key_Space)
de.text = QStringLiteral("space");
- else if (keyEvent->key() == Qt::Key_CapsLock)
+ else if (keyEvent->key() == Qt::Key_CapsLock) {
de.text = QStringLiteral("Caps_Lock");
- else if (keyEvent->key() == Qt::Key_NumLock)
+ if (event->type() == QEvent::KeyPress)
+ inCapsLock = true;
+ else
+ inCapsLock = false;
+ } else if (keyEvent->key() == Qt::Key_NumLock)
de.text = QStringLiteral("Num_Lock");
else if (keyEvent->key() == Qt::Key_Insert)
de.text = QStringLiteral("Insert");
@@ -155,18 +161,30 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
// Long term the spec will hopefully change to just use keycodes.
de.isText = !de.text.isEmpty();
+ de.modifiers = 0;
+ if (!inCapsLock && keyEvent->modifiers() & Qt::ShiftModifier)
+ de.modifiers |= 1 << ATSPI_MODIFIER_SHIFT;
+ if (inCapsLock && (keyEvent->key() != Qt::Key_CapsLock))
+ de.modifiers |= 1 << ATSPI_MODIFIER_SHIFTLOCK;
+ if ((keyEvent->modifiers() & Qt::ControlModifier) && (keyEvent->key() != Qt::Key_Control))
+ de.modifiers |= 1 << ATSPI_MODIFIER_CONTROL;
+ if ((keyEvent->modifiers() & Qt::AltModifier) && (keyEvent->key() != Qt::Key_Alt))
+ de.modifiers |= 1 << ATSPI_MODIFIER_ALT;
+ if ((keyEvent->modifiers() & Qt::MetaModifier) && (keyEvent->key() != Qt::Key_Meta))
+ de.modifiers |= 1 << ATSPI_MODIFIER_META;
+
#ifdef KEYBOARD_DEBUG
- qDebug() << QStringLiteral("Key event text: ") << event->type() << de.isText << QStringLiteral(" ") << de.text
- << QStringLiteral(" hardware code: ") << de.hardwareCode
- << QStringLiteral(" native sc: ") << keyEvent->nativeScanCode()
- << QStringLiteral(" native mod: ") << keyEvent->nativeModifiers()
- << QStringLiteral("native virt: ") << keyEvent->nativeVirtualKey();
+ qDebug() << QStringLiteral("Key event text:") << event->type() << de.text
+ << QStringLiteral("native virtual key:") << de.id
+ << QStringLiteral("hardware code/scancode:") << de.hardwareCode
+ << QStringLiteral("modifiers:") << de.modifiers
+ << QStringLiteral("text:") << de.text;
#endif
QDBusMessage m = QDBusMessage::createMethodCall(QStringLiteral("org.a11y.atspi.Registry"),
QStringLiteral("/org/a11y/atspi/registry/deviceeventcontroller"),
QStringLiteral("org.a11y.atspi.DeviceEventController"), QStringLiteral("NotifyListenersSync"));
- m.setArguments(QVariantList() <<QVariant::fromValue(de));
+ m.setArguments(QVariantList() << QVariant::fromValue(de));
// FIXME: this is critical, the timeout should probably be pretty low to allow normal processing
int timeout = 100;
@@ -175,9 +193,6 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event)
if (sent) {
//queue the event and send it after callback
keyEvents.enqueue(QPair<QPointer<QObject>, QKeyEvent*> (QPointer<QObject>(target), copyKeyEvent(keyEvent)));
-#ifdef KEYBOARD_DEBUG
- qDebug() << QStringLiteral("Sent key: ") << de.text;
-#endif
return true;
}
}
diff --git a/src/platformsupport/linuxaccessibility/application_p.h b/src/platformsupport/linuxaccessibility/application_p.h
index 9a33c21ab6..32036eb2c4 100644
--- a/src/platformsupport/linuxaccessibility/application_p.h
+++ b/src/platformsupport/linuxaccessibility/application_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -89,6 +89,7 @@ private:
QQueue<QPair<QPointer<QObject>, QKeyEvent*> > keyEvents;
QDBusConnection dbusConnection;
+ bool inCapsLock;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index 84f82cdeda..2207ea9968 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -51,6 +51,7 @@
#include "socket_interface.h"
#include "constant_mappings_p.h"
+#include "../accessibility/qaccessiblebridgeutils_p.h"
#include "application_p.h"
/*!
@@ -910,6 +911,11 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
notifyAboutDestruction(event->accessibleInterface());
break;
}
+ case QAccessible::ObjectReorder: {
+ if (sendObject || sendObject_children_changed)
+ childrenChanged(event->accessibleInterface());
+ break;
+ }
case QAccessible::NameChanged: {
if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
QString path = pathForInterface(event->accessibleInterface());
@@ -1078,16 +1084,14 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
QAccessibleInterface * iface = event->accessibleInterface();
if (!iface || !(iface->role() == QAccessible::Window && (sendWindow || sendWindow_activate)))
return;
+ int isActive = iface->state().active;
QString windowTitle = iface->text(QAccessible::Name);
QDBusVariant data;
data.setVariant(windowTitle);
QVariantList args = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(data));
-
- QString status = iface->state().active ? QLatin1String("Activate") : QLatin1String("Deactivate");
+ QString status = isActive ? QLatin1String("Activate") : QLatin1String("Deactivate");
QString path = pathForInterface(iface);
sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_WINDOW), status, args);
-
- int isActive = iface->state().active;
notifyStateChange(iface, QLatin1String("active"), isActive);
} else if (stateChange.disabled) {
QAccessibleInterface *iface = event->accessibleInterface();
@@ -1150,7 +1154,6 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
case QAccessible::TextAttributeChanged:
case QAccessible::TextColumnChanged:
case QAccessible::VisibleDataChanged:
- case QAccessible::ObjectReorder:
case QAccessible::SelectionAdd:
case QAccessible::SelectionWithin:
case QAccessible::LocationChanged:
@@ -1186,6 +1189,17 @@ void AtSpiAdaptor::sendFocusChanged(QAccessibleInterface *interface) const
}
}
+void AtSpiAdaptor::childrenChanged(QAccessibleInterface *interface) const
+{
+ QString parentPath = pathForInterface(interface);
+ int childCount = interface->childCount();
+ for (int i = 0; i < interface->childCount(); ++i) {
+ QString childPath = pathForInterface(interface->child(i));
+ QVariantList args = packDBusSignalArguments(QLatin1String("add"), childCount, 0, childPath);
+ sendDBusSignal(parentPath, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), QLatin1String("ChildrenChanged"), args);
+ }
+}
+
void AtSpiAdaptor::notifyAboutCreation(QAccessibleInterface *interface) const
{
// // say hello to d-bus
@@ -1472,7 +1486,7 @@ QStringList AtSpiAdaptor::accessibleInterfaces(QAccessibleInterface *interface)
if (interface->role() == QAccessible::Application)
ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_APPLICATION);
- if (interface->actionInterface())
+ if (interface->actionInterface() || interface->valueInterface())
ifaces << QLatin1String(ATSPI_DBUS_INTERFACE_ACTION);
if (interface->textInterface())
@@ -1641,13 +1655,13 @@ bool AtSpiAdaptor::componentInterface(QAccessibleInterface *interface, const QSt
size << rect.width() << rect.height();
connection.send(message.createReply(size));
} else if (function == QLatin1String("GrabFocus")) {
-// FIXME: implement focus grabbing
-// if (interface->object() && interface->object()->isWidgetType()) {
-// QWidget* w = static_cast<QWidget*>(interface->object());
-// w->setFocus(Qt::OtherFocusReason);
-// sendReply(connection, message, true);
-// }
- sendReply(connection, message, false);
+ QAccessibleActionInterface *actionIface = interface->actionInterface();
+ if (actionIface && actionIface->actionNames().contains(QAccessibleActionInterface::setFocusAction())) {
+ actionIface->doAction(QAccessibleActionInterface::setFocusAction());
+ sendReply(connection, message, true);
+ } else {
+ sendReply(connection, message, false);
+ }
} else if (function == QLatin1String("SetExtents")) {
// int x = message.arguments().at(0).toInt();
// int y = message.arguments().at(1).toInt();
@@ -1682,36 +1696,44 @@ QRect AtSpiAdaptor::getExtents(QAccessibleInterface *interface, uint coordType)
// Action interface
bool AtSpiAdaptor::actionInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
{
- QAccessibleActionInterface *actionIface = interface->actionInterface();
- if (!actionIface)
- return false;
-
if (function == QLatin1String("GetNActions")) {
- sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(actionIface->actionNames().count()))));
+ int count = QAccessibleBridgeUtils::effectiveActionNames(interface).count();
+ sendReply(connection, message, QVariant::fromValue(QDBusVariant(QVariant::fromValue(count))));
} else if (function == QLatin1String("DoAction")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
- interface->actionInterface()->doAction(actionIface->actionNames().at(index));
- sendReply(connection, message, true);
+ const QString actionName = actionNames.at(index);
+ bool success = QAccessibleBridgeUtils::performEffectiveAction(interface, actionName);
+ sendReply(connection, message, success);
} else if (function == QLatin1String("GetActions")) {
- sendReply(connection, message, QVariant::fromValue(getActions(actionIface)));
+ sendReply(connection, message, QVariant::fromValue(getActions(interface)));
} else if (function == QLatin1String("GetName")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
- sendReply(connection, message, actionIface->actionNames().at(index));
+ sendReply(connection, message, actionNames.at(index));
} else if (function == QLatin1String("GetDescription")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
- sendReply(connection, message, actionIface->localizedActionDescription(actionIface->actionNames().at(index)));
+ QString description;
+ if (QAccessibleActionInterface *actionIface = interface->actionInterface())
+ description = actionIface->localizedActionDescription(actionNames.at(index));
+ else
+ description = qAccessibleLocalizedActionDescription(actionNames.at(index));
+ sendReply(connection, message, description);
} else if (function == QLatin1String("GetKeyBinding")) {
int index = message.arguments().at(0).toInt();
- if (index < 0 || index >= actionIface->actionNames().count())
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ if (index < 0 || index >= actionNames.count())
return false;
QStringList keyBindings;
- keyBindings = actionIface->keyBindingsForAction(actionIface->actionNames().value(index));
+ if (QAccessibleActionInterface *actionIface = interface->actionInterface())
+ keyBindings = actionIface->keyBindingsForAction(actionNames.at(index));
if (keyBindings.isEmpty()) {
QString acc = interface->text(QAccessible::Accelerator);
if (!acc.isEmpty())
@@ -1728,20 +1750,24 @@ bool AtSpiAdaptor::actionInterface(QAccessibleInterface *interface, const QStrin
return true;
}
-QSpiActionArray AtSpiAdaptor::getActions(QAccessibleActionInterface *actionInterface) const
+QSpiActionArray AtSpiAdaptor::getActions(QAccessibleInterface *interface) const
{
+ QAccessibleActionInterface *actionInterface = interface->actionInterface();
QSpiActionArray actions;
- Q_FOREACH (const QString &actionName, actionInterface->actionNames()) {
+ Q_FOREACH (const QString &actionName, QAccessibleBridgeUtils::effectiveActionNames(interface)) {
QSpiAction action;
QStringList keyBindings;
action.name = actionName;
- action.description = actionInterface->localizedActionDescription(actionName);
-
- keyBindings = actionInterface->keyBindingsForAction(actionName);
+ if (actionInterface) {
+ action.description = actionInterface->localizedActionDescription(actionName);
+ keyBindings = actionInterface->keyBindingsForAction(actionName);
+ } else {
+ action.description = qAccessibleLocalizedActionDescription(actionName);
+ }
if (keyBindings.length() > 0)
- action.keyBinding = keyBindings[0];
+ action.keyBinding = keyBindings[0];
else
action.keyBinding = QString();
@@ -1952,17 +1978,17 @@ QVariantList AtSpiAdaptor::getAttributeValue(QAccessibleInterface *interface, in
return list;
}
-QRect AtSpiAdaptor::getCharacterExtents(QAccessibleInterface *interface, int offset, uint coordType) const
+QList<QVariant> AtSpiAdaptor::getCharacterExtents(QAccessibleInterface *interface, int offset, uint coordType) const
{
QRect rect = interface->textInterface()->characterRect(offset);
if (coordType == ATSPI_COORD_TYPE_WINDOW)
rect = translateRectToWindowCoordinates(interface, rect);
- return rect;
+ return QList<QVariant>() << rect.x() << rect.y() << rect.width() << rect.height();
}
-QRect AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
+QList<QVariant> AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
int startOffset, int endOffset, uint coordType) const
{
if (endOffset == -1)
@@ -1970,7 +1996,7 @@ QRect AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
QAccessibleTextInterface *textInterface = interface->textInterface();
if (endOffset <= startOffset || !textInterface)
- return QRect();
+ return QList<QVariant>() << -1 << -1 << 0 << 0;
QRect rect = textInterface->characterRect(startOffset);
for (int i=startOffset + 1; i <= endOffset; i++)
@@ -1980,7 +2006,7 @@ QRect AtSpiAdaptor::getRangeExtents(QAccessibleInterface *interface,
if (coordType == ATSPI_COORD_TYPE_WINDOW)
rect = translateRectToWindowCoordinates(interface, rect);
- return rect;
+ return QList<QVariant>() << rect.x() << rect.y() << rect.width() << rect.height();
}
QRect AtSpiAdaptor::translateRectToWindowCoordinates(QAccessibleInterface *interface, const QRect &rect)
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor_p.h b/src/platformsupport/linuxaccessibility/atspiadaptor_p.h
index 8e7f55fdbc..eae30c7d7b 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor_p.h
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -102,6 +102,7 @@ private:
void sendFocusChanged(QAccessibleInterface *interface) const;
void notifyAboutCreation(QAccessibleInterface *interface) const;
void notifyAboutDestruction(QAccessibleInterface *interface) const;
+ void childrenChanged(QAccessibleInterface *interface) const;
// handlers for the different accessible interfaces
bool applicationInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection);
@@ -131,13 +132,13 @@ private:
static QRect translateRectToWindowCoordinates(QAccessibleInterface *interface, const QRect &rect);
// action helper functions
- QSpiActionArray getActions(QAccessibleActionInterface* interface) const;
+ QSpiActionArray getActions(QAccessibleInterface *interface) const;
// text helper functions
QVariantList getAttributes(QAccessibleInterface *, int offset, bool includeDefaults) const;
QVariantList getAttributeValue(QAccessibleInterface *, int offset, const QString &attributeName) const;
- QRect getCharacterExtents(QAccessibleInterface *, int offset, uint coordType) const;
- QRect getRangeExtents(QAccessibleInterface *, int startOffset, int endOffset, uint coordType) const;
+ QList<QVariant> getCharacterExtents(QAccessibleInterface *, int offset, uint coordType) const;
+ QList<QVariant> getRangeExtents(QAccessibleInterface *, int startOffset, int endOffset, uint coordType) const;
QAccessible::TextBoundaryType qAccessibleBoundaryType(int atspiTextBoundaryType) const;
static bool inheritsQAction(QObject *object);
diff --git a/src/platformsupport/linuxaccessibility/bridge.cpp b/src/platformsupport/linuxaccessibility/bridge.cpp
index 350c67f1ed..9c34687d55 100644
--- a/src/platformsupport/linuxaccessibility/bridge.cpp
+++ b/src/platformsupport/linuxaccessibility/bridge.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -135,8 +135,8 @@ static RoleMapping map[] = {
{ QAccessible::Caret, ATSPI_ROLE_UNKNOWN, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "text caret") },
//: Role of an accessible object
{ QAccessible::AlertMessage, ATSPI_ROLE_ALERT, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "alert message") },
- //: Role of an accessible object
- { QAccessible::Window, ATSPI_ROLE_WINDOW, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "window") },
+ //: Role of an accessible object: a window with frame and title
+ { QAccessible::Window, ATSPI_ROLE_FRAME, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "frame") },
//: Role of an accessible object
{ QAccessible::Client, ATSPI_ROLE_FILLER, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "filler") },
//: Role of an accessible object
@@ -244,6 +244,24 @@ static RoleMapping map[] = {
//: Role of an accessible object
{ QAccessible::LayeredPane, ATSPI_ROLE_LAYERED_PANE, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "layered pane") },
//: Role of an accessible object
+ { QAccessible::WebDocument, ATSPI_ROLE_DOCUMENT_WEB, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "web document") },
+ //: Role of an accessible object
+ { QAccessible::Paragraph, ATSPI_ROLE_PARAGRAPH, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "paragraph") },
+ //: Role of an accessible object
+ { QAccessible::Section, ATSPI_ROLE_SECTION, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "section") },
+ //: Role of an accessible object
+ { QAccessible::ColorChooser, ATSPI_ROLE_COLOR_CHOOSER, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "color chooser") },
+ //: Role of an accessible object
+ { QAccessible::Footer, ATSPI_ROLE_FOOTER, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "footer") },
+ //: Role of an accessible object
+ { QAccessible::Form, ATSPI_ROLE_FORM, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "form") },
+ //: Role of an accessible object
+ { QAccessible::Heading, ATSPI_ROLE_HEADING, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "heading") },
+ //: Role of an accessible object
+ { QAccessible::Note, ATSPI_ROLE_COMMENT, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "note") },
+ //: Role of an accessible object
+ { QAccessible::ComplementaryContent, ATSPI_ROLE_SECTION, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "complementary content") },
+ //: Role of an accessible object
{ QAccessible::UserRole, ATSPI_ROLE_UNKNOWN, QT_TRANSLATE_NOOP("QSpiAccessibleBridge", "unknown") }
};
diff --git a/src/platformsupport/linuxaccessibility/bridge_p.h b/src/platformsupport/linuxaccessibility/bridge_p.h
index f4b1680b15..bcf73a489a 100644
--- a/src/platformsupport/linuxaccessibility/bridge_p.h
+++ b/src/platformsupport/linuxaccessibility/bridge_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/cache.cpp b/src/platformsupport/linuxaccessibility/cache.cpp
index f9d519b9cd..a850c6dec4 100644
--- a/src/platformsupport/linuxaccessibility/cache.cpp
+++ b/src/platformsupport/linuxaccessibility/cache.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/cache_p.h b/src/platformsupport/linuxaccessibility/cache_p.h
index 8f262cba55..661e775e4c 100644
--- a/src/platformsupport/linuxaccessibility/cache_p.h
+++ b/src/platformsupport/linuxaccessibility/cache_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/constant_mappings.cpp b/src/platformsupport/linuxaccessibility/constant_mappings.cpp
index 9de667158b..0bafaa036c 100644
--- a/src/platformsupport/linuxaccessibility/constant_mappings.cpp
+++ b/src/platformsupport/linuxaccessibility/constant_mappings.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/constant_mappings_p.h b/src/platformsupport/linuxaccessibility/constant_mappings_p.h
index 9e653feb66..15554dd8e4 100644
--- a/src/platformsupport/linuxaccessibility/constant_mappings_p.h
+++ b/src/platformsupport/linuxaccessibility/constant_mappings_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/src/platformsupport/linuxaccessibility/dbusconnection.cpp
index 18915f8e08..f73f2b842a 100644
--- a/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+++ b/src/platformsupport/linuxaccessibility/dbusconnection.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -84,8 +84,14 @@ void DBusConnection::serviceRegistered()
QDBusConnection c = QDBusConnection::sessionBus();
OrgA11yStatusInterface *a11yStatus = new OrgA11yStatusInterface(A11Y_SERVICE, A11Y_PATH, c, this);
+ //The variable was introduced because on some embedded platforms there are custom accessibility
+ //clients which don't set Status.ScreenReaderEnabled to true. The variable is also useful for
+ //debugging.
+ static const bool a11yAlwaysOn = qEnvironmentVariableIsSet("QT_LINUX_ACCESSIBILITY_ALWAYS_ON");
+
// a11yStatus->isEnabled() returns always true (since Gnome 3.6)
- bool enabled = a11yStatus->screenReaderEnabled();
+ bool enabled = a11yAlwaysOn || a11yStatus->screenReaderEnabled();
+
if (enabled != m_enabled) {
m_enabled = enabled;
if (m_a11yConnection.isConnected()) {
diff --git a/src/platformsupport/linuxaccessibility/dbusconnection_p.h b/src/platformsupport/linuxaccessibility/dbusconnection_p.h
index 1e75a10de8..90b07f45b7 100644
--- a/src/platformsupport/linuxaccessibility/dbusconnection_p.h
+++ b/src/platformsupport/linuxaccessibility/dbusconnection_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/linuxaccessibility.pri b/src/platformsupport/linuxaccessibility/linuxaccessibility.pri
index 1b65fb1cad..1d51d2876c 100644
--- a/src/platformsupport/linuxaccessibility/linuxaccessibility.pri
+++ b/src/platformsupport/linuxaccessibility/linuxaccessibility.pri
@@ -2,6 +2,7 @@ contains(QT_CONFIG, accessibility-atspi-bridge) {
QT_FOR_PRIVATE += dbus
include(../../3rdparty/atspi2/atspi2.pri)
+ include(../accessibility/accessibility.pri)
INCLUDEPATH += $$PWD
diff --git a/src/platformsupport/linuxaccessibility/struct_marshallers.cpp b/src/platformsupport/linuxaccessibility/struct_marshallers.cpp
index a5b663bfec..8c6f4959de 100644
--- a/src/platformsupport/linuxaccessibility/struct_marshallers.cpp
+++ b/src/platformsupport/linuxaccessibility/struct_marshallers.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/linuxaccessibility/struct_marshallers_p.h b/src/platformsupport/linuxaccessibility/struct_marshallers_p.h
index 8f7da0df9a..5043a28bb2 100644
--- a/src/platformsupport/linuxaccessibility/struct_marshallers_p.h
+++ b/src/platformsupport/linuxaccessibility/struct_marshallers_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 5b4d2b1fb3..32ce2e3887 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -18,6 +18,7 @@ include(input/input.pri)
include(devicediscovery/devicediscovery.pri)
include(services/services.pri)
include(themes/themes.pri)
+include(accessibility/accessibility.pri)
include(linuxaccessibility/linuxaccessibility.pri)
include(clipboard/clipboard.pri)
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 4a1d67f4b5..dac417ad80 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -51,6 +51,7 @@
#include <QtCore/QFileInfo>
#include <QtCore/QFile>
#include <QtCore/QDebug>
+#include <QtCore/QHash>
#include <QtCore/QSettings>
#include <QtCore/QVariant>
#include <QtCore/QStringList>
@@ -171,26 +172,26 @@ QVariant QGenericUnixTheme::themeHint(ThemeHint hint) const
class QKdeThemePrivate : public QPlatformThemePrivate
{
public:
- QKdeThemePrivate(const QString &kdeHome, int kdeVersion)
- : kdeHome(kdeHome)
+ QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion)
+ : kdeDirs(kdeDirs)
, kdeVersion(kdeVersion)
, toolButtonStyle(Qt::ToolButtonTextBesideIcon)
, toolBarIconSize(0)
, singleClick(true)
{ }
- QString globalSettingsFile() const
+ static QString kdeGlobals(const QString &kdeDir)
{
- return kdeHome + QStringLiteral("/share/config/kdeglobals");
+ return kdeDir + QStringLiteral("/share/config/kdeglobals");
}
void refresh();
- static void readKdeSystemPalette(const QSettings &kdeSettings, QPalette *pal);
- static QFont *readKdeFontSetting(const QSettings &settings, const QString &key);
- static QStringList kdeIconThemeSearchPaths(const QString &kdeHome);
+ static QVariant readKdeSetting(const QString &key, const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings);
+ static void readKdeSystemPalette(const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings, QPalette *pal);
+ static QFont *kdeFont(const QVariant &fontValue);
+ static QStringList kdeIconThemeSearchPaths(const QStringList &kdeDirs);
-
- const QString kdeHome;
+ const QStringList kdeDirs;
const int kdeVersion;
ResourceHelper resources;
@@ -212,36 +213,33 @@ void QKdeThemePrivate::refresh()
styleNames << QStringLiteral("Oxygen") << QStringLiteral("fusion") << QStringLiteral("windows");
iconFallbackThemeName = iconThemeName = QStringLiteral("oxygen");
- // Read settings file.
- const QString settingsFile = globalSettingsFile();
- if (!QFileInfo(settingsFile).isReadable())
- return;
-
- const QSettings kdeSettings(settingsFile, QSettings::IniFormat);
+ QHash<QString, QSettings*> kdeSettings;
QPalette systemPalette = QPalette();
- readKdeSystemPalette(kdeSettings, &systemPalette);
+ readKdeSystemPalette(kdeDirs, kdeSettings, &systemPalette);
resources.palettes[QPlatformTheme::SystemPalette] = new QPalette(systemPalette);
//## TODO tooltip color
- const QVariant styleValue = kdeSettings.value(QStringLiteral("widgetStyle"));
+ const QVariant styleValue = readKdeSetting(QStringLiteral("widgetStyle"), kdeDirs, kdeSettings);
if (styleValue.isValid()) {
const QString style = styleValue.toString();
if (style != styleNames.front())
styleNames.push_front(style);
}
- singleClick = kdeSettings.value(QStringLiteral("KDE/SingleClick"), true).toBool();
+ const QVariant singleClickValue = readKdeSetting(QStringLiteral("KDE/SingleClick"), kdeDirs, kdeSettings);
+ if (singleClickValue.isValid())
+ singleClick = singleClickValue.toBool();
- const QVariant themeValue = kdeSettings.value(QStringLiteral("Icons/Theme"));
+ const QVariant themeValue = readKdeSetting(QStringLiteral("Icons/Theme"), kdeDirs, kdeSettings);
if (themeValue.isValid())
iconThemeName = themeValue.toString();
- const QVariant toolBarIconSizeValue = kdeSettings.value(QStringLiteral("ToolbarIcons/Size"));
+ const QVariant toolBarIconSizeValue = readKdeSetting(QStringLiteral("ToolbarIcons/Size"), kdeDirs, kdeSettings);
if (toolBarIconSizeValue.isValid())
toolBarIconSize = toolBarIconSizeValue.toInt();
- const QVariant toolbarStyleValue = kdeSettings.value(QStringLiteral("ToolButtonStyle"));
+ const QVariant toolbarStyleValue = readKdeSetting(QStringLiteral("Toolbar style/ToolButtonStyle"), kdeDirs, kdeSettings);
if (toolbarStyleValue.isValid()) {
const QString toolBarStyle = toolbarStyleValue.toString();
if (toolBarStyle == QStringLiteral("TextBesideIcon"))
@@ -253,26 +251,46 @@ void QKdeThemePrivate::refresh()
}
// Read system font, ignore 'smallestReadableFont'
- if (QFont *systemFont = readKdeFontSetting(kdeSettings, QStringLiteral("font")))
+ if (QFont *systemFont = kdeFont(readKdeSetting(QStringLiteral("font"), kdeDirs, kdeSettings)))
resources.fonts[QPlatformTheme::SystemFont] = systemFont;
else
resources.fonts[QPlatformTheme::SystemFont] = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
- if (QFont *fixedFont = readKdeFontSetting(kdeSettings, QStringLiteral("fixed"))) {
+ if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeSettings))) {
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
} else {
fixedFont = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
fixedFont->setStyleHint(QFont::TypeWriter);
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
}
+
+ qDeleteAll(kdeSettings);
+}
+
+QVariant QKdeThemePrivate::readKdeSetting(const QString &key, const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings)
+{
+ foreach (const QString &kdeDir, kdeDirs) {
+ QSettings *settings = kdeSettings.value(kdeDir);
+ if (!settings) {
+ const QString kdeGlobalsPath = kdeGlobals(kdeDir);
+ if (QFileInfo(kdeGlobalsPath).isReadable()) {
+ settings = new QSettings(kdeGlobalsPath, QSettings::IniFormat);
+ kdeSettings.insert(kdeDir, settings);
+ }
+ }
+ if (settings) {
+ const QVariant value = settings->value(key);
+ if (value.isValid())
+ return value;
+ }
+ }
+ return QVariant();
}
// Reads the color from the KDE configuration, and store it in the
// palette with the given color role if found.
-static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role,
- const QSettings &kdeSettings, const QString &key)
+static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role, const QVariant &value)
{
- const QVariant value = kdeSettings.value(key);
if (!value.isValid())
return false;
const QStringList values = value.toStringList();
@@ -282,9 +300,9 @@ static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role,
return true;
}
-void QKdeThemePrivate::readKdeSystemPalette(const QSettings &kdeSettings, QPalette *pal)
+void QKdeThemePrivate::readKdeSystemPalette(const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings, QPalette *pal)
{
- if (!kdeSettings.contains(QStringLiteral("Colors:Button/BackgroundNormal"))) {
+ if (!kdeColor(pal, QPalette::Button, readKdeSetting(QStringLiteral("Colors:Button/BackgroundNormal"), kdeDirs, kdeSettings))) {
// kcolorscheme.cpp: SetDefaultColors
const QColor defaultWindowBackground(214, 210, 208);
const QColor defaultButtonBackground(223, 220, 217);
@@ -292,19 +310,18 @@ void QKdeThemePrivate::readKdeSystemPalette(const QSettings &kdeSettings, QPalet
return;
}
- kdeColor(pal, QPalette::Button, kdeSettings, QStringLiteral("Colors:Button/BackgroundNormal"));
- kdeColor(pal, QPalette::Window, kdeSettings, QStringLiteral("Colors:Window/BackgroundNormal"));
- kdeColor(pal, QPalette::Text, kdeSettings, QStringLiteral("Colors:View/ForegroundNormal"));
- kdeColor(pal, QPalette::WindowText, kdeSettings, QStringLiteral("Colors:Window/ForegroundNormal"));
- kdeColor(pal, QPalette::Base, kdeSettings, QStringLiteral("Colors:View/BackgroundNormal"));
- kdeColor(pal, QPalette::Highlight, kdeSettings, QStringLiteral("Colors:Selection/BackgroundNormal"));
- kdeColor(pal, QPalette::HighlightedText, kdeSettings, QStringLiteral("Colors:Selection/ForegroundNormal"));
- kdeColor(pal, QPalette::AlternateBase, kdeSettings, QStringLiteral("Colors:View/BackgroundAlternate"));
- kdeColor(pal, QPalette::ButtonText, kdeSettings, QStringLiteral("Colors:Button/ForegroundNormal"));
- kdeColor(pal, QPalette::Link, kdeSettings, QStringLiteral("Colors:View/ForegroundLink"));
- kdeColor(pal, QPalette::LinkVisited, kdeSettings, QStringLiteral("Colors:View/ForegroundVisited"));
- kdeColor(pal, QPalette::ToolTipBase, kdeSettings, QStringLiteral("Colors:Tooltip/BackgroundNormal"));
- kdeColor(pal, QPalette::ToolTipText, kdeSettings, QStringLiteral("Colors:Tooltip/ForegroundNormal"));
+ kdeColor(pal, QPalette::Window, readKdeSetting(QStringLiteral("Colors:Window/BackgroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::Text, readKdeSetting(QStringLiteral("Colors:View/ForegroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::WindowText, readKdeSetting(QStringLiteral("Colors:Window/ForegroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::Base, readKdeSetting(QStringLiteral("Colors:View/BackgroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::Highlight, readKdeSetting(QStringLiteral("Colors:Selection/BackgroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::HighlightedText, readKdeSetting(QStringLiteral("Colors:Selection/ForegroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::AlternateBase, readKdeSetting(QStringLiteral("Colors:View/BackgroundAlternate"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::ButtonText, readKdeSetting(QStringLiteral("Colors:Button/ForegroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::Link, readKdeSetting(QStringLiteral("Colors:View/ForegroundLink"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::LinkVisited, readKdeSetting(QStringLiteral("Colors:View/ForegroundVisited"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::ToolTipBase, readKdeSetting(QStringLiteral("Colors:Tooltip/BackgroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::ToolTipText, readKdeSetting(QStringLiteral("Colors:Tooltip/ForegroundNormal"), kdeDirs, kdeSettings));
// The above code sets _all_ color roles to "normal" colors. In KDE, the disabled
// color roles are calculated by applying various effects described in kdeglobals.
@@ -347,15 +364,14 @@ void QKdeThemePrivate::readKdeSystemPalette(const QSettings &kdeSettings, QPalet
const char *QKdeTheme::name = "kde";
-QKdeTheme::QKdeTheme(const QString &kdeHome, int kdeVersion)
- : QPlatformTheme(new QKdeThemePrivate(kdeHome,kdeVersion))
+QKdeTheme::QKdeTheme(const QStringList& kdeDirs, int kdeVersion)
+ : QPlatformTheme(new QKdeThemePrivate(kdeDirs,kdeVersion))
{
d_func()->refresh();
}
-QFont *QKdeThemePrivate::readKdeFontSetting(const QSettings &settings, const QString &key)
+QFont *QKdeThemePrivate::kdeFont(const QVariant &fontValue)
{
- const QVariant fontValue = settings.value(key);
if (fontValue.isValid()) {
// Read font value: Might be a QStringList as KDE stores fonts without quotes.
// Also retrieve the family for the constructor since we cannot use the
@@ -382,16 +398,11 @@ QFont *QKdeThemePrivate::readKdeFontSetting(const QSettings &settings, const QSt
}
-QStringList QKdeThemePrivate::kdeIconThemeSearchPaths(const QString &kdeHome)
+QStringList QKdeThemePrivate::kdeIconThemeSearchPaths(const QStringList &kdeDirs)
{
- QStringList candidates = QStringList(kdeHome);
- const QString kdeDirs = QFile::decodeName(qgetenv("KDEDIRS"));
- if (!kdeDirs.isEmpty())
- candidates.append(kdeDirs.split(QLatin1Char(':')));
-
QStringList paths = QGenericUnixTheme::xdgIconThemePaths();
const QString iconPath = QStringLiteral("/share/icons");
- foreach (const QString &candidate, candidates) {
+ foreach (const QString &candidate, kdeDirs) {
const QFileInfo fi(candidate + iconPath);
if (fi.isDir())
paths.append(fi.absoluteFilePath());
@@ -418,7 +429,7 @@ QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
case QPlatformTheme::SystemIconFallbackThemeName:
return QVariant(d->iconFallbackThemeName);
case QPlatformTheme::IconThemeSearchPaths:
- return QVariant(d->kdeIconThemeSearchPaths(d->kdeHome));
+ return QVariant(d->kdeIconThemeSearchPaths(d->kdeDirs));
case QPlatformTheme::StyleNames:
return QVariant(d->styleNames);
case QPlatformTheme::KeyboardScheme:
@@ -445,26 +456,52 @@ const QFont *QKdeTheme::font(Font type) const
QPlatformTheme *QKdeTheme::createKdeTheme()
{
- // Check for version >= 4 and determine home folder from environment,
- // defaulting to ~/.kde<version>, ~/.kde
const QByteArray kdeVersionBA = qgetenv("KDE_SESSION_VERSION");
const int kdeVersion = kdeVersionBA.toInt();
if (kdeVersion < 4)
return 0;
- const QString kdeHomePathVar = QString::fromLocal8Bit(qgetenv("KDEHOME"));
+
+ // Determine KDE prefixes in the following priority order:
+ // - KDEHOME and KDEDIRS environment variables
+ // - ~/.kde(<version>)
+ // - read prefixes from /etc/kde<version>rc
+ // - fallback to /etc/kde<version>
+
+ QStringList kdeDirs;
+ const QString kdeHomePathVar = QFile::decodeName(qgetenv("KDEHOME"));
if (!kdeHomePathVar.isEmpty())
- return new QKdeTheme(kdeHomePathVar, kdeVersion);
+ kdeDirs += kdeHomePathVar;
+
+ const QString kdeDirsVar = QFile::decodeName(qgetenv("KDEDIRS"));
+ if (!kdeDirsVar.isEmpty())
+ kdeDirs += kdeDirsVar.split(QLatin1Char(':'), QString::SkipEmptyParts);
- const QString kdeVersionHomePath = QDir::homePath() + QStringLiteral("/.kde") + QLatin1String(kdeVersionBA);
- if (QFileInfo(kdeVersionHomePath).isDir())
- return new QKdeTheme(kdeVersionHomePath, kdeVersion);
+ const QString kdeVersionHomePath = QDir::homePath() + QStringLiteral("/.kde") + QLatin1String(kdeVersionBA);
+ if (QFileInfo(kdeVersionHomePath).isDir())
+ kdeDirs += kdeVersionHomePath;
- const QString kdeHomePath = QDir::homePath() + QStringLiteral("/.kde");
- if (QFileInfo(kdeHomePath).isDir())
- return new QKdeTheme(kdeHomePath, kdeVersion);
+ const QString kdeHomePath = QDir::homePath() + QStringLiteral("/.kde");
+ if (QFileInfo(kdeHomePath).isDir())
+ kdeDirs += kdeHomePath;
- qWarning("%s: Unable to determine KDEHOME", Q_FUNC_INFO);
- return 0;
+ const QString kdeRcPath = QStringLiteral("/etc/kde") + QLatin1String(kdeVersionBA) + QStringLiteral("rc");
+ if (QFileInfo(kdeRcPath).isReadable()) {
+ QSettings kdeSettings(kdeRcPath, QSettings::IniFormat);
+ kdeSettings.beginGroup(QStringLiteral("Directories-default"));
+ kdeDirs += kdeSettings.value(QStringLiteral("prefixes")).toStringList();
+ }
+
+ const QString kdeVersionPrefix = QStringLiteral("/etc/kde") + QLatin1String(kdeVersionBA);
+ if (QFileInfo(kdeVersionPrefix).isDir())
+ kdeDirs += kdeVersionPrefix;
+
+ kdeDirs.removeDuplicates();
+ if (kdeDirs.isEmpty()) {
+ qWarning("%s: Unable to determine KDE dirs", Q_FUNC_INFO);
+ return 0;
+ }
+
+ return new QKdeTheme(kdeDirs, kdeVersion);
}
#endif // QT_NO_SETTINGS
@@ -482,15 +519,23 @@ const char *QGnomeTheme::name = "gnome";
class QGnomeThemePrivate : public QPlatformThemePrivate
{
public:
- QGnomeThemePrivate()
- : systemFont(QLatin1Literal(defaultSystemFontNameC), defaultSystemFontSize)
- , fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
+ QGnomeThemePrivate() : fontsConfigured(false) { }
+ void configureFonts(QString gtkFontName) const
{
+ Q_ASSERT(!fontsConfigured);
+ const int split = gtkFontName.lastIndexOf(QChar::Space);
+ float size = gtkFontName.mid(split+1).toFloat();
+ QString fontName = gtkFontName.left(split);
+
+ systemFont = QFont(fontName, size);
+ fixedFont = QFont(QLatin1String("monospace"), systemFont.pointSize());
fixedFont.setStyleHint(QFont::TypeWriter);
+ fontsConfigured = true;
}
- const QFont systemFont;
- QFont fixedFont;
+ mutable QFont systemFont;
+ mutable QFont fixedFont;
+ mutable bool fontsConfigured;
};
QGnomeTheme::QGnomeTheme()
@@ -528,9 +573,11 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
const QFont *QGnomeTheme::font(Font type) const
{
Q_D(const QGnomeTheme);
+ if (!d->fontsConfigured)
+ d->configureFonts(gtkFontName());
switch (type) {
case QPlatformTheme::SystemFont:
- return &d->systemFont;
+ return &d->systemFont;
case QPlatformTheme::FixedFont:
return &d->fixedFont;
default:
@@ -538,6 +585,11 @@ const QFont *QGnomeTheme::font(Font type) const
}
}
+QString QGnomeTheme::gtkFontName() const
+{
+ return QStringLiteral("%1 %2").arg(QLatin1String(defaultSystemFontNameC)).arg(defaultSystemFontSize);
+}
+
QString QGnomeTheme::standardButtonText(int button) const
{
switch (button) {
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
index b8f6737ea0..0810d4ce12 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
@@ -98,7 +98,7 @@ class QKdeTheme : public QPlatformTheme
{
Q_DECLARE_PRIVATE(QKdeTheme)
public:
- QKdeTheme(const QString &kdeHome, int kdeVersion);
+ QKdeTheme(const QStringList& kdeDirs, int kdeVersion);
static QPlatformTheme *createKdeTheme();
virtual QVariant themeHint(ThemeHint hint) const;
@@ -122,6 +122,8 @@ public:
virtual const QFont *font(Font type) const;
QString standardButtonText(int button) const Q_DECL_OVERRIDE;
+ virtual QString gtkFontName() const;
+
static const char *name;
};