From 47c7ae25c6c6fccf00c027c0fcb2dab11e686c2b Mon Sep 17 00:00:00 2001 From: Rolland Dudemaine Date: Thu, 29 Oct 2015 15:59:48 +0100 Subject: [PATCH] Add INTEGRITY Framebuffer-based plugin as a platform plugin. The plugin builds as a static plugin. It is based on the Linuxfb plugin. It uses the INTEGRITY FB API for framebuffer for display, and HID API for input (mouse, keyboard, touch). Because this is the only supported plugin and requires to be included as a static plugin, automatically add the platform to any application through qmake.conf. Change-Id: Ic228afb59cb39dd02c2d538de46caf6e6ea7d153 Reviewed-by: Oswald Buddenhagen Reviewed-by: Andy Nichols --- configure | 10 + mkspecs/integrity-armv7/qmake.conf | 2 + mkspecs/integrity-x86/qmake.conf | 2 + .../platforms/integrity/integrity.json | 3 + src/plugins/platforms/integrity/integrity.pro | 23 ++ src/plugins/platforms/integrity/main.cpp | 59 ++++ .../integrity/qintegrityfbintegration.cpp | 130 +++++++++ .../integrity/qintegrityfbintegration.h | 79 ++++++ .../integrity/qintegrityfbscreen.cpp | 243 +++++++++++++++++ .../platforms/integrity/qintegrityfbscreen.h | 74 +++++ .../integrity/qintegrityhidmanager.cpp | 252 ++++++++++++++++++ .../integrity/qintegrityhidmanager.h | 63 +++++ src/plugins/platforms/platforms.pro | 2 + 13 files changed, 942 insertions(+) create mode 100644 src/plugins/platforms/integrity/integrity.json create mode 100644 src/plugins/platforms/integrity/integrity.pro create mode 100644 src/plugins/platforms/integrity/main.cpp create mode 100644 src/plugins/platforms/integrity/qintegrityfbintegration.cpp create mode 100644 src/plugins/platforms/integrity/qintegrityfbintegration.h create mode 100644 src/plugins/platforms/integrity/qintegrityfbscreen.cpp create mode 100644 src/plugins/platforms/integrity/qintegrityfbscreen.h create mode 100644 src/plugins/platforms/integrity/qintegrityhidmanager.cpp create mode 100644 src/plugins/platforms/integrity/qintegrityhidmanager.h diff --git a/configure b/configure index 87982e389d..1e8a7ff16a 100755 --- a/configure +++ b/configure @@ -695,6 +695,7 @@ CFG_EGLFS_VIV_WL=no CFG_DIRECTFB=auto CFG_GBM=auto CFG_LINUXFB=auto +CFG_INTEGRITYFB=no CFG_KMS=auto CFG_MIRCLIENT=auto CFG_LIBUDEV=auto @@ -4714,6 +4715,7 @@ if [ "$XPLATFORM_QNX" = "yes" ]; then fi if [ "$XPLATFORM_INTEGRITY" = "yes" ]; then + CFG_INTEGRITYFB=yes CFG_SHARED=no CFG_LARGEFILE=no fi @@ -5918,6 +5920,8 @@ if [ -z "$QT_QPA_DEFAULT_PLATFORM" ]; then QT_QPA_DEFAULT_PLATFORM="cocoa" elif [ "$UNAME_SYSTEM" = "QNX" ]; then QT_QPA_DEFAULT_PLATFORM="qnx" + elif [ "$XPLATFORM_INTEGRITY" = "yes" ]; then + QT_QPA_DEFAULT_PLATFORM="integrityfb" else QT_QPA_DEFAULT_PLATFORM="xcb" fi @@ -5940,6 +5944,9 @@ fi if [ "$CFG_LINUXFB" = "yes" ]; then QT_CONFIG="$QT_CONFIG linuxfb" fi +if [ "$CFG_INTEGRITYFB" = "yes" ]; then + QT_CONFIG="$QT_CONFIG integrityfb" +fi if [ "$CFG_KMS" = "yes" ]; then QT_CONFIG="$QT_CONFIG kms" fi @@ -7462,6 +7469,9 @@ report_support " EGLFS GBM .........." "$CFG_EGLFS_GBM" report_support " EGLFS Mali ........." "$CFG_EGLFS_MALI" report_support " EGLFS Raspberry Pi ." "$CFG_EGLFS_BRCM" report_support " EGLFS X11 .........." "$CFG_EGL_X" +if [ "$XPLATFORM_INTEGRITY" = "yes" ]; then + report_support " INTEGRITY Framebuffer " "$CFG_INTEGRITYFB" +fi report_support " LinuxFB .............." "$CFG_LINUXFB" report_support " Mir client............" "$CFG_MIRCLIENT" report_support " XCB .................." "$CFG_XCB" system "system library" qt "bundled copy" diff --git a/mkspecs/integrity-armv7/qmake.conf b/mkspecs/integrity-armv7/qmake.conf index c2d850b8b4..0cac2ebdc0 100644 --- a/mkspecs/integrity-armv7/qmake.conf +++ b/mkspecs/integrity-armv7/qmake.conf @@ -6,3 +6,5 @@ include(../common/ghs-integrity-armv7.conf) DEFINES += QT_NO_CLIPBOARD DEFINES += QT_STATICPLUGIN + +QTPLUGIN.platforms += integrityfb diff --git a/mkspecs/integrity-x86/qmake.conf b/mkspecs/integrity-x86/qmake.conf index e70b54652a..4a5cfcc49d 100644 --- a/mkspecs/integrity-x86/qmake.conf +++ b/mkspecs/integrity-x86/qmake.conf @@ -7,3 +7,5 @@ include(../common/ghs-integrity-x86.conf) QMAKE_CFLAGS += -cpu=Corei DEFINES += QT_NO_CLIPBOARD DEFINES += QT_STATICPLUGIN + +QTPLUGIN.platforms += integrityfb diff --git a/src/plugins/platforms/integrity/integrity.json b/src/plugins/platforms/integrity/integrity.json new file mode 100644 index 0000000000..d6dd1a6351 --- /dev/null +++ b/src/plugins/platforms/integrity/integrity.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "integrityfb" ] +} diff --git a/src/plugins/platforms/integrity/integrity.pro b/src/plugins/platforms/integrity/integrity.pro new file mode 100644 index 0000000000..07dbf4093d --- /dev/null +++ b/src/plugins/platforms/integrity/integrity.pro @@ -0,0 +1,23 @@ +TARGET = integrityfb + +QT += core-private gui-private platformsupport-private + +SOURCES = \ + main.cpp \ + qintegrityfbintegration.cpp \ + qintegrityfbscreen.cpp \ + qintegrityhidmanager.cpp + +HEADERS = \ + qintegrityfbintegration.h \ + qintegrityfbscreen.h \ + qintegrityhidmanager.h + +CONFIG += qpa/genericunixfontdatabase + +OTHER_FILES += integrity.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QIntegrityFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/integrity/main.cpp b/src/plugins/platforms/integrity/main.cpp new file mode 100644 index 0000000000..3330ddc5ae --- /dev/null +++ b/src/plugins/platforms/integrity/main.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qintegrityfbintegration.h" + +QT_BEGIN_NAMESPACE + +class QIntegrityFbIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "integrity.json") +public: + QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; +}; + +QPlatformIntegration* QIntegrityFbIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (!system.compare(QLatin1String("integrityfb"), Qt::CaseInsensitive)) + return new QIntegrityFbIntegration(paramList); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" + diff --git a/src/plugins/platforms/integrity/qintegrityfbintegration.cpp b/src/plugins/platforms/integrity/qintegrityfbintegration.cpp new file mode 100644 index 0000000000..5332718c5e --- /dev/null +++ b/src/plugins/platforms/integrity/qintegrityfbintegration.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qintegrityfbintegration.h" +#include "qintegrityfbscreen.h" +#include "qintegrityhidmanager.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include + + +QT_BEGIN_NAMESPACE + +QIntegrityFbIntegration::QIntegrityFbIntegration(const QStringList ¶mList) + : m_fontDb(new QGenericUnixFontDatabase), + m_services(new QGenericUnixServices) +{ + m_primaryScreen = new QIntegrityFbScreen(paramList); +} + +QIntegrityFbIntegration::~QIntegrityFbIntegration() +{ + destroyScreen(m_primaryScreen); +} + +void QIntegrityFbIntegration::initialize() +{ + if (m_primaryScreen->initialize()) + screenAdded(m_primaryScreen); + else + qWarning("integrityfb: Failed to initialize screen"); + + m_inputContext = QPlatformInputContextFactory::create(); + + m_nativeInterface.reset(new QPlatformNativeInterface); + + if (!qEnvironmentVariableIntValue("QT_QPA_FB_DISABLE_INPUT")) + createInputHandlers(); +} + +bool QIntegrityFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case ThreadedPixmaps: return true; + case WindowManagement: return false; + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformBackingStore *QIntegrityFbIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QFbBackingStore(window); +} + +QPlatformWindow *QIntegrityFbIntegration::createPlatformWindow(QWindow *window) const +{ + return new QFbWindow(window); +} + +QAbstractEventDispatcher *QIntegrityFbIntegration::createEventDispatcher() const +{ + return createUnixEventDispatcher(); +} + +QList QIntegrityFbIntegration::screens() const +{ + QList list; + list.append(m_primaryScreen); + return list; +} + +QPlatformFontDatabase *QIntegrityFbIntegration::fontDatabase() const +{ + return m_fontDb.data(); +} + +QPlatformServices *QIntegrityFbIntegration::services() const +{ + return m_services.data(); +} + +void QIntegrityFbIntegration::createInputHandlers() +{ + new QIntegrityHIDManager("HID", "", this); +} + +QPlatformNativeInterface *QIntegrityFbIntegration::nativeInterface() const +{ + return m_nativeInterface.data(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/integrity/qintegrityfbintegration.h b/src/plugins/platforms/integrity/qintegrityfbintegration.h new file mode 100644 index 0000000000..3210cc9369 --- /dev/null +++ b/src/plugins/platforms/integrity/qintegrityfbintegration.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QINTEGRITYFBINTEGRATION_H +#define QINTEGRITYFBINTEGRATION_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QAbstractEventDispatcher; +class QIntegrityFbScreen; + +class QIntegrityFbIntegration : public QPlatformIntegration, public QPlatformNativeInterface +{ +public: + QIntegrityFbIntegration(const QStringList ¶mList); + ~QIntegrityFbIntegration(); + + void initialize() Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + + QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + + QList screens() const; + +private: + void createInputHandlers(); + + QIntegrityFbScreen *m_primaryScreen; + QPlatformInputContext *m_inputContext; + QScopedPointer m_fontDb; + QScopedPointer m_services; + QScopedPointer m_nativeInterface; +}; + +QT_END_NAMESPACE + +#endif // QINTEGRITYFBINTEGRATION_H diff --git a/src/plugins/platforms/integrity/qintegrityfbscreen.cpp b/src/plugins/platforms/integrity/qintegrityfbscreen.cpp new file mode 100644 index 0000000000..e043da7786 --- /dev/null +++ b/src/plugins/platforms/integrity/qintegrityfbscreen.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qintegrityfbscreen.h" +#include +#include +#include +#include + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +static QImage::Format determineFormat(const FBInfo *fbinfo) +{ + QImage::Format format = QImage::Format_Invalid; + + switch (fbinfo->BitsPerPixel) { + case 32: + if (fbinfo->Alpha.Bits) + format = QImage::Format_ARGB32; + else + format = QImage::Format_RGB32; + break; + case 24: + format = QImage::Format_RGB888; + break; + case 18: + format = QImage::Format_RGB666; + break; + case 16: + format = QImage::Format_RGB16; + break; + case 15: + format = QImage::Format_RGB555; + break; + case 12: + format = QImage::Format_RGB444; + break; + case 8: + break; + case 1: + format = QImage::Format_Mono; //###: LSB??? + break; + default: + break; + } + + return format; +} + +QIntegrityFbScreen::QIntegrityFbScreen(const QStringList &args) + : mArgs(args), mBlitter(0) +{ +} + +QIntegrityFbScreen::~QIntegrityFbScreen() +{ + if (mFbh) { + MemoryRegion vmr; + CheckSuccess(gh_FB_close_munmap(mFbh, &vmr)); + CheckSuccess(DeallocateMemoryRegionWithCookie(__ghs_VirtualMemoryRegionPool, + vmr, mVMRCookie)); + } + + delete mBlitter; +} + +bool QIntegrityFbScreen::initialize() +{ + Error err; + QRegularExpression fbRx(QLatin1String("fb=(.*)")); + QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)")); + QRegularExpression offsetRx(QLatin1String("offset=(\\d+)x(\\d+)")); + + QString fbDevice; + QRect userGeometry; + + // Parse arguments + foreach (const QString &arg, mArgs) { + QRegularExpressionMatch match; + if (arg.contains(sizeRx, &match)) + userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt())); + else if (arg.contains(offsetRx, &match)) + userGeometry.setTopLeft(QPoint(match.captured(1).toInt(), match.captured(2).toInt())); + else if (arg.contains(fbRx, &match)) + fbDevice = match.captured(1); + } + + if (fbDevice.isEmpty()) { + /* no driver specified, try to get default one */ + err = gh_FB_get_driver_by_name(NULL, &mFbd); + if (err != Success) { + uintptr_t context = 0; + /* no default driver, take the first available one */ + err = gh_FB_get_next_driver(&context, &mFbd); + } + } else { + err = gh_FB_get_driver_by_name(qPrintable(fbDevice), &mFbd); + } + if (err != Success) { + qErrnoWarning("Failed to open framebuffer %s: %d", qPrintable(fbDevice), err); + return false; + } + + memset(&mFbinfo, 0, sizeof(FBInfo)); + CheckSuccess(gh_FB_check_info(mFbd, &mFbinfo)); + if (userGeometry.width() && userGeometry.height()) { + mFbinfo.Width = userGeometry.width(); + mFbinfo.Height = userGeometry.height(); + err = gh_FB_check_info(mFbd, &mFbinfo); + if (err != Success) { + qErrnoWarning("Unsupported resolution %dx%d for %s: %d", + userGeometry.width(), userGeometry.height(), + qPrintable(fbDevice), err); + return false; + } + } + + if (mFbinfo.MMapSize) { + err = AllocateAnyMemoryRegionWithCookie(__ghs_VirtualMemoryRegionPool, + mFbinfo.MMapSize, &mVMR, &mVMRCookie); + if (err != Success) { + qErrnoWarning("Could not mmap: %d", err); + return false; + } + + err = gh_FB_open_mmap(mFbd, &mFbinfo, mVMR, &mFbh); + } else { + err = gh_FB_open(mFbd, &mFbinfo, &mFbh); + } + if (err != Success) { + qErrnoWarning("Could not open framebuffer: %d", err); + return false; + } + + CheckSuccess(gh_FB_get_info(mFbh, &mFbinfo)); + + mDepth = mFbinfo.BitsPerPixel; + mGeometry = QRect(0, 0, mFbinfo.Width, mFbinfo.Height); + mFormat = determineFormat(&mFbinfo); + + const int dpi = 100; + int mmWidth = qRound((mFbinfo.Width * 25.4) / dpi); + int mmHeight = qRound((mFbinfo.Height * 25.4) / dpi); + mPhysicalSize = QSizeF(mmWidth, mmHeight); + + QFbScreen::initializeCompositor(); + mFbScreenImage = QImage((uchar *)mFbinfo.Start, mFbinfo.Width, mFbinfo.Height, + mFbinfo.BytesPerLine, mFormat); + + mCursor = new QFbCursor(this); + + return true; +} + +QRegion QIntegrityFbScreen::doRedraw() +{ + QRegion touched = QFbScreen::doRedraw(); + + if (touched.isEmpty()) + return touched; + + if (!mBlitter) + mBlitter = new QPainter(&mFbScreenImage); + + QVector rects = touched.rects(); + for (int i = 0; i < rects.size(); i++) { + FBRect fbrect = { + (uint32_t)rects[i].left(), + (uint32_t)rects[i].top(), + (uint32_t)rects[i].width(), + (uint32_t)rects[i].height() + }; + mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); + gh_FB_expose(mFbh, &fbrect, NULL); + } + return touched; +} + +// grabWindow() grabs "from the screen" not from the backingstores. +// In integrityfb's case it will also include the mouse cursor. +QPixmap QIntegrityFbScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + if (!wid) { + if (width < 0) + width = mFbScreenImage.width() - x; + if (height < 0) + height = mFbScreenImage.height() - y; + return QPixmap::fromImage(mFbScreenImage).copy(x, y, width, height); + } + + QFbWindow *window = windowForId(wid); + if (window) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(mFbScreenImage).copy(rect); + } + + return QPixmap(); +} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/integrity/qintegrityfbscreen.h b/src/plugins/platforms/integrity/qintegrityfbscreen.h new file mode 100644 index 0000000000..2a83f3426f --- /dev/null +++ b/src/plugins/platforms/integrity/qintegrityfbscreen.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QINTEGRITYFBSCREEN_H +#define QINTEGRITYFBSCREEN_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QPainter; +class QFbCursor; + +class QIntegrityFbScreen : public QFbScreen +{ + Q_OBJECT +public: + QIntegrityFbScreen(const QStringList &args); + ~QIntegrityFbScreen(); + + bool initialize(); + + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + + QRegion doRedraw() Q_DECL_OVERRIDE; + +private: + QStringList mArgs; + FBDriver *mFbd; + FBHandle mFbh; + FBInfo mFbinfo; + MemoryRegion mVMR; + Address mVMRCookie; + + QImage mFbScreenImage; + + QPainter *mBlitter; +}; + +QT_END_NAMESPACE + +#endif // QINTEGRITYFBSCREEN_H + diff --git a/src/plugins/platforms/integrity/qintegrityhidmanager.cpp b/src/plugins/platforms/integrity/qintegrityhidmanager.cpp new file mode 100644 index 0000000000..64eda98e2a --- /dev/null +++ b/src/plugins/platforms/integrity/qintegrityhidmanager.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Green Hills Software +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qintegrityhidmanager.h" +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class IntNotifier +{ + static const Value ActivityPriority = 2; +protected: + Activity act; +public: + IntNotifier() + { + CheckSuccess(CreateActivity(CurrentTask(), ActivityPriority, false, (Value)this, &act)); + }; + ~IntNotifier() + { + CheckSuccess(CloseActivity(act)); + }; + virtual void process_event() = 0; + virtual void async_wait() = 0; +}; + +class HIDDeviceHandler : IntNotifier +{ +public: + HIDDeviceHandler(HIDDriver *hidd, HIDHandle hidh) + : driver(hidd), handle(hidh), currentPos(0, 0) { } + ~HIDDeviceHandler() + { + CheckSuccess(gh_hid_close(handle)); + }; + void process_event(void) Q_DECL_OVERRIDE; + void async_wait(void) Q_DECL_OVERRIDE; + HIDDriver *get_driver(void) { return driver; }; + HIDHandle get_handle(void) { return handle; }; +private: + HIDDriver *driver; + HIDHandle handle; + QPoint currentPos; + Qt::MouseButtons buttons; +}; + +class HIDDriverHandler : IntNotifier +{ +public: + HIDDriverHandler(HIDDriver *hidd) : IntNotifier(), driver(hidd) { } + ~HIDDriverHandler() + { + qDeleteAll(devices); + }; + void process_event(void) Q_DECL_OVERRIDE; + void async_wait(void) Q_DECL_OVERRIDE; + void find_devices(void); +private: + QHash devices; + HIDDriver *driver; +}; + +void HIDDriverHandler::process_event() +{ + find_devices(); +} + +void HIDDriverHandler::async_wait() +{ + gh_hid_wait_for_new_device(driver, act); +} + +void HIDDriverHandler::find_devices() +{ + Error err; + uintptr_t devicecontext; + uint32_t device_id; + HIDHandle handle; + HIDDeviceHandler *hidnot; + + devicecontext = 0; + forever { + err = gh_hid_enum_devices(driver, &device_id, &devicecontext); + if (err == OperationNotImplemented) + break; + else if (err == Failure) + break; + if (!devices.contains(device_id)) { + err = gh_hid_init_device(driver, device_id, &handle); + if (err == Success) { + hidnot = new HIDDeviceHandler(driver, handle); + devices.insert(device_id, hidnot); + hidnot->async_wait(); + } + } + } + if (err == OperationNotImplemented) { + /* fallback on legacy enumeration where we assume 0-based + * contiguous indexes */ + device_id = 0; + err = Success; + do { + if (!devices.contains(device_id)) { + err = gh_hid_init_device(driver, device_id, &handle); + if (err != Success) + break; + hidnot = new HIDDeviceHandler(driver, handle); + devices.insert(device_id, hidnot); + hidnot->async_wait(); + } + device_id++; + } while (err == Success); + } + + async_wait(); +} + + +void HIDDeviceHandler::process_event() +{ + HIDEvent event; + uint32_t num_events = 1; + + while (gh_hid_get_event(handle, &event, &num_events) == Success) { + if (event.type == HID_TYPE_AXIS) { + switch (event.index) { + case HID_AXIS_ABSX: + currentPos.setX(event.value); + break; + case HID_AXIS_ABSY: + currentPos.setY(event.value); + break; + case HID_AXIS_RELX: + currentPos.setX(currentPos.x() + event.value); + break; + case HID_AXIS_RELY: + currentPos.setY(currentPos.y() + event.value); + break; + default: + /* ignore the rest for now */ + break; + } + } else if (event.type == HID_TYPE_KEY) { + switch (event.index) { + case HID_BUTTON_LEFT: + if (event.value) + buttons |= Qt::LeftButton; + else + buttons &= ~Qt::LeftButton; + break; + case HID_BUTTON_MIDDLE: + if (event.value) + buttons |= Qt::MiddleButton; + else + buttons &= ~Qt::MiddleButton; + break; + case HID_BUTTON_RIGHT: + if (event.value) + buttons |= Qt::RightButton; + else + buttons &= ~Qt::RightButton; + break; + default: + /* ignore the rest for now */ + break; + } + } else if (event.type == HID_TYPE_SYNC) { + QWindowSystemInterface::handleMouseEvent(0, currentPos, currentPos, buttons, + QGuiApplication::keyboardModifiers()); + } else if (event.type == HID_TYPE_DISCONNECT) { + /* FIXME */ + } + } + async_wait(); +} + +void HIDDeviceHandler::async_wait() +{ + CheckSuccess(gh_hid_async_wait_for_event(handle, act)); +} + +void QIntegrityHIDManager::open_devices() +{ + HIDDriver *hidd; + uintptr_t context = 0; + HIDDriverHandler *hidnot; + + while (gh_hid_enum_drivers(&hidd, &context) == Success) { + hidnot = new HIDDriverHandler(hidd); + m_drivers.append(hidnot); + hidnot->find_devices(); + } +} + +void QIntegrityHIDManager::run() +{ + IntNotifier *notifier; + open_devices(); + /* main loop */ + forever { + WaitForActivity((Value *)¬ifier); + notifier->process_event(); + } +} + +QIntegrityHIDManager::QIntegrityHIDManager(const QString &key, const QString &spec, QObject *parent) + : QThread(parent) +{ + start(); +} + +QIntegrityHIDManager::~QIntegrityHIDManager() +{ + terminate(); + qDeleteAll(m_drivers); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/integrity/qintegrityhidmanager.h b/src/plugins/platforms/integrity/qintegrityhidmanager.h new file mode 100644 index 0000000000..9a0f27d833 --- /dev/null +++ b/src/plugins/platforms/integrity/qintegrityhidmanager.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Green Hills Software +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QINTEGRITYHIDMANAGER_P_H +#define QINTEGRITYHIDMANAGER_P_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class HIDDriverHandler; + +class QIntegrityHIDManager : public QThread +{ + Q_OBJECT +public: + QIntegrityHIDManager(const QString &key, const QString &specification, QObject *parent = 0); + ~QIntegrityHIDManager(); + + void run(void); +private: + void open_devices(void); + + QString m_spec; + QList m_drivers; + +}; + +QT_END_NAMESPACE + +#endif // QINTEGRITYHIDMANAGER_P_H diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 43bb04e318..eba16f90ed 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -42,3 +42,5 @@ haiku { } contains(QT_CONFIG, mirclient): SUBDIRS += mirclient + +contains(QT_CONFIG, integrityfb): SUBDIRS += integrity