diff options
Diffstat (limited to 'src/platformsupport/fbconvenience')
-rw-r--r-- | src/platformsupport/fbconvenience/qfbbackingstore.cpp | 16 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbbackingstore_p.h | 20 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbcursor.cpp | 87 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbcursor_p.h | 45 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbscreen.cpp | 31 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbscreen_p.h | 23 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbvthandler.cpp | 174 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbvthandler_p.h | 33 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbwindow.cpp | 14 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbwindow_p.h | 14 |
10 files changed, 332 insertions, 125 deletions
diff --git a/src/platformsupport/fbconvenience/qfbbackingstore.cpp b/src/platformsupport/fbconvenience/qfbbackingstore.cpp index 733235ff42..2800a81507 100644 --- a/src/platformsupport/fbconvenience/qfbbackingstore.cpp +++ b/src/platformsupport/fbconvenience/qfbbackingstore.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -46,7 +46,7 @@ QFbBackingStore::QFbBackingStore(QWindow *window) if (window->handle()) (static_cast<QFbWindow *>(window->handle()))->setBackingStore(this); else - (static_cast<QFbScreen *>(window->screen()->handle()))->addBackingStore(this); + (static_cast<QFbScreen *>(window->screen()->handle()))->addPendingBackingStore(this); } QFbBackingStore::~QFbBackingStore() diff --git a/src/platformsupport/fbconvenience/qfbbackingstore_p.h b/src/platformsupport/fbconvenience/qfbbackingstore_p.h index a9917e1450..c725cbc6d7 100644 --- a/src/platformsupport/fbconvenience/qfbbackingstore_p.h +++ b/src/platformsupport/fbconvenience/qfbbackingstore_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -60,10 +60,10 @@ public: QFbBackingStore(QWindow *window); ~QFbBackingStore(); - virtual QPaintDevice *paintDevice() { return &mImage; } - virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + virtual QPaintDevice *paintDevice() Q_DECL_OVERRIDE { return &mImage; } + virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - virtual void resize(const QSize &size, const QRegion ®ion); + virtual void resize(const QSize &size, const QRegion ®ion) Q_DECL_OVERRIDE; const QImage image(); diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp index 49bc88d854..c727d67e72 100644 --- a/src/platformsupport/fbconvenience/qfbcursor.cpp +++ b/src/platformsupport/fbconvenience/qfbcursor.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -34,40 +34,88 @@ #include "qfbcursor_p.h" #include "qfbscreen_p.h" #include <QtGui/QPainter> +#include <QtGui/private/qguiapplication_p.h> QT_BEGIN_NAMESPACE +bool QFbCursorDeviceListener::hasMouse() const +{ + return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; +} + +void QFbCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +{ + if (type == QInputDeviceManager::DeviceTypePointer) + m_cursor->updateMouseStatus(); +} + QFbCursor::QFbCursor(QFbScreen *screen) - : mScreen(screen), mDirty(false), mOnScreen(false) + : mVisible(true), + mScreen(screen), + mDirty(false), + mOnScreen(false), + mGraphic(0), + mDeviceListener(0) { + QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR"); + if (!hideCursorVal.isEmpty()) + mVisible = hideCursorVal.toInt() == 0; + if (!mVisible) + return; + mGraphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); setCursor(Qt::ArrowCursor); + + mDeviceListener = new QFbCursorDeviceListener(this); + connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, + mDeviceListener, &QFbCursorDeviceListener::onDeviceListChanged); + updateMouseStatus(); +} + +QFbCursor::~QFbCursor() +{ + delete mDeviceListener; } QRect QFbCursor::getCurrentRect() { QRect rect = mGraphic->image()->rect().translated(-mGraphic->hotspot().x(), -mGraphic->hotspot().y()); - rect.translate(QCursor::pos()); + rect.translate(m_pos); QPoint mScreenOffset = mScreen->geometry().topLeft(); rect.translate(-mScreenOffset); // global to local translation return rect; } +QPoint QFbCursor::pos() const +{ + return m_pos; +} -void QFbCursor::pointerEvent(const QMouseEvent & e) +void QFbCursor::setPos(const QPoint &pos) { - Q_UNUSED(e); - QPoint mScreenOffset = mScreen->geometry().topLeft(); + QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); + m_pos = pos; mCurrentRect = getCurrentRect(); - // global to local translation - if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreenOffset))) { + if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreen->geometry().topLeft()))) + setDirty(); +} + +void QFbCursor::pointerEvent(const QMouseEvent &e) +{ + if (e.type() != QEvent::MouseMove) + return; + m_pos = e.screenPos().toPoint(); + mCurrentRect = getCurrentRect(); + if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreen->geometry().topLeft()))) setDirty(); - } } QRect QFbCursor::drawCursor(QPainter & painter) { + if (!mVisible) + return QRect(); + mDirty = false; if (mCurrentRect.isNull()) return QRect(); @@ -131,10 +179,19 @@ void QFbCursor::changeCursor(QCursor * widgetCursor, QWindow *window) void QFbCursor::setDirty() { + if (!mVisible) + return; + if (!mDirty) { mDirty = true; mScreen->scheduleUpdate(); } } +void QFbCursor::updateMouseStatus() +{ + mVisible = mDeviceListener->hasMouse(); + mScreen->setDirty(mVisible ? getCurrentRect() : lastPainted()); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h index 0354989a8b..9c5506b455 100644 --- a/src/platformsupport/fbconvenience/qfbcursor_p.h +++ b/src/platformsupport/fbconvenience/qfbcursor_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -46,24 +46,46 @@ // #include <qpa/qplatformcursor.h> +#include <QtGui/private/qinputdevicemanager_p.h> QT_BEGIN_NAMESPACE class QFbScreen; +class QFbCursor; + +class QFbCursorDeviceListener : public QObject +{ + Q_OBJECT + +public: + QFbCursorDeviceListener(QFbCursor *cursor) : m_cursor(cursor) { } + bool hasMouse() const; + +public slots: + void onDeviceListChanged(QInputDeviceManager::DeviceType type); + +private: + QFbCursor *m_cursor; +}; class QFbCursor : public QPlatformCursor { + Q_OBJECT + public: QFbCursor(QFbScreen *screen); + ~QFbCursor(); // output methods QRect dirtyRect(); virtual QRect drawCursor(QPainter &painter); // input methods - virtual void pointerEvent(const QMouseEvent &event); + void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; + QPoint pos() const Q_DECL_OVERRIDE; + void setPos(const QPoint &pos) Q_DECL_OVERRIDE; #ifndef QT_NO_CURSOR - virtual void changeCursor(QCursor *widgetCursor, QWindow *window); + void changeCursor(QCursor *widgetCursor, QWindow *window) Q_DECL_OVERRIDE; #endif virtual void setDirty(); @@ -71,18 +93,23 @@ public: virtual bool isOnScreen() const { return mOnScreen; } virtual QRect lastPainted() const { return mPrevRect; } + void updateMouseStatus(); + private: void setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY); void setCursor(Qt::CursorShape shape); void setCursor(const QImage &image, int hotx, int hoty); QRect getCurrentRect(); + bool mVisible; QFbScreen *mScreen; QRect mCurrentRect; // next place to draw the cursor QRect mPrevRect; // last place the cursor was drawn bool mDirty; bool mOnScreen; QPlatformCursorImage *mGraphic; + QFbCursorDeviceListener *mDeviceListener; + QPoint m_pos; }; QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index 13341344d8..566f84c9ea 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -74,15 +74,15 @@ bool QFbScreen::event(QEvent *event) void QFbScreen::addWindow(QFbWindow *window) { mWindowStack.prepend(window); - if (!mBackingStores.isEmpty()) { + if (!mPendingBackingStores.isEmpty()) { //check if we have a backing store for this window - for (int i = 0; i < mBackingStores.size(); ++i) { - QFbBackingStore *bs = mBackingStores.at(i); + for (int i = 0; i < mPendingBackingStores.size(); ++i) { + QFbBackingStore *bs = mPendingBackingStores.at(i); // this gets called during QWindow::create() at a point where the // invariant (window->handle()->window() == window) is broken if (bs->window() == window->window()) { window->setBackingStore(bs); - mBackingStores.removeAt(i); + mPendingBackingStores.removeAt(i); break; } } @@ -295,5 +295,14 @@ QRegion QFbScreen::doRedraw() return touchedRegion; } +QFbWindow *QFbScreen::windowForId(WId wid) const +{ + for (int i = 0; i < mWindowStack.count(); ++i) + if (mWindowStack[i]->winId() == wid) + return mWindowStack[i]; + + return 0; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h index 55aacab9bc..17b2cab43d 100644 --- a/src/platformsupport/fbconvenience/qfbscreen_p.h +++ b/src/platformsupport/fbconvenience/qfbscreen_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -80,7 +80,7 @@ public: virtual void lower(QFbWindow *window); virtual void topWindowChanged(QWindow *) {} - void addBackingStore(QFbBackingStore *bs) {mBackingStores << bs;} + void addPendingBackingStore(QFbBackingStore *bs) { mPendingBackingStores << bs; } void scheduleUpdate(); @@ -89,13 +89,14 @@ public slots: void setPhysicalSize(const QSize &size); void setGeometry(const QRect &rect); -protected slots: +protected: virtual QRegion doRedraw(); -protected: void initializeCompositor(); bool event(QEvent *event); + QFbWindow *windowForId(WId wid) const; + QList<QFbWindow *> mWindowStack; QRegion mRepaintRegion; bool mUpdatePending; @@ -113,7 +114,7 @@ private: QPainter *mCompositePainter; QVector<QPair<QRect, int> > mCachedRects; - QList <QFbBackingStore*> mBackingStores; + QList<QFbBackingStore*> mPendingBackingStores; friend class QFbWindow; bool mIsUpToDate; diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp index 511f723dd9..c46e470c34 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler.cpp +++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -32,72 +32,172 @@ ****************************************************************************/ #include "qfbvthandler_p.h" -#include <QtCore/private/qcrashhandler_p.h> -#include <QtGui/private/qguiapplication_p.h> +#include <QtCore/QSocketNotifier> -#if defined(Q_OS_LINUX) && !defined(QT_NO_EVDEV) -#define HAS_VT -#endif +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && (!defined(QT_NO_EVDEV) || !defined(QT_NO_LIBINPUT)) -#ifdef HAS_VT +#define VTH_ENABLED +#include <private/qcore_unix_p.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/signalfd.h> #include <sys/ioctl.h> #include <linux/kd.h> +#ifndef KDSKBMUTE +#define KDSKBMUTE 0x4B51 +#endif + #ifdef K_OFF #define KBD_OFF_MODE K_OFF #else #define KBD_OFF_MODE K_RAW #endif -#endif // HAS_VT +#endif QT_BEGIN_NAMESPACE -QFbVtHandler *QFbVtHandler::self = 0; +#ifdef VTH_ENABLED +static void setTTYCursor(bool enable) +{ + const char * const devs[] = { "/dev/tty0", "/dev/tty", "/dev/console", 0 }; + int fd = -1; + for (const char * const *dev = devs; *dev; ++dev) { + fd = QT_OPEN(*dev, O_RDWR); + if (fd != -1) { + // Enable/disable screen blanking and the blinking cursor. + const char *termctl = enable ? "\033[9;15]\033[?33h\033[?25h\033[?0c" : "\033[9;0]\033[?33l\033[?25l\033[?1c"; + QT_WRITE(fd, termctl, strlen(termctl) + 1); + QT_CLOSE(fd); + return; + } + } +} +#endif QFbVtHandler::QFbVtHandler(QObject *parent) - : QObject(parent), m_tty(-1) + : QObject(parent), + m_tty(-1), + m_signalFd(-1), + m_signalNotifier(0) { - Q_ASSERT(!self); - self = this; +#ifdef VTH_ENABLED + setTTYCursor(false); + + if (isatty(0)) { + m_tty = 0; + ioctl(m_tty, KDGKBMODE, &m_oldKbdMode); + + if (!qEnvironmentVariableIntValue("QT_QPA_ENABLE_TERMINAL_KEYBOARD")) { + // Disable the tty keyboard. + ioctl(m_tty, KDSKBMUTE, 1); + ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE); + } + } -#ifdef HAS_VT - if (!isatty(0)) - return; + // SIGSEGV and such cannot safely be blocked. We cannot handle them in an + // async-safe manner either. Restoring the keyboard, video mode, etc. may + // all contain calls that cannot safely be made from a signal handler. + + // Other signals: block them and use signalfd. + sigset_t mask; + sigemptyset(&mask); + + // Catch Ctrl+C. + sigaddset(&mask, SIGINT); + + // Ctrl+Z. Up to the platform plugins to handle it in a meaningful way. + sigaddset(&mask, SIGTSTP); + sigaddset(&mask, SIGCONT); + + // Default signal used by kill. To overcome the common issue of no cleaning + // up when killing a locally started app via a remote session. + sigaddset(&mask, SIGTERM); - m_tty = 0; - ::ioctl(m_tty, KDGKBMODE, &m_oldKbdMode); - if (!qgetenv("QT_QPA_ENABLE_TERMINAL_KEYBOARD").toInt()) { - ::ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE); - QGuiApplicationPrivate *appd = QGuiApplicationPrivate::instance(); - Q_ASSERT(appd); - QSegfaultHandler::initialize(appd->argv, appd->argc); - QSegfaultHandler::installCrashHandler(crashHandler); + m_signalFd = signalfd(-1, &mask, SFD_CLOEXEC); + if (m_signalFd < 0) { + qErrnoWarning(errno, "signalfd() failed"); + } else { + m_signalNotifier = new QSocketNotifier(m_signalFd, QSocketNotifier::Read, this); + connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal); + + // Block the signals that are handled via signalfd. Applies only to the current + // thread, but new threads will inherit the creator's signal mask. + pthread_sigmask(SIG_BLOCK, &mask, 0); } #endif } QFbVtHandler::~QFbVtHandler() { - self->cleanup(); - self = 0; +#ifdef VTH_ENABLED + restoreKeyboard(); + setTTYCursor(true); + + if (m_signalFd != -1) + close(m_signalFd); +#endif } -void QFbVtHandler::cleanup() +void QFbVtHandler::restoreKeyboard() { +#ifdef VTH_ENABLED if (m_tty == -1) return; -#ifdef HAS_VT - ::ioctl(m_tty, KDSKBMODE, m_oldKbdMode); + ioctl(m_tty, KDSKBMUTE, 0); + ioctl(m_tty, KDSKBMODE, m_oldKbdMode); +#endif +} + +// To be called from the slot connected to suspendRequested() in case the +// platform plugin does in fact allow suspending on Ctrl+Z. +void QFbVtHandler::suspend() +{ +#ifdef VTH_ENABLED + kill(getpid(), SIGSTOP); +#endif +} + +void QFbVtHandler::handleSignal() +{ +#ifdef VTH_ENABLED + m_signalNotifier->setEnabled(false); + + signalfd_siginfo sig; + if (read(m_signalFd, &sig, sizeof(sig)) == sizeof(sig)) { + switch (sig.ssi_signo) { + case SIGINT: // fallthrough + case SIGTERM: + handleInt(); + break; + case SIGTSTP: + emit suspendRequested(); + break; + case SIGCONT: + emit resumed(); + break; + default: + break; + } + } + + m_signalNotifier->setEnabled(true); #endif } -void QFbVtHandler::crashHandler() +void QFbVtHandler::handleInt() { - Q_ASSERT(self); - self->cleanup(); +#ifdef VTH_ENABLED + emit interrupted(); + restoreKeyboard(); + setTTYCursor(true); + _exit(1); +#endif } QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbvthandler_p.h b/src/platformsupport/fbconvenience/qfbvthandler_p.h index eac7f82df8..3681def9f0 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler_p.h +++ b/src/platformsupport/fbconvenience/qfbvthandler_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE +class QSocketNotifier; + class QFbVtHandler : public QObject { Q_OBJECT @@ -57,13 +59,24 @@ public: QFbVtHandler(QObject *parent = 0); ~QFbVtHandler(); + void suspend(); + +signals: + void interrupted(); + void suspendRequested(); + void resumed(); + +private slots: + void handleSignal(); + private: - void cleanup(); - static void crashHandler(); + void restoreKeyboard(); + void handleInt(); - static QFbVtHandler *self; int m_tty; int m_oldKbdMode; + int m_signalFd; + QSocketNotifier *m_signalNotifier; }; QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbwindow.cpp b/src/platformsupport/fbconvenience/qfbwindow.cpp index 93fa00d819..44a04de1ea 100644 --- a/src/platformsupport/fbconvenience/qfbwindow.cpp +++ b/src/platformsupport/fbconvenience/qfbwindow.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ diff --git a/src/platformsupport/fbconvenience/qfbwindow_p.h b/src/platformsupport/fbconvenience/qfbwindow_p.h index f1630764b0..9d90d8f8bc 100644 --- a/src/platformsupport/fbconvenience/qfbwindow_p.h +++ b/src/platformsupport/fbconvenience/qfbwindow_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ |