summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-09-25 14:02:04 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2015-09-25 14:02:04 +0200
commita1ad9a74ebb3c556c5f70f7e03be68b09598ac53 (patch)
tree615a96db418219a57a745a5899e39a9ac90744ec /src/plugins
parent6d78b7a0c46ea04f4bb771d960e2f7dff1362341 (diff)
parent462f355e4fb16cc7a1838fa2dda0f763eee58c84 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/corelib/io/io.pri src/corelib/io/qdatastream.cpp src/corelib/io/qdatastream.h src/network/socket/qabstractsocket.cpp src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h src/widgets/styles/qgtkstyle.cpp tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro tests/auto/dbus/qdbusconnection/qdbusconnection.pro tests/auto/dbus/qdbuspendingcall/tst_qdbuspendingcall.cpp tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp Change-Id: I347549a024eb5bfa986699e0a11f96cc55c797a7
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp51
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.json2
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp3
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp44
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm13
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm31
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm4
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp19
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm52
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm5
-rw-r--r--src/plugins/platforms/kms/kms.json3
-rw-r--r--src/plugins/platforms/kms/kms.pro37
-rw-r--r--src/plugins/platforms/kms/main.cpp58
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp217
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h72
-rw-r--r--src/plugins/platforms/kms/qkmscontext.cpp136
-rw-r--r--src/plugins/platforms/kms/qkmscontext.h71
-rw-r--r--src/plugins/platforms/kms/qkmscursor.cpp116
-rw-r--r--src/plugins/platforms/kms/qkmscursor.h66
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp118
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.h81
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp204
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h108
-rw-r--r--src/plugins/platforms/kms/qkmsnativeinterface.cpp135
-rw-r--r--src/plugins/platforms/kms/qkmsnativeinterface.h64
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp275
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h122
-rw-r--r--src/plugins/platforms/kms/qkmswindow.cpp66
-rw-r--r--src/plugins/platforms/kms/qkmswindow.h57
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp31
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp43
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp55
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp114
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h2
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp18
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp16
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp30
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp280
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.h12
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp26
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp4
-rw-r--r--src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp26
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp120
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h27
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp115
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp241
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp163
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp17
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.cpp4
76 files changed, 1252 insertions, 2521 deletions
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 2ddbc4519b..19525397fa 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -100,9 +100,10 @@ public:
static bool write(QIODevice *device, const QVector<QImage> &images);
+ bool readIconEntry(int index, ICONDIRENTRY * iconEntry);
+
private:
bool readHeader();
- bool readIconEntry(int index, ICONDIRENTRY * iconEntry);
bool readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header);
void findColorInfo(QImage & image);
@@ -341,7 +342,7 @@ bool ICOReader::readHeader()
bool ICOReader::readIconEntry(int index, ICONDIRENTRY *iconEntry)
{
- if (iod) {
+ if (readHeader()) {
if (iod->seek(startpos + ICONDIR_SIZE + (index * ICONDIRENTRY_SIZE))) {
return readIconDirEntry(iod, iconEntry);
}
@@ -558,10 +559,10 @@ QImage ICOReader::iconAt(int index)
if (icoAttrib.ncolors > 256) //color table can't be more than 256
return img;
icoAttrib.w = iconEntry.bWidth;
- if (icoAttrib.w == 0)
+ if (icoAttrib.w == 0) // means 256 pixels
icoAttrib.w = header.biWidth;
icoAttrib.h = iconEntry.bHeight;
- if (icoAttrib.h == 0)
+ if (icoAttrib.h == 0) // means 256 pixels
icoAttrib.h = header.biHeight/2;
QImage::Format format = QImage::Format_ARGB32;
@@ -658,10 +659,11 @@ bool ICOReader::write(QIODevice *device, const QVector<QImage> &images)
for (int i=0; i<id.idCount; i++) {
QImage image = images[i];
- // Scale down the image if it is larger than 128 pixels in either width or height
- if (image.width() > 128 || image.height() > 128)
+ // Scale down the image if it is larger than 256 pixels in either width or height
+ // because this is a maximum size of image in the ICO file.
+ if (image.width() > 256 || image.height() > 256)
{
- image = image.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ image = image.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
QImage maskImage(image.width(), image.height(), QImage::Format_Mono);
image = image.convertToFormat(QImage::Format_ARGB32);
@@ -778,25 +780,37 @@ QtIcoHandler::~QtIcoHandler()
QVariant QtIcoHandler::option(ImageOption option) const
{
- if (option == Size) {
- QIODevice *device = QImageIOHandler::device();
- qint64 oldPos = device->pos();
+ if (option == Size || option == ImageFormat) {
ICONDIRENTRY iconEntry;
- if (device->seek(oldPos + ICONDIR_SIZE + (m_currentIconIndex * ICONDIRENTRY_SIZE))) {
- if (readIconDirEntry(device, &iconEntry)) {
- device->seek(oldPos);
- return QSize(iconEntry.bWidth, iconEntry.bHeight);
+ if (m_pICOReader->readIconEntry(m_currentIconIndex, &iconEntry)) {
+ switch (option) {
+ case Size:
+ return QSize(iconEntry.bWidth ? iconEntry.bWidth : 256,
+ iconEntry.bHeight ? iconEntry.bHeight : 256);
+
+ case ImageFormat:
+ switch (iconEntry.wBitCount) {
+ case 2:
+ return QImage::Format_Mono;
+ case 24:
+ return QImage::Format_RGB32;
+ case 32:
+ return QImage::Format_ARGB32;
+ default:
+ return QImage::Format_Indexed8;
+ }
+ break;
+ default:
+ break;
}
}
- if (!device->isSequential())
- device->seek(oldPos);
}
return QVariant();
}
bool QtIcoHandler::supportsOption(ImageOption option) const
{
- return option == Size;
+ return (option == Size || option == ImageFormat);
}
/*!
@@ -881,9 +895,10 @@ bool QtIcoHandler::jumpToImage(int imageNumber)
{
if (imageNumber < imageCount()) {
m_currentIconIndex = imageNumber;
+ return true;
}
- return imageNumber < imageCount();
+ return false;
}
/*! \reimp
diff --git a/src/plugins/platforminputcontexts/compose/compose.json b/src/plugins/platforminputcontexts/compose/compose.json
index 2daf89ed30..fb95f1bfb0 100644
--- a/src/plugins/platforminputcontexts/compose/compose.json
+++ b/src/plugins/platforminputcontexts/compose/compose.json
@@ -1,3 +1,3 @@
{
- "Keys": [ "compose" ]
+ "Keys": [ "compose", "xim" ]
}
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp
index 96f6424ba2..15c98ed006 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp
@@ -52,7 +52,8 @@ QComposeInputContext *QComposePlatformInputContextPlugin::create(const QString &
{
Q_UNUSED(paramList);
- if (system.compare(system, QLatin1String("compose"), Qt::CaseInsensitive) == 0)
+ if (system.compare(system, QLatin1String("compose"), Qt::CaseInsensitive) == 0
+ || system.compare(system, QLatin1String("xim"), Qt::CaseInsensitive) == 0)
return new QComposeInputContext;
return 0;
}
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index 2027e010d0..9a41244c63 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -301,12 +301,12 @@ bool QIBusPlatformInputContext::filterEvent(const QEvent *event)
quint32 sym = keyEvent->nativeVirtualKey();
quint32 code = keyEvent->nativeScanCode();
quint32 state = keyEvent->nativeModifiers();
+ quint32 ibusState = state;
if (keyEvent->type() != QEvent::KeyPress)
- state |= IBUS_RELEASE_MASK;
+ ibusState |= IBUS_RELEASE_MASK;
- code -= 8; // ###
- QDBusPendingReply<bool> reply = d->context->ProcessKeyEvent(sym, code, state);
+ QDBusPendingReply<bool> reply = d->context->ProcessKeyEvent(sym, code - 8, ibusState);
if (m_eventFilterUseSynchronousMode || reply.isFinished()) {
bool retval = reply.value();
@@ -315,17 +315,36 @@ bool QIBusPlatformInputContext::filterEvent(const QEvent *event)
}
Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
+ const int qtcode = keyEvent->key();
+
+ // From QKeyEvent::modifiers()
+ switch (qtcode) {
+ case Qt::Key_Shift:
+ modifiers ^= Qt::ShiftModifier;
+ break;
+ case Qt::Key_Control:
+ modifiers ^= Qt::ControlModifier;
+ break;
+ case Qt::Key_Alt:
+ modifiers ^= Qt::AltModifier;
+ break;
+ case Qt::Key_Meta:
+ modifiers ^= Qt::MetaModifier;
+ break;
+ case Qt::Key_AltGr:
+ modifiers ^= Qt::GroupSwitchModifier;
+ break;
+ }
QVariantList args;
args << QVariant::fromValue(keyEvent->timestamp());
args << QVariant::fromValue(static_cast<uint>(keyEvent->type()));
- args << QVariant::fromValue(keyEvent->key());
+ args << QVariant::fromValue(qtcode);
args << QVariant::fromValue(code) << QVariant::fromValue(sym) << QVariant::fromValue(state);
args << QVariant::fromValue(keyEvent->text());
args << QVariant::fromValue(keyEvent->isAutoRepeat());
- args << QVariant::fromValue(keyEvent->count());
- QIBusFilterEventWatcher *watcher = new QIBusFilterEventWatcher(reply, this, qApp->focusObject(), modifiers, args);
+ QIBusFilterEventWatcher *watcher = new QIBusFilterEventWatcher(reply, this, QGuiApplication::focusWindow(), modifiers, args);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &QIBusPlatformInputContext::filterEventFinished);
return true;
@@ -343,9 +362,9 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
// Use watcher's window instead of the current focused window
// since there is a time lag until filterEventFinished() returns.
- QObject *input = watcher->input();
+ QWindow *window = watcher->window();
- if (!input) {
+ if (!window) {
call->deleteLater();
return;
}
@@ -360,14 +379,12 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
const quint32 state = args.at(5).toUInt();
const QString string = args.at(6).toString();
const bool isAutoRepeat = args.at(7).toBool();
- const int count = args.at(8).toInt();
// copied from QXcbKeyboard::handleKeyEvent()
bool retval = reply.value();
qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << retval;
if (!retval) {
#ifndef QT_NO_CONTEXTMENU
- QWindow *window = dynamic_cast<QWindow *>(input);
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu
&& window != NULL) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
@@ -376,10 +393,9 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
globalPos, modifiers);
}
#endif // QT_NO_CONTEXTMENU
- QKeyEvent event(type, qtcode, modifiers, code, sym,
- state, string, isAutoRepeat, count);
- event.setTimestamp(time);
- QCoreApplication::sendEvent(input, &event);
+ QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
+ code, sym, state, string, isAutoRepeat);
+
}
call->deleteLater();
}
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
index 91f15ea159..127db7df8b 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -38,6 +38,7 @@
#include <QtCore/qpointer.h>
#include <QtDBus/qdbuspendingreply.h>
#include <QLoggingCategory>
+#include <QWindow>
QT_BEGIN_NAMESPACE
@@ -51,23 +52,23 @@ class QIBusFilterEventWatcher: public QDBusPendingCallWatcher
public:
explicit QIBusFilterEventWatcher(const QDBusPendingCall &call,
QObject *parent = 0,
- QObject *input = 0,
+ QWindow *window = 0,
const Qt::KeyboardModifiers modifiers = 0,
const QVariantList arguments = QVariantList())
: QDBusPendingCallWatcher(call, parent)
- , m_input(input)
+ , m_window(window)
, m_modifiers(modifiers)
, m_arguments(arguments)
{}
~QIBusFilterEventWatcher()
{}
- inline QObject *input() const { return m_input; }
+ inline QWindow *window() const { return m_window; }
inline const Qt::KeyboardModifiers modifiers() const { return m_modifiers; }
inline const QVariantList arguments() const { return m_arguments; }
private:
- QPointer<QObject> m_input;
+ QPointer<QWindow> m_window;
const Qt::KeyboardModifiers m_modifiers;
const QVariantList m_arguments;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index 18ea884091..2d1aa41a9a 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -38,6 +38,8 @@
#include <QtGui>
#include <qpa/qplatformaccessibility.h>
+#ifndef QT_NO_ACCESSIBILITY
+
QT_BEGIN_NAMESPACE
class QCocoaAccessibility : public QPlatformAccessibility
@@ -85,4 +87,6 @@ id getValueAttribute(QAccessibleInterface *interface);
QT_END_NAMESPACE
-#endif
+#endif // QT_NO_ACCESSIBILITY
+
+#endif // QCOCOAACCESIBILITY_H
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 56042e72ea..f83d15f48e 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -37,6 +37,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_ACCESSIBILITY
+
QCocoaAccessibility::QCocoaAccessibility()
{
@@ -378,5 +380,7 @@ id getValueAttribute(QAccessibleInterface *interface)
} // namespace QCocoaAccessible
+#endif // QT_NO_ACCESSIBILITY
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
index 33a7ef4add..73aeae129b 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
@@ -37,7 +37,10 @@
#include "qt_mac_p.h"
-#import <AppKit/AppKit.h>
+#ifndef QT_NO_ACCESSIBILITY
+
+#import <Cocoa/Cocoa.h>
+#import <AppKit/NSAccessibility.h>
#import <qaccessible.h>
@@ -55,4 +58,6 @@
QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement);
-#endif
+#endif // QT_NO_ACCESSIBILITY
+
+#endif // QCOCOAACCESIBILITYELEMENT_H
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index fd5962cc34..050fb7ba0a 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -42,6 +42,8 @@
QT_USE_NAMESPACE
+#ifndef QT_NO_ACCESSIBILITY
+
static void convertLineOffset(QAccessibleTextInterface *text, int &line, int &offset, NSUInteger *start = 0, NSUInteger *end = 0)
{
Q_ASSERT(line == -1 || offset == -1);
@@ -582,3 +584,5 @@ static void convertLineOffset(QAccessibleTextInterface *text, int &line, int &of
}
@end
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index cac50825af..caa8884661 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -221,12 +221,8 @@ QT_END_NAMESPACE
const QWindowList topLevels = QGuiApplication::topLevelWindows();
for (int i = 0; i < topLevels.size(); ++i) {
QWindow *topLevelWindow = topLevels.at(i);
- // Widgets have alreay received a CloseEvent from the QApplication
- // QCloseEvent handler. (see canQuit above). Prevent running the
- // CloseEvent logic twice, call close() directly.
- if (topLevelWindow->inherits("QWidgetWindow"))
- topLevelWindow->close();
- else
+ // Already closed windows will not have a platform window, skip those
+ if (topLevelWindow->handle())
QWindowSystemInterface::handleCloseEvent(topLevelWindow);
}
QWindowSystemInterface::flushWindowSystemEvents();
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 6a4f7ed8ee..ca92103826 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -44,6 +44,8 @@ QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
QCocoaBackingStore::~QCocoaBackingStore()
{
+ if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()))
+ [cocoaWindow->m_qtView clearBackingStore:this];
}
QPaintDevice *QCocoaBackingStore::paintDevice()
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 93ee4e8624..9dc013ba4d 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -588,9 +588,6 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuInd
emit filterSelected(menuIndex >= 0 && menuIndex < filters.size() ? filters.at(menuIndex) : QString());
}
-extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
-extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); // qglobal.cpp
-
void QCocoaFileDialogHelper::setDirectory(const QUrl &directory)
{
if (mDelegate)
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index cdeef1c6db..d43c8e5ee9 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -146,19 +146,25 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
QMacAutoReleasePool pool; // For the SG Canvas render thread
+ // create native context for the requested pixel format and share
NSOpenGLPixelFormat *pixelFormat = static_cast <NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat(m_format));
m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nsOpenGLContext() : nil;
+ m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_shareContext];
- m_context = [NSOpenGLContext alloc];
- [m_context initWithFormat:pixelFormat shareContext:m_shareContext];
-
+ // retry without sharing on context creation failure.
if (!m_context && m_shareContext) {
- // try without shared context
m_shareContext = nil;
- [m_context initWithFormat:pixelFormat shareContext:nil];
+ m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
+ if (m_context)
+ qWarning("QCocoaGLContext: Falling back to unshared context.");
}
+ // give up if we still did not get a native context
[pixelFormat release];
+ if (!m_context) {
+ qWarning("QCocoaGLContext: Failed to create context.");
+ return;
+ }
const GLint interval = format.swapInterval() >= 0 ? format.swapInterval() : 1;
[m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 5977d88e87..c7875af83e 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -121,7 +121,9 @@ public:
QCoreTextFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
QCocoaNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
+#ifndef QT_NO_ACCESSIBILITY
QCocoaAccessibility *accessibility() const Q_DECL_OVERRIDE;
+#endif
QCocoaClipboard *clipboard() const Q_DECL_OVERRIDE;
QCocoaDrag *drag() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index c988bdc6a7..e469ec5c74 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -47,6 +47,7 @@
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
+#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/qcoreapplication.h>
@@ -286,9 +287,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
qWarning("Creating multiple Cocoa platform integrations is not supported");
mInstance = this;
- mInputContext.reset(QPlatformInputContextFactory::create());
- if (mInputContext.isNull())
- mInputContext.reset(new QCocoaInputContext());
+ QString icStr = QPlatformInputContextFactory::requested();
+ icStr.isNull() ? mInputContext.reset(new QCocoaInputContext)
+ : mInputContext.reset(QPlatformInputContextFactory::create(icStr));
initResources();
QMacAutoReleasePool pool;
@@ -501,14 +502,12 @@ QPlatformInputContext *QCocoaIntegration::inputContext() const
return mInputContext.data();
}
+#ifndef QT_NO_ACCESSIBILITY
QCocoaAccessibility *QCocoaIntegration::accessibility() const
{
-#ifndef QT_NO_ACCESSIBILITY
return mAccessibility.data();
-#else
- return 0;
-#endif
}
+#endif
QCocoaClipboard *QCocoaIntegration::clipboard() const
{
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 7e09116a37..a49a42378d 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -51,8 +51,7 @@ QT_END_NAMESPACE
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> {
- QImage m_backingStore;
- qreal m_pixelRatio;
+ QCocoaBackingStore* m_backingStore;
QPoint m_backingStoreOffset;
CGImageRef m_maskImage;
uchar *m_maskData;
@@ -86,6 +85,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
#endif
- (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset;
+- (void)clearBackingStore:(QCocoaBackingStore *)backingStore;
- (void)setMaskRegion:(const QRegion *)region;
- (void)invalidateWindowShadowIfNeeded;
- (void)drawRect:(NSRect)dirtyRect;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index edcbd16dca..4db55c1b73 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -134,7 +134,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
{
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
if (self) {
- m_pixelRatio = 1.;
+ m_backingStore = 0;
m_maskImage = 0;
m_shouldInvalidateWindowShadow = false;
m_window = 0;
@@ -376,7 +376,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (!m_platformWindow->m_inSetGeometry)
QWindowSystemInterface::flushWindowSystemEvents();
else
- m_backingStore = QImage();
+ m_backingStore = 0;
}
}
@@ -481,12 +481,16 @@ QT_WARNING_POP
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
- m_backingStore = backingStore->toImage();
- m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio();
- m_backingStoreOffset = offset * m_pixelRatio;
- foreach (QRect rect, region.rects()) {
+ m_backingStore = backingStore;
+ m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
+ foreach (QRect rect, region.rects())
[self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
- }
+}
+
+- (void)clearBackingStore:(QCocoaBackingStore *)backingStore
+{
+ if (backingStore == m_backingStore)
+ m_backingStore = 0;
}
- (BOOL) hasMask
@@ -549,7 +553,7 @@ QT_WARNING_POP
if (m_platformWindow->m_drawContentBorderGradient)
NSDrawWindowBackground(dirtyRect);
- if (m_backingStore.isNull())
+ if (!m_backingStore)
return;
// Calculate source and target rects. The target rect is the dirtyRect:
@@ -557,10 +561,11 @@ QT_WARNING_POP
// The backing store source rect will be larger on retina displays.
// Scale dirtyRect by the device pixel ratio:
- CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * m_pixelRatio,
- dirtyRect.origin.y * m_pixelRatio,
- dirtyRect.size.width * m_pixelRatio,
- dirtyRect.size.height * m_pixelRatio);
+ const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio();
+ CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio,
+ dirtyRect.origin.y * devicePixelRatio,
+ dirtyRect.size.width * devicePixelRatio,
+ dirtyRect.size.height * devicePixelRatio);
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort];
@@ -586,7 +591,7 @@ QT_WARNING_POP
dirtyBackingRect.size.width,
dirtyBackingRect.size.height
);
- CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore);
+ CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore->toImage());
CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect);
// Optimization: Copy frame buffer content instead of blending for
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index 93f0817aad..1f15da5b3b 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -44,6 +44,8 @@
#import <AppKit/NSAccessibility.h>
+#ifndef QT_NO_ACCESSIBILITY
+
@implementation QNSView (QNSViewAccessibility)
- (id)childAccessibleElement {
@@ -80,3 +82,5 @@
}
@end
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index aec5a5e179..f0946b9b64 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -40,6 +40,7 @@
#include <QtGui/QScreen>
#include <QtGui/QOffscreenSurface>
#include <QtGui/QWindow>
+#include <QtCore/QLoggingCategory>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontextfactory_p.h>
@@ -62,6 +63,10 @@
#include <QtPlatformHeaders/QEGLNativeContext>
+#ifndef QT_NO_LIBINPUT
+#include <QtPlatformSupport/private/qlibinputhandler_p.h>
+#endif
+
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
@@ -124,13 +129,14 @@ void QEglFSIntegration::initialize()
m_vtHandler.reset(new QFbVtHandler);
- if (!m_disableInputHandlers)
- createInputHandlers();
-
if (qt_egl_device_integration()->usesDefaultScreen())
addScreen(new QEglFSScreen(display()));
else
qt_egl_device_integration()->screenInit();
+
+ // Input code may rely on the screens, so do it only after the screen init.
+ if (!m_disableInputHandlers)
+ createInputHandlers();
}
void QEglFSIntegration::destroy()
@@ -389,6 +395,13 @@ void QEglFSIntegration::loadKeymapStatic(const QString &filename)
void QEglFSIntegration::createInputHandlers()
{
+#ifndef QT_NO_LIBINPUT
+ if (!qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT")) {
+ new QLibInputHandler(QLatin1String("libinput"), QString());
+ return;
+ }
+#endif
+
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index e2c61e1161..e4917593db 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -344,6 +344,46 @@
// -------------------------------------------------------------------------
+- (void)sendKeyPressRelease:(Qt::Key)key modifiers:(Qt::KeyboardModifiers)modifiers
+{
+ QKeyEvent press(QEvent::KeyPress, key, modifiers);
+ QKeyEvent release(QEvent::KeyRelease, key, modifiers);
+ [self sendEventToFocusObject:press];
+ [self sendEventToFocusObject:release];
+}
+
+- (void)cut:(id)sender
+{
+ Q_UNUSED(sender);
+ [self sendKeyPressRelease:Qt::Key_X modifiers:Qt::ControlModifier];
+}
+
+- (void)copy:(id)sender
+{
+ Q_UNUSED(sender);
+ [self sendKeyPressRelease:Qt::Key_C modifiers:Qt::ControlModifier];
+}
+
+- (void)paste:(id)sender
+{
+ Q_UNUSED(sender);
+ [self sendKeyPressRelease:Qt::Key_V modifiers:Qt::ControlModifier];
+}
+
+- (void)selectAll:(id)sender
+{
+ Q_UNUSED(sender);
+ [self sendKeyPressRelease:Qt::Key_A modifiers:Qt::ControlModifier];
+}
+
+- (void)delete:(id)sender
+{
+ Q_UNUSED(sender);
+ [self sendKeyPressRelease:Qt::Key_Delete modifiers:Qt::ControlModifier];
+}
+
+// -------------------------------------------------------------------------
+
- (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties
{
// As documented, we should not report textWillChange/textDidChange unless the text
@@ -560,7 +600,7 @@
if (cursorPos != int(r.location + r.length) || cursorPos != anchorPos) {
attrs = QList<QInputMethodEvent::Attribute>();
- attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, cursorPos, (cursorPos - anchorPos), 0);
+ attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, qMin(cursorPos, anchorPos), qAbs(cursorPos - anchorPos), 0);
e = QInputMethodEvent(m_markedText, attrs);
[self sendEventToFocusObject:e];
}
@@ -678,10 +718,7 @@
return;
if ([text isEqualToString:@"\n"]) {
- QKeyEvent press(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
- QKeyEvent release(QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier);
- [self sendEventToFocusObject:press];
- [self sendEventToFocusObject:release];
+ [self sendKeyPressRelease:Qt::Key_Return modifiers:Qt::NoModifier];
if (self.returnKeyType == UIReturnKeyDone || self.returnKeyType == UIReturnKeyGo
|| self.returnKeyType == UIReturnKeySend || self.returnKeyType == UIReturnKeySearch)
@@ -700,10 +737,7 @@
// Since we're posting im events directly to the focus object, we should do the
// same for key events. Otherwise they might end up in a different place or out
// of sync with im events.
- QKeyEvent press(QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier);
- QKeyEvent release(QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier);
- [self sendEventToFocusObject:press];
- [self sendEventToFocusObject:release];
+ [self sendKeyPressRelease:Qt::Key_Backspace modifiers:Qt::NoModifier];
}
@end
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index 4ea5fc7de1..67b33ce235 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -143,7 +143,7 @@
if (uiWindow.screen != [UIScreen mainScreen] && self.subviews.count == 1) {
// Removing the last view of an external screen, go back to mirror mode
- uiWindow.screen = nil;
+ uiWindow.screen = [UIScreen mainScreen];
uiWindow.hidden = YES;
}
}
@@ -190,8 +190,9 @@
- (void)setBounds:(CGRect)newBounds
{
+ Q_UNUSED(newBounds);
CGRect transformedWindowBounds = [self convertRect:self.window.bounds fromView:self.window];
- [super setBounds:CGRectMake(0, 0, CGRectGetWidth(newBounds), CGRectGetHeight(transformedWindowBounds))];
+ [super setBounds:CGRectMake(0, 0, CGRectGetWidth(transformedWindowBounds), CGRectGetHeight(transformedWindowBounds))];
}
- (void)setCenter:(CGPoint)newCenter
diff --git a/src/plugins/platforms/kms/kms.json b/src/plugins/platforms/kms/kms.json
deleted file mode 100644
index be662226ae..0000000000
--- a/src/plugins/platforms/kms/kms.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "kms" ]
-}
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
deleted file mode 100644
index baa8778153..0000000000
--- a/src/plugins/platforms/kms/kms.pro
+++ /dev/null
@@ -1,37 +0,0 @@
-TARGET = qkms
-
-PLUGIN_TYPE = platforms
-PLUGIN_CLASS_NAME = QKmsIntegrationPlugin
-!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-qtHaveModule(opengl):QT += opengl-private
-
-DEFINES += MESA_EGL_NO_X11_HEADERS __GBM__
-
-CONFIG += link_pkgconfig egl qpa/genericunixfontdatabase
-
-PKGCONFIG += libdrm libudev egl gbm glesv2
-
-SOURCES = main.cpp \
- qkmsintegration.cpp \
- qkmsscreen.cpp \
- qkmscontext.cpp \
- qkmswindow.cpp \
- qkmscursor.cpp \
- qkmsdevice.cpp \
- qkmsbackingstore.cpp \
- qkmsnativeinterface.cpp
-
-HEADERS = qkmsintegration.h \
- qkmsscreen.h \
- qkmscontext.h \
- qkmswindow.h \
- qkmscursor.h \
- qkmsdevice.h \
- qkmsbackingstore.h \
- qkmsnativeinterface.h
-
-OTHER_FILES += \
- kms.json
diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp
deleted file mode 100644
index 565ac7a7d4..0000000000
--- a/src/plugins/platforms/kms/main.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qpa/qplatformintegrationplugin.h>
-#include "qkmsintegration.h"
-
-QT_BEGIN_NAMESPACE
-
-class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "kms.json")
-public:
- QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE;
-};
-
-QPlatformIntegration *QKmsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
-{
- Q_UNUSED(paramList);
- if (!system.compare(QLatin1String("kms"), Qt::CaseInsensitive))
- return new QKmsIntegration;
-
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#include "main.moc"
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp
deleted file mode 100644
index 6e5a3f9192..0000000000
--- a/src/plugins/platforms/kms/qkmsbackingstore.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsbackingstore.h"
-
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QScreen>
-
-QT_BEGIN_NAMESPACE
-
-QKmsBackingStore::QKmsBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
- , m_context(new QOpenGLContext)
- , m_texture(0)
- , m_program(0)
- , m_initialized(false)
-{
- m_context->setFormat(window->requestedFormat());
- m_context->setScreen(window->screen());
- m_context->create();
-}
-
-QKmsBackingStore::~QKmsBackingStore()
-{
- delete m_program;
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- delete m_context;
-}
-
-QPaintDevice *QKmsBackingStore::paintDevice()
-{
- return &m_image;
-}
-
-void QKmsBackingStore::beginPaint(const QRegion &rgn)
-{
- m_dirty |= rgn;
-}
-
-void QKmsBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(region)
- Q_UNUSED(offset)
-
- m_context->makeCurrent(window);
-
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
-
- if (!m_program) {
- static const char *textureVertexProgram =
- "attribute highp vec2 vertexCoordEntry;\n"
- "attribute highp vec2 textureCoordEntry;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " textureCoord = textureCoordEntry;\n"
- " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n"
- "}\n";
-
- static const char *textureFragmentProgram =
- "uniform sampler2D texture;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
- "}\n";
-
- m_program = new QOpenGLShaderProgram;
-
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->bindAttributeLocation("vertexCoordEntry", 0);
- m_program->bindAttributeLocation("textureCoordEntry", 1);
- m_program->link();
- }
-
- m_program->bind();
-
- QRectF r = window->geometry();
- QRectF sr = window->screen()->geometry();
-
- GLfloat x1 = (r.left() / sr.width()) * 2 - 1;
- GLfloat x2 = (r.right() / sr.width()) * 2 - 1;
- GLfloat y1 = -1 * ((r.top() / sr.height()) * 2 - 1);
- GLfloat y2 = -1 * ((r.bottom() / sr.height()) * 2 - 1);
-
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
-
- const GLfloat textureCoordinates[] = {
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
-
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
-
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
-
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
- if (!m_dirty.isNull()) {
- QRect imageRect = m_image.rect();
- QRegion fixed;
- Q_FOREACH (const QRect &rect, m_dirty.rects()) {
- // intersect with image rect to be sure
- QRect r = imageRect & rect;
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (r.width() >= imageRect.width() / 2) {
- r.setX(0);
- r.setWidth(imageRect.width());
- }
- fixed |= r;
- }
-
- Q_FOREACH (const QRect &rect, fixed.rects()) {
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's no gap between scanlines
- if (rect.width() == imageRect.width()) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(),
- rect.width(), rect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.constScanLine(rect.y()));
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(),
- rect.width(), rect.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.copy(rect).constBits());
- }
- }
-
- m_dirty = QRegion();
- }
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- m_program->release();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
-
- m_context->swapBuffers(window);
-
- m_context->doneCurrent();
-}
-
-void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents)
-{
- Q_UNUSED(staticContents)
-
- m_image = QImage(size, QImage::Format_RGB32);
-
- m_context->makeCurrent(window());
-
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
-
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h
deleted file mode 100644
index a34b10d3d9..0000000000
--- a/src/plugins/platforms/kms/qkmsbackingstore.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBACKINGSTORE_KMS_H
-#define QBACKINGSTORE_KMS_H
-
-#include <qpa/qplatformbackingstore.h>
-#include <QtGui/QOpenGLFunctions>
-#include <QImage>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLContext;
-class QOpenGLShaderProgram;
-
-class QKmsBackingStore : public QPlatformBackingStore, public QOpenGLFunctions
-{
-public:
- QKmsBackingStore(QWindow *window);
- ~QKmsBackingStore();
-
- QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
-
- void beginPaint(const QRegion &) 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 { return m_image; }
-
-private:
- QOpenGLContext *m_context;
- QImage m_image;
- uint m_texture;
- QOpenGLShaderProgram *m_program;
- QRegion m_dirty;
- bool m_initialized;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/kms/qkmscontext.cpp b/src/plugins/platforms/kms/qkmscontext.cpp
deleted file mode 100644
index e00835fbac..0000000000
--- a/src/plugins/platforms/kms/qkmscontext.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsscreen.h"
-#include "qkmsdevice.h"
-#include "qkmscontext.h"
-#include "qkmswindow.h"
-#include "qkmsintegration.h"
-
-#include <QtGui/QOpenGLContext>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsContext::QKmsContext(QOpenGLContext *context, QKmsDevice *device)
- : m_device(device)
-{
- EGLDisplay display = m_device->eglDisplay();
- EGLConfig config = q_configFromGLFormat(display, QKmsScreen::tweakFormat(context->format()));
- m_format = q_glFormatFromConfig(display, config);
-
- //Initialize EGLContext
- static EGLint contextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, context->format().majorVersion(),
- EGL_NONE
- };
-
- eglBindAPI(EGL_OPENGL_ES_API);
-
- EGLContext share = EGL_NO_CONTEXT;
- if (context->shareContext())
- share = static_cast<QKmsContext *>(context->shareContext()->handle())->eglContext();
-
- m_eglContext = eglCreateContext(display, config, share, contextAttribs);
- if (m_eglContext == EGL_NO_CONTEXT) {
- qWarning("QKmsContext::QKmsContext(): eglError: %x, this: %p",
- eglGetError(), this);
- m_eglContext = 0;
- }
-}
-
-bool QKmsContext::isValid() const
-{
- return m_eglContext != EGL_NO_CONTEXT;
-}
-
-bool QKmsContext::makeCurrent(QPlatformSurface *surface)
-{
- Q_ASSERT(surface->surface()->supportsOpenGL());
-
- EGLDisplay display = m_device->eglDisplay();
- EGLSurface eglSurface;
-
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
- QKmsScreen *screen = static_cast<QKmsScreen *>(QPlatformScreen::platformScreenForWindow(window->window()));
- eglSurface = screen->eglSurface();
- screen->waitForPageFlipComplete();
- } else {
- eglSurface = static_cast<QKmsOffscreenWindow *>(surface)->surface();
- }
-
- bool ok = eglMakeCurrent(display, eglSurface, eglSurface, m_eglContext);
- if (!ok)
- qWarning("QKmsContext::makeCurrent(): eglError: %x, this: %p",
- eglGetError(), this);
-
- return true;
-}
-
-void QKmsContext::doneCurrent()
-{
- bool ok = eglMakeCurrent(m_device->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- if (!ok)
- qWarning("QKmsContext::doneCurrent(): eglError: %x, this: %p",
- eglGetError(), this);
-
-}
-
-void QKmsContext::swapBuffers(QPlatformSurface *surface)
-{
- //Cast context to a window surface and get the screen the context
- //is on and call swapBuffers on that screen.
- QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
- QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
- screen->swapBuffers();
-}
-
-void (*QKmsContext::getProcAddress(const QByteArray &procName)) ()
-{
- return eglGetProcAddress(procName.data());
-}
-
-
-EGLContext QKmsContext::eglContext() const
-{
- return m_eglContext;
-}
-
-QSurfaceFormat QKmsContext::format() const
-{
- return m_format;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscontext.h b/src/plugins/platforms/kms/qkmscontext.h
deleted file mode 100644
index 59cf9b1e34..0000000000
--- a/src/plugins/platforms/kms/qkmscontext.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSCONTEXT_H
-#define QKMSCONTEXT_H
-
-#include <qpa/qplatformopenglcontext.h>
-
-#define EGL_EGLEXT_PROTOTYPES 1
-#include <EGL/egl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsDevice;
-
-class QKmsContext : public QPlatformOpenGLContext
-{
-public:
- QKmsContext(QOpenGLContext *context, QKmsDevice *device);
-
- bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- void doneCurrent() Q_DECL_OVERRIDE;
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE;
-
- bool isValid() const Q_DECL_OVERRIDE;
-
- QSurfaceFormat format() const Q_DECL_OVERRIDE;
-
- EGLContext eglContext() const;
-
-private:
- EGLContext m_eglContext;
- QSurfaceFormat m_format;
-
- QKmsDevice *m_device;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSCONTEXT_H
diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp
deleted file mode 100644
index 44212cd3c8..0000000000
--- a/src/plugins/platforms/kms/qkmscursor.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-//#include <QDebug>
-#include "qkmscursor.h"
-#include "qkmsscreen.h"
-#include "qkmsdevice.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef DRM_CAP_CURSOR_WIDTH
-#define DRM_CAP_CURSOR_WIDTH 0x8
-#endif
-
-#ifndef DRM_CAP_CURSOR_HEIGHT
-#define DRM_CAP_CURSOR_HEIGHT 0x9
-#endif
-
-QKmsCursor::QKmsCursor(QKmsScreen *screen)
- : m_screen(screen),
- m_graphicsBufferManager(screen->device()->gbmDevice()),
- m_cursorImage(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)),
- m_moved(false),
- m_cursorSize(64, 64)
-{
- uint64_t value = 0;
- if (!drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &value))
- m_cursorSize.setWidth(value);
- if (!drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_HEIGHT, &value))
- m_cursorSize.setHeight(value);
-
- m_cursorBufferObject = gbm_bo_create(m_graphicsBufferManager, m_cursorSize.width(), m_cursorSize.height(),
- GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
-}
-
-QKmsCursor::~QKmsCursor()
-{
- drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0, 0);
- gbm_bo_destroy(m_cursorBufferObject);
-}
-
-void QKmsCursor::pointerEvent(const QMouseEvent &event)
-{
- m_moved = true;
- int status = drmModeMoveCursor(m_screen->device()->fd(),
- m_screen->crtcId(),
- event.globalX(),
- event.globalY());
- if (status) {
- qWarning("failed to move cursor: %d", status);
- }
-}
-
-void QKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window)
-{
- Q_UNUSED(window)
-
- if (!m_moved)
- drmModeMoveCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0);
-
- const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor;
- if (newShape != Qt::BitmapCursor) {
- m_cursorImage->set(newShape);
- } else {
- m_cursorImage->set(windowCursor->pixmap().toImage(),
- windowCursor->hotSpot().x(),
- windowCursor->hotSpot().y());
- }
-
- if (m_cursorImage->image()->width() > m_cursorSize.width() || m_cursorImage->image()->width() > m_cursorSize.height())
- qWarning("cursor larger than %dx%d, cursor truncated", m_cursorSize.width(), m_cursorSize.height());
-
- QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_ARGB32)
- .copy(0, 0, m_cursorSize.width(), m_cursorSize.height());
- gbm_bo_write(m_cursorBufferObject, cursorImage.constBits(), cursorImage.byteCount());
-
- quint32 handle = gbm_bo_get_handle(m_cursorBufferObject).u32;
- int status = drmModeSetCursor(m_screen->device()->fd(),
- m_screen->crtcId(), handle,
- m_cursorSize.width(), m_cursorSize.height());
-
- if (status) {
- qWarning("failed to set cursor: %d", status);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h
deleted file mode 100644
index 9aadf407c0..0000000000
--- a/src/plugins/platforms/kms/qkmscursor.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSCURSOR_H
-#define QKMSCURSOR_H
-
-#include <qpa/qplatformcursor.h>
-
-struct gbm_device;
-struct gbm_bo;
-
-QT_BEGIN_NAMESPACE
-
-class QKmsScreen;
-
-class QKmsCursor : public QPlatformCursor
-{
-public:
- QKmsCursor(QKmsScreen *screen);
- ~QKmsCursor();
-
- void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
- void changeCursor(QCursor *windowCursor, QWindow *window) Q_DECL_OVERRIDE;
-
-private:
- QKmsScreen *m_screen;
- gbm_device *m_graphicsBufferManager;
- gbm_bo *m_cursorBufferObject;
- QPlatformCursorImage *m_cursorImage;
- bool m_moved;
- QSize m_cursorSize;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSCURSOR_H
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
deleted file mode 100644
index 74fa59c16a..0000000000
--- a/src/plugins/platforms/kms/qkmsdevice.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-//#include <QDebug>
-#include "qkmsscreen.h"
-#include "qkmsdevice.h"
-
-#include "qkmsintegration.h"
-
-#include <QtCore/QSocketNotifier>
-#include <QtCore/private/qcore_unix_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsDevice::QKmsDevice(const QString &path, QKmsIntegration *parent) :
- QObject(0), m_integration(parent)
-{
- m_fd = QT_OPEN(path.toLatin1().constData(), O_RDWR);
- if (m_fd < 0) {
- qWarning("Could not open %s.", path.toLatin1().constData());
- qFatal("No DRM display device");
- }
-
- m_graphicsBufferManager = gbm_create_device(m_fd);
- m_eglDisplay = eglGetDisplay(m_graphicsBufferManager);
-
- if (m_eglDisplay == EGL_NO_DISPLAY) {
- qWarning("Could not open EGL display");
- qFatal("EGL error");
- }
-
- EGLint major;
- EGLint minor;
- if (!eglInitialize(m_eglDisplay, &major, &minor)) {
- qWarning("Could not initialize EGL display");
- qFatal("EGL error");
- }
-
- createScreens();
-
-// QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
-// connect(notifier, SIGNAL(activated(int)), this, SLOT(handlePageFlipCompleted()));
-}
-
-QKmsDevice::~QKmsDevice()
-{
-}
-
-void QKmsDevice::createScreens()
-{
- drmModeRes *resources = drmModeGetResources(m_fd);
- if (!resources)
- qFatal("drmModeGetResources failed");
-
- //Iterate connectors and create screens on each one active
- for (int i = 0; i < resources->count_connectors; i++) {
- drmModeConnector *connector = 0;
- connector = drmModeGetConnector(m_fd, resources->connectors[i]);
- if (connector && connector->connection == DRM_MODE_CONNECTED) {
- m_integration->addScreen(new QKmsScreen(this, resources, connector));
- }
- drmModeFreeConnector(connector);
- }
- drmModeFreeResources(resources);
-}
-
-void QKmsDevice::handlePageFlipCompleted()
-{
- drmEventContext eventContext;
-
- memset(&eventContext, 0, sizeof eventContext);
- eventContext.version = DRM_EVENT_CONTEXT_VERSION;
- eventContext.page_flip_handler = QKmsDevice::pageFlipHandler;
- drmHandleEvent(m_fd, &eventContext);
-
-}
-
-void QKmsDevice::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
-{
- Q_UNUSED(fd)
- Q_UNUSED(frame)
- Q_UNUSED(sec)
- Q_UNUSED(usec)
-
- QKmsScreen *screen = static_cast<QKmsScreen *>(data);
- screen->handlePageFlipped();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsdevice.h b/src/plugins/platforms/kms/qkmsdevice.h
deleted file mode 100644
index d5e33cb8c7..0000000000
--- a/src/plugins/platforms/kms/qkmsdevice.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSDEVICE_H
-#define QKMSDEVICE_H
-
-#include <stddef.h>
-
-extern "C" {
-#include <gbm.h>
-}
-#include <EGL/egl.h>
-
-#include <QObject>
-
-struct gbm_device;
-
-QT_BEGIN_NAMESPACE
-
-class QKmsIntegration;
-
-class QKmsDevice : public QObject
-{
- Q_OBJECT
-public:
- explicit QKmsDevice(const QString &path, QKmsIntegration *parent);
- ~QKmsDevice();
-
- EGLDisplay eglDisplay() { return m_eglDisplay; }
- gbm_device *gbmDevice() { return m_graphicsBufferManager; }
- int fd() const { return m_fd; }
-
- static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec,
- unsigned int usec, void *data);
-
-public slots:
- void handlePageFlipCompleted();
-private:
- void createScreens();
-
- QKmsIntegration *m_integration;
-
- EGLDisplay m_eglDisplay;
- EGLContext m_eglContext;
- gbm_device *m_graphicsBufferManager;
- int m_fd;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSDEVICE_H
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
deleted file mode 100644
index f48c868ae5..0000000000
--- a/src/plugins/platforms/kms/qkmsintegration.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsintegration.h"
-#include "qkmsdevice.h"
-#include "qkmsscreen.h"
-#include "qkmswindow.h"
-#include "qkmsbackingstore.h"
-#include "qkmscontext.h"
-#include "qkmsnativeinterface.h"
-
-#if !defined(QT_NO_EVDEV)
-#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
-#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
-#include <QtPlatformSupport/private/qevdevtouch_p.h>
-#endif
-
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtPlatformSupport/private/qfbvthandler_p.h>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QScreen>
-#include <QtGui/QOffscreenSurface>
-#include <qpa/qplatformoffscreensurface.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsIntegration::QKmsIntegration()
- : QPlatformIntegration(),
- m_fontDatabase(new QGenericUnixFontDatabase()),
- m_nativeInterface(new QKmsNativeInterface),
- m_vtHandler(0),
- m_deviceDiscovery(0)
-{
-}
-
-QKmsIntegration::~QKmsIntegration()
-{
- delete m_deviceDiscovery;
- foreach (QKmsDevice *device, m_devices) {
- delete device;
- }
- foreach (QPlatformScreen *screen, m_screens) {
- destroyScreen(screen);
- }
- delete m_fontDatabase;
- delete m_vtHandler;
-}
-
-void QKmsIntegration::initialize()
-{
- qputenv("EGL_PLATFORM", "drm");
- m_vtHandler = new QFbVtHandler;
-
- m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_DRM | QDeviceDiscovery::Device_DRM_PrimaryGPU, 0);
- if (m_deviceDiscovery) {
- QStringList devices = m_deviceDiscovery->scanConnectedDevices();
- foreach (const QString &device, devices)
- addDevice(device);
-
- connect(m_deviceDiscovery, SIGNAL(deviceDetected(QString)), this, SLOT(addDevice(QString)));
- connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeDevice(QString)));
- }
-
-#if !defined(QT_NO_EVDEV)
- new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
- new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
- new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
-#endif
-}
-
-void QKmsIntegration::addDevice(const QString &deviceNode)
-{
- m_devices.append(new QKmsDevice(deviceNode, this));
-}
-
-void QKmsIntegration::removeDevice(const QString &deviceNode)
-{
- // TODO: support hot-plugging some day?
- Q_UNUSED(deviceNode);
-}
-
-bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
-{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return true;
- case ThreadedOpenGL: return false;
- case RasterGLSurface: return true;
- default: return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-QPlatformOpenGLContext *QKmsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
-{
- QKmsScreen *screen = static_cast<QKmsScreen *>(context->screen()->handle());
- return new QKmsContext(context, screen->device());
-}
-
-QPlatformWindow *QKmsIntegration::createPlatformWindow(QWindow *window) const
-{
- QKmsWindow *w = new QKmsWindow(window);
- w->requestActivateWindow();
- return w;
-}
-
-QPlatformBackingStore *QKmsIntegration::createPlatformBackingStore(QWindow *window) const
-{
- return new QKmsBackingStore(window);
-}
-
-// Neither a pbuffer nor a hidden QWindow is suitable. Just use an additional, small gbm surface.
-QKmsOffscreenWindow::QKmsOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
- : QPlatformOffscreenSurface(offscreenSurface)
- , m_format(format)
- , m_display(display)
- , m_surface(EGL_NO_SURFACE)
- , m_window(0)
-{
- QKmsScreen *screen = static_cast<QKmsScreen *>(offscreenSurface->screen()->handle());
- m_window = gbm_surface_create(screen->device()->gbmDevice(),
- 10, 10,
- GBM_FORMAT_XRGB8888,
- GBM_BO_USE_RENDERING);
- if (!m_window) {
- qWarning("QKmsOffscreenWindow: Failed to create native window");
- return;
- }
-
- EGLConfig config = q_configFromGLFormat(m_display, m_format);
- m_surface = eglCreateWindowSurface(m_display, config, m_window, 0);
- if (m_surface != EGL_NO_SURFACE)
- m_format = q_glFormatFromConfig(m_display, config);
-}
-
-QKmsOffscreenWindow::~QKmsOffscreenWindow()
-{
- if (m_surface != EGL_NO_SURFACE)
- eglDestroySurface(m_display, m_surface);
- if (m_window)
- gbm_surface_destroy((gbm_surface *) m_window);
-}
-
-QPlatformOffscreenSurface *QKmsIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
-{
- QKmsScreen *screen = static_cast<QKmsScreen *>(surface->screen()->handle());
- return new QKmsOffscreenWindow(screen->device()->eglDisplay(), QKmsScreen::tweakFormat(surface->format()), surface);
-}
-
-QPlatformFontDatabase *QKmsIntegration::fontDatabase() const
-{
- return m_fontDatabase;
-}
-
-void QKmsIntegration::addScreen(QKmsScreen *screen)
-{
- m_screens.append(screen);
- screenAdded(screen);
-}
-
-QAbstractEventDispatcher *QKmsIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
-QPlatformNativeInterface *QKmsIntegration::nativeInterface() const
-{
- return m_nativeInterface;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
deleted file mode 100644
index bcf9ac7296..0000000000
--- a/src/plugins/platforms/kms/qkmsintegration.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLATFORMINTEGRATION_KMS_H
-#define QPLATFORMINTEGRATION_KMS_H
-
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformnativeinterface.h>
-#include <qpa/qplatformoffscreensurface.h>
-#include <QtPlatformSupport/private/qdevicediscovery_p.h>
-#include <EGL/egl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsScreen;
-class QKmsDevice;
-class QFbVtHandler;
-
-class QKmsOffscreenWindow : public QPlatformOffscreenSurface
-{
-public:
- QKmsOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface);
- ~QKmsOffscreenWindow();
-
- QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- bool isValid() const Q_DECL_OVERRIDE { return m_surface != EGL_NO_SURFACE; }
-
- EGLSurface surface() const { return m_surface; }
-
-private:
- QSurfaceFormat m_format;
- EGLDisplay m_display;
- EGLSurface m_surface;
- EGLNativeWindowType m_window;
-};
-
-class QKmsIntegration : public QObject, public QPlatformIntegration
-{
- Q_OBJECT
-
-public:
- QKmsIntegration();
- ~QKmsIntegration();
-
- void initialize() Q_DECL_OVERRIDE;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
-
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
-
- QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
-
- QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
-
- void addScreen(QKmsScreen *screen);
- QObject *createDevice(const char *);
-
-private slots:
- void addDevice(const QString &deviceNode);
- void removeDevice(const QString &deviceNode);
-
-private:
- QStringList findDrmDevices();
-
- QList<QPlatformScreen *> m_screens;
- QList<QKmsDevice *> m_devices;
- QPlatformFontDatabase *m_fontDatabase;
- QPlatformNativeInterface *m_nativeInterface;
- QFbVtHandler *m_vtHandler;
- QDeviceDiscovery *m_deviceDiscovery;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/kms/qkmsnativeinterface.cpp b/src/plugins/platforms/kms/qkmsnativeinterface.cpp
deleted file mode 100644
index 1538a7f8c3..0000000000
--- a/src/plugins/platforms/kms/qkmsnativeinterface.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qguiapplication_p.h>
-#include "qkmsnativeinterface.h"
-#include "qkmsdevice.h"
-
-#include "qscreen.h"
-#include "qkmscontext.h"
-#include <QOpenGLContext>
-
-class QKmsResourceMap : public QMap<QByteArray, QKmsNativeInterface::ResourceType>
-{
-public:
- QKmsResourceMap()
- :QMap<QByteArray, QKmsNativeInterface::ResourceType>()
- {
- insert("egldisplay", QKmsNativeInterface::EglDisplay);
- insert("eglcontext", QKmsNativeInterface::EglContext);
- }
-};
-
-Q_GLOBAL_STATIC(QKmsResourceMap, qKmsResourceMap)
-
-void *QKmsNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
-{
- QByteArray lowerCaseResource = resourceString.toLower();
- ResourceType resource = qKmsResourceMap()->value(lowerCaseResource);
- void *result = 0;
- switch (resource) {
- case EglDisplay:
- result = eglDisplay();
- break;
- default:
- result = 0;
- }
- return result;
-
-}
-void *QKmsNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
-{
- QByteArray lowerCaseResource = resourceString.toLower();
- ResourceType resource = qKmsResourceMap()->value(lowerCaseResource);
- void *result = 0;
- switch (resource) {
- case EglDisplay:
- result = eglDisplayForWindow(window);
- break;
- case EglContext:
- result = eglContextForWindow(window);
- break;
- default:
- result = 0;
- }
- return result;
-}
-
-QPlatformNativeInterface::NativeResourceForContextFunction QKmsNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource)
-{
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context") {
- return eglContextForContext;
- }
- return 0;
-}
-
-void *QKmsNativeInterface::eglDisplay()
-{
- //QKmsIntegration *integration = static_cast<QKmsIntegration *>(QGuiApplicationPrivate::platformIntegration());
- QKmsScreen *screen = static_cast<QKmsScreen *>(QGuiApplication::primaryScreen()->handle());
- if (!screen || !screen->device())
- return 0;
- return screen->device()->eglDisplay();
-}
-
-void *QKmsNativeInterface::eglDisplayForWindow(QWindow *window)
-{
- QKmsScreen *screen = qPlatformScreenForWindow(window);
- if (!screen)
- return 0;
- QKmsDevice *device = screen->device();
- if (!device)
- return 0;
- return device->eglDisplay();
-}
-
-void *QKmsNativeInterface::eglContextForWindow(QWindow *)
-{
- return 0;
-}
-
-QKmsScreen *QKmsNativeInterface::qPlatformScreenForWindow(QWindow *window)
-{
- QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
- return static_cast<QKmsScreen *>(screen->handle());
-}
-
-void *QKmsNativeInterface::eglContextForContext(QOpenGLContext *context)
-{
- Q_ASSERT(context);
-
- QKmsContext *eglPlatformContext = static_cast<QKmsContext *>(context->handle());
-
- return eglPlatformContext->eglContext();
-}
diff --git a/src/plugins/platforms/kms/qkmsnativeinterface.h b/src/plugins/platforms/kms/qkmsnativeinterface.h
deleted file mode 100644
index 56879d0a3a..0000000000
--- a/src/plugins/platforms/kms/qkmsnativeinterface.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSNATIVEINTERFACE_H
-#define QKMSNATIVEINTERFACE_H
-
-#include "qkmsscreen.h"
-
-#include <qpa/qplatformnativeinterface.h>
-
-class QKmsNativeInterface : public QPlatformNativeInterface
-{
-public:
- enum ResourceType {
- EglDisplay,
- EglContext
- };
-
- void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
- void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) Q_DECL_OVERRIDE;
-
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
-
- void *eglDisplay();
- void *eglDisplayForWindow(QWindow *window);
- void *eglContextForWindow(QWindow *window);
- static void *eglContextForContext(QOpenGLContext *context);
-
-private:
- static QKmsScreen *qPlatformScreenForWindow(QWindow *window);
-};
-
-
-#endif // QKMSNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
deleted file mode 100644
index 6392b99cd5..0000000000
--- a/src/plugins/platforms/kms/qkmsscreen.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmsscreen.h"
-#include "qkmscursor.h"
-#include "qkmsdevice.h"
-#include "qkmscontext.h"
-
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
-#include <QCoreApplication>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.kms.screen")
-
-//Fallback mode (taken from Wayland DRM demo compositor)
-static drmModeModeInfo builtin_1024x768 = {
- 63500, //clock
- 1024, 1072, 1176, 1328, 0,
- 768, 771, 775, 798, 0,
- 59920,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
- 0,
- "1024x768"
-};
-
-QKmsScreen::QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector)
- : m_device(device),
- m_current_bo(0),
- m_next_bo(0),
- m_connectorId(connector->connector_id),
- m_depth(32),
- m_format(QImage::Format_Invalid),
- m_eglWindowSurface(EGL_NO_SURFACE),
- m_modeSet(false)
-{
- m_cursor = new QKmsCursor(this);
- initializeScreenMode(resources, connector);
-}
-
-QKmsScreen::~QKmsScreen()
-{
- delete m_cursor;
- drmModeSetCrtc(m_device->fd(), m_oldCrtc->crtc_id, m_oldCrtc->buffer_id,
- m_oldCrtc->x, m_oldCrtc->y,
- &m_connectorId, 1, &m_oldCrtc->mode);
- drmModeFreeCrtc(m_oldCrtc);
- if (m_eglWindowSurface != EGL_NO_SURFACE)
- eglDestroySurface(m_device->eglDisplay(), m_eglWindowSurface);
- gbm_surface_destroy(m_gbmSurface);
-}
-
-QRect QKmsScreen::geometry() const
-{
- return m_geometry;
-}
-
-int QKmsScreen::depth() const
-{
- return m_depth;
-}
-
-QImage::Format QKmsScreen::format() const
-{
- return m_format;
-}
-
-QSizeF QKmsScreen::physicalSize() const
-{
- return m_physicalSize;
-}
-
-QPlatformCursor *QKmsScreen::cursor() const
-{
- return m_cursor;
-}
-
-void QKmsScreen::initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector)
-{
- //Determine optimal mode for screen
- drmModeModeInfo *mode = 0;
- for (int i = 0; i < connector->count_modes; ++i) {
- if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
- mode = &connector->modes[i];
- break;
- }
- }
- if (!mode) {
- if (connector->count_modes > 0)
- mode = &connector->modes[0];
- else
- mode = &builtin_1024x768;
- }
-
- drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
- if (encoder == 0)
- qFatal("No encoder for connector.");
-
- int i;
- for (i = 0; i < resources->count_crtcs; i++) {
- if (encoder->possible_crtcs & (1 << i))
- break;
- }
- if (i == resources->count_crtcs)
- qFatal("No usable crtc for encoder.");
-
- m_oldCrtc = drmModeGetCrtc(m_device->fd(), encoder->crtc_id);
-
- m_crtcId = resources->crtcs[i];
- m_mode = *mode;
- m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
- qCDebug(lcQpaScreen) << "kms initialized with geometry" << m_geometry;
- m_depth = 32;
- m_format = QImage::Format_RGB32;
- m_physicalSize = QSizeF(connector->mmWidth, connector->mmHeight);
-
- m_gbmSurface = gbm_surface_create(m_device->gbmDevice(),
- m_mode.hdisplay, m_mode.vdisplay,
- GBM_BO_FORMAT_XRGB8888,
- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
-
- qCDebug(lcQpaScreen) << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay;
- //Cleanup
- drmModeFreeEncoder(encoder);
-}
-
-QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format)
-{
- QSurfaceFormat fmt = format;
- fmt.setRedBufferSize(8);
- fmt.setGreenBufferSize(8);
- fmt.setBlueBufferSize(8);
- if (fmt.alphaBufferSize() != -1)
- fmt.setAlphaBufferSize(8);
- return fmt;
-}
-
-void QKmsScreen::initializeWithFormat(const QSurfaceFormat &format)
-{
- EGLDisplay display = m_device->eglDisplay();
- EGLConfig config = q_configFromGLFormat(display, tweakFormat(format));
-
- m_eglWindowSurface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_gbmSurface, NULL);
- qCDebug(lcQpaScreen) << "created window surface";
- m_surfaceFormat = q_glFormatFromConfig(display, config);
-}
-
-void QKmsScreen::swapBuffers()
-{
- eglSwapBuffers(m_device->eglDisplay(), m_eglWindowSurface);
-
- m_next_bo = gbm_surface_lock_front_buffer(m_gbmSurface);
- if (!m_next_bo)
- qFatal("kms: Failed to lock front buffer");
-
- performPageFlip();
-}
-
-void QKmsScreen::performPageFlip()
-{
- if (!m_next_bo)
- return;
-
- uint32_t width = gbm_bo_get_width(m_next_bo);
- uint32_t height = gbm_bo_get_height(m_next_bo);
- uint32_t stride = gbm_bo_get_stride(m_next_bo);
- uint32_t handle = gbm_bo_get_handle(m_next_bo).u32;
-
- uint32_t fb_id;
- int ret = drmModeAddFB(m_device->fd(), width, height, 24, 32,
- stride, handle, &fb_id);
- if (ret) {
- qFatal("kms: Failed to create fb: fd %d, w %d, h %d, stride %d, handle %d, ret %d",
- m_device->fd(), width, height, stride, handle, ret);
- }
-
- if (!m_modeSet) {
- //Set the Mode of the screen.
- int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, fb_id,
- 0, 0, &m_connectorId, 1, &m_mode);
- if (ret)
- qFatal("failed to set mode");
- m_modeSet = true;
-
- // Initialize cursor
-
- static int hideCursor = qEnvironmentVariableIntValue("QT_QPA_KMS_HIDECURSOR");
- if (!hideCursor) {
- QCursor cursor(Qt::ArrowCursor);
- m_cursor->changeCursor(&cursor, 0);
- }
- }
-
- int pageFlipStatus = drmModePageFlip(m_device->fd(), m_crtcId,
- fb_id,
- DRM_MODE_PAGE_FLIP_EVENT, this);
- if (pageFlipStatus)
- {
- qWarning("Pageflip status: %d", pageFlipStatus);
- gbm_surface_release_buffer(m_gbmSurface, m_next_bo);
- m_next_bo = 0;
- }
-}
-
-void QKmsScreen::handlePageFlipped()
-{
- if (m_current_bo)
- gbm_surface_release_buffer(m_gbmSurface, m_current_bo);
-
- m_current_bo = m_next_bo;
- m_next_bo = 0;
-}
-
-QKmsDevice * QKmsScreen::device() const
-{
- return m_device;
-}
-
-void QKmsScreen::waitForPageFlipComplete()
-{
- while (m_next_bo) {
-#if 0
- //Check manually if there is something to be read on the device
- //as there are senarios where the signal is not received (starvation)
- fd_set fdSet;
- timeval timeValue;
- int returnValue;
-
- FD_ZERO(&fdSet);
- FD_SET(m_device->fd(), &fdSet);
- timeValue.tv_sec = 0;
- timeValue.tv_usec = 1000;
-
- returnValue = select(1, &fdSet, 0, 0, &timeValue);
- printf("select returns %d\n", returnValue);
-#endif
-
- m_device->handlePageFlipCompleted();
- }
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
deleted file mode 100644
index c52d0211b3..0000000000
--- a/src/plugins/platforms/kms/qkmsscreen.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSSCREEN_H
-#define QKMSSCREEN_H
-
-#include <stddef.h>
-
-#define EGL_EGLEXT_PROTOTYPES 1
-#define GL_GLEXT_PROTOTYPES 1
-
-extern "C" {
-#include <gbm.h>
-#include <xf86drmMode.h>
-#include <xf86drm.h>
-}
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <QtGui/qopengl.h>
-#include <QtGui/qsurfaceformat.h>
-#include <QtCore/qloggingcategory.h>
-
-#include <qpa/qplatformscreen.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
-
-class QKmsCursor;
-class QKmsDevice;
-class QKmsContext;
-
-class QKmsScreen : public QPlatformScreen
-{
-public:
- QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector);
- ~QKmsScreen();
-
- QRect geometry() const Q_DECL_OVERRIDE;
- int depth() const Q_DECL_OVERRIDE;
- QImage::Format format() const Q_DECL_OVERRIDE;
- QSizeF physicalSize() const Q_DECL_OVERRIDE;
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
-
- quint32 crtcId() const { return m_crtcId; }
- QKmsDevice *device() const;
-
- void initializeWithFormat(const QSurfaceFormat &format);
-
- //Called by context for each screen
- void swapBuffers();
- void handlePageFlipped();
-
- EGLSurface eglSurface() const { return m_eglWindowSurface; }
-
- void waitForPageFlipComplete();
-
- static QSurfaceFormat tweakFormat(const QSurfaceFormat &format);
-
- QSurfaceFormat surfaceFormat() const { return m_surfaceFormat; }
-
-private:
- void performPageFlip();
- void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector);
-
- QKmsDevice *m_device;
- gbm_bo *m_current_bo;
- gbm_bo *m_next_bo;
- quint32 m_connectorId;
-
- quint32 m_crtcId;
- drmModeModeInfo m_mode;
- QRect m_geometry;
- QSizeF m_physicalSize;
- int m_depth;
- QImage::Format m_format;
-
- drmModeCrtcPtr m_oldCrtc;
-
- QKmsCursor *m_cursor;
-
- gbm_surface *m_gbmSurface;
- EGLSurface m_eglWindowSurface;
-
- bool m_modeSet;
- QSurfaceFormat m_surfaceFormat;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSSCREEN_H
diff --git a/src/plugins/platforms/kms/qkmswindow.cpp b/src/plugins/platforms/kms/qkmswindow.cpp
deleted file mode 100644
index 3b01dfedca..0000000000
--- a/src/plugins/platforms/kms/qkmswindow.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkmswindow.h"
-#include "qkmsscreen.h"
-
-#include <qpa/qwindowsysteminterface.h>
-#include <qpa/qplatformwindow_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QKmsWindow::QKmsWindow(QWindow *window)
- : QPlatformWindow(window)
-{
- Q_D(QPlatformWindow);
- m_screen = QPlatformScreen::platformScreenForWindow(window);
- static_cast<QKmsScreen *>(m_screen)->initializeWithFormat(window->requestedFormat());
- setGeometry(d->rect); // rect is set to window->geometry() in base ctor
-}
-
-void QKmsWindow::setGeometry(const QRect &rect)
-{
- // All windows must be fullscreen
- QRect fullscreenRect = m_screen->availableGeometry();
- if (rect != fullscreenRect)
- QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
-
- QPlatformWindow::setGeometry(fullscreenRect);
-}
-
-QSurfaceFormat QKmsWindow::format() const
-{
- return static_cast<QKmsScreen *>(m_screen)->surfaceFormat();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmswindow.h b/src/plugins/platforms/kms/qkmswindow.h
deleted file mode 100644
index aec6d55b5d..0000000000
--- a/src/plugins/platforms/kms/qkmswindow.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKMSWINDOW_H
-#define QKMSWINDOW_H
-
-#include <qpa/qplatformwindow.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsWindow : public QPlatformWindow
-{
- Q_DECLARE_PRIVATE(QPlatformWindow)
-
-public:
- QKmsWindow(QWindow *window);
-
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
- QSurfaceFormat format() const Q_DECL_OVERRIDE;
-
-private:
- QPlatformScreen *m_screen;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSWINDOW_H
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index ccf86dafb2..8c8c8a15ea 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -46,6 +46,10 @@
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatforminputcontextfactory_p.h>
+#ifndef QT_NO_LIBINPUT
+#include <QtPlatformSupport/private/qlibinputhandler_p.h>
+#endif
+
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
@@ -130,6 +134,13 @@ QPlatformServices *QLinuxFbIntegration::services() const
void QLinuxFbIntegration::createInputHandlers()
{
+#ifndef QT_NO_LIBINPUT
+ if (!qEnvironmentVariableIntValue("QT_QPA_FB_NO_LIBINPUT")) {
+ new QLibInputHandler(QLatin1String("libinput"), QString());
+ return;
+ }
+#endif
+
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this);
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 925427ac30..97459a4d97 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -109,8 +109,11 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const
{
IDataObject * pDataObj = 0;
- if (OleGetClipboard(&pDataObj) == S_OK)
+ if (OleGetClipboard(&pDataObj) == S_OK) {
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
return pDataObj;
+ }
return 0;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 717adcc47f..4ec34c05bd 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -33,6 +33,7 @@
****************************************************************************/
#include "qwindowscontext.h"
+#include "qwindowsintegration.h"
#include "qwindowswindow.h"
#include "qwindowskeymapper.h"
#include "qwindowsguieventdispatcher.h"
@@ -907,16 +908,30 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
}
}
+ if (et & QtWindows::InputMethodEventFlag) {
+ QWindowsInputContext *windowsInputContext =
+ qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+ // Disable IME assuming this is a special implementation hooking into keyboard input.
+ // "Real" IME implementations should use a native event filter intercepting IME events.
+ if (!windowsInputContext) {
+ QWindowsInputContext::setWindowsImeEnabled(platformWindow, false);
+ return false;
+ }
+ switch (et) {
+ case QtWindows::InputMethodStartCompositionEvent:
+ return windowsInputContext->startComposition(hwnd);
+ case QtWindows::InputMethodCompositionEvent:
+ return windowsInputContext->composition(hwnd, lParam);
+ case QtWindows::InputMethodEndCompositionEvent:
+ return windowsInputContext->endComposition(hwnd);
+ case QtWindows::InputMethodRequest:
+ return windowsInputContext->handleIME_Request(wParam, lParam, result);
+ default:
+ break;
+ }
+ } // InputMethodEventFlag
switch (et) {
- case QtWindows::InputMethodStartCompositionEvent:
- return QWindowsInputContext::instance()->startComposition(hwnd);
- case QtWindows::InputMethodCompositionEvent:
- return QWindowsInputContext::instance()->composition(hwnd, lParam);
- case QtWindows::InputMethodEndCompositionEvent:
- return QWindowsInputContext::instance()->endComposition(hwnd);
- case QtWindows::InputMethodRequest:
- return QWindowsInputContext::instance()->handleIME_Request(wParam, lParam, result);
case QtWindows::GestureEvent:
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result);
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index 06c9985cac..e4ec3f3cf8 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -350,16 +350,16 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester:
{
const HDC dc = QWindowsContext::instance()->displayContext();
if (!dc){
- qWarning("%s: No Display", Q_FUNC_INFO);
+ qWarning("%s: No Display", __FUNCTION__);
return 0;
}
if (!libEGL.init()) {
- qWarning("%s: Failed to load and resolve libEGL functions", Q_FUNC_INFO);
+ qWarning("%s: Failed to load and resolve libEGL functions", __FUNCTION__);
return 0;
}
if (!libGLESv2.init()) {
- qWarning("%s: Failed to load and resolve libGLESv2 functions", Q_FUNC_INFO);
+ qWarning("%s: Failed to load and resolve libGLESv2 functions", __FUNCTION__);
return 0;
}
@@ -396,15 +396,15 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester:
if (display == EGL_NO_DISPLAY)
display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc);
if (!display) {
- qWarning("%s: Could not obtain EGL display", Q_FUNC_INFO);
+ qWarning("%s: Could not obtain EGL display", __FUNCTION__);
return 0;
}
if (!major && !libEGL.eglInitialize(display, &major, &minor)) {
int err = libEGL.eglGetError();
- qWarning("%s: Could not initialize EGL display: error 0x%x\n", Q_FUNC_INFO, err);
+ qWarning("%s: Could not initialize EGL display: error 0x%x", __FUNCTION__, err);
if (err == 0x3001)
- qWarning("%s: When using ANGLE, check if d3dcompiler_4x.dll is available", Q_FUNC_INFO);
+ qWarning("%s: When using ANGLE, check if d3dcompiler_4x.dll is available", __FUNCTION__);
return 0;
}
@@ -430,7 +430,7 @@ void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *na
(EGLNativeWindowType) nativeWindow, 0);
if (surface == EGL_NO_SURFACE) {
*err = libEGL.eglGetError();
- qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, *err);
+ qWarning("%s: Could not create the EGL window surface: 0x%x", __FUNCTION__, *err);
}
return surface;
@@ -533,7 +533,12 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
}
if (m_eglContext == EGL_NO_CONTEXT) {
- qWarning("QWindowsEGLContext: eglError: %x, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ int err = QWindowsEGLStaticContext::libEGL.eglGetError();
+ qWarning("QWindowsEGLContext: Failed to create context, eglError: %x, this: %p", err, this);
+ // ANGLE gives bad alloc when it fails to reset a previously lost D3D device.
+ // A common cause for this is disabling the graphics adapter used by the app.
+ if (err == EGL_BAD_ALLOC)
+ qWarning("QWindowsEGLContext: Graphics device lost. (Did the adapter get disabled?)");
return;
}
@@ -594,6 +599,12 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
if (err == EGL_CONTEXT_LOST) {
m_eglContext = EGL_NO_CONTEXT;
qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this;
+ } else if (err == EGL_BAD_ACCESS) {
+ // With ANGLE this means no (D3D) device and can happen when disabling/changing graphics adapters.
+ qCDebug(lcQpaGl) << "Bad access (missing device?) in createWindowSurface() for context" << this;
+ // Simulate context loss as the context is useless.
+ QWindowsEGLStaticContext::libEGL.eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
}
return false;
}
@@ -623,7 +634,7 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
// Drop the surface. Will recreate on the next makeCurrent.
window->invalidateSurface();
} else {
- qWarning("QWindowsEGLContext::makeCurrent: eglError: %x, this: %p \n", err, this);
+ qWarning("%s: Failed to make surface current. eglError: %x, this: %p", __FUNCTION__, err, this);
}
}
@@ -635,7 +646,8 @@ void QWindowsEGLContext::doneCurrent()
QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
bool ok = QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!ok)
- qWarning("QWindowsEGLContext::doneCurrent: eglError: %d, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ qWarning("%s: Failed to make no context/surface current. eglError: %d, this: %p", __FUNCTION__,
+ QWindowsEGLStaticContext::libEGL.eglGetError(), this);
}
void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface)
@@ -653,8 +665,15 @@ void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface)
}
bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface);
- if (!ok)
- qWarning("QWindowsEGLContext::swapBuffers: eglError: %d, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ if (!ok) {
+ err = QWindowsEGLStaticContext::libEGL.eglGetError();
+ if (err == EGL_CONTEXT_LOST) {
+ m_eglContext = EGL_NO_CONTEXT;
+ qCDebug(lcQpaGl) << "Got EGL context lost in eglSwapBuffers()";
+ } else {
+ qWarning("%s: Failed to swap buffers. eglError: %d, this: %p", __FUNCTION__, err, this);
+ }
+ }
}
QFunctionPointer QWindowsEGLContext::getProcAddress(const QByteArray &procName)
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 16b9118e81..3685197430 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -181,9 +181,8 @@ void QWindowsFontEngine::getCMap()
bool symb = false;
if (ttf) {
cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
- int size = 0;
cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
- cmapTable.size(), &symb, &size);
+ cmapTable.size(), &symb, &cmapSize);
}
if (!cmap) {
ttf = false;
@@ -218,16 +217,16 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa
QStringIterator it(str, str + numChars);
while (it.hasNext()) {
const uint uc = it.next();
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
++glyph_pos;
}
} else if (ttf) {
QStringIterator it(str, str + numChars);
while (it.hasNext()) {
const uint uc = it.next();
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
++glyph_pos;
}
} else {
@@ -275,6 +274,7 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
hasOutline(0),
lw(0),
cmap(0),
+ cmapSize(0),
lbearing(SHRT_MIN),
rbearing(SHRT_MIN),
x_height(-1),
@@ -346,11 +346,11 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const
#if !defined(Q_OS_WINCE)
if (symbol) {
- glyph = getTrueTypeGlyphIndex(cmap, ucs4);
+ glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
if (glyph == 0 && ucs4 < 0x100)
- glyph = getTrueTypeGlyphIndex(cmap, ucs4 + 0xf000);
+ glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
} else if (ttf) {
- glyph = getTrueTypeGlyphIndex(cmap, ucs4);
+ glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
#else
if (tm.tmFirstChar > 60000) {
glyph = ucs4;
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 6df69c34db..409b44264e 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -146,6 +146,7 @@ private:
TEXTMETRIC tm;
int lw;
const unsigned char *cmap;
+ int cmapSize;
QByteArray cmapTable;
mutable qreal lbearing;
mutable qreal rbearing;
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 485b876fc7..e016b84bba 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -199,32 +199,44 @@ void QWindowsInputContext::reset()
doneContext();
}
-void QWindowsInputContext::setFocusObject(QObject *object)
+void QWindowsInputContext::setFocusObject(QObject *)
{
// ### fixme: On Windows 8.1, it has been observed that the Input context
// remains active when this happens resulting in a lock-up. Consecutive
// key events still have VK_PROCESSKEY set and are thus ignored.
if (m_compositionContext.isComposing)
- imeNotifyCancelComposition(m_compositionContext.hwnd);
+ reset();
+ updateEnabled();
+}
+void QWindowsInputContext::updateEnabled()
+{
+ if (!QGuiApplication::focusObject())
+ return;
const QWindow *window = QGuiApplication::focusWindow();
- if (object && window && window->handle()) {
+ if (window && window->handle()) {
QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window);
- if (inputMethodAccepted()) {
- // Re-enable IME by associating default context saved on first disabling.
- if (platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) {
- ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext);
- platformWindow->clearFlag(QWindowsWindow::InputMethodDisabled);
- }
- } else {
- // Disable IME by associating 0 context. Store context first time.
- if (!platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) {
- const HIMC oldImC = ImmAssociateContext(platformWindow->handle(), 0);
- platformWindow->setFlag(QWindowsWindow::InputMethodDisabled);
- if (!QWindowsInputContext::m_defaultContext && oldImC)
- QWindowsInputContext::m_defaultContext = oldImC;
- }
- }
+ const bool accepted = inputMethodAccepted();
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << window << "accepted=" << accepted;
+ QWindowsInputContext::setWindowsImeEnabled(platformWindow, accepted);
+ }
+}
+
+void QWindowsInputContext::setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled)
+{
+ if (!platformWindow || platformWindow->testFlag(QWindowsWindow::InputMethodDisabled) == !enabled)
+ return;
+ if (enabled) {
+ // Re-enable Windows IME by associating default context saved on first disabling.
+ ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext);
+ platformWindow->clearFlag(QWindowsWindow::InputMethodDisabled);
+ } else {
+ // Disable Windows IME by associating 0 context. Store context first time.
+ const HIMC oldImC = ImmAssociateContext(platformWindow->handle(), 0);
+ platformWindow->setFlag(QWindowsWindow::InputMethodDisabled);
+ if (!QWindowsInputContext::m_defaultContext && oldImC)
+ QWindowsInputContext::m_defaultContext = oldImC;
}
}
@@ -234,6 +246,8 @@ void QWindowsInputContext::setFocusObject(QObject *object)
void QWindowsInputContext::update(Qt::InputMethodQueries queries)
{
+ if (queries & Qt::ImEnabled)
+ updateEnabled();
QPlatformInputContext::update(queries);
}
@@ -295,11 +309,6 @@ void QWindowsInputContext::invokeAction(QInputMethod::Action action, int cursorP
ImmReleaseContext(m_compositionContext.hwnd, himc);
}
-QWindowsInputContext *QWindowsInputContext::instance()
-{
- return static_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
-}
-
static inline QString getCompositionString(HIMC himc, DWORD dwIndex)
{
enum { bufferSize = 256 };
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
index 83a39989f6..eb4e3a3faa 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.h
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -42,6 +42,7 @@
QT_BEGIN_NAMESPACE
class QInputMethodEvent;
+class QWindowsWindow;
class QWindowsInputContext : public QPlatformInputContext
{
@@ -62,14 +63,14 @@ public:
explicit QWindowsInputContext();
~QWindowsInputContext();
+ static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled);
+
bool hasCapability(Capability capability) const Q_DECL_OVERRIDE;
void reset() Q_DECL_OVERRIDE;
void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE;
void setFocusObject(QObject *object) Q_DECL_OVERRIDE;
- static QWindowsInputContext *instance();
-
bool startComposition(HWND hwnd);
bool composition(HWND hwnd, LPARAM lParam);
bool endComposition(HWND hwnd);
@@ -87,6 +88,7 @@ private:
void doneContext();
void startContextComposition();
void endContextComposition();
+ void updateEnabled();
const DWORD m_WM_MSIME_MOUSE;
static HIMC m_defaultContext;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 081a800913..402ab9ad71 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -266,10 +266,9 @@ QWindowsIntegration::~QWindowsIntegration()
void QWindowsIntegration::initialize()
{
- if (QPlatformInputContext *pluginContext = QPlatformInputContextFactory::create())
- d->m_inputContext.reset(pluginContext);
- else
- d->m_inputContext.reset(new QWindowsInputContext);
+ QString icStr = QPlatformInputContextFactory::requested();
+ icStr.isNull() ? d->m_inputContext.reset(new QWindowsInputContext)
+ : d->m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
}
bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 3636bb7893..f8e2ded228 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -33,6 +33,7 @@
#include "qwindowskeymapper.h"
#include "qwindowscontext.h"
+#include "qwindowsintegration.h"
#include "qwindowswindow.h"
#include "qwindowsguieventdispatcher.h"
#include "qwindowsinputcontext.h"
@@ -1074,7 +1075,9 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
// results, if we map this virtual key-code directly (for eg '?' US layouts). So try
// to find the correct key using the current message parameters & keyboard state.
if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
- if (!QWindowsInputContext::instance()->isComposing())
+ const QWindowsInputContext *windowsInputContext =
+ qobject_cast<const QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+ if (!(windowsInputContext && windowsInputContext->isComposing()))
vk_key = ImmGetVirtualKey((HWND)window->winId());
BYTE keyState[256];
wchar_t newKey[3] = {0};
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index f86ab9fee3..375a7f11db 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -299,8 +299,6 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image)
return true;
}
-//#define QMIME_DEBUG
-
// helpers for using global memory
static int getCf(const FORMATETC &formatetc)
@@ -380,6 +378,73 @@ static bool canGetData(int cf, IDataObject * pDataObj)
return true;
}
+#ifndef QT_NO_DEBUG_OUTPUT
+QDebug operator<<(QDebug d, const FORMATETC &tc)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "FORMATETC(cfFormat=" << tc.cfFormat << ' ';
+ switch (tc.cfFormat) {
+ case CF_TEXT:
+ d << "CF_TEXT";
+ break;
+ case CF_BITMAP:
+ d << "CF_BITMAP";
+ break;
+ case CF_TIFF:
+ d << "CF_TIFF";
+ break;
+ case CF_OEMTEXT:
+ d << "CF_OEMTEXT";
+ break;
+ case CF_DIB:
+ d << "CF_DIB";
+ break;
+ case CF_DIBV5:
+ d << "CF_DIBV5";
+ break;
+ case CF_UNICODETEXT:
+ d << "CF_UNICODETEXT";
+ break;
+#ifndef Q_OS_WINCE
+ case CF_ENHMETAFILE:
+ d << "CF_ENHMETAFILE";
+ break;
+#endif // !Q_OS_WINCE
+ default:
+ d << QWindowsMimeConverter::clipboardFormatName(tc.cfFormat);
+ break;
+ }
+ d << ", dwAspect=" << tc.dwAspect << ", lindex=" << tc.lindex
+ << ", tymed=" << tc.tymed << ", ptd=" << tc.ptd << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, IDataObject *dataObj)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "IDataObject(";
+ if (dataObj) { // Output formats contained in IDataObject.
+ IEnumFORMATETC *enumFormatEtc;
+ if (SUCCEEDED(dataObj->EnumFormatEtc(DATADIR_GET, &enumFormatEtc)) && enumFormatEtc) {
+ FORMATETC formatEtc[1];
+ ULONG fetched;
+ if (SUCCEEDED(enumFormatEtc->Reset())) {
+ while (SUCCEEDED(enumFormatEtc->Next(1, formatEtc, &fetched)) && fetched)
+ d << formatEtc[0] << ',';
+ enumFormatEtc->Release();
+ }
+ }
+ } else {
+ d << '0';
+ }
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_OUTPUT
+
/*!
\class QWindowsMime
\brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
@@ -894,11 +959,7 @@ QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pData
QVariant result;
if (canConvertToMime(mime, pDataObj)) {
QByteArray html = getData(CF_HTML, pDataObj);
-#ifdef QMIME_DEBUG
- qDebug("QWindowsMimeHtml::convertToMime");
- qDebug("raw :");
- qDebug(html);
-#endif
+ qCDebug(lcQpaMime) << __FUNCTION__ << "raw:" << html;
int start = html.indexOf("StartHTML:");
int end = html.indexOf("EndHTML:");
@@ -990,13 +1051,14 @@ QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, co
{
QVector<FORMATETC> formatetcs;
if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) {
- //add DIBV5 if image has alpha channel
+ //add DIBV5 if image has alpha channel. Do not add CF_PNG here as it will confuse MS Office (QTBUG47656).
QImage image = qvariant_cast<QImage>(mimeData->imageData());
if (!image.isNull() && image.hasAlphaChannel())
formatetcs += setCf(CF_DIBV5);
formatetcs += setCf(CF_DIB);
- formatetcs += setCf(CF_PNG); // QTBUG-86848, Paste into GIMP queries for PNG.
}
+ if (!formatetcs.isEmpty())
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeType << formatetcs;
return formatetcs;
}
@@ -1024,11 +1086,7 @@ bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMi
const QImage image = qvariant_cast<QImage>(mimeData->imageData());
if (image.isNull())
return false;
- // QTBUG-11463, deny CF_DIB support for images with alpha to prevent loss of
- // transparency in conversion.
- return cf == CF_DIBV5
- || (cf == CF_DIB && !image.hasAlphaChannel())
- || cf == int(CF_PNG);
+ return cf == CF_DIBV5 || (cf == CF_DIB) || cf == int(CF_PNG);
}
bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
@@ -1221,9 +1279,7 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat
if (canConvertToMime(mimeType, pDataObj)) {
QByteArray data = getData(inFormats.key(mimeType), pDataObj);
if (!data.isEmpty()) {
-#ifdef QMIME_DEBUG
- qDebug("QBuiltInMimes::convertToMime()");
-#endif
+ qCDebug(lcQpaMime) << __FUNCTION__;
if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) {
// text/html is in wide chars on windows (compatible with Mozilla)
val = QString::fromWCharArray((const wchar_t *)data.data());
@@ -1331,6 +1387,8 @@ QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, con
that->formats.insert(cf, mimeType);
formatetcs += setCf(cf);
}
+ if (!formatetcs.isEmpty())
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeType << formatetcs;
return formatetcs;
}
static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\"";
@@ -1405,11 +1463,8 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
if (!format.isEmpty())
return format;
- wchar_t buffer[256];
- int len = GetClipboardFormatName(getCf(formatetc), buffer, 256);
-
- if (len) {
- QString clipFormat = QString::fromWCharArray(buffer, len);
+ const QString clipFormat = QWindowsMimeConverter::clipboardFormatName(getCf(formatetc));
+ if (!clipFormat.isEmpty()) {
#ifndef QT_NO_DRAGANDDROP
if (QInternalMimeData::canReadData(clipFormat))
format = clipFormat;
@@ -1475,15 +1530,12 @@ QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) con
if (hr == NOERROR) {
FORMATETC fmtetc;
while (S_OK == fmtenum->Next(1, &fmtetc, 0)) {
-#if defined(QMIME_DEBUG)
- wchar_t buf[256] = {0};
- GetClipboardFormatName(fmtetc.cfFormat, buf, 255);
- qDebug("CF = %d : %s", fmtetc.cfFormat, qPrintable(QString::fromWCharArray(buf)));
-#endif
for (int i= m_mimes.size() - 1; i >= 0; --i) {
QString format = m_mimes.at(i)->mimeForFormat(fmtetc);
if (!format.isEmpty() && !formats.contains(format)) {
formats += format;
+ if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled())
+ qCDebug(lcQpaMime) << __FUNCTION__ << fmtetc << format;
}
}
// as documented in MSDN to avoid possible memleak
@@ -1499,6 +1551,7 @@ QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) con
QWindowsMime * QWindowsMimeConverter::converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
{
ensureInitialized();
+ qCDebug(lcQpaMime) << __FUNCTION__ << formatetc;
for (int i = m_mimes.size()-1; i >= 0; --i) {
if (m_mimes.at(i)->canConvertFromMime(formatetc, mimeData))
return m_mimes.at(i);
@@ -1533,6 +1586,13 @@ void QWindowsMimeConverter::ensureInitialized() const
}
}
+QString QWindowsMimeConverter::clipboardFormatName(int cf)
+{
+ wchar_t buf[256] = {0};
+ return GetClipboardFormatName(cf, buf, 255)
+ ? QString::fromWCharArray(buf) : QString();
+}
+
QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
IDataObject *pDataObj,
QVariant::Type preferredType,
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
index 952410e14b..17fddef1bc 100644
--- a/src/plugins/platforms/windows/qwindowsmime.h
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -42,6 +42,7 @@
QT_BEGIN_NAMESPACE
+class QDebug;
class QMimeData;
class QWindowsMime
@@ -83,6 +84,8 @@ public:
void registerMime(QWindowsMime *mime);
void unregisterMime(QWindowsMime *mime) { m_mimes.removeOne(mime); }
+ static QString clipboardFormatName(int cf);
+
private:
void ensureInitialized() const;
@@ -90,6 +93,11 @@ private:
mutable int m_internalMimeCount;
};
+#ifndef QT_NO_DEBUG_OUTPUT
+QDebug operator<<(QDebug, const FORMATETC &);
+QDebug operator<<(QDebug d, IDataObject *);
+#endif
+
QT_END_NAMESPACE
#endif // QWINDOWSMIME_H
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 200eb11855..90cb6fe195 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -368,7 +368,10 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
m_previousCaptureWindow = hasCapture ? window : 0;
- return true;
+ // QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND
+ // is sent for unhandled WM_XBUTTONDOWN.
+ return (msg.message != WM_XBUTTONUP && msg.message != WM_XBUTTONDOWN && msg.message != WM_XBUTTONDBLCLK)
+ || QWindowSystemInterface::flushWindowSystemEvents();
}
static bool isValidWheelReceiver(QWindow *candidate)
@@ -474,7 +477,12 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList;
Q_ASSERT(m_touchDevice);
- const QRect screenGeometry = window->screen()->geometry();
+ const QScreen *screen = window->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ if (!screen)
+ return true;
+ const QRect screenGeometry = screen->geometry();
const int winTouchPointCount = msg.wParam;
QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]);
@@ -566,7 +574,12 @@ bool QWindowsMouseHandler::translateGestureEvent(QWindow *window, HWND hwnd,
if (gi.dwID != GID_DIRECTMANIPULATION)
return true;
static QPoint lastTouchPos;
- const QRect screenGeometry = window->screen()->geometry();
+ const QScreen *screen = window->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ if (!screen)
+ return true;
+ const QRect screenGeometry = screen->geometry();
QWindowSystemInterface::TouchPoint touchPoint;
static QWindowSystemInterface::TouchPoint touchPoint2;
touchPoint.id = 0;//gi.dwInstanceID;
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index 6f5a521af8..e480c1ebcf 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -132,12 +132,6 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
{
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
- if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled()) {
- wchar_t buf[256] = {0};
- GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << QString::fromWCharArray(buf);
- }
-
if (data) {
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
if (QWindowsMime *converter = mc.converterFromMime(*pformatetc, data))
@@ -145,11 +139,8 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
hr = ResultFromScode(S_OK);
}
- if (QWindowsContext::verbose > 1) {
- wchar_t buf[256] = {0};
- GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << " returns 0x" << int(hr) << dec;
- }
+ if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled())
+ qCDebug(lcQpaMime) <<__FUNCTION__ << *pformatetc << "returns" << hex << showbase << quint64(hr);
return hr;
}
@@ -211,7 +202,7 @@ STDMETHODIMP
QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaMime) << __FUNCTION__;
+ qCDebug(lcQpaMime) << __FUNCTION__ << "dwDirection=" << dwDirection;
if (!data)
return ResultFromScode(DATA_E_FORMATETC);
@@ -274,7 +265,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs)
m_dwRefs(1), m_nIndex(0), m_isNull(false)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaMime) << __FUNCTION__;
+ qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs;
m_lpfmtetcs.reserve(fmtetcs.count());
for (int idx = 0; idx < fmtetcs.count(); ++idx) {
LPFORMATETC destetc = new FORMATETC();
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 391735a035..e6abfb2403 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -276,18 +276,6 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
return result;
}
-QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w)
-{
- if (w)
- if (const QScreen *s = w->screen())
- if (QPlatformScreen *pscr = s->handle())
- return static_cast<QWindowsScreen *>(pscr);
- if (const QScreen *ps = QGuiApplication::primaryScreen())
- if (QPlatformScreen *ppscr = ps->handle())
- return static_cast<QWindowsScreen *>(ppscr);
- return 0;
-}
-
qreal QWindowsScreen::pixelDensity() const
{
const qreal physicalDpi = m_data.geometry.width() / m_data.physicalSizeMM.width() * qreal(25.4);
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 67e7ff644b..bc8fbf553b 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -79,8 +79,6 @@ public:
explicit QWindowsScreen(const QWindowsScreenData &data);
- static QWindowsScreen *screenOf(const QWindow *w = 0);
-
QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; }
int depth() const Q_DECL_OVERRIDE { return m_data.depth; }
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 05bddec530..3951401273 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -54,7 +54,7 @@
#include <QtCore/private/qsystemlibrary_p.h>
// Note: The definition of the PACKET structure in pktdef.h depends on this define.
-#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z | PK_TIME)
#include <pktdef.h>
QT_BEGIN_NAMESPACE
@@ -342,17 +342,18 @@ QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueI
bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
{
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
+ if (!totalPacks)
+ return false;
if (!LOWORD(lParam)) {
qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
- QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
+ m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
m_devices.at(m_currentDevice).uniqueId);
return true;
}
- PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
- const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
- if (!totalPacks)
- return false;
const UINT currentCursor = proximityBuffer[0].pkCursor;
UINT physicalCursorId;
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
@@ -370,7 +371,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
qCDebug(lcQpaTablet) << "enter proximity for device #"
<< m_currentDevice << m_devices.at(m_currentDevice);
- QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ QWindowSystemInterface::handleTabletEnterProximityEvent(proximityBuffer[0].pkTime,
+ m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
m_devices.at(m_currentDevice).uniqueId);
return true;
@@ -473,7 +475,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
}
- QWindowSystemInterface::handleTabletEvent(target, QPointF(localPos), globalPosF,
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
currentDevice, currentPointer,
static_cast<Qt::MouseButtons>(packet.pkButtons),
pressureNew, tiltX, tiltY,
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 1b5d7b87bc..abfddcfed6 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1045,8 +1045,8 @@ void QWindowsWindow::setDropSiteEnabled(bool dropEnabled)
RegisterDragDrop(m_data.hwnd, m_dropTarget);
CoLockObjectExternal(m_dropTarget, true, true);
} else {
- m_dropTarget->Release();
CoLockObjectExternal(m_dropTarget, false, true);
+ m_dropTarget->Release();
RevokeDragDrop(m_data.hwnd);
m_dropTarget = 0;
}
@@ -1637,8 +1637,12 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
bool QWindowsWindow::isFullScreen_sys() const
{
const QWindow *w = window();
- return w->isTopLevel()
- && geometry_sys() == QHighDpi::toNativePixels(w->screen()->geometry(), w);
+ if (!w->isTopLevel())
+ return false;
+ const QScreen *screen = w->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ return screen && geometry_sys() == QHighDpi::toNativePixels(screen->geometry(), w);
}
/*!
@@ -1708,7 +1712,9 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
// Use geometry of QWindow::screen() within creation or the virtual screen the
// window is in (QTBUG-31166, QTBUG-30724).
const QScreen *screen = window()->screen();
- const QRect r = QHighDpi::toNativePixels(screen->geometry(), window());
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ const QRect r = screen ? QHighDpi::toNativePixels(screen->geometry(), window()) : m_savedFrameGeometry;
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(SynchronousGeometryChangeEvent);
@@ -1825,7 +1831,7 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
windowPos->cx, windowPos->cy);
const QRect suggestedGeometry = suggestedFrameGeometry - margins;
- const QRectF correctedGeometryF = qWindow->handle()->windowClosestAcceptableGeometry(suggestedGeometry);
+ const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
if (!correctedGeometryF.isValid())
return false;
const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
index 44aab266ca..9cb45336d6 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -56,7 +56,6 @@ public:
EGLDisplay eglDisplay;
EGLConfig eglConfig;
EGLContext eglContext;
- QHash<QPlatformSurface *, EGLSurface> surfaceForWindow;
};
QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context)
@@ -70,8 +69,6 @@ QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context)
QWinRTEGLContext::~QWinRTEGLContext()
{
Q_D(QWinRTEGLContext);
- foreach (const EGLSurface &surface, d->surfaceForWindow)
- eglDestroySurface(d->eglDisplay, surface);
if (d->eglContext != EGL_NO_CONTEXT)
eglDestroyContext(d->eglDisplay, d->eglContext);
if (d->eglDisplay != EGL_NO_DISPLAY)
@@ -112,23 +109,13 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
Q_D(QWinRTEGLContext);
Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
- EGLSurface surface = d->surfaceForWindow.value(windowSurface);
- if (surface == EGL_NO_SURFACE) {
- QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
- HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d, window, &surface]() {
- surface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig,
- reinterpret_cast<EGLNativeWindowType>(window->winId()),
- nullptr);
- if (surface == EGL_NO_SURFACE) {
- qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
- return E_FAIL;
- }
- return S_OK;
- });
- if (FAILED(hr))
- return false;
- d->surfaceForWindow.insert(windowSurface, surface);
- }
+ QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
+ if (window->eglSurface() == EGL_NO_SURFACE)
+ window->createEglSurface(d->eglDisplay, d->eglConfig);
+
+ EGLSurface surface = window->eglSurface();
+ if (surface == EGL_NO_SURFACE)
+ return false;
const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext);
if (!ok) {
@@ -153,7 +140,8 @@ void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface)
Q_D(QWinRTEGLContext);
Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
- eglSwapBuffers(d->eglDisplay, d->surfaceForWindow.value(windowSurface));
+ const QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
+ eglSwapBuffers(d->eglDisplay, window->eglSurface());
}
QSurfaceFormat QWinRTEGLContext::format() const
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
index e1b2a07d5f..05b1fd76b1 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
@@ -37,25 +37,32 @@
#include "qwinrtfiledialoghelper.h"
#include "qwinrtfileengine.h"
+#include <QtCore/qcoreapplication.h>
#include <QtCore/QEventLoop>
#include <QtCore/QMap>
#include <QtCore/QVector>
#include <QtCore/qfunctions_winrt.h>
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.storage.pickers.h>
+#include <Windows.ApplicationModel.activation.h>
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::ApplicationModel::Activation;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::Storage;
using namespace ABI::Windows::Storage::Pickers;
+#ifndef Q_OS_WINPHONE
typedef IAsyncOperationCompletedHandler<StorageFile *> SingleFileHandler;
typedef IAsyncOperationCompletedHandler<IVectorView<StorageFile *> *> MultipleFileHandler;
typedef IAsyncOperationCompletedHandler<StorageFolder *> SingleFolderHandler;
+#endif
QT_BEGIN_NAMESPACE
@@ -142,6 +149,16 @@ private:
QVector<HSTRING> impl;
};
+#ifdef Q_OS_WINPHONE
+class QActivationEvent : public QEvent
+{
+public:
+ IInspectable *args() const {
+ return reinterpret_cast<IInspectable *>(d);
+ }
+};
+#endif
+
template<typename T>
static bool initializePicker(HSTRING runtimeId, T **picker, const QSharedPointer<QFileDialogOptions> &options)
{
@@ -200,6 +217,99 @@ static bool initializeOpenPickerOptions(T *picker, const QSharedPointer<QFileDia
return true;
}
+static bool pickFiles(IFileOpenPicker *picker, QWinRTFileDialogHelper *helper, bool singleFile)
+{
+ Q_ASSERT(picker);
+ Q_ASSERT(helper);
+ HRESULT hr;
+#ifdef Q_OS_WINPHONE
+ hr = QEventDispatcherWinRT::runOnXamlThread([picker, singleFile]() {
+ HRESULT hr;
+ ComPtr<IFileOpenPicker2> picker2;
+ hr = picker->QueryInterface(IID_PPV_ARGS(picker2.GetAddressOf()));
+ RETURN_HR_IF_FAILED("Failed to cast file picker");
+ if (singleFile)
+ return picker2->PickSingleFileAndContinue();
+ else
+ return picker2->PickMultipleFilesAndContinue();
+ });
+ RETURN_FALSE_IF_FAILED("Failed to open file picker");
+ QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
+ Q_ASSERT(eventDispatcher);
+ eventDispatcher->installEventFilter(helper);
+ return true;
+#else
+ if (singleFile) {
+ ComPtr<IAsyncOperation<StorageFile *>> op;
+ hr = picker->PickSingleFileAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open single file picker");
+ hr = op->put_Completed(Callback<SingleFileHandler>(helper, &QWinRTFileDialogHelper::onSingleFilePicked).Get());
+ RETURN_FALSE_IF_FAILED("Failed to attach file picker callback");
+ } else {
+ ComPtr<IAsyncOperation<IVectorView<StorageFile *> *>> op;
+ hr = picker->PickMultipleFilesAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open multi file picker");
+ hr = op->put_Completed(Callback<MultipleFileHandler>(helper, &QWinRTFileDialogHelper::onMultipleFilesPicked).Get());
+ RETURN_FALSE_IF_FAILED("Failed to attach multi file callback");
+ }
+ return true;
+#endif
+}
+
+static bool pickFolder(IFolderPicker *picker, QWinRTFileDialogHelper *helper)
+{
+ Q_ASSERT(picker);
+ Q_ASSERT(helper);
+ HRESULT hr;
+#ifdef Q_OS_WINPHONE
+ hr = QEventDispatcherWinRT::runOnXamlThread([picker]() {
+ HRESULT hr;
+ ComPtr<IFolderPicker2> picker2;
+ hr = picker->QueryInterface(IID_PPV_ARGS(picker2.GetAddressOf()));
+ RETURN_HR_IF_FAILED("Failed to cast folder picker");
+ return picker2->PickFolderAndContinue();
+ });
+ RETURN_FALSE_IF_FAILED("Failed to open folder picker");
+ QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
+ Q_ASSERT(eventDispatcher);
+ eventDispatcher->installEventFilter(helper);
+#else
+ ComPtr<IAsyncOperation<StorageFolder *>> op;
+ hr = picker->PickSingleFolderAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open folder picker");
+ hr = op->put_Completed(Callback<SingleFolderHandler>(helper, &QWinRTFileDialogHelper::onSingleFolderPicked).Get());
+ RETURN_FALSE_IF_FAILED("Failed to attach folder picker callback");
+#endif
+ return true;
+}
+
+static bool pickSaveFile(IFileSavePicker *picker, QWinRTFileDialogHelper *helper)
+{
+ Q_ASSERT(picker);
+ Q_ASSERT(helper);
+ HRESULT hr;
+#ifdef Q_OS_WINPHONE
+ hr = QEventDispatcherWinRT::runOnXamlThread([picker]() {
+ HRESULT hr;
+ ComPtr<IFileSavePicker2> picker2;
+ hr = picker->QueryInterface(IID_PPV_ARGS(picker2.GetAddressOf()));
+ RETURN_HR_IF_FAILED("Failed to cast save file picker");
+ return picker2->PickSaveFileAndContinue();
+ });
+ RETURN_FALSE_IF_FAILED("Failed to open single file picker");
+ QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
+ Q_ASSERT(eventDispatcher);
+ eventDispatcher->installEventFilter(helper);
+#else
+ ComPtr<IAsyncOperation<StorageFile *>> op;
+ hr = picker->PickSaveFileAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open save file picker");
+ hr = op->put_Completed(Callback<SingleFileHandler>(helper, &QWinRTFileDialogHelper::onSingleFilePicked).Get());
+ RETURN_FALSE_IF_FAILED("Failed to attach save file picker callback");
+#endif
+ return true;
+}
+
class QWinRTFileDialogHelperPrivate
{
public:
@@ -260,18 +370,9 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
if (!initializeOpenPickerOptions(picker.Get(), dialogOptions))
return false;
- if (dialogOptions->fileMode() == QFileDialogOptions::ExistingFiles) {
- ComPtr<IAsyncOperation<IVectorView<StorageFile *> *>> op;
- hr = picker->PickMultipleFilesAsync(&op);
- RETURN_FALSE_IF_FAILED("Failed to open multi file picker");
- hr = op->put_Completed(Callback<MultipleFileHandler>(this, &QWinRTFileDialogHelper::onMultipleFilesPicked).Get());
- } else {
- ComPtr<IAsyncOperation<StorageFile *>> op;
- hr = picker->PickSingleFileAsync(&op);
- RETURN_FALSE_IF_FAILED("Failed to open single file picker");
- hr = op->put_Completed(Callback<SingleFileHandler>(this, &QWinRTFileDialogHelper::onSingleFilePicked).Get());
- }
- RETURN_FALSE_IF_FAILED("Failed to attach file picker callback");
+ if (!pickFiles(picker.Get(), this, dialogOptions->fileMode() == QFileDialogOptions::ExistingFile))
+ return false;
+
break;
}
case QFileDialogOptions::Directory:
@@ -284,11 +385,9 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
if (!initializeOpenPickerOptions(picker.Get(), dialogOptions))
return false;
- ComPtr<IAsyncOperation<StorageFolder *>> op;
- hr = picker->PickSingleFolderAsync(&op);
- RETURN_FALSE_IF_FAILED("Failed to open folder picker");
- hr = op->put_Completed(Callback<SingleFolderHandler>(this, &QWinRTFileDialogHelper::onSingleFolderPicked).Get());
- RETURN_FALSE_IF_FAILED("Failed to attach folder picker callback");
+ if (!pickFolder(picker.Get(), this))
+ return false;
+
break;
}
}
@@ -344,11 +443,9 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
RETURN_FALSE_IF_FAILED("Failed to set suggested file name");
}
- ComPtr<IAsyncOperation<StorageFile *>> op;
- hr = picker->PickSaveFileAsync(&op);
- RETURN_FALSE_IF_FAILED("Failed to open save file picker");
- hr = op->put_Completed(Callback<SingleFileHandler>(this, &QWinRTFileDialogHelper::onSingleFilePicked).Get());
- RETURN_FALSE_IF_FAILED("Failed to attach file picker callback");
+ if (!pickSaveFile(picker.Get(), this))
+ return false;
+
break;
}
}
@@ -367,6 +464,68 @@ void QWinRTFileDialogHelper::hide()
d->shown = false;
}
+#ifdef Q_OS_WINPHONE
+bool QWinRTFileDialogHelper::eventFilter(QObject *, QEvent *e)
+{
+ if (e->type() != QEvent::WinEventAct)
+ return false;
+
+ HRESULT hr;
+ QActivationEvent *event = static_cast<QActivationEvent *>(e);
+ ComPtr<IInspectable> inspectable = event->args();
+ ComPtr<IActivatedEventArgs> arguments;
+ hr = inspectable.As(&arguments);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ActivationKind activationKind;
+ hr = arguments->get_Kind(&activationKind);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Handle only File, Folder and Save file pick continuation here.
+ if (activationKind != ActivationKind_PickFileContinuation
+ && activationKind != ActivationKind_PickFolderContinuation
+ && activationKind != ActivationKind_PickSaveFileContinuation) {
+ return false;
+ }
+
+ QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
+ Q_ASSERT(eventDispatcher);
+ eventDispatcher->removeEventFilter(this);
+ e->accept();
+
+ if (activationKind == ActivationKind_PickFileContinuation) {
+ ComPtr<IFileOpenPickerContinuationEventArgs> fileContinuationArgs;
+ hr = arguments.As(&fileContinuationArgs);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<StorageFile *>> files;
+ hr = fileContinuationArgs->get_Files(&files);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = onFilesPicked(files.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ } else if (activationKind == ActivationKind_PickFolderContinuation) {
+ ComPtr<IFolderPickerContinuationEventArgs> folderContinuationArgs;
+ hr = arguments.As(&folderContinuationArgs);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IStorageFolder> folder;
+ hr = folderContinuationArgs->get_Folder(&folder);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = onFolderPicked(folder.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ } else {
+ ComPtr<IFileSavePickerContinuationEventArgs> saveFileContinuationArgs;
+ hr = arguments.As(&saveFileContinuationArgs);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IStorageFile> file;
+ hr = saveFileContinuationArgs->get_File(&file);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = onFilePicked(file.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ return true;
+}
+#endif
+
void QWinRTFileDialogHelper::setDirectory(const QUrl &directory)
{
Q_D(QWinRTFileDialogHelper);
@@ -403,6 +562,7 @@ QString QWinRTFileDialogHelper::selectedNameFilter() const
return d->selectedNameFilter;
}
+#ifndef Q_OS_WINPHONE
HRESULT QWinRTFileDialogHelper::onSingleFilePicked(IAsyncOperation<StorageFile *> *args, AsyncStatus status)
{
Q_D(QWinRTFileDialogHelper);
@@ -419,14 +579,7 @@ HRESULT QWinRTFileDialogHelper::onSingleFilePicked(IAsyncOperation<StorageFile *
ComPtr<IStorageFile> file;
hr = args->GetResults(&file);
Q_ASSERT_SUCCEEDED(hr);
- if (!file) {
- emit reject();
- return S_OK;
- }
-
- appendFile(file.Get());
- emit accept();
- return S_OK;
+ return onFilePicked(file.Get());
}
HRESULT QWinRTFileDialogHelper::onMultipleFilesPicked(IAsyncOperation<IVectorView<StorageFile *> *> *args, AsyncStatus status)
@@ -445,17 +598,50 @@ HRESULT QWinRTFileDialogHelper::onMultipleFilesPicked(IAsyncOperation<IVectorVie
ComPtr<IVectorView<StorageFile *>> fileList;
hr = args->GetResults(&fileList);
RETURN_HR_IF_FAILED("Failed to get file list");
+ return onFilesPicked(fileList.Get());
+}
+
+HRESULT QWinRTFileDialogHelper::onSingleFolderPicked(IAsyncOperation<StorageFolder *> *args, AsyncStatus status)
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ QEventLoopLocker locker(&d->loop);
+ d->shown = false;
+ d->selectedFiles.clear();
+ if (status == Canceled || status == Error) {
+ emit reject();
+ return S_OK;
+ }
+
+ HRESULT hr;
+ ComPtr<IStorageFolder> folder;
+ hr = args->GetResults(&folder);
+ Q_ASSERT_SUCCEEDED(hr);
+ return onFolderPicked(folder.Get());
+}
+#endif //Q_OS_WINPHONE
+
+HRESULT QWinRTFileDialogHelper::onFilesPicked(IVectorView<StorageFile *> *files)
+{
+#ifdef Q_OS_WINPHONE
+ Q_D(QWinRTFileDialogHelper);
+ QEventLoopLocker locker(&d->loop);
+ d->shown = false;
+ d->selectedFiles.clear();
+#endif
+ HRESULT hr;
quint32 size;
- hr = fileList->get_Size(&size);
+ hr = files->get_Size(&size);
Q_ASSERT_SUCCEEDED(hr);
if (!size) {
emit reject();
return S_OK;
}
+
for (quint32 i = 0; i < size; ++i) {
ComPtr<IStorageFile> file;
- hr = fileList->GetAt(i, &file);
+ hr = files->GetAt(i, &file);
Q_ASSERT_SUCCEEDED(hr);
appendFile(file.Get());
}
@@ -464,28 +650,40 @@ HRESULT QWinRTFileDialogHelper::onMultipleFilesPicked(IAsyncOperation<IVectorVie
return S_OK;
}
-HRESULT QWinRTFileDialogHelper::onSingleFolderPicked(IAsyncOperation<StorageFolder *> *args, AsyncStatus status)
+HRESULT QWinRTFileDialogHelper::onFolderPicked(IStorageFolder *folder)
{
+#ifdef Q_OS_WINPHONE
Q_D(QWinRTFileDialogHelper);
-
QEventLoopLocker locker(&d->loop);
d->shown = false;
d->selectedFiles.clear();
- if (status == Canceled || status == Error) {
+#endif
+
+ if (!folder) {
emit reject();
return S_OK;
}
- HRESULT hr;
- ComPtr<IStorageFolder> folder;
- hr = args->GetResults(&folder);
- Q_ASSERT_SUCCEEDED(hr);
- if (!folder) {
+ appendFile(folder);
+ emit accept();
+ return S_OK;
+}
+
+HRESULT QWinRTFileDialogHelper::onFilePicked(IStorageFile *file)
+{
+#ifdef Q_OS_WINPHONE
+ Q_D(QWinRTFileDialogHelper);
+ QEventLoopLocker locker(&d->loop);
+ d->shown = false;
+ d->selectedFiles.clear();
+#endif
+
+ if (!file) {
emit reject();
return S_OK;
}
- appendFile(folder.Get());
+ appendFile(file);
emit accept();
return S_OK;
}
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
index 51b79c84ef..d6bacd2db9 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
@@ -47,6 +47,7 @@ namespace ABI {
class StorageFile;
class StorageFolder;
struct IStorageFile;
+ struct IStorageFolder;
}
namespace Foundation {
enum class AsyncStatus;
@@ -71,6 +72,9 @@ public:
void exec() Q_DECL_OVERRIDE;
bool show(Qt::WindowFlags, Qt::WindowModality, QWindow *) Q_DECL_OVERRIDE;
void hide() Q_DECL_OVERRIDE;
+#ifdef Q_OS_WINPHONE
+ bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
+#endif
bool defaultNameFilterDisables() const Q_DECL_OVERRIDE { return false; }
void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
@@ -81,13 +85,19 @@ public:
void selectNameFilter(const QString &selectedNameFilter) Q_DECL_OVERRIDE;
QString selectedNameFilter() const;
-private:
+#ifndef Q_OS_WINPHONE
HRESULT onSingleFilePicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFile *> *,
ABI::Windows::Foundation::AsyncStatus);
HRESULT onMultipleFilesPicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile *> *> *,
ABI::Windows::Foundation::AsyncStatus);
HRESULT onSingleFolderPicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFolder *> *,
ABI::Windows::Foundation::AsyncStatus);
+#endif
+
+private:
+ HRESULT onFilesPicked(ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile *> *files);
+ HRESULT onFolderPicked(ABI::Windows::Storage::IStorageFolder *folder);
+ HRESULT onFilePicked(ABI::Windows::Storage::IStorageFile *file);
void appendFile(IInspectable *);
QScopedPointer<QWinRTFileDialogHelperPrivate> d_ptr;
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
index 7bd9e87ca6..f3b390b4d6 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -37,7 +37,9 @@
#include "qwinrtinputcontext.h"
#include "qwinrtscreen.h"
#include <QtGui/QWindow>
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
#include <wrl.h>
#include <roapi.h>
#include <windows.ui.viewmanagement.h>
@@ -163,10 +165,14 @@ void QWinRTInputContext::showInputPanel()
if (FAILED(hr))
return;
- boolean success;
- hr = inputPane->TryShow(&success);
- if (FAILED(hr))
- qErrnoWarning(hr, "Failed to show input panel.");
+ QEventDispatcherWinRT::runOnXamlThread([&inputPane]() {
+ HRESULT hr;
+ boolean success;
+ hr = inputPane->TryShow(&success);
+ if (FAILED(hr) || !success)
+ qErrnoWarning(hr, "Failed to show input panel.");
+ return hr;
+ });
}
void QWinRTInputContext::hideInputPanel()
@@ -176,10 +182,14 @@ void QWinRTInputContext::hideInputPanel()
if (FAILED(hr))
return;
- boolean success;
- hr = inputPane->TryHide(&success);
- if (FAILED(hr))
- qErrnoWarning(hr, "Failed to hide input panel.");
+ QEventDispatcherWinRT::runOnXamlThread([&inputPane]() {
+ HRESULT hr;
+ boolean success;
+ hr = inputPane->TryHide(&success);
+ if (FAILED(hr) || !success)
+ qErrnoWarning(hr, "Failed to hide input panel.");
+ return hr;
+ });
}
#endif // Q_OS_WINPHONE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index 7079d46523..fce77c56d1 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -188,9 +188,9 @@ bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
case ThreadedPixmaps:
case OpenGL:
case ApplicationState:
- return true;
case NonFullScreenWindows:
- return false;
+ case MultipleWindows:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
index 4fc1fea626..68bf1fdcac 100644
--- a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
@@ -38,7 +38,9 @@
#include "qwinrttheme.h"
#include <QtCore/qfunctions_winrt.h>
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
#include <windows.ui.popups.h>
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
@@ -168,16 +170,20 @@ bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModa
}
}
- ComPtr<IAsyncOperation<IUICommand *>> op;
- hr = dialog->ShowAsync(&op);
- RETURN_FALSE_IF_FAILED("Failed to show dialog");
- hr = op->put_Completed(Callback<DialogCompletedHandler>(this, &QWinRTMessageDialogHelper::onCompleted).Get());
- RETURN_FALSE_IF_FAILED("Failed to set dialog callback");
-
- d->shown = true;
- hr = op.As(&d->info);
- RETURN_FALSE_IF_FAILED("Failed to acquire AsyncInfo for MessageDialog");
-
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d, dialog]() {
+ HRESULT hr;
+ ComPtr<IAsyncOperation<IUICommand *>> op;
+ hr = dialog->ShowAsync(&op);
+ RETURN_HR_IF_FAILED("Failed to show dialog");
+ hr = op->put_Completed(Callback<DialogCompletedHandler>(this, &QWinRTMessageDialogHelper::onCompleted).Get());
+ RETURN_HR_IF_FAILED("Failed to set dialog callback");
+ d->shown = true;
+ hr = op.As(&d->info);
+ RETURN_HR_IF_FAILED("Failed to acquire AsyncInfo for MessageDialog");
+ return hr;
+ });
+
+ RETURN_FALSE_IF_FAILED("Failed to show dialog")
return true;
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 89ad33657b..563753cfcb 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -83,6 +83,9 @@ typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
+#ifdef Q_OS_WINPHONE
+typedef ITypedEventHandler<StatusBar*, IInspectable*> StatusBarHandler;
+#endif
QT_BEGIN_NAMESPACE
@@ -405,6 +408,10 @@ typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistr
uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken);
uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
+#ifdef Q_OS_WINPHONE
+typedef HRESULT (__stdcall IStatusBar::*StatusBarCallbackRemover)(EventRegistrationToken);
+uint qHash(StatusBarCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
+#endif
class QWinRTScreenPrivate
{
@@ -414,11 +421,12 @@ public:
ComPtr<Xaml::IDependencyObject> canvas;
ComPtr<IApplicationView> view;
ComPtr<IDisplayInformation> displayInformation;
+#ifdef Q_OS_WINPHONE
+ ComPtr<IStatusBar> statusBar;
+#endif
QScopedPointer<QWinRTCursor> cursor;
-
QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
-
QSizeF logicalSize;
QSurfaceFormat surfaceFormat;
qreal logicalDpi;
@@ -433,6 +441,9 @@ public:
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
+#ifdef Q_OS_WINPHONE
+ QHash<StatusBarCallbackRemover, EventRegistrationToken> statusBarTokens;
+#endif
};
// To be called from the XAML thread
@@ -472,8 +483,10 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
Q_ASSERT_SUCCEEDED(hr);
+#ifndef Q_OS_WINPHONE
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
Q_ASSERT_SUCCEEDED(hr);
+#endif
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
@@ -535,6 +548,19 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
Q_ASSERT_SUCCEEDED(hr);
d->cursor.reset(new QWinRTCursor);
+
+#ifdef Q_OS_WINPHONE
+ ComPtr<IStatusBarStatics> statusBarStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_StatusBar).Get(),
+ IID_PPV_ARGS(&statusBarStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = statusBarStatics->GetForCurrentView(&d->statusBar);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->statusBar->add_Showing(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]);
+ Q_ASSERT_SUCCEEDED(hr);
+#endif // Q_OS_WINPHONE
}
QWinRTScreen::~QWinRTScreen()
@@ -553,6 +579,12 @@ QWinRTScreen::~QWinRTScreen()
hr = (d->displayInformation.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
+#ifdef Q_OS_WINPHONE
+ for (QHash<StatusBarCallbackRemover, EventRegistrationToken>::const_iterator i = d->statusBarTokens.begin(); i != d->statusBarTokens.end(); ++i) {
+ hr = (d->statusBar.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+#endif //Q_OS_WINPHONE
return hr;
});
RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks");
@@ -564,6 +596,31 @@ QRect QWinRTScreen::geometry() const
return QRect(QPoint(), (d->logicalSize * d->scaleFactor).toSize());
}
+#ifdef Q_OS_WINPHONE
+QRect QWinRTScreen::availableGeometry() const
+{
+ Q_D(const QWinRTScreen);
+ QRect statusBar;
+ QEventDispatcherWinRT::runOnXamlThread([d, &statusBar]() {
+ HRESULT hr;
+ Rect rect;
+ hr = d->statusBar->get_OccludedRect(&rect);
+ Q_ASSERT_SUCCEEDED(hr);
+ statusBar.setRect(qRound(rect.X * d->scaleFactor),
+ qRound(rect.Y * d->scaleFactor),
+ qRound(rect.Width * d->scaleFactor),
+ qRound(rect.Height * d->scaleFactor));
+ return S_OK;
+ });
+
+ return geometry().adjusted(
+ d->orientation == Qt::LandscapeOrientation ? statusBar.width() : 0,
+ d->orientation == Qt::PortraitOrientation ? statusBar.height() : 0,
+ d->orientation == Qt::InvertedLandscapeOrientation ? -statusBar.width() : 0,
+ 0);
+}
+#endif //Q_OS_WINPHONE
+
int QWinRTScreen::depth() const
{
return 32;
@@ -649,6 +706,26 @@ Xaml::IDependencyObject *QWinRTScreen::canvas() const
return d->canvas.Get();
}
+#ifdef Q_OS_WINPHONE
+void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window)
+{
+ Q_D(QWinRTScreen);
+ if (!window || (window->flags() & Qt::WindowType_Mask) != Qt::Window)
+ return;
+
+ QEventDispatcherWinRT::runOnXamlThread([d, visible]() {
+ HRESULT hr;
+ ComPtr<IAsyncAction> op;
+ if (visible)
+ hr = d->statusBar->ShowAsync(&op);
+ else
+ hr = d->statusBar->HideAsync(&op);
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+}
+#endif //Q_OS_WINPHONE
+
QWindow *QWinRTScreen::topWindow() const
{
Q_D(const QWinRTScreen);
@@ -660,6 +737,12 @@ void QWinRTScreen::addWindow(QWindow *window)
Q_D(QWinRTScreen);
if (window == topWindow())
return;
+
+#ifdef Q_OS_WINPHONE
+ if (window->visibility() != QWindow::Maximized && window->visibility() != QWindow::Windowed)
+ setStatusBarVisibility(false, window);
+#endif
+
d->visibleWindows.prepend(window);
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
handleExpose();
@@ -668,6 +751,12 @@ void QWinRTScreen::addWindow(QWindow *window)
void QWinRTScreen::removeWindow(QWindow *window)
{
Q_D(QWinRTScreen);
+
+#ifdef Q_OS_WINPHONE
+ if (window->visibility() == QWindow::Minimized)
+ setStatusBarVisibility(false, window);
+#endif
+
const bool wasTopWindow = window == topWindow();
if (!d->visibleWindows.removeAll(window))
return;
@@ -964,13 +1053,8 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
HRESULT hr;
hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds");
- QSizeF logicalSize = QSizeF(size.Width, size.Height);
- if (d->logicalSize == logicalSize)
- return S_OK;
-
- d->logicalSize = logicalSize;
- const QRect newGeometry = geometry();
- QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
+ d->logicalSize = QSizeF(size.Width, size.Height);
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
return S_OK;
@@ -1024,7 +1108,11 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
if (d->orientation != newOrientation) {
d->orientation = newOrientation;
+#ifdef Q_OS_WINPHONE
+ onSizeChanged(nullptr, nullptr);
+#endif
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
+ handleExpose(); // Clean broken frames caused by race between Qt and ANGLE
}
return S_OK;
}
@@ -1062,4 +1150,18 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
return S_OK;
}
+#ifdef Q_OS_WINPHONE
+HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *)
+{
+ onSizeChanged(nullptr, nullptr);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *)
+{
+ onSizeChanged(nullptr, nullptr);
+ return S_OK;
+}
+#endif //Q_OS_WINPHONE
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index 796e6abb80..3297617740 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -61,6 +61,9 @@ namespace ABI {
struct IDependencyObject;
struct IWindow;
}
+ namespace ViewManagement {
+ struct IStatusBar;
+ }
}
namespace Graphics {
namespace Display {
@@ -82,17 +85,20 @@ class QWinRTScreen : public QPlatformScreen
public:
explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow);
~QWinRTScreen();
- QRect geometry() const;
- int depth() const;
- QImage::Format format() const;
+ QRect geometry() const Q_DECL_OVERRIDE;
+#ifdef Q_OS_WINPHONE
+ QRect availableGeometry() const Q_DECL_OVERRIDE;
+#endif
+ int depth() const Q_DECL_OVERRIDE;
+ QImage::Format format() const Q_DECL_OVERRIDE;
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
qreal scaleFactor() const;
- QPlatformCursor *cursor() const;
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers keyboardModifiers() const;
- Qt::ScreenOrientation nativeOrientation() const;
- Qt::ScreenOrientation orientation() const;
+ Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
QWindow *topWindow() const;
void addWindow(QWindow *window);
@@ -105,6 +111,10 @@ public:
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
ABI::Windows::UI::Xaml::IDependencyObject *canvas() const;
+#ifdef Q_OS_WINPHONE
+ void setStatusBarVisibility(bool visible, QWindow *window);
+#endif
+
private:
void handleExpose();
@@ -124,6 +134,11 @@ private:
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
+#ifdef Q_OS_WINPHONE
+ HRESULT onStatusBarShowing(ABI::Windows::UI::ViewManagement::IStatusBar *, IInspectable *);
+ HRESULT onStatusBarHiding(ABI::Windows::UI::ViewManagement::IStatusBar *, IInspectable *);
+#endif
+
QScopedPointer<QWinRTScreenPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTScreen)
};
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 634d62ef24..c5b06a5d8a 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -64,9 +64,22 @@ using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::UI;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::UI::Xaml::Controls;
QT_BEGIN_NAMESPACE
+static void setUIElementVisibility(IUIElement *uiElement, bool visibility)
+{
+ Q_ASSERT(uiElement);
+ QEventDispatcherWinRT::runOnXamlThread([uiElement, visibility]() {
+ HRESULT hr;
+ hr = uiElement->put_Visibility(visibility ? Visibility_Visible : Visibility_Collapsed);
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+}
+
class QWinRTWindowPrivate
{
public:
@@ -74,8 +87,13 @@ public:
QSurfaceFormat surfaceFormat;
QString windowTitle;
+ Qt::WindowState state;
+ EGLDisplay display;
+ EGLSurface surface;
- ComPtr<Xaml::Controls::ISwapChainPanel> swapChainPanel;
+ ComPtr<ISwapChainPanel> swapChainPanel;
+ ComPtr<ICanvasStatics> canvas;
+ ComPtr<IUIElement> uiElement;
};
QWinRTWindow::QWinRTWindow(QWindow *window)
@@ -84,6 +102,8 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
{
Q_D(QWinRTWindow);
+ d->surface = EGL_NO_SURFACE;
+ d->display = EGL_NO_DISPLAY;
d->screen = static_cast<QWinRTScreen *>(screen());
setWindowFlags(window->flags());
setWindowState(window->windowState());
@@ -101,24 +121,26 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(),
+ IID_PPV_ARGS(&d->canvas));
+ Q_ASSERT_SUCCEEDED(hr);
hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
// Create a new swapchain and place it inside the canvas
HRESULT hr;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_SwapChainPanel).Get(),
&d->swapChainPanel);
Q_ASSERT_SUCCEEDED(hr);
- ComPtr<Xaml::IUIElement> uiElement;
- hr = d->swapChainPanel.As(&uiElement);
+ hr = d->swapChainPanel.As(&d->uiElement);
Q_ASSERT_SUCCEEDED(hr);
- ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
- ComPtr<Xaml::Controls::IPanel> panel;
+ ComPtr<IDependencyObject> canvas = d->screen->canvas();
+ ComPtr<IPanel> panel;
hr = canvas.As(&panel);
Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IVector<Xaml::UIElement *>> children;
+ ComPtr<IVector<UIElement *>> children;
hr = panel->get_Children(&children);
Q_ASSERT_SUCCEEDED(hr);
- hr = children->Append(uiElement.Get());
+ hr = children->Append(d->uiElement.Get());
Q_ASSERT_SUCCEEDED(hr);
return S_OK;
});
@@ -134,20 +156,16 @@ QWinRTWindow::~QWinRTWindow()
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
HRESULT hr;
- ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
- ComPtr<Xaml::Controls::IPanel> panel;
+ ComPtr<IDependencyObject> canvas = d->screen->canvas();
+ ComPtr<IPanel> panel;
hr = canvas.As(&panel);
Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IVector<Xaml::UIElement *>> children;
+ ComPtr<IVector<UIElement *>> children;
hr = panel->get_Children(&children);
Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<Xaml::IUIElement> uiElement;
- hr = d->swapChainPanel.As(&uiElement);
- Q_ASSERT_SUCCEEDED(hr);
quint32 index;
boolean found;
- hr = children->IndexOf(uiElement.Get(), &index, &found);
+ hr = children->IndexOf(d->uiElement.Get(), &index, &found);
Q_ASSERT_SUCCEEDED(hr);
if (found) {
hr = children->RemoveAt(index);
@@ -156,6 +174,11 @@ QWinRTWindow::~QWinRTWindow()
return S_OK;
});
RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down");
+
+ EGLBoolean value = eglDestroySurface(d->display, d->surface);
+ d->surface = EGL_NO_SURFACE;
+ if (value == EGL_FALSE)
+ qCritical("Failed to destroy EGL window surface: 0x%x", eglGetError());
}
QSurfaceFormat QWinRTWindow::format() const
@@ -180,8 +203,10 @@ void QWinRTWindow::setGeometry(const QRect &rect)
{
Q_D(QWinRTWindow);
- if (window()->isTopLevel()) {
- QPlatformWindow::setGeometry(d->screen->geometry());
+ const Qt::WindowFlags windowFlags = window()->flags();
+ if (window()->isTopLevel() && (windowFlags & Qt::WindowType_Mask) == Qt::Window) {
+ QPlatformWindow::setGeometry(windowFlags & Qt::MaximizeUsingFullscreenGeometryHint
+ ? d->screen->geometry() : d->screen->availableGeometry());
QWindowSystemInterface::handleGeometryChange(window(), geometry());
} else {
QPlatformWindow::setGeometry(rect);
@@ -191,10 +216,16 @@ void QWinRTWindow::setGeometry(const QRect &rect)
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
HRESULT hr;
+ const QRect windowGeometry = geometry();
+ const QPointF topLeft= QPointF(windowGeometry.topLeft()) / d->screen->scaleFactor();
+ hr = d->canvas->SetTop(d->uiElement.Get(), topLeft.y());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->canvas->SetLeft(d->uiElement.Get(), topLeft.x());
+ Q_ASSERT_SUCCEEDED(hr);
ComPtr<Xaml::IFrameworkElement> frameworkElement;
hr = d->swapChainPanel.As(&frameworkElement);
Q_ASSERT_SUCCEEDED(hr);
- const QSizeF size = QSizeF(geometry().size()) / d->screen->scaleFactor();
+ const QSizeF size = QSizeF(windowGeometry.size()) / d->screen->scaleFactor();
hr = frameworkElement->put_Width(size.width());
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Height(size.height());
@@ -209,10 +240,13 @@ void QWinRTWindow::setVisible(bool visible)
Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
- if (visible)
+ if (visible) {
d->screen->addWindow(window());
- else
+ setUIElementVisibility(d->uiElement.Get(), d->state != Qt::WindowMinimized);
+ } else {
d->screen->removeWindow(window());
+ setUIElementVisibility(d->uiElement.Get(), false);
+ }
}
void QWinRTWindow::setWindowTitle(const QString &title)
@@ -249,4 +283,45 @@ qreal QWinRTWindow::devicePixelRatio() const
return screen()->devicePixelRatio();
}
+void QWinRTWindow::setWindowState(Qt::WindowState state)
+{
+ Q_D(QWinRTWindow);
+ if (d->state == state)
+ return;
+
+#ifdef Q_OS_WINPHONE
+ d->screen->setStatusBarVisibility(state == Qt::WindowMaximized || state == Qt::WindowNoState, window());
+#endif
+
+ if (state == Qt::WindowMinimized)
+ setUIElementVisibility(d->uiElement.Get(), false);
+
+ if (d->state == Qt::WindowMinimized)
+ setUIElementVisibility(d->uiElement.Get(), true);
+
+ d->state = state;
+}
+
+EGLSurface QWinRTWindow::eglSurface() const
+{
+ Q_D(const QWinRTWindow);
+ return d->surface;
+}
+
+void QWinRTWindow::createEglSurface(EGLDisplay display, EGLConfig config)
+{
+ Q_D(QWinRTWindow);
+ if (d->surface == EGL_NO_SURFACE) {
+ d->display = display;
+ QEventDispatcherWinRT::runOnXamlThread([this, d, display, config]() {
+ d->surface = eglCreateWindowSurface(display, config,
+ reinterpret_cast<EGLNativeWindowType>(winId()),
+ nullptr);
+ if (d->surface == EGL_NO_SURFACE)
+ qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
+ return S_OK;
+ });
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 88c149b080..9ac7adbf4d 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -39,6 +39,7 @@
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
+#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +62,10 @@ public:
WId winId() const Q_DECL_OVERRIDE;
qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+ void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
+
+ EGLSurface eglSurface() const;
+ void createEglSurface(EGLDisplay display, EGLConfig config);
private:
QScopedPointer<QWinRTWindowPrivate> d_ptr;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 15d3575e60..c35b019f7e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -107,6 +107,24 @@ Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen")
#define XCB_GE_GENERIC 35
#endif
+// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
+// - "pad0" became "extension"
+// - "pad1" and "pad" became "pad0"
+// New and old version of this struct share the following fields:
+typedef struct qt_xcb_ge_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+} qt_xcb_ge_event_t;
+
+static inline bool isXIEvent(xcb_generic_event_t *event, int opCode)
+{
+ qt_xcb_ge_event_t *e = (qt_xcb_ge_event_t *)event;
+ return e->extension == opCode;
+}
+
#ifdef XCB_USE_XLIB
static const char * const xcbConnectionErrors[] = {
"No error", /* Error 0 */
@@ -305,13 +323,10 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
screen->updateRefreshRate(output.mode);
// If the screen became primary, reshuffle the order in QGuiApplicationPrivate
- // TODO: add a proper mechanism for updating primary screen
if (!wasPrimary && screen->isPrimary()) {
- QScreen *realScreen = static_cast<QPlatformScreen*>(screen)->screen();
- QGuiApplicationPrivate::screen_list.removeOne(realScreen);
- QGuiApplicationPrivate::screen_list.prepend(realScreen);
- m_screens.removeOne(screen);
- m_screens.prepend(screen);
+ const int idx = m_screens.indexOf(screen);
+ m_screens.swap(0, idx);
+ QXcbIntegration::instance()->setPrimaryScreen(screen);
}
qCDebug(lcQpaScreen) << "output has changed" << screen;
}
@@ -590,9 +605,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
qCDebug(QT_XCB_GLINTEGRATION) << "Failed to create xcb gl-integration";
sync();
-
- if (qEnvironmentVariableIsEmpty("QT_IM_MODULE"))
- qputenv("QT_IM_MODULE", QByteArray("compose"));
}
QXcbConnection::~QXcbConnection()
@@ -1115,7 +1127,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
#if defined(XCB_USE_XINPUT2)
case XCB_GE_GENERIC:
// Here the windowEventListener is invoked from xi2HandleEvent()
- if (m_xi2Enabled)
+ if (m_xi2Enabled && isXIEvent(event, m_xiOpCode))
xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
break;
#endif
@@ -1288,10 +1300,12 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
memset(&event, 0, sizeof(event));
const xcb_window_t eventListener = xcb_generate_id(m_connection);
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
+ xcb_screen_t *screen = it.data;
Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
- eventListener, m_screens.at(0)->root(),
+ eventListener, screen->root,
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- m_screens.at(0)->screen()->root_visual, 0, 0));
+ screen->root_visual, 0, 0));
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
@@ -1437,6 +1451,105 @@ void *QXcbConnection::createVisualInfoForDefaultVisualId() const
#endif
+#if defined(XCB_USE_XINPUT2)
+// it is safe to cast XI_* events here as long as we are only touching the first 32 bytes,
+// after that position event needs memmove, see xi2PrepareXIGenericDeviceEvent
+static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type)
+{
+ if (!isXIEvent(event, opCode))
+ return false;
+
+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+ return xiEvent->evtype == type;
+}
+#endif
+static inline bool isValid(xcb_generic_event_t *event)
+{
+ return event && (event->response_type & ~0x80);
+}
+
+/*! \internal
+
+ Compresses events of the same type to avoid swamping the event queue.
+ If event compression is not desired there are several options what developers can do:
+
+ 1) Write responsive applications. We drop events that have been buffered in the event
+ queue while waiting on unresponsive GUI thread.
+ 2) Use QAbstractNativeEventFilter to get all events from X connection. This is not optimal
+ because it requires working with native event types.
+ 3) Or add public API to Qt for disabling event compression QTBUG-44964
+
+*/
+bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const
+{
+ uint responseType = event->response_type & ~0x80;
+ int nextIndex = currentIndex + 1;
+
+ if (responseType == XCB_MOTION_NOTIFY) {
+ // compress XCB_MOTION_NOTIFY notify events
+ for (int j = nextIndex; j < eventqueue->size(); ++j) {
+ xcb_generic_event_t *next = eventqueue->at(j);
+ if (!isValid(next))
+ continue;
+ if (next->response_type == XCB_MOTION_NOTIFY)
+ return true;
+ }
+ return false;
+ }
+#if defined(XCB_USE_XINPUT2)
+ // compress XI_* events
+ if (responseType == XCB_GE_GENERIC) {
+ if (!m_xi2Enabled)
+ return false;
+
+ // compress XI_Motion
+ if (isXIType(event, m_xiOpCode, XI_Motion)) {
+ for (int j = nextIndex; j < eventqueue->size(); ++j) {
+ xcb_generic_event_t *next = eventqueue->at(j);
+ if (!isValid(next))
+ continue;
+ if (isXIType(next, m_xiOpCode, XI_Motion))
+ return true;
+ }
+ return false;
+ }
+#ifdef XCB_USE_XINPUT22
+ // compress XI_TouchUpdate for the same touch point id
+ if (isXIType(event, m_xiOpCode, XI_TouchUpdate)) {
+ xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ uint32_t id = xiDeviceEvent->detail % INT_MAX;
+ for (int j = nextIndex; j < eventqueue->size(); ++j) {
+ xcb_generic_event_t *next = eventqueue->at(j);
+ if (!isValid(next))
+ continue;
+ if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) {
+ xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast<xXIDeviceEvent *>(next);
+ if (id == xiDeviceNextEvent->detail % INT_MAX)
+ return true;
+ }
+ }
+ return false;
+ }
+#endif
+ return false;
+ }
+#endif
+ if (responseType == XCB_CONFIGURE_NOTIFY) {
+ // compress multiple configure notify events for the same window
+ for (int j = nextIndex; j < eventqueue->size(); ++j) {
+ xcb_generic_event_t *next = eventqueue->at(j);
+ if (isValid(next) && next->response_type == XCB_CONFIGURE_NOTIFY
+ && ((xcb_configure_notify_event_t *)next)->event == ((xcb_configure_notify_event_t*)event)->event)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return false;
+}
+
void QXcbConnection::processXcbEvents()
{
int connection_error = xcb_connection_has_error(xcb_connection());
@@ -1447,61 +1560,39 @@ void QXcbConnection::processXcbEvents()
QXcbEventArray *eventqueue = m_reader->lock();
- for(int i = 0; i < eventqueue->size(); ++i) {
+ for (int i = 0; i < eventqueue->size(); ++i) {
xcb_generic_event_t *event = eventqueue->at(i);
if (!event)
continue;
QScopedPointer<xcb_generic_event_t, QScopedPointerPodDeleter> eventGuard(event);
(*eventqueue)[i] = 0;
- uint response_type = event->response_type & ~0x80;
-
- if (!response_type) {
+ if (!(event->response_type & ~0x80)) {
handleXcbError((xcb_generic_error_t *)event);
- } else {
- if (response_type == XCB_MOTION_NOTIFY) {
- // compress multiple motion notify events in a row
- // to avoid swamping the event queue
- xcb_generic_event_t *next = eventqueue->value(i+1, 0);
- if (next && (next->response_type & ~0x80) == XCB_MOTION_NOTIFY)
- continue;
- }
+ continue;
+ }
- if (response_type == XCB_CONFIGURE_NOTIFY) {
- // compress multiple configure notify events for the same window
- bool found = false;
- for (int j = i; j < eventqueue->size(); ++j) {
- xcb_generic_event_t *other = eventqueue->at(j);
- if (other && (other->response_type & ~0x80) == XCB_CONFIGURE_NOTIFY
- && ((xcb_configure_notify_event_t *)other)->event == ((xcb_configure_notify_event_t *)event)->event)
- {
- found = true;
- break;
- }
- }
- if (found)
- continue;
- }
+ if (compressEvent(event, i, eventqueue))
+ continue;
- bool accepted = false;
- if (clipboard()->processIncr())
- clipboard()->incrTransactionPeeker(event, accepted);
- if (accepted)
- continue;
+ bool accepted = false;
+ if (clipboard()->processIncr())
+ clipboard()->incrTransactionPeeker(event, accepted);
+ if (accepted)
+ continue;
- QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
- while (it != m_peekFuncs.end()) {
- // These callbacks return true if the event is what they were
- // waiting for, remove them from the list in that case.
- if ((*it)(this, event))
- it = m_peekFuncs.erase(it);
- else
- ++it;
- }
- m_reader->unlock();
- handleXcbEvent(event);
- m_reader->lock();
+ QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
+ while (it != m_peekFuncs.end()) {
+ // These callbacks return true if the event is what they were
+ // waiting for, remove them from the list in that case.
+ if ((*it)(this, event))
+ it = m_peekFuncs.erase(it);
+ else
+ ++it;
}
+ m_reader->unlock();
+ handleXcbEvent(event);
+ m_reader->lock();
}
eventqueue->clear();
@@ -1746,7 +1837,8 @@ static const char * xcb_atomnames = {
"_XSETTINGS_SETTINGS\0"
"_COMPIZ_DECOR_PENDING\0"
"_COMPIZ_DECOR_REQUEST\0"
- "_COMPIZ_DECOR_DELETE_PIXMAP\0" // \0\0 terminates loop.
+ "_COMPIZ_DECOR_DELETE_PIXMAP\0"
+ "_COMPIZ_TOOLKIT_ACTION\0" // \0\0 terminates loop.
};
QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const
@@ -2043,34 +2135,13 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
return true;
}
-// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
-// - "pad0" became "extension"
-// - "pad1" and "pad" became "pad0"
-// New and old version of this struct share the following fields:
-// NOTE: API might change again in the next release of xcb in which case this comment will
-// need to be updated to reflect the reality.
-typedef struct qt_xcb_ge_event_t {
- uint8_t response_type;
- uint8_t extension;
- uint16_t sequence;
- uint32_t length;
- uint16_t event_type;
-} qt_xcb_ge_event_t;
-
-bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode)
-{
- qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev;
- // xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from
- // the xcb version 1.9.3, prior to that it was called "pad0".
- if (event->extension == opCode) {
- // xcb event structs contain stuff that wasn't on the wire, the full_sequence field
- // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
- // Move this data back to have the same layout in memory as it was on the wire
- // and allow casting, overwriting the full_sequence field.
- memmove((char*) event + 32, (char*) event + 36, event->length * 4);
- return true;
- }
- return false;
+void QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event)
+{
+ // xcb event structs contain stuff that wasn't on the wire, the full_sequence field
+ // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
+ // Move this data back to have the same layout in memory as it was on the wire
+ // and allow casting, overwriting the full_sequence field.
+ memmove((char*) event + 32, (char*) event + 36, event->length * 4);
}
#endif // defined(XCB_USE_XINPUT2)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 4a0348aa0c..6ee32bf600 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -286,6 +286,7 @@ namespace QXcbAtom {
_COMPIZ_DECOR_PENDING,
_COMPIZ_DECOR_REQUEST,
_COMPIZ_DECOR_DELETE_PIXMAP,
+ _COMPIZ_TOOLKIT_ACTION,
NPredefinedAtoms,
@@ -522,6 +523,7 @@ private:
bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output);
void initializeScreens();
void updateScreens(const xcb_randr_notify_event_t *event);
+ bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
bool m_xi2Enabled;
int m_xi2Minor;
@@ -574,7 +576,7 @@ private:
QHash<int, ScrollingDevice> m_scrollingDevices;
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
- static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
+ static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event);
#endif
xcb_connection_t *m_connection;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 5a2ea74258..8097cce709 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -216,6 +216,12 @@ void QXcbConnection::xi2SetupDevices()
isTablet = true;
tabletData.pointerType = QTabletEvent::Pen;
dbgType = QLatin1String("pen");
+ } else if (name.contains("waltop") && name.contains("tablet")) {
+ // other "Genius" tablets
+ // WALTOP International Corp. Slim Tablet
+ isTablet = true;
+ tabletData.pointerType = QTabletEvent::Pen;
+ dbgType = QLatin1String("pen");
} else {
isTablet = false;
}
@@ -413,8 +419,10 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
hasRelativeCoords = true;
dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
} else if (vci->label == atom(QXcbAtom::AbsX)) {
+ caps |= QTouchDevice::Position;
dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
} else if (vci->label == atom(QXcbAtom::AbsY)) {
+ caps |= QTouchDevice::Position;
dev->size.setWidth((vci->max - vci->min) * 1000.0 / vci->resolution);
}
break;
@@ -459,82 +467,81 @@ static inline qreal fixed1616ToReal(FP1616 val)
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
- if (xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) {
- xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
- int sourceDeviceId = xiEvent->deviceid; // may be the master id
- xXIDeviceEvent *xiDeviceEvent = 0;
- QXcbWindowEventListener *eventListener = 0;
+ xi2PrepareXIGenericDeviceEvent(event);
+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+ int sourceDeviceId = xiEvent->deviceid; // may be the master id
+ xXIDeviceEvent *xiDeviceEvent = 0;
+ QXcbWindowEventListener *eventListener = 0;
- switch (xiEvent->evtype) {
- case XI_ButtonPress:
- case XI_ButtonRelease:
- case XI_Motion:
+ switch (xiEvent->evtype) {
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_Motion:
#ifdef XCB_USE_XINPUT22
- case XI_TouchBegin:
- case XI_TouchUpdate:
- case XI_TouchEnd:
+ case XI_TouchBegin:
+ case XI_TouchUpdate:
+ case XI_TouchEnd:
#endif
- {
- xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
- eventListener = windowEventListenerFromId(xiDeviceEvent->event);
- if (eventListener) {
- long result = 0;
- if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result))
- return;
- }
- sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
- break;
- }
- case XI_HierarchyChanged:
- xi2HandleHierachyEvent(xiEvent);
- return;
- case XI_DeviceChanged:
- xi2HandleDeviceChangedEvent(xiEvent);
- return;
- default:
- break;
+ {
+ xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ eventListener = windowEventListenerFromId(xiDeviceEvent->event);
+ if (eventListener) {
+ long result = 0;
+ if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result))
+ return;
}
+ sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
+ break;
+ }
+ case XI_HierarchyChanged:
+ xi2HandleHierachyEvent(xiEvent);
+ return;
+ case XI_DeviceChanged:
+ xi2HandleDeviceChangedEvent(xiEvent);
+ return;
+ default:
+ break;
+ }
#ifndef QT_NO_TABLETEVENT
- for (int i = 0; i < m_tabletData.count(); ++i) {
- if (m_tabletData.at(i).deviceId == sourceDeviceId) {
- if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener))
- return;
- }
+ for (int i = 0; i < m_tabletData.count(); ++i) {
+ if (m_tabletData.at(i).deviceId == sourceDeviceId) {
+ if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener))
+ return;
}
+ }
#endif // QT_NO_TABLETEVENT
#ifdef XCB_USE_XINPUT21
- QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(sourceDeviceId);
- if (device != m_scrollingDevices.end())
- xi2HandleScrollEvent(xiEvent, device.value());
+ QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(sourceDeviceId);
+ if (device != m_scrollingDevices.end())
+ xi2HandleScrollEvent(xiEvent, device.value());
#endif // XCB_USE_XINPUT21
#ifdef XCB_USE_XINPUT22
- if (xiDeviceEvent) {
- switch (xiDeviceEvent->evtype) {
- case XI_ButtonPress:
- case XI_ButtonRelease:
- case XI_Motion:
- if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated))
- eventListener->handleXIMouseEvent(event);
- break;
+ if (xiDeviceEvent) {
+ switch (xiDeviceEvent->evtype) {
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_Motion:
+ if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated))
+ eventListener->handleXIMouseEvent(event);
+ break;
- case XI_TouchBegin:
- case XI_TouchUpdate:
- case XI_TouchEnd:
- if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled()))
- qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x",
- event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail,
- fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
- fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event);
- if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event))
- xi2ProcessTouch(xiDeviceEvent, platformWindow);
- break;
- }
+ case XI_TouchBegin:
+ case XI_TouchUpdate:
+ case XI_TouchEnd:
+ if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled()))
+ qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x",
+ event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail,
+ fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
+ fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event);
+ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event))
+ xi2ProcessTouch(xiDeviceEvent, platformWindow);
+ break;
}
-#endif // XCB_USE_XINPUT22
}
+#endif // XCB_USE_XINPUT22
}
#ifdef XCB_USE_XINPUT22
@@ -967,15 +974,6 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
xXIGenericDeviceEvent *xiEvent = static_cast<xXIGenericDeviceEvent *>(event);
xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(xiEvent);
-#ifdef XCB_USE_XINPUT22
- // Synthesize mouse events since otherwise there are no mouse events from
- // the pen on the XI 2.2+ path.
- if (xi2MouseEvents() && eventListener)
- eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event));
-#else
- Q_UNUSED(eventListener);
-#endif
-
switch (xiEvent->evtype) {
case XI_ButtonPress: {
Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail);
@@ -1029,9 +1027,8 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
tabletData->inProximity = true;
tabletData->tool = toolIdToTabletDevice(tool);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_TOOL_SERIAL]);
- QWindowSystemInterface::handleTabletEnterProximityEvent(tabletData->tool,
- tabletData->pointerType,
- tabletData->serialId);
+ QWindowSystemInterface::handleTabletEnterProximityEvent(ev->time,
+ tabletData->tool, tabletData->pointerType, tabletData->serialId);
} else {
tabletData->inProximity = false;
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_ID]);
@@ -1040,9 +1037,8 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
if (!tabletData->tool)
tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_SERIAL]);
tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_LAST_TOOL_SERIAL]);
- QWindowSystemInterface::handleTabletLeaveProximityEvent(tabletData->tool,
- tabletData->pointerType,
- tabletData->serialId);
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(ev->time,
+ tabletData->tool, tabletData->pointerType, tabletData->serialId);
}
// TODO maybe have a hash of tabletData->deviceId to device data so we can
// look up the tablet name here, and distinguish multiple tablets
@@ -1060,6 +1056,16 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
handled = false;
break;
}
+
+#ifdef XCB_USE_XINPUT22
+ // Synthesize mouse events since otherwise there are no mouse events from
+ // the pen on the XI 2.2+ path.
+ if (xi2MouseEvents() && eventListener)
+ eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event));
+#else
+ Q_UNUSED(eventListener);
+#endif
+
return handled;
}
@@ -1110,13 +1116,14 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
}
if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled()))
- qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
- tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail,
+ qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d time %d "
+ "pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
+ tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, ev->time,
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
(int)tabletData.buttons, pressure, xTilt, yTilt, rotation);
- QWindowSystemInterface::handleTabletEvent(window, local, global,
+ QWindowSystemInterface::handleTabletEvent(window, ev->time, local, global,
tabletData.tool, tabletData.pointerType,
tabletData.buttons, pressure,
xTilt, yTilt, tangentialPressure,
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index a3e646ed7a..de23c59a63 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -444,7 +444,7 @@ void QXcbDrag::move(const QPoint &globalPos)
DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0];
if (w)
- handleEnter(w, &enter);
+ handleEnter(w, &enter, current_proxy_target);
else if (target)
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&enter);
waiting_for_status = false;
@@ -665,7 +665,7 @@ static bool checkEmbedded(QWidget* w, const XEvent* xe)
#endif
-void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event)
+void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event, xcb_window_t proxy)
{
Q_UNUSED(window);
DEBUG() << "handleEnter" << window;
@@ -677,6 +677,9 @@ void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_eve
return;
xdnd_dragsource = event->data.data32[0];
+ if (!proxy)
+ proxy = xdndProxy(connection(), xdnd_dragsource);
+ current_proxy_target = proxy ? proxy : xdnd_dragsource;
if (event->data.data32[1] & 1) {
// get the types from XdndTypeList
@@ -775,7 +778,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
if (xdnd_dragsource == connection()->clipboard()->owner())
handle_xdnd_status(&response);
else
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (const char *)&response));
}
@@ -967,7 +970,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
finished.data.data32[1] = response.isAccepted(); // flags
finished.data.data32[2] = toXdndAction(response.acceptedAction());
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (char *)&finished));
xdnd_dragsource = 0;
@@ -1132,7 +1135,11 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
}
}
- xcb_send_event(xcb_connection(), false, event->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&notify);
+ xcb_window_t proxy_target = xdndProxy(connection(), event->requestor);
+ if (!proxy_target)
+ proxy_target = event->requestor;
+
+ xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&notify);
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 699d402ea6..9584c04238 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -76,7 +76,7 @@ public:
void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
void endDrag() Q_DECL_OVERRIDE;
- void handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event);
+ void handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event, xcb_window_t proxy = 0);
void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event);
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index fc06f1a7b0..9cedfa77ad 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -268,7 +268,10 @@ void QXcbIntegration::initialize()
{
// Perform everything that may potentially need the event dispatcher (timers, socket
// notifiers) here instead of the constructor.
- m_inputContext.reset(QPlatformInputContextFactory::create());
+ QString icStr = QPlatformInputContextFactory::requested();
+ if (icStr.isNull())
+ icStr = QLatin1String("compose");
+ m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
}
void QXcbIntegration::moveToScreen(QWindow *window, int screen)
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index f9a85cdf44..d751c6d48a 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1971,7 +1971,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
// and other messages.
} else if (event->type == atom(QXcbAtom::_COMPIZ_DECOR_PENDING)
|| event->type == atom(QXcbAtom::_COMPIZ_DECOR_REQUEST)
- || event->type == atom(QXcbAtom::_COMPIZ_DECOR_DELETE_PIXMAP)) {
+ || event->type == atom(QXcbAtom::_COMPIZ_DECOR_DELETE_PIXMAP)
+ || event->type == atom(QXcbAtom::_COMPIZ_TOOLKIT_ACTION)) {
//silence the _COMPIZ messages for now
} else {
qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type);
@@ -2208,17 +2209,17 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event)
switch (ev->evtype) {
case XI_ButtonPress:
- qCDebug(lcQpaXInput, "XI2 mouse press, button %d", button);
+ qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d", button, ev->time);
conn->setButton(button, true);
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time);
break;
case XI_ButtonRelease:
- qCDebug(lcQpaXInput, "XI2 mouse release, button %d", button);
+ qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d", button, ev->time);
conn->setButton(button, false);
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time);
break;
case XI_Motion:
- qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d", event_x, event_y);
+ qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d", event_x, event_y, ev->time);
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time);
break;
default:
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
index 7d31ac7118..82c1c1de77 100644
--- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
@@ -94,14 +94,14 @@ void QXcbWMSupport::updateVirtualRoots()
int offset = 0;
int remaining = 0;
do {
- xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_ATOM, offset, 1024);
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, offset, 1024);
xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL);
if (!reply)
break;
remaining = 0;
- if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
+ if (reply->type == XCB_ATOM_WINDOW && reply->format == 32) {
int len = xcb_get_property_value_length(reply)/sizeof(xcb_window_t);
xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(reply);
int s = net_virtual_roots.size();