summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fbconvenience
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/fbconvenience')
-rw-r--r--src/platformsupport/fbconvenience/qfbbackingstore.cpp16
-rw-r--r--src/platformsupport/fbconvenience/qfbbackingstore_p.h20
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor.cpp87
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor_p.h45
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp31
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen_p.h23
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler.cpp174
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler_p.h33
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow.cpp14
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow_p.h14
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 &region, const QPoint &offset);
+ virtual QPaintDevice *paintDevice() Q_DECL_OVERRIDE { return &mImage; }
+ virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
- virtual void resize(const QSize &size, const QRegion &region);
+ virtual void resize(const QSize &size, const QRegion &region) 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$