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 <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
This commit is contained in:
Rolland Dudemaine 2015-10-29 15:59:48 +01:00
parent cb72faf2f2
commit 47c7ae25c6
13 changed files with 942 additions and 0 deletions

10
configure vendored
View File

@ -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"

View File

@ -6,3 +6,5 @@ include(../common/ghs-integrity-armv7.conf)
DEFINES += QT_NO_CLIPBOARD
DEFINES += QT_STATICPLUGIN
QTPLUGIN.platforms += integrityfb

View File

@ -7,3 +7,5 @@ include(../common/ghs-integrity-x86.conf)
QMAKE_CFLAGS += -cpu=Corei
DEFINES += QT_NO_CLIPBOARD
DEFINES += QT_STATICPLUGIN
QTPLUGIN.platforms += integrityfb

View File

@ -0,0 +1,3 @@
{
"Keys": [ "integrityfb" ]
}

View File

@ -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)

View File

@ -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 <qpa/qplatformintegrationplugin.h>
#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"

View File

@ -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 <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qfbbackingstore_p.h>
#include <QtPlatformSupport/private/qfbwindow_p.h>
#include <QtPlatformSupport/private/qfbcursor_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatforminputcontextfactory_p.h>
QT_BEGIN_NAMESPACE
QIntegrityFbIntegration::QIntegrityFbIntegration(const QStringList &paramList)
: 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<QPlatformScreen *> QIntegrityFbIntegration::screens() const
{
QList<QPlatformScreen *> 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

View File

@ -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 <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
class QIntegrityFbScreen;
class QIntegrityFbIntegration : public QPlatformIntegration, public QPlatformNativeInterface
{
public:
QIntegrityFbIntegration(const QStringList &paramList);
~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<QPlatformScreen *> screens() const;
private:
void createInputHandlers();
QIntegrityFbScreen *m_primaryScreen;
QPlatformInputContext *m_inputContext;
QScopedPointer<QPlatformFontDatabase> m_fontDb;
QScopedPointer<QPlatformServices> m_services;
QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
};
QT_END_NAMESPACE
#endif // QINTEGRITYFBINTEGRATION_H

View File

@ -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 <QtPlatformSupport/private/qfbcursor_p.h>
#include <QtPlatformSupport/private/qfbwindow_p.h>
#include <QtCore/QRegularExpression>
#include <QtGui/QPainter>
#include <qimage.h>
#include <qdebug.h>
#include <INTEGRITY.h>
#include <memory_region.h>
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<QRect> 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

View File

@ -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 <QtPlatformSupport/private/qfbscreen_p.h>
#include <device/fbdriver.h>
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

View File

@ -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 <QList>
#include <QPoint>
#include <QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
#include <device/hiddriver.h>
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<Value, HIDDeviceHandler *> 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 *)&notifier);
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

View File

@ -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 <QObject>
#include <QList>
#include <QThread>
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<HIDDriverHandler *> m_drivers;
};
QT_END_NAMESPACE
#endif // QINTEGRITYHIDMANAGER_P_H

View File

@ -42,3 +42,5 @@ haiku {
}
contains(QT_CONFIG, mirclient): SUBDIRS += mirclient
contains(QT_CONFIG, integrityfb): SUBDIRS += integrity