QEvdev: Replace manual memory management with unique_ptr
Make create() return, and m_mice/m_keyboards/etc store, handlers by unique_ptr.
In most cases, we can't use qt_make_unique(), since the ctor we're calling is
marked as private.
Since QHash can't hold move-only types, use a std::vector<{QString, unique_ptr}>
instead. As this pattern repeats in all four QEvdev*Manager classes, create a
small class template.
Saves almost 6KiB on optimized Linux AMD64 GCC 9.1 builds across all .so's that
link to QtInputSupport.a.
Change-Id: I8f62b6b629d6e1855314c0a4fb4fc069db9ae0ce
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
parent
12938ba70b
commit
3bc10fb9bb
|
|
@ -98,7 +98,7 @@ QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
|
|||
unloadKeymap();
|
||||
}
|
||||
|
||||
QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
|
||||
std::unique_ptr<QEvdevKeyboardHandler> QEvdevKeyboardHandler::create(const QString &device,
|
||||
const QString &specification,
|
||||
const QString &defaultKeymapFile)
|
||||
{
|
||||
|
|
@ -138,10 +138,10 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
|
|||
::ioctl(fd.get(), EVIOCSREP, kbdrep);
|
||||
}
|
||||
|
||||
return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile);
|
||||
return std::unique_ptr<QEvdevKeyboardHandler>(new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile));
|
||||
} else {
|
||||
qErrnoWarning("Cannot open keyboard input device '%ls'", qUtf16Printable(device));
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
#include <QTimer>
|
||||
#include <QDataStream>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSocketNotifier;
|
||||
|
|
@ -168,7 +170,7 @@ public:
|
|||
SwitchConsoleMask = 0x0000007f
|
||||
};
|
||||
|
||||
static QEvdevKeyboardHandler *create(const QString &device,
|
||||
static std::unique_ptr<QEvdevKeyboardHandler> create(const QString &device,
|
||||
const QString &specification,
|
||||
const QString &defaultKeymapFile = QString());
|
||||
|
||||
|
|
|
|||
|
|
@ -98,17 +98,14 @@ QEvdevKeyboardManager::QEvdevKeyboardManager(const QString &key, const QString &
|
|||
|
||||
QEvdevKeyboardManager::~QEvdevKeyboardManager()
|
||||
{
|
||||
qDeleteAll(m_keyboards);
|
||||
m_keyboards.clear();
|
||||
}
|
||||
|
||||
void QEvdevKeyboardManager::addKeyboard(const QString &deviceNode)
|
||||
{
|
||||
qCDebug(qLcEvdevKey, "Adding keyboard at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevKeyboardHandler *keyboard;
|
||||
keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec, m_defaultKeymapFile);
|
||||
auto keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec, m_defaultKeymapFile);
|
||||
if (keyboard) {
|
||||
m_keyboards.insert(deviceNode, keyboard);
|
||||
m_keyboards.add(deviceNode, std::move(keyboard));
|
||||
updateDeviceCount();
|
||||
} else {
|
||||
qWarning("Failed to open keyboard device %ls", qUtf16Printable(deviceNode));
|
||||
|
|
@ -117,12 +114,9 @@ void QEvdevKeyboardManager::addKeyboard(const QString &deviceNode)
|
|||
|
||||
void QEvdevKeyboardManager::removeKeyboard(const QString &deviceNode)
|
||||
{
|
||||
if (m_keyboards.contains(deviceNode)) {
|
||||
if (m_keyboards.remove(deviceNode)) {
|
||||
qCDebug(qLcEvdevKey, "Removing keyboard at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevKeyboardHandler *keyboard = m_keyboards.value(deviceNode);
|
||||
m_keyboards.remove(deviceNode);
|
||||
updateDeviceCount();
|
||||
delete keyboard;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,22 +139,22 @@ void QEvdevKeyboardManager::loadKeymap(const QString &file)
|
|||
if (arg.startsWith(QLatin1String("keymap=")))
|
||||
keymapFromSpec = arg.mid(7).toString();
|
||||
}
|
||||
foreach (QEvdevKeyboardHandler *handler, m_keyboards) {
|
||||
for (const auto &keyboard : m_keyboards) {
|
||||
if (keymapFromSpec.isEmpty())
|
||||
handler->unloadKeymap();
|
||||
keyboard.handler->unloadKeymap();
|
||||
else
|
||||
handler->loadKeymap(keymapFromSpec);
|
||||
keyboard.handler->loadKeymap(keymapFromSpec);
|
||||
}
|
||||
} else {
|
||||
foreach (QEvdevKeyboardHandler *handler, m_keyboards)
|
||||
handler->loadKeymap(file);
|
||||
for (const auto &keyboard : m_keyboards)
|
||||
keyboard.handler->loadKeymap(file);
|
||||
}
|
||||
}
|
||||
|
||||
void QEvdevKeyboardManager::switchLang()
|
||||
{
|
||||
foreach (QEvdevKeyboardHandler *handler, m_keyboards)
|
||||
handler->switchLang();
|
||||
for (const auto &keyboard : m_keyboards)
|
||||
keyboard.handler->switchLang();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
|
||||
#include "qevdevkeyboardhandler_p.h"
|
||||
|
||||
#include <QtInputSupport/private/devicehandlerlist_p.h>
|
||||
#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h>
|
||||
|
||||
#include <QObject>
|
||||
|
|
@ -77,7 +78,7 @@ private:
|
|||
void updateDeviceCount();
|
||||
|
||||
QString m_spec;
|
||||
QHash<QString,QEvdevKeyboardHandler*> m_keyboards;
|
||||
QtInputSupport::DeviceHandlerList<QEvdevKeyboardHandler> m_keyboards;
|
||||
QDeviceDiscovery *m_deviceDiscovery;
|
||||
QString m_defaultKeymapFile;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
Q_LOGGING_CATEGORY(qLcEvdevMouse, "qt.qpa.input")
|
||||
|
||||
QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QString &specification)
|
||||
std::unique_ptr<QEvdevMouseHandler> QEvdevMouseHandler::create(const QString &device, const QString &specification)
|
||||
{
|
||||
qCDebug(qLcEvdevMouse) << "create mouse handler for" << device << specification;
|
||||
|
||||
|
|
@ -91,10 +91,10 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr
|
|||
fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
|
||||
if (fd >= 0) {
|
||||
::ioctl(fd, EVIOCGRAB, grab);
|
||||
return new QEvdevMouseHandler(device, fd, abs, compression, jitterLimit);
|
||||
return std::unique_ptr<QEvdevMouseHandler>(new QEvdevMouseHandler(device, fd, abs, compression, jitterLimit));
|
||||
} else {
|
||||
qErrnoWarning(errno, "Cannot open mouse input device %s", qPrintable(device));
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@
|
|||
#include <QPoint>
|
||||
#include <QEvent>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSocketNotifier;
|
||||
|
|
@ -64,7 +66,7 @@ class QEvdevMouseHandler : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static QEvdevMouseHandler *create(const QString &device, const QString &specification);
|
||||
static std::unique_ptr<QEvdevMouseHandler> create(const QString &device, const QString &specification);
|
||||
~QEvdevMouseHandler();
|
||||
|
||||
void readMouseData();
|
||||
|
|
|
|||
|
|
@ -111,8 +111,6 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif
|
|||
|
||||
QEvdevMouseManager::~QEvdevMouseManager()
|
||||
{
|
||||
qDeleteAll(m_mice);
|
||||
m_mice.clear();
|
||||
}
|
||||
|
||||
void QEvdevMouseManager::clampPosition()
|
||||
|
|
@ -160,13 +158,13 @@ void QEvdevMouseManager::handleWheelEvent(QPoint delta)
|
|||
void QEvdevMouseManager::addMouse(const QString &deviceNode)
|
||||
{
|
||||
qCDebug(qLcEvdevMouse, "Adding mouse at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevMouseHandler *handler = QEvdevMouseHandler::create(deviceNode, m_spec);
|
||||
auto handler = QEvdevMouseHandler::create(deviceNode, m_spec);
|
||||
if (handler) {
|
||||
connect(handler, &QEvdevMouseHandler::handleMouseEvent,
|
||||
connect(handler.get(), &QEvdevMouseHandler::handleMouseEvent,
|
||||
this, &QEvdevMouseManager::handleMouseEvent);
|
||||
connect(handler, &QEvdevMouseHandler::handleWheelEvent,
|
||||
connect(handler.get(), &QEvdevMouseHandler::handleWheelEvent,
|
||||
this, &QEvdevMouseManager::handleWheelEvent);
|
||||
m_mice.insert(deviceNode, handler);
|
||||
m_mice.add(deviceNode, std::move(handler));
|
||||
updateDeviceCount();
|
||||
} else {
|
||||
qWarning("evdevmouse: Failed to open mouse device %ls", qUtf16Printable(deviceNode));
|
||||
|
|
@ -175,12 +173,9 @@ void QEvdevMouseManager::addMouse(const QString &deviceNode)
|
|||
|
||||
void QEvdevMouseManager::removeMouse(const QString &deviceNode)
|
||||
{
|
||||
if (m_mice.contains(deviceNode)) {
|
||||
if (m_mice.remove(deviceNode)) {
|
||||
qCDebug(qLcEvdevMouse, "Removing mouse at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevMouseHandler *handler = m_mice.value(deviceNode);
|
||||
m_mice.remove(deviceNode);
|
||||
updateDeviceCount();
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
|
||||
#include "qevdevmousehandler_p.h"
|
||||
|
||||
#include <QtInputSupport/private/devicehandlerlist_p.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QSocketNotifier>
|
||||
|
|
@ -80,7 +82,7 @@ private:
|
|||
void updateDeviceCount();
|
||||
|
||||
QString m_spec;
|
||||
QHash<QString,QEvdevMouseHandler*> m_mice;
|
||||
QtInputSupport::DeviceHandlerList<QEvdevMouseHandler> m_mice;
|
||||
QDeviceDiscovery *m_deviceDiscovery;
|
||||
int m_x;
|
||||
int m_y;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <private/qinputdevicemanager_p_p.h>
|
||||
#include <private/qmemory_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -99,16 +100,14 @@ QEvdevTabletManager::QEvdevTabletManager(const QString &key, const QString &spec
|
|||
|
||||
QEvdevTabletManager::~QEvdevTabletManager()
|
||||
{
|
||||
qDeleteAll(m_activeDevices);
|
||||
}
|
||||
|
||||
void QEvdevTabletManager::addDevice(const QString &deviceNode)
|
||||
{
|
||||
qCDebug(qLcEvdevTablet, "Adding device at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevTabletHandlerThread *handler;
|
||||
handler = new QEvdevTabletHandlerThread(deviceNode, m_spec);
|
||||
auto handler = qt_make_unique<QEvdevTabletHandlerThread>(deviceNode, m_spec);
|
||||
if (handler) {
|
||||
m_activeDevices.insert(deviceNode, handler);
|
||||
m_activeDevices.add(deviceNode, std::move(handler));
|
||||
updateDeviceCount();
|
||||
} else {
|
||||
qWarning("evdevtablet: Failed to open tablet device %ls", qUtf16Printable(deviceNode));
|
||||
|
|
@ -117,12 +116,9 @@ void QEvdevTabletManager::addDevice(const QString &deviceNode)
|
|||
|
||||
void QEvdevTabletManager::removeDevice(const QString &deviceNode)
|
||||
{
|
||||
if (m_activeDevices.contains(deviceNode)) {
|
||||
if (m_activeDevices.remove(deviceNode)) {
|
||||
qCDebug(qLcEvdevTablet, "Removing device at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevTabletHandlerThread *handler = m_activeDevices.value(deviceNode);
|
||||
m_activeDevices.remove(deviceNode);
|
||||
updateDeviceCount();
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtInputSupport/private/devicehandlerlist_p.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QSocketNotifier>
|
||||
|
|
@ -74,7 +76,7 @@ private:
|
|||
|
||||
QString m_spec;
|
||||
QDeviceDiscovery *m_deviceDiscovery;
|
||||
QHash<QString, QEvdevTabletHandlerThread *> m_activeDevices;
|
||||
QtInputSupport::DeviceHandlerList<QEvdevTabletHandlerThread> m_activeDevices;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <private/qinputdevicemanager_p_p.h>
|
||||
#include <private/qmemory_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -99,17 +100,15 @@ QEvdevTouchManager::QEvdevTouchManager(const QString &key, const QString &specif
|
|||
|
||||
QEvdevTouchManager::~QEvdevTouchManager()
|
||||
{
|
||||
qDeleteAll(m_activeDevices);
|
||||
}
|
||||
|
||||
void QEvdevTouchManager::addDevice(const QString &deviceNode)
|
||||
{
|
||||
qCDebug(qLcEvdevTouch, "evdevtouch: Adding device at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevTouchScreenHandlerThread *handler;
|
||||
handler = new QEvdevTouchScreenHandlerThread(deviceNode, m_spec);
|
||||
auto handler = qt_make_unique<QEvdevTouchScreenHandlerThread>(deviceNode, m_spec);
|
||||
if (handler) {
|
||||
m_activeDevices.insert(deviceNode, handler);
|
||||
connect(handler, &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount);
|
||||
m_activeDevices.add(deviceNode, std::move(handler));
|
||||
connect(handler.get(), &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount);
|
||||
} else {
|
||||
qWarning("evdevtouch: Failed to open touch device %ls", qUtf16Printable(deviceNode));
|
||||
}
|
||||
|
|
@ -117,12 +116,8 @@ void QEvdevTouchManager::addDevice(const QString &deviceNode)
|
|||
|
||||
void QEvdevTouchManager::removeDevice(const QString &deviceNode)
|
||||
{
|
||||
if (m_activeDevices.contains(deviceNode)) {
|
||||
if (m_activeDevices.remove(deviceNode)) {
|
||||
qCDebug(qLcEvdevTouch, "evdevtouch: Removing device at %ls", qUtf16Printable(deviceNode));
|
||||
QEvdevTouchScreenHandlerThread *handler = m_activeDevices.value(deviceNode);
|
||||
m_activeDevices.remove(deviceNode);
|
||||
delete handler;
|
||||
|
||||
updateInputDeviceCount();
|
||||
}
|
||||
}
|
||||
|
|
@ -130,8 +125,8 @@ void QEvdevTouchManager::removeDevice(const QString &deviceNode)
|
|||
void QEvdevTouchManager::updateInputDeviceCount()
|
||||
{
|
||||
int registeredTouchDevices = 0;
|
||||
Q_FOREACH (QEvdevTouchScreenHandlerThread *handler, m_activeDevices) {
|
||||
if (handler->isTouchDeviceRegistered())
|
||||
for (const auto &device : m_activeDevices) {
|
||||
if (device.handler->isTouchDeviceRegistered())
|
||||
++registeredTouchDevices;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtInputSupport/private/devicehandlerlist_p.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QSocketNotifier>
|
||||
|
|
@ -74,7 +76,7 @@ public:
|
|||
private:
|
||||
QString m_spec;
|
||||
QDeviceDiscovery *m_deviceDiscovery;
|
||||
QHash<QString, QEvdevTouchScreenHandlerThread *> m_activeDevices;
|
||||
QtInputSupport::DeviceHandlerList<QEvdevTouchScreenHandlerThread> m_activeDevices;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and 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 QTINPUTSUPPORT_DEVICEHANDLERLIST_P_H
|
||||
#define QTINPUTSUPPORT_DEVICEHANDLERLIST_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace QtInputSupport {
|
||||
|
||||
template <typename Handler>
|
||||
class DeviceHandlerList {
|
||||
public:
|
||||
struct Device {
|
||||
QString deviceNode;
|
||||
std::unique_ptr<Handler> handler;
|
||||
};
|
||||
|
||||
void add(const QString &deviceNode, std::unique_ptr<Handler> handler)
|
||||
{
|
||||
v.push_back({deviceNode, std::move(handler)});
|
||||
}
|
||||
|
||||
bool remove(const QString &deviceNode)
|
||||
{
|
||||
const auto deviceNodeMatches = [&] (const Device &d) { return d.deviceNode == deviceNode; };
|
||||
const auto it = std::find_if(v.cbegin(), v.cend(), deviceNodeMatches);
|
||||
if (it == v.cend())
|
||||
return false;
|
||||
v.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
int count() const noexcept { return static_cast<int>(v.size()); }
|
||||
|
||||
typename std::vector<Device>::const_iterator begin() const noexcept { return v.begin(); }
|
||||
typename std::vector<Device>::const_iterator end() const noexcept { return v.end(); }
|
||||
|
||||
private:
|
||||
std::vector<Device> v;
|
||||
};
|
||||
|
||||
} // QtInputSupport
|
||||
|
||||
#endif // QTINPUTSUPPORT_DEVICEHANDLERLIST_P_H
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
HEADERS += \
|
||||
$$PWD/devicehandlerlist_p.h \
|
||||
$$PWD/qtouchoutputmapping_p.h
|
||||
|
||||
SOURCES += \
|
||||
|
|
|
|||
Loading…
Reference in New Issue