diff options
Diffstat (limited to 'src/plugins')
36 files changed, 762 insertions, 1077 deletions
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 73aa9d0e8a..13f9dc5a68 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -233,6 +233,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const case ForeignWindows: return QtAndroid::activity(); case ThreadedOpenGL: return !needsBasicRenderloopWorkaround() && QtAndroid::activity(); case RasterGLSurface: return QtAndroid::activity(); + case TopStackedNativeChildWindows: return false; default: return QPlatformIntegration::hasCapability(cap); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index 3951f46a82..6920a81e94 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -173,6 +173,28 @@ qreal QEglFSKmsScreen::refreshRate() const return refresh > 0 ? refresh : 60; } +QVector<QPlatformScreen::Mode> QEglFSKmsScreen::modes() const +{ + QVector<QPlatformScreen::Mode> list; + list.reserve(m_output.modes.size()); + + for (const drmModeModeInfo &info : qAsConst(m_output.modes)) + list.append({QSize(info.hdisplay, info.vdisplay), + qreal(info.vrefresh > 0 ? info.vrefresh : 60)}); + + return list; +} + +int QEglFSKmsScreen::currentMode() const +{ + return m_output.mode; +} + +int QEglFSKmsScreen::preferredMode() const +{ + return m_output.preferred_mode; +} + QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const { return m_output.subpixelAntialiasingTypeHint(); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h index 80bbb0c7f1..c90e917f0a 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -77,6 +77,11 @@ public: QList<QPlatformScreen *> virtualSiblings() const override { return m_siblings; } void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; } + QVector<QPlatformScreen::Mode> modes() const override; + + int currentMode() const override; + int preferredMode() const override; + QKmsDevice *device() const { return m_device; } void destroySurface(); diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index d5cd9ac6db..d9c3d6ac14 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -61,40 +61,7 @@ static inline T *coTaskMemAllocArray(int size) /**************************************************************\ * AccessibleApplication * **************************************************************/ -// IUnknown -HRESULT STDMETHODCALLTYPE AccessibleApplication::QueryInterface(REFIID id, LPVOID *iface) -{ - *iface = 0; - if (id == IID_IUnknown) { - qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IUnknown"; - *iface = static_cast<IUnknown *>(this); - } else if (id == IID_IAccessibleApplication) { - qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IAccessibleApplication"; - *iface = static_cast<IAccessibleApplication*>(this); - } - - if (*iface) { - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -ULONG STDMETHODCALLTYPE AccessibleApplication::AddRef() -{ - return ++m_ref; -} -ULONG STDMETHODCALLTYPE AccessibleApplication::Release() -{ - if (!--m_ref) { - delete this; - return 0; - } - return m_ref; -} - -/* IAccessibleApplication */ HRESULT STDMETHODCALLTYPE AccessibleApplication::get_appName(/* [retval][out] */ BSTR *name) { const QString appName = QGuiApplication::applicationName(); @@ -127,40 +94,11 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitVersion(/* [retval][ **************************************************************/ AccessibleRelation::AccessibleRelation(const QList<QAccessibleInterface *> &targets, QAccessible::Relation relation) - : m_targets(targets), m_relation(relation), m_ref(1) + : m_targets(targets), m_relation(relation) { Q_ASSERT(m_targets.count()); } -/* IUnknown */ -HRESULT STDMETHODCALLTYPE AccessibleRelation::QueryInterface(REFIID id, LPVOID *iface) -{ - *iface = 0; - if (id == IID_IUnknown || id == IID_IAccessibleRelation) - *iface = static_cast<IUnknown *>(this); - - if (*iface) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - -ULONG STDMETHODCALLTYPE AccessibleRelation::AddRef() -{ - return ++m_ref; -} - -ULONG STDMETHODCALLTYPE AccessibleRelation::Release() -{ - if (!--m_ref) { - delete this; - return 0; - } - return m_ref; -} - /* IAccessibleRelation */ HRESULT STDMETHODCALLTYPE AccessibleRelation::get_relationType( /* [retval][out] */ BSTR *relationType) @@ -237,56 +175,53 @@ HRESULT STDMETHODCALLTYPE AccessibleRelation::get_targets( **************************************************************/ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOID *iface) { + *iface = nullptr; QAccessibleInterface *accessible = accessibleInterface(); if (!accessible) return E_NOINTERFACE; - HRESULT hr = QWindowsMsaaAccessible::QueryInterface(id, iface); - if (!SUCCEEDED(hr)) { - if (id == IID_IServiceProvider) { - *iface = static_cast<IServiceProvider *>(this); - } else if (id == IID_IAccessible2) { - *iface = static_cast<IAccessible2 *>(this); - } else if (id == IID_IAccessibleAction) { - if (accessible->actionInterface()) - *iface = static_cast<IAccessibleAction *>(this); - } else if (id == IID_IAccessibleComponent) { - *iface = static_cast<IAccessibleComponent *>(this); - } else if (id == IID_IAccessibleEditableText) { - if (accessible->editableTextInterface() || - accessible->role() == QAccessible::EditableText) - { - *iface = static_cast<IAccessibleEditableText *>(this); - } - } else if (id == IID_IAccessibleHyperlink) { - //*iface = static_cast<IAccessibleHyperlink *>(this); - } else if (id == IID_IAccessibleHypertext) { - //*iface = static_cast<IAccessibleHypertext *>(this); - } else if (id == IID_IAccessibleImage) { - //*iface = static_cast<IAccessibleImage *>(this); - } else if (id == IID_IAccessibleTable) { - //*iface = static_cast<IAccessibleTable *>(this); // not supported - } else if (id == IID_IAccessibleTable2) { - if (accessible->tableInterface()) - *iface = static_cast<IAccessibleTable2 *>(this); - } else if (id == IID_IAccessibleTableCell) { - if (accessible->tableCellInterface()) - *iface = static_cast<IAccessibleTableCell *>(this); - } else if (id == IID_IAccessibleText) { - if (accessible->textInterface()) - *iface = static_cast<IAccessibleText *>(this); - } else if (id == IID_IAccessibleValue) { - if (accessible->valueInterface()) - *iface = static_cast<IAccessibleValue *>(this); - } - if (*iface) { - AddRef(); - hr = S_OK; - } else { - hr = E_NOINTERFACE; + if (SUCCEEDED(QWindowsMsaaAccessible::QueryInterface(id, iface)) + || qWindowsComQueryInterface<IServiceProvider>(this, id, iface) + || qWindowsComQueryInterface<IAccessible2>(this, id, iface) + || qWindowsComQueryInterface<IAccessibleComponent>(this, id, iface)) { + return S_OK; + } + + if (id == IID_IAccessibleAction) { + if (accessible->actionInterface()) + *iface = static_cast<IAccessibleAction *>(this); + } else if (id == IID_IAccessibleEditableText) { + if (accessible->editableTextInterface() || + accessible->role() == QAccessible::EditableText) + { + *iface = static_cast<IAccessibleEditableText *>(this); } + } else if (id == IID_IAccessibleHyperlink) { + //*iface = static_cast<IAccessibleHyperlink *>(this); + } else if (id == IID_IAccessibleHypertext) { + //*iface = static_cast<IAccessibleHypertext *>(this); + } else if (id == IID_IAccessibleImage) { + //*iface = static_cast<IAccessibleImage *>(this); + } else if (id == IID_IAccessibleTable) { + //*iface = static_cast<IAccessibleTable *>(this); // not supported + } else if (id == IID_IAccessibleTable2) { + if (accessible->tableInterface()) + *iface = static_cast<IAccessibleTable2 *>(this); + } else if (id == IID_IAccessibleTableCell) { + if (accessible->tableCellInterface()) + *iface = static_cast<IAccessibleTableCell *>(this); + } else if (id == IID_IAccessibleText) { + if (accessible->textInterface()) + *iface = static_cast<IAccessibleText *>(this); + } else if (id == IID_IAccessibleValue) { + if (accessible->valueInterface()) + *iface = static_cast<IAccessibleValue *>(this); } - return hr; + if (*iface) { + AddRef(); + return S_OK; + } + return E_NOINTERFACE; } @@ -1593,7 +1528,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryService(REFGUID guidServic return E_POINTER; Q_UNUSED(guidService); *iface = 0; - qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QS(): " << IIDToString(riid); + qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QS(): " << QWindowsAccessibleGuid(riid); if (guidService == IID_IAccessible) { @@ -1692,45 +1627,6 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface* return count > 0 ? S_OK : S_FALSE; } -#define IF_EQUAL_RETURN_IIDSTRING(id, iid) if (id == iid) return QByteArray(#iid) - -QByteArray QWindowsIA2Accessible::IIDToString(REFIID id) -{ - QByteArray strGuid = QWindowsMsaaAccessible::IIDToString(id); - if (!strGuid.isEmpty()) - return strGuid; - - IF_EQUAL_RETURN_IIDSTRING(id, IID_IUnknown); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IDispatch); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessible); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IOleWindow); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IServiceProvider); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessible2); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleAction); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleApplication); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleComponent); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleEditableText); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleHyperlink); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleHypertext); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleImage); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleRelation); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleTable); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleTable2); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleTableCell); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleText); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleValue); - - // else... -#if 0 // Can be useful for debugging, but normally we'd like to reduce the noise a bit... - OLECHAR szGuid[39]={0}; - ::StringFromGUID2(id, szGuid, 39); - strGuid.reserve(40); - ::WideCharToMultiByte(CP_UTF8, 0, szGuid, 39, strGuid.data(), 39, NULL, NULL); - strGuid[38] = '\0'; -#endif - return strGuid; -} - // Q_STATIC_ASSERT(IA2_ROLE_CANVAS == QAccessible::Canvas); // ### Qt 6: make them the same Q_STATIC_ASSERT(IA2_ROLE_COLOR_CHOOSER == static_cast<IA2Role>(QAccessible::ColorChooser)); Q_STATIC_ASSERT(IA2_ROLE_FOOTER == static_cast<IA2Role>(QAccessible::Footer)); diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.h b/src/plugins/platforms/windows/accessible/iaccessible2.h index bc5f5be60f..d5c67f8b51 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.h +++ b/src/plugins/platforms/windows/accessible/iaccessible2.h @@ -42,6 +42,7 @@ #include <QtCore/QtConfig> #ifndef QT_NO_ACCESSIBILITY +#include "qwindowscombase.h" #include "qwindowsmsaaaccessible.h" #include "comutils.h" @@ -249,7 +250,6 @@ private: HRESULT getRelationsHelper(IAccessibleRelation **relations, int startIndex, long maxRelations, long *nRelations = 0); HRESULT wrapListOfCells(const QList<QAccessibleInterface*> &inputCells, IUnknown ***outputAccessibles, long *nCellCount); - QByteArray IIDToString(REFIID id); QString textForRange(int startOffset, int endOffset) const; void replaceTextFallback(long startOffset, long endOffset, const QString &txt); @@ -258,28 +258,18 @@ private: /**************************************************************\ * AccessibleApplication * **************************************************************/ -class AccessibleApplication : public IAccessibleApplication +class AccessibleApplication : public QWindowsComBase<IAccessibleApplication> { public: - AccessibleApplication() : m_ref(1) - { - - } + AccessibleApplication() {} virtual ~AccessibleApplication() {} - /* IUnknown */ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - /* IAccessibleApplication */ HRESULT STDMETHODCALLTYPE get_appName(/* [retval][out] */ BSTR *name); HRESULT STDMETHODCALLTYPE get_appVersion(/* [retval][out] */ BSTR *version); HRESULT STDMETHODCALLTYPE get_toolkitName(/* [retval][out] */ BSTR *name); HRESULT STDMETHODCALLTYPE get_toolkitVersion(/* [retval][out] */ BSTR *version); -private: - ULONG m_ref; }; @@ -287,7 +277,7 @@ private: /**************************************************************\ * AccessibleRelation * **************************************************************/ -class AccessibleRelation : public IAccessibleRelation +class AccessibleRelation : public QWindowsComBase<IAccessibleRelation> { public: AccessibleRelation(const QList<QAccessibleInterface *> &targets, @@ -295,11 +285,6 @@ public: virtual ~AccessibleRelation() {} - /* IUnknown */ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - /* IAccessibleRelation */ HRESULT STDMETHODCALLTYPE get_relationType(BSTR *relationType); HRESULT STDMETHODCALLTYPE get_localizedRelationType(BSTR *localizedRelationType); @@ -341,7 +326,6 @@ private: QList<QAccessibleInterface *> m_targets; QAccessible::Relation m_relation; - ULONG m_ref; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 25b1577772..308ff59c49 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -42,6 +42,7 @@ #include "qwindowsmsaaaccessible.h" #include "qwindowsaccessibility.h" +#include "qwindowscombase.h" #include <oleacc.h> #include <servprov.h> #include <winuser.h> @@ -71,61 +72,22 @@ QT_BEGIN_NAMESPACE -class QWindowsEnumerate : public IEnumVARIANT +class QWindowsEnumerate : public QWindowsComBase<IEnumVARIANT> { public: - QWindowsEnumerate(const QVector<int> &a) - : ref(0), current(0),array(a) - { - } - + QWindowsEnumerate(const QVector<int> &a) : QWindowsComBase<IEnumVARIANT>(0), current(0),array(a) {} virtual ~QWindowsEnumerate() {} - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT **ppEnum); HRESULT STDMETHODCALLTYPE Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched); HRESULT STDMETHODCALLTYPE Reset(); HRESULT STDMETHODCALLTYPE Skip(unsigned long celt); private: - ULONG ref; ULONG current; QVector<int> array; }; -HRESULT STDMETHODCALLTYPE QWindowsEnumerate::QueryInterface(REFIID id, LPVOID *iface) -{ - *iface = 0; - if (id == IID_IUnknown) - *iface = static_cast<IUnknown *>(this); - else if (id == IID_IEnumVARIANT) - *iface = static_cast<IEnumVARIANT *>(this); - - if (*iface) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - -ULONG STDMETHODCALLTYPE QWindowsEnumerate::AddRef() -{ - return ++ref; -} - -ULONG STDMETHODCALLTYPE QWindowsEnumerate::Release() -{ - if (!--ref) { - delete this; - return 0; - } - return ref; -} - HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Clone(IEnumVARIANT **ppEnum) { QWindowsEnumerate *penum = 0; @@ -193,29 +155,17 @@ void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleIn **************************************************************/ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVOID *iface) { - *iface = 0; - - QByteArray strIID = IIDToString(id); - if (!strIID.isEmpty()) { - qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QI() - IID:" - << strIID << ", iface:" << accessibleInterface(); + *iface = nullptr; + const bool result = qWindowsComQueryUnknownInterfaceMulti<AccessibleBase>(this, id, iface) + || qWindowsComQueryInterface<IDispatch>(this, id, iface) + || qWindowsComQueryInterface<IAccessible>(this, id, iface) + || qWindowsComQueryInterface<IOleWindow>(this, id, iface); + + if (result) { + qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QI() - " + << QWindowsAccessibleGuid(id) << ", iface:" << accessibleInterface(); } - if (id == IID_IUnknown) { - *iface = static_cast<IUnknown *>(static_cast<IDispatch *>(this)); - } else if (id == IID_IDispatch) { - *iface = static_cast<IDispatch *>(this); - } else if (id == IID_IAccessible) { - *iface = static_cast<IAccessible *>(this); - } else if (id == IID_IOleWindow) { - *iface = static_cast<IOleWindow *>(this); - } - - if (*iface) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; + return result ? S_OK : E_NOINTERFACE; } ULONG STDMETHODCALLTYPE QWindowsMsaaAccessible::AddRef() @@ -1209,16 +1159,66 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::ContextSensitiveHelp(BOOL) return S_OK; } -#define IF_EQUAL_RETURN_IIDSTRING(id, iid) if (id == iid) return QByteArray(#iid) -QByteArray QWindowsMsaaAccessible::IIDToString(REFIID id) +const char *QWindowsAccessibleGuid::iidToString(const GUID &id) { - IF_EQUAL_RETURN_IIDSTRING(id, IID_IUnknown); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IDispatch); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessible); - IF_EQUAL_RETURN_IIDSTRING(id, IID_IOleWindow); + const char *result = nullptr; + if (id == IID_IUnknown) + result = "IID_IUnknown"; + else if (id == IID_IDispatch) + result = "IID_IDispatch"; + else if (id == IID_IAccessible) + result = "IID_IAccessible"; + else if (id == IID_IOleWindow) + result = "IID_IOleWindow"; + else if (id == IID_IServiceProvider) + result = "IID_IServiceProvider"; +#ifndef Q_CC_MINGW + else if (id == IID_IAccessible2) + result = "IID_IAccessible2"; + else if (id == IID_IAccessibleAction) + result = "IID_IAccessibleAction"; + else if (id == IID_IAccessibleApplication) + result = "IID_IAccessibleApplication"; + else if (id == IID_IAccessibleComponent) + result = "IID_IAccessibleComponent"; + else if (id == IID_IAccessibleEditableText) + result = "IID_IAccessibleEditableText"; + else if (id == IID_IAccessibleHyperlink) + result = "IID_IAccessibleHyperlink"; + else if (id == IID_IAccessibleHypertext) + result = "IID_IAccessibleHypertext"; + else if (id == IID_IAccessibleImage) + result = "IID_IAccessibleImage"; + else if (id == IID_IAccessibleRelation) + result = "IID_IAccessibleRelation"; + else if (id == IID_IAccessibleTable) + result = "IID_IAccessibleTable"; + else if (id == IID_IAccessibleTable2) + result = "IID_IAccessibleTable2"; + else if (id == IID_IAccessibleTableCell) + result = "IID_IAccessibleTableCell"; + else if (id == IID_IAccessibleText) + result = "IID_IAccessibleText"; + else if (id == IID_IAccessibleValue) + result = "IID_IAccessibleValue"; +#endif // !Q_CC_MINGW + return result; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug, const GUID &); - return QByteArray(); +QDebug operator<<(QDebug d, const QWindowsAccessibleGuid &aguid) +{ + QDebugStateSaver saver(d); + d.nospace(); + if (const char *ids = QWindowsAccessibleGuid::iidToString(aguid.guid())) + d << ids; + else + d << aguid.guid(); + return d; } +#endif // !QT_NO_DEBUG_STREAM QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h index fd00f8ac8b..07f10da99a 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h @@ -69,16 +69,32 @@ void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleIn QWindow *window_helper(const QAccessibleInterface *iface); +class QWindowsAccessibleGuid // Helper for QDebug, outputs known ids by name. +{ +public: + explicit QWindowsAccessibleGuid(const GUID &g) : m_guid(g) {} + GUID guid () const { return m_guid; } + static const char *iidToString(const GUID &id); + +private: + GUID m_guid; +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const QWindowsAccessibleGuid &aguid); +#endif + /**************************************************************\ * QWindowsAccessible * **************************************************************/ -class QWindowsMsaaAccessible : public -#ifdef Q_CC_MINGW - IAccessible + +#ifndef Q_CC_MINGW +typedef IAccessible2 AccessibleBase; #else - IAccessible2 +typedef IAccessible AccessibleBase; #endif - , public IOleWindow + +class QWindowsMsaaAccessible : public AccessibleBase, public IOleWindow { public: QWindowsMsaaAccessible(QAccessibleInterface *a) @@ -132,8 +148,6 @@ public: HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); protected: - virtual QByteArray IIDToString(REFIID id); - QAccessible::Id id; QAccessibleInterface *accessibleInterface() const diff --git a/src/plugins/platforms/windows/qwindowscombase.h b/src/plugins/platforms/windows/qwindowscombase.h new file mode 100644 index 0000000000..f8afcc81cf --- /dev/null +++ b/src/plugins/platforms/windows/qwindowscombase.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSCOMBASE_H +#define QWINDOWSCOMBASE_H + +#include <QtCore/QtGlobal> + +#include <unknwn.h> + +QT_BEGIN_NAMESPACE + +// Helper for implementing IUnknown::QueryInterface. +template <class DesiredInterface, class Derived> +bool qWindowsComQueryInterface(Derived *d, REFIID id, LPVOID *iface) +{ + if (id == __uuidof(DesiredInterface)) { + *iface = static_cast<DesiredInterface *>(d); + d->AddRef(); + return true; + } + return false; +} + +// Helper for implementing IUnknown::QueryInterface for IUnknown +// in the case of multiple inheritance via the first inherited class. +template <class FirstInheritedInterface, class Derived> +bool qWindowsComQueryUnknownInterfaceMulti(Derived *d, REFIID id, LPVOID *iface) +{ + if (id == __uuidof(IUnknown)) { + *iface = static_cast<FirstInheritedInterface *>(d); + d->AddRef(); + return true; + } + return false; +} + +// Helper base class to provide IUnknown methods for COM classes (single inheritance) +template <class ComInterface> class QWindowsComBase : public ComInterface +{ + Q_DISABLE_COPY(QWindowsComBase) +public: + explicit QWindowsComBase(ULONG initialRefCount = 1) : m_ref(initialRefCount) {} + virtual ~QWindowsComBase() {} + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) + { + *iface = nullptr; + return qWindowsComQueryInterface<IUnknown>(this, id, iface) || qWindowsComQueryInterface<ComInterface>(this, id, iface) + ? S_OK : E_NOINTERFACE; + } + + ULONG STDMETHODCALLTYPE AddRef() { return ++m_ref; } + + ULONG STDMETHODCALLTYPE Release() + { + if (!--m_ref) { + delete this; + return 0; + } + return m_ref; + } + +private: + ULONG m_ref; +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSCOMBASE_H diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index f4527bcc60..59e2aacee9 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -41,6 +41,7 @@ #define _WIN32_WINNT 0x0600 +#include "qwindowscombase.h" #include "qwindowsdialoghelpers.h" #include "qwindowscontext.h" @@ -504,33 +505,11 @@ inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFile class QWindowsNativeFileDialogBase; -class QWindowsNativeFileDialogEventHandler : public IFileDialogEvents +class QWindowsNativeFileDialogEventHandler : public QWindowsComBase<IFileDialogEvents> { public: static IFileDialogEvents *create(QWindowsNativeFileDialogBase *nativeFileDialog); - // IUnknown methods - IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) - { - if (riid != IID_IUnknown && riid != IID_IFileDialogEvents) { - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); - } - *ppv = this; - AddRef(); - return NOERROR; - } - - IFACEMETHODIMP_(ULONG) AddRef() { return InterlockedIncrement(&m_ref); } - - IFACEMETHODIMP_(ULONG) Release() - { - const long ref = InterlockedDecrement(&m_ref); - if (!ref) - delete this; - return ref; - } - // IFileDialogEvents methods IFACEMETHODIMP OnFileOk(IFileDialog *); IFACEMETHODIMP OnFolderChange(IFileDialog *) { return S_OK; } @@ -546,7 +525,6 @@ public: virtual ~QWindowsNativeFileDialogEventHandler() {} private: - long m_ref = 1; QWindowsNativeFileDialogBase *m_nativeFileDialog; }; diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 550415e889..9275958456 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -215,7 +215,7 @@ static inline Qt::MouseButtons toQtMouseButtons(DWORD keyState) \ingroup qt-lighthouse-win */ -class QWindowsOleDropSource : public IDropSource +class QWindowsOleDropSource : public QWindowsComBase<IDropSource> { public: enum Mode { @@ -228,11 +228,6 @@ public: void createCursors(); - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - // IDropSource methods STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState); STDMETHOD(GiveFeedback)(DWORD dwEffect); @@ -257,7 +252,6 @@ private: ActionCursorMap m_cursors; QWindowsDragCursorWindow *m_touchDragWindow; - ULONG m_refs; #ifndef QT_NO_DEBUG_STREAM friend QDebug operator<<(QDebug, const QWindowsOleDropSource::CursorEntry &); #endif @@ -268,7 +262,6 @@ QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) , m_drag(drag) , m_currentButtons(Qt::NoButton) , m_touchDragWindow(0) - , m_refs(1) { qCDebug(lcQpaMime) << __FUNCTION__ << m_mode; } @@ -373,38 +366,6 @@ void QWindowsOleDropSource::createCursors() #endif // !QT_NO_DEBUG_OUTPUT } -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - -STDMETHODIMP -QWindowsOleDropSource::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if (iid == IID_IUnknown || iid == IID_IDropSource) { - *ppv = this; - ++m_refs; - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QWindowsOleDropSource::AddRef(void) -{ - return ++m_refs; -} - -STDMETHODIMP_(ULONG) -QWindowsOleDropSource::Release(void) -{ - if (--m_refs == 0) { - delete this; - return 0; - } - return m_refs; -} - /*! \brief Check for cancel. */ @@ -504,34 +465,6 @@ QWindowsOleDropTarget::~QWindowsOleDropTarget() qCDebug(lcQpaMime) << __FUNCTION__ << this; } -STDMETHODIMP -QWindowsOleDropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if (iid == IID_IUnknown || iid == IID_IDropTarget) { - *ppv = this; - AddRef(); - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QWindowsOleDropTarget::AddRef(void) -{ - return ++m_refs; -} - -STDMETHODIMP_(ULONG) -QWindowsOleDropTarget::Release(void) -{ - if (--m_refs == 0) { - delete this; - return 0; - } - return m_refs; -} - void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &point, LPDWORD pdwEffect) { diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index 983f3a67b4..069f58cf02 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -40,6 +40,7 @@ #ifndef QWINDOWSDRAG_H #define QWINDOWSDRAG_H +#include "qwindowscombase.h" #include "qwindowsinternalmimedata.h" #include <qpa/qplatformdrag.h> @@ -57,17 +58,12 @@ public: IDataObject *retrieveDataObject() const override; }; -class QWindowsOleDropTarget : public IDropTarget +class QWindowsOleDropTarget : public QWindowsComBase<IDropTarget> { public: explicit QWindowsOleDropTarget(QWindow *w); virtual ~QWindowsOleDropTarget(); - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); - STDMETHOD_(ULONG, AddRef)(void); - STDMETHOD_(ULONG, Release)(void); - // IDropTarget methods STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); @@ -77,7 +73,6 @@ public: private: void handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &, LPDWORD pdwEffect); - ULONG m_refs = 1; QWindow *const m_window; QRect m_answerRect; QPoint m_lastPoint; diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 751807e897..78368d87de 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -145,6 +145,10 @@ #define RESET_NOTIFICATION_STRATEGY_ARB 0x8256 #define LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#ifndef WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif + QT_BEGIN_NAMESPACE QWindowsOpengl32DLL QOpenGLStaticContext::opengl32; @@ -489,7 +493,7 @@ static int choosePixelFormat(HDC hdc, const QWindowsOpenGLAdditionalFormat &additional, PIXELFORMATDESCRIPTOR *obtainedPfd) { - enum { attribSize =40 }; + enum { attribSize = 42 }; if ((additional.formatFlags & QWindowsGLRenderToPixmap) || !staticContext.hasExtensions()) return 0; @@ -570,7 +574,15 @@ static int choosePixelFormat(HDC hdc, iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; iAttributes[i++] = FALSE; } - // If sample buffer request cannot be satisfied, reduce request. + // must be the last + bool srgbRequested = format.colorSpace() == QSurfaceFormat::sRGBColorSpace; + int srgbValuePosition = 0; + if (srgbRequested) { + srgbValuePosition = i; + iAttributes[i++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT; + iAttributes[i++] = TRUE; + } + // If sample or sRGB request cannot be satisfied, reduce request. int pixelFormat = 0; uint numFormats = 0; while (true) { @@ -578,20 +590,25 @@ static int choosePixelFormat(HDC hdc, staticContext.wglChoosePixelFormatARB(hdc, iAttributes, 0, 1, &pixelFormat, &numFormats) && numFormats >= 1; - if (valid || !sampleBuffersRequested) - break; - if (iAttributes[samplesValuePosition] > 1) { - iAttributes[samplesValuePosition] /= 2; - } else if (iAttributes[samplesValuePosition] == 1) { - // Fallback in case it is unable to initialize with any - // samples to avoid falling back to the GDI path - // NB: The sample attributes needs to be at the end for this - // to work correctly - iAttributes[samplesValuePosition - 1] = FALSE; - iAttributes[samplesValuePosition] = 0; - iAttributes[samplesValuePosition + 1] = 0; - } else { + if (valid || (!sampleBuffersRequested && !srgbRequested)) break; + if (srgbRequested) { + iAttributes[srgbValuePosition] = 0; + srgbRequested = false; + } else if (sampleBuffersRequested) { + if (iAttributes[samplesValuePosition] > 1) { + iAttributes[samplesValuePosition] /= 2; + } else if (iAttributes[samplesValuePosition] == 1) { + // Fallback in case it is unable to initialize with any + // samples to avoid falling back to the GDI path + // NB: The sample attributes needs to be at the end for this + // to work correctly + iAttributes[samplesValuePosition - 1] = FALSE; + iAttributes[samplesValuePosition] = 0; + iAttributes[samplesValuePosition + 1] = 0; + } else { + break; + } } } // Verify if format is acceptable. Note that the returned @@ -628,7 +645,7 @@ static QSurfaceFormat HDC hdc, int pixelFormat, QWindowsOpenGLAdditionalFormat *additionalIn = 0) { - enum { attribSize =40 }; + enum { attribSize = 42 }; QSurfaceFormat result; result.setRenderableType(QSurfaceFormat::OpenGL); @@ -641,6 +658,7 @@ static QSurfaceFormat int i = 0; const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers); + const bool hasSrgbSupport = testFlag(staticContext.extensions, QOpenGLStaticContext::sRGBCapableFramebuffer); iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0 iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1 @@ -658,6 +676,9 @@ static QSurfaceFormat iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12 iAttributes[i++] = WGL_SAMPLES_ARB; // 13 } + if (hasSrgbSupport) + iAttributes[i++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT; // 12 or 14 + if (!staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i, iAttributes, iValues)) { qErrnoWarning("%s: wglGetPixelFormatAttribIVARB() failed for basic parameters.", __FUNCTION__); @@ -673,8 +694,14 @@ static QSurfaceFormat if (iValues[9]) result.setOption(QSurfaceFormat::StereoBuffers); - if (hasSampleBuffers) + if (hasSampleBuffers) { result.setSamples(iValues[13]); + if (hasSrgbSupport && iValues[14]) + result.setColorSpace(QSurfaceFormat::sRGBColorSpace); + } else { + if (hasSrgbSupport && iValues[12]) + result.setColorSpace(QSurfaceFormat::sRGBColorSpace); + } if (additionalIn) { if (iValues[7]) additionalIn->formatFlags |= QWindowsGLAccumBuffer; @@ -947,7 +974,8 @@ QOpenGLStaticContext::QOpenGLStaticContext() : wglChoosePixelFormatARB((WglChoosePixelFormatARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglChoosePixelFormatARB")), wglCreateContextAttribsARB((WglCreateContextAttribsARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglCreateContextAttribsARB")), wglSwapInternalExt((WglSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglSwapIntervalEXT")), - wglGetSwapInternalExt((WglGetSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetSwapIntervalEXT")) + wglGetSwapInternalExt((WglGetSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetSwapIntervalEXT")), + wglGetExtensionsStringARB((WglGetExtensionsStringARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetExtensionsStringARB")) { if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ") || extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1) @@ -1091,6 +1119,14 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext, && !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DisableArb); QWindowsOpenGLAdditionalFormat obtainedAdditional; if (tryExtensions) { + if (m_staticContext->wglGetExtensionsStringARB) { + const char *exts = m_staticContext->wglGetExtensionsStringARB(hdc); + if (exts) { + qCDebug(lcQpaGl) << __FUNCTION__ << "WGL extensions:" << exts; + if (strstr(exts, "WGL_EXT_framebuffer_sRGB")) + m_staticContext->extensions |= QOpenGLStaticContext::sRGBCapableFramebuffer; + } + } m_pixelFormat = ARB::choosePixelFormat(hdc, *m_staticContext, format, requestedAdditional, &m_obtainedPixelFormatDescriptor); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index dfaa428520..2d5b94af0e 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -139,7 +139,8 @@ class QOpenGLStaticContext : public QWindowsStaticOpenGLContext public: enum Extensions { - SampleBuffers = 0x1 + SampleBuffers = 0x1, + sRGBCapableFramebuffer = 0x2 }; typedef bool @@ -160,6 +161,9 @@ public: typedef int (APIENTRY *WglGetSwapInternalExt)(void); + typedef const char * + (APIENTRY *WglGetExtensionsStringARB)(HDC); + bool hasExtensions() const { return wglGetPixelFormatAttribIVARB && wglChoosePixelFormatARB && wglCreateContextAttribsARB; } @@ -185,6 +189,7 @@ public: WglCreateContextAttribsARB wglCreateContextAttribsARB; WglSwapInternalExt wglSwapInternalExt; WglGetSwapInternalExt wglGetSwapInternalExt; + WglGetExtensionsStringARB wglGetExtensionsStringARB; static QWindowsOpengl32DLL opengl32; }; diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp index 9b71061aa5..0ceb0d82fa 100644 --- a/src/plugins/platforms/windows/qwindowsole.cpp +++ b/src/plugins/platforms/windows/qwindowsole.cpp @@ -99,39 +99,6 @@ DWORD QWindowsOleDataObject::reportedPerformedEffect() const return performedEffect; } -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - -STDMETHODIMP -QWindowsOleDataObject::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if (iid == IID_IUnknown || iid == IID_IDataObject) { - *ppv = this; - AddRef(); - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QWindowsOleDataObject::AddRef(void) -{ - return ++m_refs; -} - -STDMETHODIMP_(ULONG) -QWindowsOleDataObject::Release(void) -{ - if (--m_refs == 0) { - releaseQt(); - delete this; - return 0; - } - return m_refs; -} - STDMETHODIMP QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) { @@ -323,35 +290,6 @@ bool QWindowsOleEnumFmtEtc::isNull() const return m_isNull; } -// IUnknown methods -STDMETHODIMP -QWindowsOleEnumFmtEtc::QueryInterface(REFIID riid, void FAR* FAR* ppvObj) -{ - if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) { - *ppvObj = this; - AddRef(); - return NOERROR; - } - *ppvObj = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QWindowsOleEnumFmtEtc::AddRef(void) -{ - return ++m_dwRefs; -} - -STDMETHODIMP_(ULONG) -QWindowsOleEnumFmtEtc::Release(void) -{ - if (--m_dwRefs == 0) { - delete this; - return 0; - } - return m_dwRefs; -} - // IEnumFORMATETC methods STDMETHODIMP QWindowsOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched) diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h index 643011272b..fc58858f2c 100644 --- a/src/plugins/platforms/windows/qwindowsole.h +++ b/src/plugins/platforms/windows/qwindowsole.h @@ -40,6 +40,7 @@ #ifndef QWINDOWSOLE_H #define QWINDOWSOLE_H +#include "qwindowscombase.h" #include <QtCore/qt_windows.h> #include <QtCore/QMap> @@ -53,7 +54,7 @@ QT_BEGIN_NAMESPACE class QMimeData; class QWindow; -class QWindowsOleDataObject : public IDataObject +class QWindowsOleDataObject : public QWindowsComBase<IDataObject> { public: explicit QWindowsOleDataObject(QMimeData *mimeData); @@ -63,11 +64,6 @@ public: QMimeData *mimeData() const; DWORD reportedPerformedEffect() const; - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - // IDataObject methods STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium); STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium); @@ -82,13 +78,12 @@ public: STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise); private: - ULONG m_refs = 1; QPointer<QMimeData> data; const int CF_PERFORMEDDROPEFFECT; DWORD performedEffect = DROPEFFECT_NONE; }; -class QWindowsOleEnumFmtEtc : public IEnumFORMATETC +class QWindowsOleEnumFmtEtc : public QWindowsComBase<IEnumFORMATETC> { public: explicit QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs); @@ -97,11 +92,6 @@ public: bool isNull() const; - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - // IEnumFORMATETC methods STDMETHOD(Next)(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched); STDMETHOD(Skip)(ULONG celt); @@ -111,7 +101,6 @@ public: private: bool copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const; - ULONG m_dwRefs = 1; ULONG m_nIndex = 0; QVector<LPFORMATETC> m_lpfmtetcs; bool m_isNull = false; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 0028ad1bd0..121fdaeabd 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -224,6 +224,23 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp) << ", rcNormalPosition=" << wp.rcNormalPosition; return d; } + +QDebug operator<<(QDebug d, const GUID &guid) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << '{' << hex << uppercasedigits << qSetPadChar(QLatin1Char('0')) + << qSetFieldWidth(8) << guid.Data1 + << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) + << guid.Data2 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) + << guid.Data3 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) + << qSetFieldWidth(2) << guid.Data4[0] << guid.Data4[1] + << qSetFieldWidth(0) << '-' << qSetFieldWidth(2); + for (int i = 2; i < 8; ++i) + d << guid.Data4[i]; + d << qSetFieldWidth(0) << '}'; + return d; +} #endif // !QT_NO_DEBUG_STREAM // QTBUG-43872, for windows that do not have WS_EX_TOOLWINDOW set, WINDOWPLACEMENT diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index e541b110a6..5664539058 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -359,6 +359,7 @@ QDebug operator<<(QDebug d, const MINMAXINFO &i); QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p); QDebug operator<<(QDebug d, const WINDOWPLACEMENT &); QDebug operator<<(QDebug d, const WINDOWPOS &); +QDebug operator<<(QDebug d, const GUID &guid); #endif // !QT_NO_DEBUG_STREAM // ---------- QWindowsGeometryHint inline functions. diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 7d3ecc8aa2..1a80526aab 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -29,6 +29,7 @@ SOURCES += \ $$PWD/qwin10helpers.cpp HEADERS += \ + $$PWD/qwindowscombase.h \ $$PWD/qwindowswindow.h \ $$PWD/qwindowsintegration.h \ $$PWD/qwindowscontext.h \ diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 1f36a1ad2a..492fbf7e10 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -711,8 +711,7 @@ void QGLXContext::queryDummyContext() bool QGLXContext::supportsThreading() { - if (!m_queriedDummyContext) - queryDummyContext(); + queryDummyContext(); return m_supportsThreading; } diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp index 77cbdd5fba..0d02062421 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp @@ -111,18 +111,13 @@ bool QXcbGlxIntegration::initialize(QXcbConnection *connection) m_glx_first_event = reply->first_event; - xcb_generic_error_t *error = 0; - xcb_glx_query_version_cookie_t xglx_query_cookie = xcb_glx_query_version(m_connection->xcb_connection(), - XCB_GLX_MAJOR_VERSION, - XCB_GLX_MINOR_VERSION); - xcb_glx_query_version_reply_t *xglx_query = xcb_glx_query_version_reply(m_connection->xcb_connection(), - xglx_query_cookie, &error); - if (!xglx_query || error) { + auto xglx_query = Q_XCB_REPLY(xcb_glx_query_version, m_connection->xcb_connection(), + XCB_GLX_MAJOR_VERSION, + XCB_GLX_MINOR_VERSION); + if (!xglx_query) { qCWarning(lcQpaGl) << "QXcbConnection: Failed to initialize GLX"; - free(error); return false; } - free(xglx_query); #endif m_native_interface_handler.reset(new QXcbGlxNativeInterfaceHandler(connection->nativeInterface())); diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp index 8df8b28f72..61fed6f5e3 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp @@ -41,6 +41,7 @@ #include "qxcbscreen.h" #include <QtGlxSupport/private/qglxconvenience_p.h> +#include <QDebug> QT_BEGIN_NAMESPACE @@ -58,13 +59,27 @@ const xcb_visualtype_t *QXcbGlxWindow::createVisual() QXcbScreen *scr = xcbScreen(); if (!scr) return Q_NULLPTR; - XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(scr), scr->screenNumber(), &m_format); + + qDebug(lcQpaGl) << "Requested format before FBConfig/Visual selection:" << m_format; + + const char *glxExts = glXQueryExtensionsString(DISPLAY_FROM_XCB(scr), scr->screenNumber()); + int flags = 0; + if (glxExts) { + qCDebug(lcQpaGl, "Available GLX extensions: %s", glxExts); + if (strstr(glxExts, "GLX_EXT_framebuffer_sRGB") || strstr(glxExts, "GLX_ARB_framebuffer_sRGB")) + flags |= QGLX_SUPPORTS_SRGB; + } + + XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(scr), scr->screenNumber(), &m_format, GLX_WINDOW_BIT, flags); if (!visualInfo) { qWarning() << "No XVisualInfo for format" << m_format; return Q_NULLPTR; } const xcb_visualtype_t *xcb_visualtype = scr->visualForId(visualInfo->visualid); XFree(visualInfo); + + qDebug(lcQpaGl) << "Got format:" << m_format; + return xcb_visualtype; } diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 6a5d40267a..a164ed0ef2 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -305,8 +305,7 @@ QXcbClipboard::~QXcbClipboard() m_timestamp[QClipboard::Selection] != XCB_CURRENT_TIME) { // First we check if there is a clipboard manager. - xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); - xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); if (reply && reply->owner != XCB_NONE) { // we delete the property so the manager saves all TARGETS. xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION)); @@ -320,7 +319,6 @@ QXcbClipboard::~QXcbClipboard() "clipboard manager in a reasonable time"); } } - free(reply); } if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection]) @@ -759,17 +757,14 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, format = &dummy_format; // Don't read anything, just get the size of the property data - xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0); if (!reply || reply->type == XCB_NONE) { - free(reply); buffer->resize(0); return false; } *type = reply->type; *format = reply->format; bytes_left = reply->bytes_after; - free(reply); int offset = 0, buffer_offset = 0; @@ -784,17 +779,15 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, while (bytes_left) { // more to read... - xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4)); - reply = xcb_get_property_reply(xcb_connection(), cookie, 0); - if (!reply || reply->type == XCB_NONE) { - free(reply); + reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4); + if (!reply || reply->type == XCB_NONE) break; - } + *type = reply->type; *format = reply->format; bytes_left = reply->bytes_after; - char *data = (char *)xcb_get_property_value(reply); - int length = xcb_get_property_value_length(reply); + char *data = (char *)xcb_get_property_value(reply.get()); + int length = xcb_get_property_value_length(reply.get()); // Here we check if we get a buffer overflow and tries to // recover -- this shouldn't normally happen, but it doesn't @@ -814,7 +807,6 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, // offset is specified in 32-bit multiples offset += length / 4; } - free(reply); } } @@ -891,13 +883,9 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int return e; if (checkManager) { - xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); - xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0); - if (!reply || reply->owner == XCB_NONE) { - free(reply); + auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER)); + if (!reply || reply->owner == XCB_NONE) return 0; - } - free(reply); } // process other clipboard events, since someone is probably requesting data from us diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 8c5f8cae08..c69adab357 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -243,11 +243,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) } else if (!screen && output.connection == XCB_RANDR_CONNECTION_CONNECTED) { // New XRandR output is available and it's enabled if (output.crtc != XCB_NONE && output.mode != XCB_NONE) { - xcb_randr_get_output_info_cookie_t outputInfoCookie = - xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); - QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo( - xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); - + auto outputInfo = Q_XCB_REPLY(xcb_randr_get_output_info, xcb_connection(), + output.output, output.config_timestamp); // Find a fake screen const auto scrs = virtualDesktop->screens(); for (QPlatformScreen *scr : scrs) { @@ -261,12 +258,12 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) if (screen) { QString nameWas = screen->name(); // Transform the fake screen into a physical screen - screen->setOutput(output.output, outputInfo.data()); + screen->setOutput(output.output, outputInfo.get()); updateScreen(screen, output); qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled; was fake:" << nameWas; } else { - screen = createScreen(virtualDesktop, output, outputInfo.data()); + screen = createScreen(virtualDesktop, output, outputInfo.get()); qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; } QHighDpiScaling::updateHighDpiScaling(); @@ -274,10 +271,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) } else if (screen) { if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { // Screen has been disabled - xcb_randr_get_output_info_cookie_t outputInfoCookie = - xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp); - QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo( - xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL)); + auto outputInfo = Q_XCB_REPLY(xcb_randr_get_output_info, xcb_connection(), + output.output, output.config_timestamp); if (outputInfo->crtc == XCB_NONE) { qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled"; destroyScreen(screen); @@ -299,16 +294,10 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) bool QXcbConnection::checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output) { - xcb_generic_error_t *error = 0; - xcb_randr_get_output_primary_cookie_t primaryCookie = - xcb_randr_get_output_primary(xcb_connection(), rootWindow); - QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary ( - xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); - if (!primary || error) { + auto primary = Q_XCB_REPLY(xcb_randr_get_output_primary, xcb_connection(), rootWindow); + if (!primary) qWarning("failed to get the primary output of the screen"); - free(error); - error = NULL; - } + const bool isPrimary = primary ? (primary->output == output) : false; return isPrimary; @@ -404,72 +393,59 @@ void QXcbConnection::initializeScreens() m_virtualDesktops.append(virtualDesktop); QList<QPlatformScreen *> siblings; if (has_randr_extension) { - xcb_generic_error_t *error = NULL; // RRGetScreenResourcesCurrent is fast but it may return nothing if the // configuration is not initialized wrt to the hardware. We should call // RRGetScreenResources in this case. - QScopedPointer<xcb_randr_get_screen_resources_reply_t, QScopedPointerPodDeleter> resources; - xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = - xcb_randr_get_screen_resources_current(xcb_connection(), xcbScreen->root); - QScopedPointer<xcb_randr_get_screen_resources_current_reply_t, QScopedPointerPodDeleter> resources_current( - xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, &error)); - if (!resources_current || error) { + auto resources_current = Q_XCB_REPLY(xcb_randr_get_screen_resources_current, + xcb_connection(), xcbScreen->root); + if (!resources_current) { qWarning("failed to get the current screen resources"); - free(error); } else { xcb_timestamp_t timestamp = 0; xcb_randr_output_t *outputs = Q_NULLPTR; - int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); + int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.get()); if (outputCount) { timestamp = resources_current->config_timestamp; - outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.data()); + outputs = xcb_randr_get_screen_resources_current_outputs(resources_current.get()); } else { - xcb_randr_get_screen_resources_cookie_t resourcesCookie = - xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root); - resources.reset(xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error)); - if (!resources || error) { + auto resources = Q_XCB_REPLY(xcb_randr_get_screen_resources, + xcb_connection(), xcbScreen->root); + if (!resources) { qWarning("failed to get the screen resources"); - free(error); } else { timestamp = resources->config_timestamp; - outputCount = xcb_randr_get_screen_resources_outputs_length(resources.data()); - outputs = xcb_randr_get_screen_resources_outputs(resources.data()); + outputCount = xcb_randr_get_screen_resources_outputs_length(resources.get()); + outputs = xcb_randr_get_screen_resources_outputs(resources.get()); } } if (outputCount) { - xcb_randr_get_output_primary_cookie_t primaryCookie = - xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root); - QScopedPointer<xcb_randr_get_output_primary_reply_t, QScopedPointerPodDeleter> primary( - xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error)); - if (!primary || error) { + auto primary = Q_XCB_REPLY(xcb_randr_get_output_primary, xcb_connection(), xcbScreen->root); + if (!primary) { qWarning("failed to get the primary output of the screen"); - free(error); } else { for (int i = 0; i < outputCount; i++) { - QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> output( - xcb_randr_get_output_info_reply(xcb_connection(), - xcb_randr_get_output_info_unchecked(xcb_connection(), outputs[i], timestamp), NULL)); - + auto output = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_output_info, + xcb_connection(), outputs[i], timestamp); // Invalid, disconnected or disabled output - if (output == NULL) + if (!output) continue; if (output->connection != XCB_RANDR_CONNECTION_CONNECTED) { qCDebug(lcQpaScreen, "Output %s is not connected", qPrintable( - QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), - xcb_randr_get_output_info_name_length(output.data())))); + QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.get()), + xcb_randr_get_output_info_name_length(output.get())))); continue; } if (output->crtc == XCB_NONE) { qCDebug(lcQpaScreen, "Output %s is not enabled", qPrintable( - QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.data()), - xcb_randr_get_output_info_name_length(output.data())))); + QString::fromUtf8((const char*)xcb_randr_get_output_info_name(output.get()), + xcb_randr_get_output_info_name_length(output.get())))); continue; } - QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.data()); + QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, outputs[i], output.get()); siblings << screen; m_screens << screen; @@ -492,12 +468,9 @@ void QXcbConnection::initializeScreens() } } else if (has_xinerama_extension) { // Xinerama is available - xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens(m_connection); - xcb_xinerama_query_screens_reply_t *screens = xcb_xinerama_query_screens_reply(m_connection, - cookie, - Q_NULLPTR); + auto screens = Q_XCB_REPLY(xcb_xinerama_query_screens, m_connection); if (screens) { - xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens); + xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens.get()); while (it.rem) { xcb_xinerama_screen_info_t *screen_info = it.data; QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, @@ -507,7 +480,6 @@ void QXcbConnection::initializeScreens() m_screens << screen; xcb_xinerama_screen_info_next(&it); } - free(screens); } } if (siblings.isEmpty()) { @@ -1461,13 +1433,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp() xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const { - xcb_connection_t *c = xcb_connection(); - xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom); - xcb_get_selection_owner_reply_t *reply; - reply = xcb_get_selection_owner_reply(c, cookie, 0); - xcb_window_t win = reply->owner; - free(reply); - return win; + return Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom)->owner; } xcb_window_t QXcbConnection::getQtSelectionOwner() @@ -1993,11 +1959,7 @@ xcb_atom_t QXcbConnection::internAtom(const char *name) if (!name || *name == 0) return XCB_NONE; - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_connection(), false, strlen(name), name); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookie, 0); - int atom = reply->atom; - free(reply); - return atom; + return Q_XCB_REPLY(xcb_intern_atom, xcb_connection(), false, strlen(name), name)->atom; } QByteArray QXcbConnection::atomName(xcb_atom_t atom) @@ -2005,18 +1967,12 @@ QByteArray QXcbConnection::atomName(xcb_atom_t atom) if (!atom) return QByteArray(); - xcb_generic_error_t *error = 0; - xcb_get_atom_name_cookie_t cookie = Q_XCB_CALL(xcb_get_atom_name(xcb_connection(), atom)); - xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error); - if (error) { + auto reply = Q_XCB_REPLY(xcb_get_atom_name, xcb_connection(), atom); + if (!reply) qWarning() << "QXcbConnection::atomName: bad Atom" << atom; - free(error); - } - if (reply) { - QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply)); - free(reply); - return result; - } + else + return QByteArray(xcb_get_atom_name_name(reply.get()), xcb_get_atom_name_name_length(reply.get())); + return QByteArray(); } @@ -2044,23 +2000,18 @@ void QXcbConnection::sync() void QXcbConnection::initializeXFixes() { - xcb_generic_error_t *error = 0; const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id); if (!reply || !reply->present) return; xfixes_first_event = reply->first_event; - xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection, - XCB_XFIXES_MAJOR_VERSION, - XCB_XFIXES_MINOR_VERSION); - xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection, - xfixes_query_cookie, &error); - if (!xfixes_query || error || xfixes_query->major_version < 2) { + auto xfixes_query = Q_XCB_REPLY(xcb_xfixes_query_version, m_connection, + XCB_XFIXES_MAJOR_VERSION, + XCB_XFIXES_MINOR_VERSION); + if (!xfixes_query || xfixes_query->major_version < 2) { qWarning("QXcbConnection: Failed to initialize XFixes"); - free(error); xfixes_first_event = 0; } - free(xfixes_query); } void QXcbConnection::initializeXRender() @@ -2070,17 +2021,11 @@ void QXcbConnection::initializeXRender() if (!reply || !reply->present) return; - xcb_generic_error_t *error = 0; - xcb_render_query_version_cookie_t xrender_query_cookie = xcb_render_query_version(m_connection, - XCB_RENDER_MAJOR_VERSION, - XCB_RENDER_MINOR_VERSION); - xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection, - xrender_query_cookie, &error); - if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) { + auto xrender_query = Q_XCB_REPLY(xcb_render_query_version, m_connection, + XCB_RENDER_MAJOR_VERSION, + XCB_RENDER_MINOR_VERSION); + if (!xrender_query || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) qWarning("QXcbConnection: Failed to initialize XRender"); - free(error); - } - free(xrender_query); #endif } @@ -2092,21 +2037,16 @@ void QXcbConnection::initializeXRandr() xrandr_first_event = reply->first_event; - xcb_generic_error_t *error = 0; - xcb_randr_query_version_cookie_t xrandr_query_cookie = xcb_randr_query_version(m_connection, - XCB_RANDR_MAJOR_VERSION, - XCB_RANDR_MINOR_VERSION); + auto xrandr_query = Q_XCB_REPLY(xcb_randr_query_version, m_connection, + XCB_RANDR_MAJOR_VERSION, + XCB_RANDR_MINOR_VERSION); has_randr_extension = true; - xcb_randr_query_version_reply_t *xrandr_query = xcb_randr_query_version_reply(m_connection, - xrandr_query_cookie, &error); - if (!xrandr_query || error || (xrandr_query->major_version < 1 || (xrandr_query->major_version == 1 && xrandr_query->minor_version < 2))) { + if (!xrandr_query || (xrandr_query->major_version < 1 || (xrandr_query->major_version == 1 && xrandr_query->minor_version < 2))) { qWarning("QXcbConnection: Failed to initialize XRandr"); - free(error); has_randr_extension = false; } - free(xrandr_query); xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(m_setup); for (; rootIter.rem; xcb_screen_next(&rootIter)) { @@ -2126,14 +2066,8 @@ void QXcbConnection::initializeXinerama() if (!reply || !reply->present) return; - xcb_generic_error_t *error = Q_NULLPTR; - xcb_xinerama_is_active_cookie_t xinerama_query_cookie = xcb_xinerama_is_active(m_connection); - xcb_xinerama_is_active_reply_t *xinerama_is_active = xcb_xinerama_is_active_reply(m_connection, - xinerama_query_cookie, - &error); - has_xinerama_extension = xinerama_is_active && !error && xinerama_is_active->state; - free(error); - free(xinerama_is_active); + auto xinerama_is_active = Q_XCB_REPLY(xcb_xinerama_is_active, m_connection); + has_xinerama_extension = xinerama_is_active && xinerama_is_active->state; } void QXcbConnection::initializeXShape() @@ -2143,16 +2077,13 @@ void QXcbConnection::initializeXShape() return; has_shape_extension = true; - xcb_shape_query_version_cookie_t cookie = xcb_shape_query_version(m_connection); - xcb_shape_query_version_reply_t *shape_query = xcb_shape_query_version_reply(m_connection, - cookie, NULL); + auto shape_query = Q_XCB_REPLY(xcb_shape_query_version, m_connection); if (!shape_query) { qWarning("QXcbConnection: Failed to initialize SHAPE extension"); } else if (shape_query->major_version > 1 || (shape_query->major_version == 1 && shape_query->minor_version >= 1)) { // The input shape is the only thing added in SHAPE 1.1 has_input_shape = true; } - free(shape_query); } void QXcbConnection::initializeXKB() @@ -2167,11 +2098,10 @@ void QXcbConnection::initializeXKB() xkb_first_event = reply->first_event; xcb_connection_t *c = connection()->xcb_connection(); - xcb_xkb_use_extension_cookie_t xkb_query_cookie; - xcb_xkb_use_extension_reply_t *xkb_query; - xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); - xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0); + auto xkb_query = Q_XCB_REPLY(xcb_xkb_use_extension, c, + XKB_X11_MIN_MAJOR_XKB_VERSION, + XKB_X11_MIN_MINOR_XKB_VERSION); if (!xkb_query) { qWarning("Qt: Failed to initialize XKB extension"); @@ -2180,12 +2110,10 @@ void QXcbConnection::initializeXKB() qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)", XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION, xkb_query->serverMajor, xkb_query->serverMinor); - free(xkb_query); return; } has_xkb = true; - free(xkb_query); const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES | XCB_XKB_MAP_PART_KEY_SYMS | @@ -2230,52 +2158,6 @@ bool QXcbConnection::xi2MouseEvents() const } #endif -#if defined(XCB_USE_XINPUT2) -static int xi2ValuatorOffset(const unsigned char *maskPtr, int maskLen, int number) -{ - int offset = 0; - for (int i = 0; i < maskLen; i++) { - if (number < 8) { - if ((maskPtr[i] & (1 << number)) == 0) - return -1; - } - for (int j = 0; j < 8; j++) { - if (j == number) - return offset; - if (maskPtr[i] & (1 << j)) - offset++; - } - number -= 8; - } - return -1; -} - -bool QXcbConnection::xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value) -{ - const xXIDeviceEvent *xideviceevent = static_cast<const xXIDeviceEvent *>(event); - const unsigned char *buttonsMaskAddr = (const unsigned char*)&xideviceevent[1]; - const unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4; - FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4); - - int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum); - if (valuatorOffset < 0) - return false; - - *value = valuatorsValuesAddr[valuatorOffset].integral; - *value += ((double)valuatorsValuesAddr[valuatorOffset].frac / (1 << 16) / (1 << 16)); - return true; -} - -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) - QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const { if (!m_systemTrayTracker) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 7f0d5cf2cc..c298c08322 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -56,6 +56,8 @@ #include <QtCore/QLoggingCategory> #include <QtCore/private/qglobal_p.h> +#include <memory> + // This is needed to make Qt compile together with XKB. xkb.h is using a variable // which is called 'explicit', this is a reserved keyword in c++ #if QT_CONFIG(xkb) @@ -731,6 +733,20 @@ private: QXcbConnection *m_connection; }; +#define Q_XCB_REPLY_CONNECTION_ARG(connection, ...) connection + +#define Q_XCB_REPLY(call, ...) \ + std::unique_ptr<call##_reply_t, decltype(std::free) *>( \ + call##_reply(Q_XCB_REPLY_CONNECTION_ARG(__VA_ARGS__), call(__VA_ARGS__), nullptr), \ + std::free \ + ) + +#define Q_XCB_REPLY_UNCHECKED(call, ...) \ + std::unique_ptr<call##_reply_t, decltype(std::free) *>( \ + call##_reply(Q_XCB_REPLY_CONNECTION_ARG(__VA_ARGS__), call##_unchecked(__VA_ARGS__), nullptr), \ + std::free \ + ) + #ifdef Q_XCB_DEBUG template <typename cookie_t> cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index f70c7138b3..f7fd2ca8b1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -1008,6 +1008,50 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin #endif // XCB_USE_XINPUT21 } +static int xi2ValuatorOffset(const unsigned char *maskPtr, int maskLen, int number) +{ + int offset = 0; + for (int i = 0; i < maskLen; i++) { + if (number < 8) { + if ((maskPtr[i] & (1 << number)) == 0) + return -1; + } + for (int j = 0; j < 8; j++) { + if (j == number) + return offset; + if (maskPtr[i] & (1 << j)) + offset++; + } + number -= 8; + } + return -1; +} + +bool QXcbConnection::xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value) +{ + const xXIDeviceEvent *xideviceevent = static_cast<const xXIDeviceEvent *>(event); + const unsigned char *buttonsMaskAddr = (const unsigned char*)&xideviceevent[1]; + const unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4; + FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4); + + int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum); + if (valuatorOffset < 0) + return false; + + *value = valuatorsValuesAddr[valuatorOffset].integral; + *value += ((double)valuatorsValuesAddr[valuatorOffset].frac / (1 << 16) / (1 << 16)); + return true; +} + +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); +} + Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b) { switch (b) { diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 80fe5a2199..7f8c7af2ae 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -629,10 +629,9 @@ void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDes *pos = QPoint(); xcb_window_t root = c->primaryVirtualDesktop()->root(); - xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root); - xcb_generic_error_t *err = 0; - xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err); - if (!err && reply) { + + auto reply = Q_XCB_REPLY(xcb_query_pointer, c->xcb_connection(), root); + if (reply) { if (virtualDesktop) { const auto virtualDesktops = c->virtualDesktops(); for (QXcbVirtualDesktop *vd : virtualDesktops) { @@ -646,11 +645,8 @@ void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDes *pos = QPoint(reply->root_x, reply->root_y); if (keybMask) *keybMask = reply->mask; - free(reply); return; } - free(err); - free(reply); } QPoint QXcbCursor::pos() const diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 58fb1f3918..4dc132c667 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -94,32 +94,27 @@ static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w) { xcb_window_t proxy = XCB_NONE; - xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, w, c->atom(QXcbAtom::XdndProxy), - XCB_ATOM_WINDOW, 0, 1), c); - xcb_get_property_reply_t *reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_property, c->xcb_connection(), + false, w, c->atom(QXcbAtom::XdndProxy), XCB_ATOM_WINDOW, 0, 1); if (reply && reply->type == XCB_ATOM_WINDOW) - proxy = *((xcb_window_t *)xcb_get_property_value(reply)); - free(reply); + proxy = *((xcb_window_t *)xcb_get_property_value(reply.get())); if (proxy == XCB_NONE) return proxy; // exists and is real? - cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, proxy, c->atom(QXcbAtom::XdndProxy), - XCB_ATOM_WINDOW, 0, 1), c); - reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0); + reply = Q_XCB_REPLY(xcb_get_property, c->xcb_connection(), + false, proxy, c->atom(QXcbAtom::XdndProxy), XCB_ATOM_WINDOW, 0, 1); if (reply && reply->type == XCB_ATOM_WINDOW) { - xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply)); + xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply.get())); if (proxy != p) proxy = 0; } else { proxy = 0; } - free(reply); - return proxy; } @@ -228,28 +223,19 @@ void QXcbDrag::endDrag() initiatorWindow.clear(); } -static xcb_translate_coordinates_reply_t * -translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int x, int y) -{ - xcb_translate_coordinates_cookie_t cookie = - xcb_translate_coordinates(c->xcb_connection(), from, to, x, y); - return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0); -} - static bool windowInteractsWithPosition(xcb_connection_t *connection, const QPoint & pos, xcb_window_t w, xcb_shape_sk_t shapeType) { bool interacts = false; - xcb_shape_get_rectangles_reply_t *reply = xcb_shape_get_rectangles_reply(connection, xcb_shape_get_rectangles(connection, w, shapeType), NULL); + auto reply = Q_XCB_REPLY(xcb_shape_get_rectangles, connection, w, shapeType); if (reply) { - xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(reply); + xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(reply.get()); if (rectangles) { - const int nRectangles = xcb_shape_get_rectangles_rectangles_length(reply); + const int nRectangles = xcb_shape_get_rectangles_rectangles_length(reply.get()); for (int i = 0; !interacts && i < nRectangles; ++i) { interacts = QRect(rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height).contains(pos); } } - free(reply); } return interacts; @@ -261,33 +247,25 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md return 0; if (md) { - xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(xcb_connection(), w); - xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply(xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_window_attributes, xcb_connection(), w); if (!reply) return 0; if (reply->map_state != XCB_MAP_STATE_VIEWABLE) return 0; - free(reply); - - xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(xcb_connection(), w); - xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(xcb_connection(), gcookie, 0); + auto greply = Q_XCB_REPLY(xcb_get_geometry, xcb_connection(), w); if (!greply) return 0; QRect windowRect(greply->x, greply->y, greply->width, greply->height); - free(greply); if (windowRect.contains(pos)) { bool windowContainsMouse = !ignoreNonXdndAwareWindows; { - xcb_get_property_cookie_t cookie = - Q_XCB_CALL(xcb_get_property(xcb_connection(), false, w, connection()->atom(QXcbAtom::XdndAware), - XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); - + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), + false, w, connection()->atom(QXcbAtom::XdndAware), + XCB_GET_PROPERTY_TYPE_ANY, 0, 0); bool isAware = reply && reply->type != XCB_NONE; - free(reply); if (isAware) { const QPoint relPos = pos - windowRect.topLeft(); // When ShapeInput and ShapeBounding are not set they return a single rectangle with the geometry of the window, this is why we @@ -303,19 +281,16 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md } } - xcb_query_tree_cookie_t cookie = xcb_query_tree (xcb_connection(), w); - xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, 0); - + auto reply = Q_XCB_REPLY(xcb_query_tree, xcb_connection(), w); if (!reply) return 0; - int nc = xcb_query_tree_children_length(reply); - xcb_window_t *c = xcb_query_tree_children(reply); + int nc = xcb_query_tree_children_length(reply.get()); + xcb_window_t *c = xcb_query_tree_children(reply.get()); xcb_window_t r = 0; for (uint i = nc; !r && i--;) r = findRealWindow(pos - windowRect.topLeft(), c[i], md-1, ignoreNonXdndAwareWindows); - free(reply); if (r) return r; @@ -356,15 +331,14 @@ void QXcbDrag::move(const QPoint &globalPos) } xcb_window_t rootwin = current_virtual_desktop->root(); - xcb_translate_coordinates_reply_t *translate = - ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y()); + auto translate = Q_XCB_REPLY(xcb_translate_coordinates, connection()->xcb_connection(), + rootwin, rootwin, globalPos.x(), globalPos.y()); if (!translate) return; xcb_window_t target = translate->child; int lx = translate->dst_x; int ly = translate->dst_y; - free (translate); if (target && target != rootwin) { xcb_window_t src = rootwin; @@ -372,7 +346,8 @@ void QXcbDrag::move(const QPoint &globalPos) DNDDEBUG << "checking target for XdndAware" << target << lx << ly; // translate coordinates - translate = ::translateCoordinates(connection(), src, target, lx, ly); + auto translate = Q_XCB_REPLY(xcb_translate_coordinates, connection()->xcb_connection(), + src, target, lx, ly); if (!translate) { target = 0; break; @@ -381,14 +356,11 @@ void QXcbDrag::move(const QPoint &globalPos) ly = translate->dst_y; src = target; xcb_window_t child = translate->child; - free(translate); // check if it has XdndAware - xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, target, - atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, target, + atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0); bool aware = reply && reply->type != XCB_NONE; - free(reply); if (aware) { DNDDEBUG << "Found XdndAware on " << target; break; @@ -422,16 +394,14 @@ void QXcbDrag::move(const QPoint &globalPos) int target_version = 1; if (proxy_target) { - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, proxy_target, - atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 1); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), + false, proxy_target, + atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 1); if (!reply || reply->type == XCB_NONE) target = 0; - target_version = *(uint32_t *)xcb_get_property_value(reply); + target_version = *(uint32_t *)xcb_get_property_value(reply.get()); target_version = qMin(xdnd_version, target_version ? target_version : 1); - - free(reply); } if (target != current_target) { @@ -714,21 +684,19 @@ void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_eve if (event->data.data32[1] & 1) { // get the types from XdndTypeList - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, xdnd_dragsource, - atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM, - 0, xdnd_max_type); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, xdnd_dragsource, + atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM, + 0, xdnd_max_type); if (reply && reply->type != XCB_NONE && reply->format == 32) { - int length = xcb_get_property_value_length(reply) / 4; + int length = xcb_get_property_value_length(reply.get()) / 4; if (length > xdnd_max_type) length = xdnd_max_type; - xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); + xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply.get()); xdnd_types.reserve(length); for (int i = 0; i < length; ++i) xdnd_types.append(atoms[i]); } - free(reply); } else { // get the types from the message for(int i = 2; i < 5; i++) { @@ -1132,28 +1100,20 @@ static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window) xcb_window_t target = 0; forever { // check if window has XdndAware - xcb_get_property_cookie_t gpCookie = Q_XCB_CALL( - xcb_get_property(c->xcb_connection(), false, window, - c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); - xcb_get_property_reply_t *gpReply = xcb_get_property_reply( - c->xcb_connection(), gpCookie, 0); + auto gpReply = Q_XCB_REPLY(xcb_get_property, c->xcb_connection(), false, window, + c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0); bool aware = gpReply && gpReply->type != XCB_NONE; - free(gpReply); if (aware) { target = window; break; } // try window's parent - xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL( - xcb_query_tree_unchecked(c->xcb_connection(), window)); - xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply( - c->xcb_connection(), qtCookie, NULL); + auto qtReply = Q_XCB_REPLY_UNCHECKED(xcb_query_tree, c->xcb_connection(), window); if (!qtReply) break; xcb_window_t root = qtReply->root; xcb_window_t parent = qtReply->parent; - free(qtReply); if (window == root) break; window = parent; diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index d4bdb6c771..67a959d8a4 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -91,19 +91,14 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap { xcb_connection_t *conn = connection->xcb_connection(); - xcb_get_image_cookie_t get_image_cookie = - xcb_get_image_unchecked(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, - 0, 0, width, height, 0xffffffff); - - xcb_get_image_reply_t *image_reply = - xcb_get_image_reply(conn, get_image_cookie, NULL); - + auto image_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_image, conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap, + 0, 0, width, height, 0xffffffff); if (!image_reply) { return QPixmap(); } - uint8_t *data = xcb_get_image_data(image_reply); - uint32_t length = xcb_get_image_data_length(image_reply); + uint8_t *data = xcb_get_image_data(image_reply.get()); + uint32_t length = xcb_get_image_data_length(image_reply.get()); QPixmap result; @@ -165,7 +160,6 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap result = QPixmap::fromImage(image.copy()); } - free(image_reply); return result; } @@ -203,22 +197,15 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image, xcb_connection_t *conn = screen->xcb_connection(); const int w = image.width(); const int h = image.height(); - xcb_generic_error_t *error = 0; - xcb_render_query_pict_formats_cookie_t formatsCookie = xcb_render_query_pict_formats(conn); - xcb_render_query_pict_formats_reply_t *formatsReply = xcb_render_query_pict_formats_reply(conn, - formatsCookie, - &error); - if (!formatsReply || error) { + auto formats = Q_XCB_REPLY(xcb_render_query_pict_formats, conn); + if (!formats) { qWarning("qt_xcb_createCursorXRender: query_pict_formats failed"); - free(formatsReply); - free(error); return XCB_NONE; } - xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formatsReply, + xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formats.get(), XCB_PICT_STANDARD_ARGB_32); if (!fmt) { qWarning("qt_xcb_createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32"); - free(formatsReply); return XCB_NONE; } @@ -230,14 +217,12 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image, 0, 0, 0); if (!xi) { qWarning("qt_xcb_createCursorXRender: xcb_image_create failed"); - free(formatsReply); return XCB_NONE; } xi->data = (uint8_t *) malloc(xi->stride * h); if (!xi->data) { qWarning("qt_xcb_createCursorXRender: Failed to malloc() image data"); xcb_image_destroy(xi); - free(formatsReply); return XCB_NONE; } memcpy(xi->data, img.constBits(), img.byteCount()); @@ -260,7 +245,6 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image, xcb_image_destroy(xi); xcb_render_free_picture(conn, pic); xcb_free_pixmap(conn, pix); - free(formatsReply); return cursor; #else diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 2e29c208c7..e71e77695c 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -612,23 +612,18 @@ Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s) const void QXcbKeyboard::readXKBConfig() { clearXKBConfig(); - xcb_generic_error_t *error; - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *config_reply; xcb_connection_t *c = xcb_connection(); xcb_window_t rootWindow = connection()->rootWindow(); - cookie = xcb_get_property(c, 0, rootWindow, - atom(QXcbAtom::_XKB_RULES_NAMES), XCB_ATOM_STRING, 0, 1024); - - config_reply = xcb_get_property_reply(c, cookie, &error); + auto config_reply = Q_XCB_REPLY(xcb_get_property, c, 0, rootWindow, + atom(QXcbAtom::_XKB_RULES_NAMES), XCB_ATOM_STRING, 0, 1024); if (!config_reply) { qWarning("Qt: Couldn't interpret the _XKB_RULES_NAMES property"); return; } - char *xkb_config = (char *)xcb_get_property_value(config_reply); - int length = xcb_get_property_value_length(config_reply); + char *xkb_config = (char *)xcb_get_property_value(config_reply.get()); + int length = xcb_get_property_value_length(config_reply.get()); // on old X servers xkb_config can be 0 even if config_reply indicates a succesfull read if (!xkb_config || length == 0) @@ -653,8 +648,6 @@ void QXcbKeyboard::readXKBConfig() xkb_names.layout = qstrdup(names[2]); xkb_names.variant = qstrdup(names[3]); xkb_names.options = qstrdup(names[4]); - - free(config_reply); } void QXcbKeyboard::clearXKBConfig() @@ -1172,23 +1165,19 @@ QXcbKeyboard::~QXcbKeyboard() void QXcbKeyboard::updateVModMapping() { #if QT_CONFIG(xkb) - xcb_xkb_get_names_cookie_t names_cookie; - xcb_xkb_get_names_reply_t *name_reply; xcb_xkb_get_names_value_list_t names_list; memset(&vmod_masks, 0, sizeof(vmod_masks)); - names_cookie = xcb_xkb_get_names(xcb_connection(), - XCB_XKB_ID_USE_CORE_KBD, - XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES); - - name_reply = xcb_xkb_get_names_reply(xcb_connection(), names_cookie, 0); + auto name_reply = Q_XCB_REPLY(xcb_xkb_get_names, xcb_connection(), + XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES); if (!name_reply) { qWarning("Qt: failed to retrieve the virtual modifier names from XKB"); return; } - const void *buffer = xcb_xkb_get_names_value_list(name_reply); + const void *buffer = xcb_xkb_get_names_value_list(name_reply.get()); xcb_xkb_get_names_value_list_unpack(buffer, name_reply->nTypes, name_reply->indicators, @@ -1233,32 +1222,27 @@ void QXcbKeyboard::updateVModMapping() else if (qstrcmp(vmod_name, "Hyper") == 0) vmod_masks.hyper = bit; } - - free(name_reply); #endif } void QXcbKeyboard::updateVModToRModMapping() { #if QT_CONFIG(xkb) - xcb_xkb_get_map_cookie_t map_cookie; - xcb_xkb_get_map_reply_t *map_reply; xcb_xkb_get_map_map_t map; memset(&rmod_masks, 0, sizeof(rmod_masks)); - map_cookie = xcb_xkb_get_map(xcb_connection(), - XCB_XKB_ID_USE_CORE_KBD, - XCB_XKB_MAP_PART_VIRTUAL_MODS, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - map_reply = xcb_xkb_get_map_reply(xcb_connection(), map_cookie, 0); + auto map_reply = Q_XCB_REPLY(xcb_xkb_get_map, + xcb_connection(), + XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_MAP_PART_VIRTUAL_MODS, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (!map_reply) { qWarning("Qt: failed to retrieve the virtual modifier map from XKB"); return; } - const void *buffer = xcb_xkb_get_map_map(map_reply); + const void *buffer = xcb_xkb_get_map_map(map_reply.get()); xcb_xkb_get_map_map_unpack(buffer, map_reply->nTypes, map_reply->nKeySyms, @@ -1301,7 +1285,6 @@ void QXcbKeyboard::updateVModToRModMapping() rmod_masks.hyper = modmap; } - free(map_reply); resolveMaskConflicts(); #endif } @@ -1315,14 +1298,10 @@ void QXcbKeyboard::updateModifiers() // process for all modifiers whenever any part of the modifier mapping is changed. memset(&rmod_masks, 0, sizeof(rmod_masks)); - xcb_generic_error_t *error = 0; xcb_connection_t *conn = xcb_connection(); - xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn); - xcb_get_modifier_mapping_reply_t *modMapReply = - xcb_get_modifier_mapping_reply(conn, modMapCookie, &error); - if (error) { + auto modMapReply = Q_XCB_REPLY(xcb_get_modifier_mapping, conn); + if (!modMapReply) { qWarning("Qt: failed to get modifier mapping"); - free(error); return; } @@ -1338,7 +1317,7 @@ void QXcbKeyboard::updateModifiers() for (size_t i = 0; i < numSymbols; ++i) modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]); - xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply); + xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply.get()); const int w = modMapReply->keycodes_per_modifier; for (size_t i = 0; i < numSymbols; ++i) { for (int bit = 0; bit < 8; ++bit) { @@ -1366,7 +1345,6 @@ void QXcbKeyboard::updateModifiers() for (size_t i = 0; i < numSymbols; ++i) free(modKeyCodes[i]); - free(modMapReply); resolveMaskConflicts(); } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 725288633a..cc05671580 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -121,28 +121,19 @@ xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const { if (m_sysTraySelectionAtom == XCB_ATOM_NONE) { const QByteArray net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen->screenNumber()).toLatin1(); - xcb_intern_atom_cookie_t intern_c = - xcb_intern_atom_unchecked(conn, true, net_sys_tray.length(), net_sys_tray); - - xcb_intern_atom_reply_t *intern_r = xcb_intern_atom_reply(conn, intern_c, 0); - + auto intern_r = Q_XCB_REPLY_UNCHECKED(xcb_intern_atom, conn, + true, net_sys_tray.length(), net_sys_tray); if (!intern_r) return XCB_WINDOW_NONE; m_sysTraySelectionAtom = intern_r->atom; - free(intern_r); } - xcb_get_selection_owner_cookie_t sel_owner_c = xcb_get_selection_owner_unchecked(conn, m_sysTraySelectionAtom); - xcb_get_selection_owner_reply_t *sel_owner_r = xcb_get_selection_owner_reply(conn, sel_owner_c, 0); - + auto sel_owner_r = Q_XCB_REPLY_UNCHECKED(xcb_get_selection_owner, conn, m_sysTraySelectionAtom); if (!sel_owner_r) return XCB_WINDOW_NONE; - xcb_window_t selection_window = sel_owner_r->owner; - free(sel_owner_r); - - return selection_window; + return sel_owner_r->owner; } bool QXcbNativeInterface::systrayVisualHasAlphaChannel() @@ -457,21 +448,13 @@ void *QXcbNativeInterface::atspiBus() QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) { xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS"); - xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property( - defaultConnection->xcb_connection(), - false, defaultConnection->rootWindow(), - atspiBusAtom, XCB_ATOM_STRING, 0, 128), - defaultConnection); - xcb_get_property_reply_t *reply = Q_XCB_CALL2(xcb_get_property_reply( - defaultConnection->xcb_connection(), - cookie, 0), - defaultConnection); + auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(), + false, defaultConnection->rootWindow(), + atspiBusAtom, XCB_ATOM_STRING, 0, 128); Q_ASSERT(!reply->bytes_after); - char *data = (char *)xcb_get_property_value(reply); - int length = xcb_get_property_value_length(reply); - QByteArray *busAddress = new QByteArray(data, length); - free(reply); - return busAddress; + char *data = (char *)xcb_get_property_value(reply.get()); + int length = xcb_get_property_value_length(reply.get()); + return new QByteArray(data, length); } return 0; } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 5e136b5d7e..b1bd0a5453 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -130,11 +130,9 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify() QRect QXcbVirtualDesktop::getWorkArea() const { QRect r; - xcb_get_property_reply_t * workArea = - xcb_get_property_reply(xcb_connection(), - xcb_get_property_unchecked(xcb_connection(), false, screen()->root, - atom(QXcbAtom::_NET_WORKAREA), - XCB_ATOM_CARDINAL, 0, 1024), NULL); + auto workArea = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), false, screen()->root, + atom(QXcbAtom::_NET_WORKAREA), + XCB_ATOM_CARDINAL, 0, 1024); if (workArea && workArea->type == XCB_ATOM_CARDINAL && workArea->format == 32 && workArea->value_len >= 4) { // If workArea->value_len > 4, the remaining ones seem to be for WM's virtual desktops // (don't mess with QXcbVirtualDesktop which represents an X screen). @@ -142,12 +140,11 @@ QRect QXcbVirtualDesktop::getWorkArea() const // "docked" panel (with _NET_WM_STRUT_PARTIAL atom set) on just one desktop. // But for now just assume the first 4 values give us the geometry of the // "work area", AKA "available geometry" - uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea); + uint32_t *geom = (uint32_t*)xcb_get_property_value(workArea.get()); r = QRect(geom[0], geom[1], geom[2], geom[3]); } else { r = QRect(QPoint(), size()); } - free(workArea); return r; } @@ -181,14 +178,11 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe { if (connection->hasXRandr()) { xcb_randr_select_input(xcb_connection(), screen()->root, true); - xcb_randr_get_crtc_info_cookie_t crtcCookie = - xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, output ? output->timestamp : 0); - xcb_randr_get_crtc_info_reply_t *crtc = - xcb_randr_get_crtc_info_reply(xcb_connection(), crtcCookie, NULL); + auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(), + m_crtc, output ? output->timestamp : 0); if (crtc) { updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation); updateRefreshRate(crtc->mode); - free(crtc); } } else if (xineramaScreenInfo) { m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org, @@ -210,10 +204,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe readXResources(); - QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs( - xcb_get_window_attributes_reply(xcb_connection(), - xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL)); - const quint32 existingEventMask = rootAttribs.isNull() ? 0 : rootAttribs->your_event_mask; + auto rootAttribs = Q_XCB_REPLY_UNCHECKED(xcb_get_window_attributes, xcb_connection(), + screen()->root); + const quint32 existingEventMask = !rootAttribs ? 0 : rootAttribs->your_event_mask; const quint32 mask = XCB_CW_EVENT_MASK; const quint32 values[] = { @@ -227,29 +220,24 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values); - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), - xcb_get_property_unchecked(xcb_connection(), false, screen()->root, - atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK), - XCB_ATOM_WINDOW, 0, 1024), NULL); - + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + false, screen()->root, + atom(QXcbAtom::_NET_SUPPORTING_WM_CHECK), + XCB_ATOM_WINDOW, 0, 1024); if (reply && reply->format == 32 && reply->type == XCB_ATOM_WINDOW) { - xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply)); + xcb_window_t windowManager = *((xcb_window_t *)xcb_get_property_value(reply.get())); if (windowManager != XCB_WINDOW_NONE) { - xcb_get_property_reply_t *windowManagerReply = - xcb_get_property_reply(xcb_connection(), - xcb_get_property_unchecked(xcb_connection(), false, windowManager, - atom(QXcbAtom::_NET_WM_NAME), - atom(QXcbAtom::UTF8_STRING), 0, 1024), NULL); + auto windowManagerReply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + false, windowManager, + atom(QXcbAtom::_NET_WM_NAME), + atom(QXcbAtom::UTF8_STRING), 0, 1024); if (windowManagerReply && windowManagerReply->format == 8 && windowManagerReply->type == atom(QXcbAtom::UTF8_STRING)) { - m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply), xcb_get_property_value_length(windowManagerReply)); + m_windowManagerName = QString::fromUtf8((const char *)xcb_get_property_value(windowManagerReply.get()), + xcb_get_property_value_length(windowManagerReply.get())); } - - free(windowManagerReply); } } - free(reply); const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id); if (!sync_reply || !sync_reply->present) @@ -311,12 +299,7 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const xcb_window_t child = root; do { - xcb_translate_coordinates_cookie_t translate_cookie = - xcb_translate_coordinates_unchecked(xcb_connection(), parent, child, x, y); - - xcb_translate_coordinates_reply_t *translate_reply = - xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, NULL); - + auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates, xcb_connection(), parent, child, x, y); if (!translate_reply) { return 0; } @@ -326,8 +309,6 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const x = translate_reply->dst_x; y = translate_reply->dst_y; - free(translate_reply); - if (!child || child == root) return 0; @@ -581,14 +562,10 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) if (!connection()->hasXRandr()) return; - xcb_randr_get_crtc_info_cookie_t crtcCookie = - xcb_randr_get_crtc_info_unchecked(xcb_connection(), m_crtc, timestamp); - xcb_randr_get_crtc_info_reply_t *crtc = - xcb_randr_get_crtc_info_reply(xcb_connection(), crtcCookie, NULL); - if (crtc) { + auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(), + m_crtc, timestamp); + if (crtc) updateGeometry(QRect(crtc->x, crtc->y, crtc->width, crtc->height), crtc->rotation); - free(crtc); - } } void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) @@ -645,13 +622,11 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode) // we can safely use get_screen_resources_current here, because in order to // get here, we must have called get_screen_resources before - xcb_randr_get_screen_resources_current_cookie_t resourcesCookie = - xcb_randr_get_screen_resources_current_unchecked(xcb_connection(), screen()->root); - xcb_randr_get_screen_resources_current_reply_t *resources = - xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, NULL); + auto resources = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_screen_resources_current, + xcb_connection(), screen()->root); if (resources) { xcb_randr_mode_info_iterator_t modesIter = - xcb_randr_get_screen_resources_current_modes_iterator(resources); + xcb_randr_get_screen_resources_current_modes_iterator(resources.get()); for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) { xcb_randr_mode_info_t *modeInfo = modesIter.data; if (modeInfo->id == mode) { @@ -662,29 +637,19 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode) } } - free(resources); QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), m_refreshRate); } } -static xcb_get_geometry_reply_t *getGeometryUnchecked(xcb_connection_t *connection, xcb_window_t window) -{ - const xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry_unchecked(connection, window); - return xcb_get_geometry_reply(connection, geometry_cookie, NULL); -} - static inline bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent, int *x, int *y) { - const xcb_translate_coordinates_cookie_t translate_cookie = - xcb_translate_coordinates_unchecked(connection, child, parent, *x, *y); - xcb_translate_coordinates_reply_t *translate_reply = - xcb_translate_coordinates_reply(connection, translate_cookie, NULL); + auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates, + connection, child, parent, *x, *y); if (!translate_reply) return false; *x = translate_reply->dst_x; *y = translate_reply->dst_y; - free(translate_reply); return true; } @@ -698,22 +663,20 @@ QPixmap QXcbScreen::grabWindow(WId window, int xIn, int yIn, int width, int heig QXcbScreen *screen = const_cast<QXcbScreen *>(this); xcb_window_t root = screen->root(); - xcb_get_geometry_reply_t *rootReply = getGeometryUnchecked(xcb_connection(), root); + auto rootReply = Q_XCB_REPLY_UNCHECKED(xcb_get_geometry, xcb_connection(), root); if (!rootReply) return QPixmap(); const quint8 rootDepth = rootReply->depth; - free(rootReply); QSize windowSize; quint8 effectiveDepth = 0; if (window) { - xcb_get_geometry_reply_t *windowReply = getGeometryUnchecked(xcb_connection(), window); + auto windowReply = Q_XCB_REPLY_UNCHECKED(xcb_get_geometry, xcb_connection(), window); if (!windowReply) return QPixmap(); windowSize = QSize(windowReply->width, windowReply->height); effectiveDepth = windowReply->depth; - free(windowReply); if (effectiveDepth == rootDepth) { // if the depth of the specified window and the root window are the // same, grab pixels from the root window (so that we get the any @@ -738,14 +701,12 @@ QPixmap QXcbScreen::grabWindow(WId window, int xIn, int yIn, int width, int heig if (height < 0) height = windowSize.height() - yIn; - xcb_get_window_attributes_reply_t *attributes_reply = - xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes_unchecked(xcb_connection(), window), NULL); + auto attributes_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_window_attributes, xcb_connection(), window); if (!attributes_reply) return QPixmap(); const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual); - free(attributes_reply); xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection()); xcb_create_pixmap(xcb_connection(), effectiveDepth, pixmap, window, width, height); @@ -819,21 +780,17 @@ void QXcbScreen::readXResources() int offset = 0; QByteArray resources; while(1) { - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), - xcb_get_property_unchecked(xcb_connection(), false, screen()->root, - XCB_ATOM_RESOURCE_MANAGER, - XCB_ATOM_STRING, offset/4, 8192), NULL); + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + false, screen()->root, + XCB_ATOM_RESOURCE_MANAGER, + XCB_ATOM_STRING, offset/4, 8192); bool more = false; if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) { - resources += QByteArray((const char *)xcb_get_property_value(reply), xcb_get_property_value_length(reply)); - offset += xcb_get_property_value_length(reply); + resources += QByteArray((const char *)xcb_get_property_value(reply.get()), xcb_get_property_value_length(reply.get())); + offset += xcb_get_property_value_length(reply.get()); more = reply->bytes_after != 0; } - if (reply) - free(reply); - if (!more) break; } diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp index fb0a4a3939..3939fc9005 100644 --- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp +++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp @@ -85,13 +85,10 @@ QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection, xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection) { - xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(connection->xcb_connection(), selection); - xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(connection->xcb_connection(), cookie, 0); + auto reply = Q_XCB_REPLY(xcb_get_selection_owner, connection->xcb_connection(), selection); if (!reply) return 0; - const xcb_window_t result = reply->owner; - free(reply); - return result; + return reply->owner; } // API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Request a window @@ -130,23 +127,16 @@ xcb_window_t QXcbSystemTrayTracker::trayWindow() // does not work for the QWindow parented on the tray. QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const { - xcb_connection_t *conn = m_connection->xcb_connection(); - xcb_get_geometry_reply_t *geomReply = - xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), 0); + auto geomReply = Q_XCB_REPLY(xcb_get_geometry, conn, window); if (!geomReply) return QRect(); - xcb_translate_coordinates_reply_t *translateReply = - xcb_translate_coordinates_reply(conn, xcb_translate_coordinates(conn, window, m_connection->rootWindow(), 0, 0), 0); - if (!translateReply) { - free(geomReply); + auto translateReply = Q_XCB_REPLY(xcb_translate_coordinates, conn, window, m_connection->rootWindow(), 0, 0); + if (!translateReply) return QRect(); - } - const QRect result(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height)); - free(translateReply); - return result; + return QRect(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height)); } inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged() @@ -180,24 +170,18 @@ bool QXcbSystemTrayTracker::visualHasAlphaChannel() xcb_atom_t tray_atom = m_connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL); // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom - xcb_get_property_cookie_t systray_atom_cookie; - xcb_get_property_reply_t *systray_atom_reply; - - systray_atom_cookie = xcb_get_property_unchecked(m_connection->xcb_connection(), false, m_trayWindow, + auto systray_atom_reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, m_connection->xcb_connection(), + false, m_trayWindow, tray_atom, XCB_ATOM_VISUALID, 0, 1); - systray_atom_reply = xcb_get_property_reply(m_connection->xcb_connection(), systray_atom_cookie, 0); - if (!systray_atom_reply) return false; xcb_visualid_t systrayVisualId = XCB_NONE; - if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) { - xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply); + if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply.get()) > 0) { + xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply.get()); systrayVisualId = vids[0]; } - free(systray_atom_reply); - if (systrayVisualId != XCB_NONE) { quint8 depth = m_connection->primaryScreen()->depthOfVisual(systrayVisualId); return depth == 32; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index f7c36ec386..abd41bb942 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -669,12 +669,10 @@ QMargins QXcbWindow::frameMargins() const { if (m_dirtyFrameMargins) { if (connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_FRAME_EXTENTS))) { - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, m_window, - atom(QXcbAtom::_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4); - QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply( - xcb_get_property_reply(xcb_connection(), cookie, NULL)); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, m_window, + atom(QXcbAtom::_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4); if (reply && reply->type == XCB_ATOM_CARDINAL && reply->format == 32 && reply->value_len == 4) { - quint32 *data = (quint32 *)xcb_get_property_value(reply.data()); + quint32 *data = (quint32 *)xcb_get_property_value(reply.get()); // _NET_FRAME_EXTENTS format is left, right, top, bottom m_frameMargins = QMargins(data[0], data[2], data[1], data[3]); m_dirtyFrameMargins = false; @@ -693,9 +691,7 @@ QMargins QXcbWindow::frameMargins() const connection()->wmSupport()->virtualRoots(); while (!foundRoot) { - xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked(xcb_connection(), parent); - - xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, NULL); + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_query_tree, xcb_connection(), parent); if (reply) { if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1 || reply->parent == XCB_WINDOW_NONE) { foundRoot = true; @@ -703,8 +699,6 @@ QMargins QXcbWindow::frameMargins() const window = parent; parent = reply->parent; } - - free(reply); } else { m_dirtyFrameMargins = false; m_frameMargins = QMargins(); @@ -714,23 +708,12 @@ QMargins QXcbWindow::frameMargins() const QPoint offset; - xcb_translate_coordinates_reply_t *reply = - xcb_translate_coordinates_reply( - xcb_connection(), - xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0), - NULL); - + auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), window, parent, 0, 0); if (reply) { offset = QPoint(reply->dst_x, reply->dst_y); - free(reply); } - xcb_get_geometry_reply_t *geom = - xcb_get_geometry_reply( - xcb_connection(), - xcb_get_geometry(xcb_connection(), parent), - NULL); - + auto geom = Q_XCB_REPLY(xcb_get_geometry, xcb_connection(), parent); if (geom) { // -- // add the border_width for the window managers frame... some window managers @@ -747,8 +730,6 @@ QMargins QXcbWindow::frameMargins() const int bottom = geom->height + geom->border_width - geometry().height() - offset.y(); m_frameMargins = QMargins(left, top, right, bottom); - - free(geom); } m_dirtyFrameMargins = false; @@ -775,6 +756,7 @@ static inline bool testShowWithoutActivating(const QWindow *window) void QXcbWindow::show() { if (window()->isTopLevel()) { + xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_wm_hints_t hints; @@ -1002,15 +984,11 @@ static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window) { QtMotifWmHints hints; - xcb_get_property_cookie_t get_cookie = - xcb_get_property_unchecked(c->xcb_connection(), 0, window, c->atom(QXcbAtom::_MOTIF_WM_HINTS), - c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20); - - xcb_get_property_reply_t *reply = - xcb_get_property_reply(c->xcb_connection(), get_cookie, NULL); + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, c->xcb_connection(), 0, window, + c->atom(QXcbAtom::_MOTIF_WM_HINTS), c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20); if (reply && reply->format == 32 && reply->type == c->atom(QXcbAtom::_MOTIF_WM_HINTS)) { - hints = *((QtMotifWmHints *)xcb_get_property_value(reply)); + hints = *((QtMotifWmHints *)xcb_get_property_value(reply.get())); } else { hints.flags = 0L; hints.functions = MWM_FUNC_ALL; @@ -1019,8 +997,6 @@ static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window) hints.status = 0L; } - free(reply); - return hints; } @@ -1044,15 +1020,12 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates() { NetWmStates result(0); - xcb_get_property_cookie_t get_cookie = - xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), - XCB_ATOM_ATOM, 0, 1024); - - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, NULL); + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + 0, m_window, atom(QXcbAtom::_NET_WM_STATE), + XCB_ATOM_ATOM, 0, 1024); if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) { - const xcb_atom_t *states = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply)); + const xcb_atom_t *states = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get())); const xcb_atom_t *statesEnd = states + reply->length; if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_ABOVE))) result |= NetWmStateAbove; @@ -1070,7 +1043,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates() result |= NetWmStateStaysOnTop; if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) result |= NetWmStateDemandsAttention; - free(reply); } else { #ifdef NET_WM_STATE_DEBUG printf("getting net wm state (%x), empty\n", m_window); @@ -1084,21 +1056,15 @@ void QXcbWindow::setNetWmStates(NetWmStates states) { QVector<xcb_atom_t> atoms; - xcb_get_property_cookie_t get_cookie = - xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), - XCB_ATOM_ATOM, 0, 1024); - - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, NULL); - + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + 0, m_window, atom(QXcbAtom::_NET_WM_STATE), + XCB_ATOM_ATOM, 0, 1024); if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { - const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply)); + const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get())); atoms.resize(reply->value_len); memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); } - free(reply); - if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) @@ -1739,15 +1705,11 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const { QXcbWindowFunctions::WmWindowTypes result(0); - xcb_get_property_cookie_t get_cookie = - xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE), - XCB_ATOM_ATOM, 0, 1024); - - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, NULL); - + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + 0, m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE), + XCB_ATOM_ATOM, 0, 1024); if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) { - const xcb_atom_t *types = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply)); + const xcb_atom_t *types = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get())); const xcb_atom_t *types_end = types + reply->length; for (; types != types_end; types++) { QXcbAtom::Atom type = connection()->qatom(*types); @@ -1801,7 +1763,6 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const break; } } - free(reply); } return result; } @@ -2087,13 +2048,11 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QPoint pos(event->x, event->y); if (!parent() && !fromSendEvent) { // Do not trust the position, query it instead. - xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(), - xcbScreen()->root(), 0, 0); - xcb_translate_coordinates_reply_t *reply = xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); + auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), + xcb_window(), xcbScreen()->root(), 0, 0); if (reply) { pos.setX(reply->dst_x); pos.setY(reply->dst_y); - free(reply); } } @@ -2148,15 +2107,12 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const return pos; QPoint ret; - xcb_translate_coordinates_cookie_t cookie = - xcb_translate_coordinates(xcb_connection(), xcb_window(), xcbScreen()->root(), - pos.x(), pos.y()); - xcb_translate_coordinates_reply_t *reply = - xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); + auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), + xcb_window(), xcbScreen()->root(), + pos.x(), pos.y()); if (reply) { ret.setX(reply->dst_x); ret.setY(reply->dst_y); - free(reply); } return ret; @@ -2168,15 +2124,12 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const return pos; QPoint ret; - xcb_translate_coordinates_cookie_t cookie = - xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(), - pos.x(), pos.y()); - xcb_translate_coordinates_reply_t *reply = - xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); + auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), + xcbScreen()->root(), xcb_window(), + pos.x(), pos.y()); if (reply) { ret.setX(reply->dst_x); ret.setY(reply->dst_y); - free(reply); } return ret; @@ -2529,15 +2482,11 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev Qt::WindowState newState = Qt::WindowNoState; if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'. - const xcb_get_property_cookie_t get_cookie = - xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::WM_STATE), - XCB_ATOM_ANY, 0, 1024); - - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, NULL); - + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), + 0, m_window, atom(QXcbAtom::WM_STATE), + XCB_ATOM_ANY, 0, 1024); if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) { - const quint32 *data = (const quint32 *)xcb_get_property_value(reply); + const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get()); if (reply->length != 0) { if (data[0] == XCB_WM_STATE_ICONIC || (data[0] == XCB_WM_STATE_WITHDRAWN @@ -2546,7 +2495,6 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev } } } - free(reply); } else { // _NET_WM_STATE can't change minimized state if (m_lastWindowStateEvent == Qt::WindowMinimized) newState = Qt::WindowMinimized; @@ -2623,13 +2571,11 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME); return true; } - xcb_grab_keyboard_cookie_t cookie = xcb_grab_keyboard(xcb_connection(), false, - m_window, XCB_TIME_CURRENT_TIME, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - xcb_grab_keyboard_reply_t *reply = xcb_grab_keyboard_reply(xcb_connection(), cookie, NULL); - bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS); - free(reply); - return result; + + auto reply = Q_XCB_REPLY(xcb_grab_keyboard, xcb_connection(), false, + m_window, XCB_TIME_CURRENT_TIME, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + return reply && reply->status == XCB_GRAB_STATUS_SUCCESS; } bool QXcbWindow::setMouseGrabEnabled(bool grab) @@ -2651,16 +2597,16 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME); return true; } - xcb_grab_pointer_cookie_t cookie = xcb_grab_pointer(xcb_connection(), false, m_window, - (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE - | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW - | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION), - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, - XCB_WINDOW_NONE, XCB_CURSOR_NONE, - XCB_TIME_CURRENT_TIME); - xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, NULL); - bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS); - free(reply); + + auto reply = Q_XCB_REPLY(xcb_grab_pointer, xcb_connection(), + false, m_window, + (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE + | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW + | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION), + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, + XCB_WINDOW_NONE, XCB_CURSOR_NONE, + XCB_TIME_CURRENT_TIME); + bool result = reply && reply->status == XCB_GRAB_STATUS_SUCCESS; if (result) connection()->setMouseGrabber(this); return result; diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp index 470f021314..05cf4c6c1a 100644 --- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp +++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp @@ -66,16 +66,15 @@ void QXcbWMSupport::updateNetWMAtoms() int offset = 0; int remaining = 0; do { - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024); if (!reply) break; remaining = 0; if (reply->type == XCB_ATOM_ATOM && reply->format == 32) { - int len = xcb_get_property_value_length(reply)/sizeof(xcb_atom_t); - xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply); + int len = xcb_get_property_value_length(reply.get())/sizeof(xcb_atom_t); + xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply.get()); int s = net_wm_atoms.size(); net_wm_atoms.resize(s + len); memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t)); @@ -83,8 +82,6 @@ void QXcbWMSupport::updateNetWMAtoms() remaining = reply->bytes_after; offset += len; } - - free(reply); } while (remaining > 0); } @@ -100,16 +97,16 @@ 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_WINDOW, offset, 1024); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, NULL); + auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), + false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, offset, 1024); if (!reply) break; remaining = 0; 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 len = xcb_get_property_value_length(reply.get())/sizeof(xcb_window_t); + xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(reply.get()); int s = net_virtual_roots.size(); net_virtual_roots.resize(s + len); memcpy(net_virtual_roots.data() + s, roots, len*sizeof(xcb_window_t)); @@ -118,7 +115,6 @@ void QXcbWMSupport::updateVirtualRoots() offset += len; } - free(reply); } while (remaining > 0); #ifdef Q_XCB_DEBUG diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp index 401eb8043c..bd398ea049 100644 --- a/src/plugins/platforms/xcb/qxcbxsettings.cpp +++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp @@ -45,10 +45,6 @@ #include <vector> #include <algorithm> -#ifdef XCB_USE_XLIB -#include <X11/extensions/XIproto.h> -#endif //XCB_USE_XLIB - QT_BEGIN_NAMESPACE /* Implementation of http://standards.freedesktop.org/xsettings-spec/xsettings-0.5.html */ @@ -110,26 +106,23 @@ public: QByteArray settings; xcb_atom_t _xsettings_atom = screen->connection()->atom(QXcbAtom::_XSETTINGS_SETTINGS); while (1) { - xcb_get_property_cookie_t get_prop_cookie = - xcb_get_property_unchecked(screen->xcb_connection(), + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, + screen->xcb_connection(), false, x_settings_window, _xsettings_atom, _xsettings_atom, offset/4, 8192); - xcb_get_property_reply_t *reply = xcb_get_property_reply(screen->xcb_connection(), get_prop_cookie, NULL); bool more = false; if (!reply) return settings; - const auto property_value_length = xcb_get_property_value_length(reply); - settings.append(static_cast<const char *>(xcb_get_property_value(reply)), property_value_length); + const auto property_value_length = xcb_get_property_value_length(reply.get()); + settings.append(static_cast<const char *>(xcb_get_property_value(reply.get())), property_value_length); offset += property_value_length; more = reply->bytes_after != 0; - free(reply); - if (!more) break; } @@ -145,19 +138,18 @@ public: return value + 4 - remainder; } -#ifdef XCB_USE_XLIB void populateSettings(const QByteArray &xSettings) { if (xSettings.length() < 12) return; char byteOrder = xSettings.at(0); - if (byteOrder != LSBFirst && byteOrder != MSBFirst) { + if (byteOrder != XCB_IMAGE_ORDER_LSB_FIRST && byteOrder != XCB_IMAGE_ORDER_MSB_FIRST) { qWarning("ByteOrder byte %d not 0 or 1", byteOrder); return; } #define ADJUST_BO(b, t, x) \ - ((b == LSBFirst) ? \ + ((b == XCB_IMAGE_ORDER_LSB_FIRST) ? \ qFromLittleEndian<t>(x) : \ qFromBigEndian<t>(x)) #define VALIDATE_LENGTH(x) \ @@ -220,7 +212,6 @@ public: } } -#endif //XCB_USE_XLIB QXcbVirtualDesktop *screen; xcb_window_t x_settings_window; @@ -234,43 +225,31 @@ QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen) { QByteArray settings_atom_for_screen("_XSETTINGS_S"); settings_atom_for_screen.append(QByteArray::number(screen->number())); - xcb_intern_atom_cookie_t atom_cookie = xcb_intern_atom(screen->xcb_connection(), - true, - settings_atom_for_screen.length(), - settings_atom_for_screen.constData()); - xcb_generic_error_t *error = 0; - xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(screen->xcb_connection(),atom_cookie,&error); - if (error) { - free(error); + auto atom_reply = Q_XCB_REPLY(xcb_intern_atom, + screen->xcb_connection(), + true, + settings_atom_for_screen.length(), + settings_atom_for_screen.constData()); + if (!atom_reply) return; - } - xcb_atom_t selection_owner_atom = atom_reply->atom; - free(atom_reply); - xcb_get_selection_owner_cookie_t selection_cookie = - xcb_get_selection_owner(screen->xcb_connection(), selection_owner_atom); + xcb_atom_t selection_owner_atom = atom_reply->atom; - xcb_get_selection_owner_reply_t *selection_result = - xcb_get_selection_owner_reply(screen->xcb_connection(), selection_cookie, &error); - if (error) { - free(error); + auto selection_result = Q_XCB_REPLY(xcb_get_selection_owner, + screen->xcb_connection(), selection_owner_atom); + if (!selection_result) return; - } d_ptr->x_settings_window = selection_result->owner; - free(selection_result); - if (!d_ptr->x_settings_window) { + if (!d_ptr->x_settings_window) return; - } const uint32_t event = XCB_CW_EVENT_MASK; const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE }; xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask); -#ifdef XCB_USE_XLIB d_ptr->populateSettings(d_ptr->getSettings()); d_ptr->initialized = true; -#endif //XCB_USE_XLIB } QXcbXSettings::~QXcbXSettings() @@ -290,9 +269,8 @@ void QXcbXSettings::handlePropertyNotifyEvent(const xcb_property_notify_event_t Q_D(QXcbXSettings); if (event->window != d->x_settings_window) return; -#ifdef XCB_USE_XLIB + d->populateSettings(d->getSettings()); -#endif //XCB_USE_XLIB } void QXcbXSettings::registerCallbackForProperty(const QByteArray &property, QXcbXSettings::PropertyChangeFunc func, void *handle) diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index 1cb0f10494..56eceeecbd 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -51,6 +51,10 @@ #include <qstringlist.h> #include <qvector.h> #include <qdebug.h> +#ifndef QT_NO_REGULAREXPRESSION +#include <qcache.h> +#include <qregularexpression.h> +#endif #if defined Q_OS_WIN # include <qt_windows.h> @@ -556,6 +560,37 @@ QVariant QSQLiteResult::handle() const ///////////////////////////////////////////////////////// +#ifndef QT_NO_REGULAREXPRESSION +static void _q_regexp(sqlite3_context* context, int argc, sqlite3_value** argv) +{ + if (Q_UNLIKELY(argc != 2)) { + sqlite3_result_int(context, 0); + return; + } + + const QString pattern = QString::fromUtf8( + reinterpret_cast<const char*>(sqlite3_value_text(argv[0]))); + const QString subject = QString::fromUtf8( + reinterpret_cast<const char*>(sqlite3_value_text(argv[1]))); + + auto cache = static_cast<QCache<QString, QRegularExpression>*>(sqlite3_user_data(context)); + QRegularExpression *regexp = cache->object(pattern); + if (!regexp) { + regexp = new QRegularExpression(pattern, QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + cache->insert(pattern, regexp); + } + const bool found = subject.contains(*regexp); + + sqlite3_result_int(context, int(found)); +} + +static void _q_regexp_cleanup(void *cache) +{ + delete static_cast<QCache<QString, QRegularExpression>*>(cache); +} +#endif + QSQLiteDriver::QSQLiteDriver(QObject * parent) : QSqlDriver(*new QSQLiteDriverPrivate, parent) { @@ -615,6 +650,11 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c bool sharedCache = false; bool openReadOnlyOption = false; bool openUriOption = false; +#ifndef QT_NO_REGULAREXPRESSION + static const QLatin1String regexpConnectOption = QLatin1String("QSQLITE_ENABLE_REGEXP"); + bool defineRegexp = false; + int regexpCacheSize = 25; +#endif const auto opts = conOpts.splitRef(QLatin1Char(';')); for (auto option : opts) { @@ -634,6 +674,22 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c } else if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE")) { sharedCache = true; } +#ifndef QT_NO_REGULAREXPRESSION + else if (option.startsWith(regexpConnectOption)) { + option = option.mid(regexpConnectOption.size()).trimmed(); + if (option.isEmpty()) { + defineRegexp = true; + } else if (option.startsWith(QLatin1Char('='))) { + bool ok = false; + const int cacheSize = option.mid(1).trimmed().toInt(&ok); + if (ok) { + defineRegexp = true; + if (cacheSize > 0) + regexpCacheSize = cacheSize; + } + } + } +#endif } int openMode = (openReadOnlyOption ? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)); @@ -646,6 +702,13 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c sqlite3_busy_timeout(d->access, timeOut); setOpen(true); setOpenError(false); +#ifndef QT_NO_REGULAREXPRESSION + if (defineRegexp) { + auto cache = new QCache<QString, QRegularExpression>(regexpCacheSize); + sqlite3_create_function_v2(d->access, "regexp", 2, SQLITE_UTF8, cache, &_q_regexp, NULL, + NULL, &_q_regexp_cleanup); + } +#endif return true; } else { if (d->access) { |