Initial import of the Blackberry QPA plugin for Qt5
This is dependent upon the following Change Id's: I5ebcffb7153f4216d69921d4818051e6b3d14d8a Iec065f528f5edd848be580807a607488dc2e401f Change-Id: I234e3c4272d7474d8f8e20fc4fea20d95c829cb5 Reviewed-by: Kevin Krammer <kevin.krammer@kdab.com> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
parent
151f17d7e6
commit
87366cc7ab
71
src/plugins/platforms/blackberry/blackberry.pro
Normal file
71
src/plugins/platforms/blackberry/blackberry.pro
Normal file
@ -0,0 +1,71 @@
|
||||
TARGET = blackberry
|
||||
include(../../qpluginbase.pri)
|
||||
|
||||
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
|
||||
QT += opengl opengl-private platformsupport platformsupport-private widgets-private
|
||||
|
||||
# Uncomment this to build with support for IMF once it becomes available in the BBNDK
|
||||
#CONFIG += qbb_imf
|
||||
|
||||
# Uncomment these to enable debugging output for various aspects of the plugin
|
||||
#DEFINES += QBBBUFFER_DEBUG
|
||||
#DEFINES += QBBCLIPBOARD_DEBUG
|
||||
#DEFINES += QBBEVENTTHREAD_DEBUG
|
||||
#DEFINES += QBBGLBACKINGSTORE_DEBUG
|
||||
#DEFINES += QBBGLCONTEXT_DEBUG
|
||||
#DEFINES += QBBINPUTCONTEXT_DEBUG
|
||||
#DEFINES += QBBINPUTCONTEXT_IMF_EVENT_DEBUG
|
||||
#DEFINES += QBBINTEGRATION_DEBUG
|
||||
#DEFINES += QBBNAVIGATORTHREAD_DEBUG
|
||||
#DEFINES += QBBRASTERBACKINGSTORE_DEBUG
|
||||
#DEFINES += QBBROOTWINDOW_DEBUG
|
||||
#DEFINES += QBBSCREEN_DEBUG
|
||||
#DEFINES += QBBVIRTUALKEYBOARD_DEBUG
|
||||
#DEFINES += QBBWINDOW_DEBUG
|
||||
|
||||
SOURCES = main.cpp \
|
||||
qbbbuffer.cpp \
|
||||
qbbeventthread.cpp \
|
||||
qbbglcontext.cpp \
|
||||
qbbglbackingstore.cpp \
|
||||
qbbintegration.cpp \
|
||||
qbbnavigatorthread.cpp \
|
||||
qbbscreen.cpp \
|
||||
qbbwindow.cpp \
|
||||
qbbrasterbackingstore.cpp \
|
||||
qbbvirtualkeyboard.cpp \
|
||||
qbbclipboard.cpp \
|
||||
qbbrootwindow.cpp
|
||||
|
||||
HEADERS = qbbbuffer.h \
|
||||
qbbeventthread.h \
|
||||
qbbkeytranslator.h \
|
||||
qbbintegration.h \
|
||||
qbbnavigatorthread.h \
|
||||
qbbglcontext.h \
|
||||
qbbglbackingstore.h \
|
||||
qbbscreen.h \
|
||||
qbbwindow.h \
|
||||
qbbrasterbackingstore.h \
|
||||
qbbvirtualkeyboard.h \
|
||||
qbbclipboard.h \
|
||||
qbbrootwindow.h
|
||||
|
||||
CONFIG(qbb_imf) {
|
||||
DEFINES += QBB_IMF
|
||||
HEADERS += qbbinputcontext_imf.h
|
||||
SOURCES += qbbinputcontext_imf.cpp
|
||||
} else {
|
||||
HEADERS += qbbinputcontext_noimf.h
|
||||
SOURCES += qbbinputcontext_noimf.cpp
|
||||
}
|
||||
|
||||
QMAKE_CXXFLAGS += -I./private
|
||||
|
||||
LIBS += -lpps -lscreen -lEGL -lclipboard
|
||||
|
||||
include (../../../platformsupport/eglconvenience/eglconvenience.pri)
|
||||
include (../../../platformsupport/fontdatabases/fontdatabases.pri)
|
||||
|
||||
target.path += $$[QT_INSTALL_PLUGINS]/platforms
|
||||
INSTALLS += target
|
72
src/plugins/platforms/blackberry/main.cpp
Normal file
72
src/plugins/platforms/blackberry/main.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui/QPlatformIntegrationPlugin>
|
||||
#include "qbbintegration.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBIntegrationPlugin : public QPlatformIntegrationPlugin
|
||||
{
|
||||
public:
|
||||
QStringList keys() const;
|
||||
QPlatformIntegration *create(const QString&, const QStringList&);
|
||||
};
|
||||
|
||||
QStringList QBBIntegrationPlugin::keys() const
|
||||
{
|
||||
QStringList list;
|
||||
list << QLatin1String("blackberry");
|
||||
return list;
|
||||
}
|
||||
|
||||
QPlatformIntegration *QBBIntegrationPlugin::create(const QString& system, const QStringList& paramList)
|
||||
{
|
||||
Q_UNUSED(paramList);
|
||||
if (system.toLower() == QLatin1String("blackberry"))
|
||||
return new QBBIntegration;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2(blackberry, QBBIntegrationPlugin)
|
||||
|
||||
QT_END_NAMESPACE
|
165
src/plugins/platforms/blackberry/qbbbuffer.cpp
Normal file
165
src/plugins/platforms/blackberry/qbbbuffer.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbbuffer.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QBBBuffer::QBBBuffer()
|
||||
: m_buffer(0)
|
||||
{
|
||||
#if defined(QBBBUFFER_DEBUG)
|
||||
qDebug() << "QBBBuffer::QBBBuffer - empty";
|
||||
#endif
|
||||
}
|
||||
|
||||
QBBBuffer::QBBBuffer(screen_buffer_t buffer)
|
||||
: m_buffer(buffer)
|
||||
{
|
||||
#if defined(QBBBUFFER_DEBUG)
|
||||
qDebug() << "QBBBuffer::QBBBuffer - normal";
|
||||
#endif
|
||||
|
||||
// Get size of buffer
|
||||
errno = 0;
|
||||
int size[2];
|
||||
int result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to query buffer size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Get stride of buffer
|
||||
errno = 0;
|
||||
int stride;
|
||||
result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to query buffer stride, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Get access to buffer's data
|
||||
errno = 0;
|
||||
uchar *dataPtr = 0;
|
||||
result = screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to query buffer pointer, errno=%d", errno);
|
||||
}
|
||||
if (dataPtr == NULL) {
|
||||
qFatal("QBB: buffer pointer is NULL, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Get format of buffer
|
||||
errno = 0;
|
||||
int screenFormat;
|
||||
result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to query buffer format, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Convert screen format to QImage format
|
||||
QImage::Format imageFormat = QImage::Format_Invalid;
|
||||
switch (screenFormat) {
|
||||
case SCREEN_FORMAT_RGBX4444:
|
||||
imageFormat = QImage::Format_RGB444;
|
||||
break;
|
||||
case SCREEN_FORMAT_RGBA4444:
|
||||
imageFormat = QImage::Format_ARGB4444_Premultiplied;
|
||||
break;
|
||||
case SCREEN_FORMAT_RGBX5551:
|
||||
imageFormat = QImage::Format_RGB555;
|
||||
break;
|
||||
case SCREEN_FORMAT_RGB565:
|
||||
imageFormat = QImage::Format_RGB16;
|
||||
break;
|
||||
case SCREEN_FORMAT_RGBX8888:
|
||||
imageFormat = QImage::Format_RGB32;
|
||||
break;
|
||||
case SCREEN_FORMAT_RGBA8888:
|
||||
imageFormat = QImage::Format_ARGB32_Premultiplied;
|
||||
break;
|
||||
default:
|
||||
qFatal("QBB: unsupported buffer format, format=%d", screenFormat);
|
||||
}
|
||||
|
||||
// wrap buffer in an image
|
||||
m_image = QImage(dataPtr, size[0], size[1], stride, imageFormat);
|
||||
}
|
||||
|
||||
QBBBuffer::QBBBuffer(const QBBBuffer &other)
|
||||
: m_buffer(other.m_buffer),
|
||||
m_image(other.m_image)
|
||||
{
|
||||
#if defined(QBBBUFFER_DEBUG)
|
||||
qDebug() << "QBBBuffer::QBBBuffer - copy";
|
||||
#endif
|
||||
}
|
||||
|
||||
QBBBuffer::~QBBBuffer()
|
||||
{
|
||||
#if defined(QBBBUFFER_DEBUG)
|
||||
qDebug() << "QBBBuffer::~QBBBuffer";
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBBBuffer::invalidateInCache()
|
||||
{
|
||||
#if defined(QBBBUFFER_DEBUG)
|
||||
qDebug() << "QBBBuffer::invalidateInCache";
|
||||
#endif
|
||||
|
||||
// Verify native buffer exists
|
||||
if (m_buffer == 0) {
|
||||
qFatal("QBB: can't invalidate cache for null buffer");
|
||||
}
|
||||
|
||||
// Evict buffer's data from cache
|
||||
errno = 0;
|
||||
int result = msync(m_image.bits(), m_image.height() * m_image.bytesPerLine(), MS_INVALIDATE | MS_CACHE_ONLY);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to invalidate cache, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
74
src/plugins/platforms/blackberry/qbbbuffer.h
Normal file
74
src/plugins/platforms/blackberry/qbbbuffer.h
Normal file
@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBBUFFER_H
|
||||
#define QBBBUFFER_H
|
||||
|
||||
#include <QtGui/QImage>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBBuffer
|
||||
{
|
||||
public:
|
||||
QBBBuffer();
|
||||
QBBBuffer(screen_buffer_t buffer);
|
||||
QBBBuffer(const QBBBuffer &other);
|
||||
virtual ~QBBBuffer();
|
||||
|
||||
screen_buffer_t nativeBuffer() const { return m_buffer; }
|
||||
const QImage *image() const { return (m_buffer != NULL) ? &m_image : NULL; }
|
||||
QImage *image() { return (m_buffer != NULL) ? &m_image : NULL; }
|
||||
|
||||
QRect rect() const { return m_image.rect(); }
|
||||
|
||||
void invalidateInCache();
|
||||
|
||||
private:
|
||||
screen_buffer_t m_buffer;
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBBUFFER_H
|
132
src/plugins/platforms/blackberry/qbbclipboard.cpp
Normal file
132
src/plugins/platforms/blackberry/qbbclipboard.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
|
||||
#include "qbbclipboard.h"
|
||||
|
||||
#include <QtGui/QColor>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
#include <clipboard/clipboard.h>
|
||||
#include <errno.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
static const char *typeList[] = {"text/html", "text/plain", "application/x-color"};
|
||||
|
||||
QBBClipboard::QBBClipboard()
|
||||
{
|
||||
m_mimeData = 0;
|
||||
}
|
||||
|
||||
QBBClipboard::~QBBClipboard()
|
||||
{
|
||||
delete m_mimeData;
|
||||
}
|
||||
|
||||
void QBBClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
|
||||
{
|
||||
if (mode != QClipboard::Clipboard)
|
||||
return;
|
||||
|
||||
if (m_mimeData != data) {
|
||||
delete m_mimeData;
|
||||
m_mimeData = data;
|
||||
}
|
||||
|
||||
empty_clipboard();
|
||||
|
||||
if (data == 0)
|
||||
return;
|
||||
|
||||
QStringList format = data->formats();
|
||||
for (int i = 0; i < format.size(); ++i) {
|
||||
QString type = format.at(i);
|
||||
QByteArray buf = data->data(type);
|
||||
if (!buf.size())
|
||||
continue;
|
||||
|
||||
int ret = set_clipboard_data(type.toUtf8().data(), buf.size(), buf.data());
|
||||
#if defined(QBBCLIPBOARD_DEBUG)
|
||||
qDebug() << "QBB: set " << type.toUtf8().data() << "to clipboard, size=" << buf.size() << ";ret=" << ret;
|
||||
#else
|
||||
Q_UNUSED(ret);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void QBBClipboard::readClipboardBuff(const char *type)
|
||||
{
|
||||
char *pbuffer;
|
||||
if (is_clipboard_format_present(type) == 0) {
|
||||
int size = get_clipboard_data(type, &pbuffer);
|
||||
if (size != -1 && pbuffer) {
|
||||
QString qtype = type;
|
||||
#if defined(QBBCLIPBOARD_DEBUG)
|
||||
qDebug() << "QBB: clipboard has " << qtype;
|
||||
#endif
|
||||
m_mimeData->setData(qtype, QByteArray(pbuffer, size));
|
||||
delete pbuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMimeData *QBBClipboard::mimeData(QClipboard::Mode mode)
|
||||
{
|
||||
if (mode != QClipboard::Clipboard)
|
||||
return 0;
|
||||
|
||||
if (!m_mimeData)
|
||||
m_mimeData = new QMimeData();
|
||||
|
||||
m_mimeData->clear();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
readClipboardBuff(typeList[i]);
|
||||
|
||||
return m_mimeData;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif //QT_NO_CLIPBOAR
|
67
src/plugins/platforms/blackberry/qbbclipboard.h
Normal file
67
src/plugins/platforms/blackberry/qbbclipboard.h
Normal file
@ -0,0 +1,67 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBCLIPBOARD_H
|
||||
#define QBBCLIPBOARD_H
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
#include <QtGui/QPlatformClipboard>
|
||||
#include <QMimeData>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBClipboard : public QPlatformClipboard
|
||||
{
|
||||
public:
|
||||
QBBClipboard();
|
||||
virtual ~QBBClipboard();
|
||||
virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
|
||||
virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
|
||||
|
||||
private:
|
||||
QMimeData *m_mimeData;
|
||||
void readClipboardBuff(const char *type);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif //QT_NO_CLIPBOARD
|
||||
#endif //QBBCLIPBOARD_H
|
559
src/plugins/platforms/blackberry/qbbeventthread.cpp
Normal file
559
src/plugins/platforms/blackberry/qbbeventthread.cpp
Normal file
@ -0,0 +1,559 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbeventthread.h"
|
||||
#include "qbbintegration.h"
|
||||
#include "qbbkeytranslator.h"
|
||||
|
||||
#if defined(QBB_IMF)
|
||||
#include "qbbinputcontext_imf.h"
|
||||
#else
|
||||
#include "qbbinputcontext_noimf.h"
|
||||
#endif
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QPlatformScreen>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/keycodes.h>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
QBBEventThread::QBBEventThread(screen_context_t context, QPlatformScreen& screen)
|
||||
: QThread(),
|
||||
m_screenContext(context),
|
||||
m_platformScreen(screen),
|
||||
m_quit(false),
|
||||
m_lastButtonState(Qt::NoButton),
|
||||
m_lastMouseWindow(0)
|
||||
{
|
||||
// Create a touch device
|
||||
m_touchDevice = new QTouchDevice;
|
||||
m_touchDevice->setType(QTouchDevice::TouchScreen);
|
||||
m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
|
||||
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
|
||||
|
||||
// initialize array of touch points
|
||||
for (int i = 0; i < MaximumTouchPoints; i++) {
|
||||
|
||||
// map array index to id
|
||||
m_touchPoints[i].id = i;
|
||||
|
||||
// pressure is not supported - use default
|
||||
m_touchPoints[i].pressure = 1.0;
|
||||
|
||||
// nothing touching
|
||||
m_touchPoints[i].state = Qt::TouchPointReleased;
|
||||
}
|
||||
}
|
||||
|
||||
QBBEventThread::~QBBEventThread()
|
||||
{
|
||||
// block until thread terminates
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void QBBEventThread::run()
|
||||
{
|
||||
screen_event_t event;
|
||||
|
||||
// create screen event
|
||||
errno = 0;
|
||||
int result = screen_create_event(&event);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to create event, errno=%d", errno);
|
||||
}
|
||||
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: event loop started";
|
||||
#endif
|
||||
|
||||
// loop indefinitely
|
||||
while (!m_quit) {
|
||||
|
||||
// block until screen event is available
|
||||
errno = 0;
|
||||
result = screen_get_event(m_screenContext, event, -1);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to get event, errno=%d", errno);
|
||||
}
|
||||
|
||||
// process received event
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: event loop stopped";
|
||||
#endif
|
||||
|
||||
// cleanup
|
||||
screen_destroy_event(event);
|
||||
}
|
||||
|
||||
void QBBEventThread::shutdown()
|
||||
{
|
||||
screen_event_t event;
|
||||
|
||||
// create screen event
|
||||
errno = 0;
|
||||
int result = screen_create_event(&event);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to create event, errno=%d", errno);
|
||||
}
|
||||
|
||||
// set the event type as user
|
||||
errno = 0;
|
||||
int type = SCREEN_EVENT_USER;
|
||||
result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to set event type, errno=%d", errno);
|
||||
}
|
||||
|
||||
// NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events
|
||||
|
||||
// post event to event loop so it will wake up and die
|
||||
errno = 0;
|
||||
result = screen_send_event(m_screenContext, event, getpid());
|
||||
if (result) {
|
||||
qFatal("QBB: failed to set event type, errno=%d", errno);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
screen_destroy_event(event);
|
||||
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: event loop shutdown begin";
|
||||
#endif
|
||||
|
||||
// block until thread terminates
|
||||
wait();
|
||||
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: event loop shutdown end";
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBBEventThread::dispatchEvent(screen_event_t event)
|
||||
{
|
||||
// get the event type
|
||||
errno = 0;
|
||||
int qnxType;
|
||||
int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event type, errno=%d", errno);
|
||||
}
|
||||
|
||||
switch (qnxType) {
|
||||
case SCREEN_EVENT_MTOUCH_TOUCH:
|
||||
case SCREEN_EVENT_MTOUCH_MOVE:
|
||||
case SCREEN_EVENT_MTOUCH_RELEASE:
|
||||
handleTouchEvent(event, qnxType);
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_KEYBOARD:
|
||||
handleKeyboardEvent(event);
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_POINTER:
|
||||
handlePointerEvent(event);
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_CLOSE:
|
||||
handleCloseEvent(event);
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_USER:
|
||||
// treat all user events as shutdown requests
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: QNX user event";
|
||||
#endif
|
||||
m_quit = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
// event ignored
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: QNX unknown event";
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QBBEventThread::handleKeyboardEvent(screen_event_t event)
|
||||
{
|
||||
// get flags of key event
|
||||
errno = 0;
|
||||
int flags;
|
||||
int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event flags, errno=%d", errno);
|
||||
}
|
||||
|
||||
// get key code
|
||||
errno = 0;
|
||||
int sym;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event sym, errno=%d", errno);
|
||||
}
|
||||
|
||||
int modifiers;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event modifiers, errno=%d", errno);
|
||||
}
|
||||
|
||||
int scan;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event modifiers, errno=%d", errno);
|
||||
}
|
||||
|
||||
int cap;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event cap, errno=%d", errno);
|
||||
}
|
||||
|
||||
injectKeyboardEvent(flags, sym, modifiers, scan, cap);
|
||||
}
|
||||
|
||||
void QBBEventThread::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap)
|
||||
{
|
||||
Q_UNUSED(scan);
|
||||
|
||||
Qt::KeyboardModifiers qtMod = Qt::NoModifier;
|
||||
if (modifiers & KEYMOD_SHIFT)
|
||||
qtMod |= Qt::ShiftModifier;
|
||||
if (modifiers & KEYMOD_CTRL)
|
||||
qtMod |= Qt::ControlModifier;
|
||||
if (modifiers & KEYMOD_ALT)
|
||||
qtMod |= Qt::AltModifier;
|
||||
|
||||
// determine event type
|
||||
QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease;
|
||||
|
||||
// Check if the key cap is valid
|
||||
if (flags & KEY_CAP_VALID) {
|
||||
Qt::Key key;
|
||||
QString keyStr;
|
||||
|
||||
if (cap >= 0x20 && cap <= 0x0ff) {
|
||||
key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case.
|
||||
|
||||
if ( qtMod & Qt::ControlModifier ) {
|
||||
keyStr = QChar((int)(key & 0x3f));
|
||||
} else {
|
||||
if (flags & KEY_SYM_VALID) {
|
||||
keyStr = QChar(sym);
|
||||
}
|
||||
}
|
||||
} else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) {
|
||||
key = (Qt::Key)cap;
|
||||
keyStr = QChar(sym);
|
||||
} else {
|
||||
if (isKeypadKey(cap))
|
||||
qtMod |= Qt::KeypadModifier; // Is this right?
|
||||
key = keyTranslator(cap);
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, keyStr);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt key t=" << type << ", k=" << key << ", s=" << keyStr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void QBBEventThread::handlePointerEvent(screen_event_t event)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
// Query the window that was clicked
|
||||
screen_window_t qnxWindow;
|
||||
void *handle;
|
||||
int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event window, errno=%d", errno);
|
||||
}
|
||||
qnxWindow = static_cast<screen_window_t>(handle);
|
||||
|
||||
// Query the button states
|
||||
int buttonState = 0;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event button state, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Query the window position
|
||||
int windowPos[2];
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event window position, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Query the screen position
|
||||
int pos[2];
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event position, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Query the wheel delta
|
||||
int wheelDelta = 0;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event wheel delta, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Map window handle to top-level QWindow
|
||||
QWindow *w = QBBIntegration::window(qnxWindow);
|
||||
|
||||
// Generate enter and leave events as needed.
|
||||
if (qnxWindow != m_lastMouseWindow) {
|
||||
QWindow *wOld = QBBIntegration::window(m_lastMouseWindow);
|
||||
|
||||
if (wOld) {
|
||||
QWindowSystemInterface::handleLeaveEvent(wOld);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt leave, w=" << wOld;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (w) {
|
||||
QWindowSystemInterface::handleEnterEvent(w);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt enter, w=" << w;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
m_lastMouseWindow = qnxWindow;
|
||||
|
||||
// Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale
|
||||
// this via a system preference at some point. But for now this is a sane value and makes
|
||||
// the wheel usable.
|
||||
wheelDelta *= -10;
|
||||
|
||||
// convert point to local coordinates
|
||||
QPoint globalPoint(pos[0], pos[1]);
|
||||
QPoint localPoint(windowPos[0], windowPos[1]);
|
||||
|
||||
// Convert buttons.
|
||||
Qt::MouseButtons buttons = Qt::NoButton;
|
||||
if (buttonState & 1)
|
||||
buttons |= Qt::LeftButton;
|
||||
if (buttonState & 2)
|
||||
buttons |= Qt::MidButton;
|
||||
if (buttonState & 4)
|
||||
buttons |= Qt::RightButton;
|
||||
|
||||
if (w) {
|
||||
// Inject mouse event into Qt only if something has changed.
|
||||
if (m_lastGlobalMousePoint != globalPoint ||
|
||||
m_lastLocalMousePoint != localPoint ||
|
||||
m_lastButtonState != buttons) {
|
||||
QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast<int>(buttons);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (wheelDelta) {
|
||||
// Screen only supports a single wheel, so we will assume Vertical orientation for
|
||||
// now since that is pretty much standard.
|
||||
QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast<int>(wheelDelta);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
m_lastGlobalMousePoint = globalPoint;
|
||||
m_lastLocalMousePoint = localPoint;
|
||||
m_lastButtonState = buttons;
|
||||
}
|
||||
|
||||
void QBBEventThread::handleTouchEvent(screen_event_t event, int qnxType)
|
||||
{
|
||||
// get display coordinates of touch
|
||||
errno = 0;
|
||||
int pos[2];
|
||||
int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event position, errno=%d", errno);
|
||||
}
|
||||
|
||||
// get window coordinates of touch
|
||||
errno = 0;
|
||||
int windowPos[2];
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event window position, errno=%d", errno);
|
||||
}
|
||||
|
||||
// determine which finger touched
|
||||
errno = 0;
|
||||
int touchId;
|
||||
result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event touch id, errno=%d", errno);
|
||||
}
|
||||
|
||||
// determine which window was touched
|
||||
errno = 0;
|
||||
void *handle;
|
||||
result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
|
||||
if (result) {
|
||||
qFatal("QBB: failed to query event window, errno=%d", errno);
|
||||
}
|
||||
screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
|
||||
|
||||
// check if finger is valid
|
||||
if (touchId < MaximumTouchPoints) {
|
||||
|
||||
// Map window handle to top-level QWindow
|
||||
QWindow *w = QBBIntegration::window(qnxWindow);
|
||||
|
||||
// Generate enter and leave events as needed.
|
||||
if (qnxWindow != m_lastMouseWindow) {
|
||||
QWindow *wOld = QBBIntegration::window(m_lastMouseWindow);
|
||||
|
||||
if (wOld) {
|
||||
QWindowSystemInterface::handleLeaveEvent(wOld);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt leave, w=" << wOld;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (w) {
|
||||
QWindowSystemInterface::handleEnterEvent(w);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt enter, w=" << w;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
m_lastMouseWindow = qnxWindow;
|
||||
|
||||
if (w) {
|
||||
// convert primary touch to mouse event
|
||||
if (touchId == 0) {
|
||||
|
||||
// convert point to local coordinates
|
||||
QPoint globalPoint(pos[0], pos[1]);
|
||||
QPoint localPoint(windowPos[0], windowPos[1]);
|
||||
|
||||
// map touch state to button state
|
||||
Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton;
|
||||
|
||||
// inject event into Qt
|
||||
QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons;
|
||||
#endif
|
||||
}
|
||||
|
||||
// get size of screen which contains window
|
||||
QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w);
|
||||
QSizeF screenSize = platformScreen->physicalSize();
|
||||
|
||||
// update cached position of current touch point
|
||||
m_touchPoints[touchId].normalPosition = QPointF( static_cast<qreal>(pos[0]) / screenSize.width(), static_cast<qreal>(pos[1]) / screenSize.height() );
|
||||
m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 );
|
||||
|
||||
// determine event type and update state of current touch point
|
||||
QEvent::Type type = QEvent::None;
|
||||
switch (qnxType) {
|
||||
case SCREEN_EVENT_MTOUCH_TOUCH:
|
||||
m_touchPoints[touchId].state = Qt::TouchPointPressed;
|
||||
type = QEvent::TouchBegin;
|
||||
break;
|
||||
case SCREEN_EVENT_MTOUCH_MOVE:
|
||||
m_touchPoints[touchId].state = Qt::TouchPointMoved;
|
||||
type = QEvent::TouchUpdate;
|
||||
break;
|
||||
case SCREEN_EVENT_MTOUCH_RELEASE:
|
||||
m_touchPoints[touchId].state = Qt::TouchPointReleased;
|
||||
type = QEvent::TouchEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
// build list of active touch points
|
||||
QList<QWindowSystemInterface::TouchPoint> pointList;
|
||||
for (int i = 0; i < MaximumTouchPoints; i++) {
|
||||
if (i == touchId) {
|
||||
// current touch point is always active
|
||||
pointList.append(m_touchPoints[i]);
|
||||
} else if (m_touchPoints[i].state != Qt::TouchPointReleased) {
|
||||
// finger is down but did not move
|
||||
m_touchPoints[i].state = Qt::TouchPointStationary;
|
||||
pointList.append(m_touchPoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// inject event into Qt
|
||||
QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList);
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QBBEventThread::handleCloseEvent(screen_event_t event)
|
||||
{
|
||||
// Query the window that was closed
|
||||
void *handle;
|
||||
int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to query event window, errno=%d", errno);
|
||||
}
|
||||
screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
|
||||
|
||||
// Map window handle to top-level QWindow
|
||||
QWindow *w = QBBIntegration::window(qnxWindow);
|
||||
if (w != 0) {
|
||||
QWindowSystemInterface::handleCloseEvent(w);
|
||||
}
|
||||
}
|
||||
|
90
src/plugins/platforms/blackberry/qbbeventthread.h
Normal file
90
src/plugins/platforms/blackberry/qbbeventthread.h
Normal file
@ -0,0 +1,90 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBEVENTTHREAD_H
|
||||
#define QBBEVENTTHREAD_H
|
||||
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <QtGui/QPlatformScreen>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBEventThread : public QThread
|
||||
{
|
||||
public:
|
||||
QBBEventThread(screen_context_t context, QPlatformScreen& screen);
|
||||
virtual ~QBBEventThread();
|
||||
|
||||
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
|
||||
|
||||
protected:
|
||||
virtual void run();
|
||||
|
||||
private:
|
||||
enum {
|
||||
MaximumTouchPoints = 10
|
||||
};
|
||||
|
||||
void shutdown();
|
||||
void dispatchEvent(screen_event_t event);
|
||||
void handleKeyboardEvent(screen_event_t event);
|
||||
void handlePointerEvent(screen_event_t event);
|
||||
void handleTouchEvent(screen_event_t event, int type);
|
||||
void handleCloseEvent(screen_event_t event);
|
||||
|
||||
screen_context_t m_screenContext;
|
||||
QPlatformScreen& m_platformScreen;
|
||||
bool m_quit;
|
||||
QPoint m_lastGlobalMousePoint;
|
||||
QPoint m_lastLocalMousePoint;
|
||||
Qt::MouseButtons m_lastButtonState;
|
||||
screen_window_t m_lastMouseWindow;
|
||||
QTouchDevice *m_touchDevice;
|
||||
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBEVENTTHREAD_H
|
189
src/plugins/platforms/blackberry/qbbglbackingstore.cpp
Normal file
189
src/plugins/platforms/blackberry/qbbglbackingstore.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbglbackingstore.h"
|
||||
#include "qbbglcontext.h"
|
||||
#include "qbbwindow.h"
|
||||
#include "qbbscreen.h"
|
||||
|
||||
#include <QtGui/qwindow.h>
|
||||
|
||||
#include <QtOpenGL/private/qgl_p.h>
|
||||
#include <QtOpenGL/QGLContext>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QBBGLPaintDevice::QBBGLPaintDevice(QWindow *window)
|
||||
: QGLPaintDevice(),
|
||||
m_window(0),
|
||||
m_glContext(0)
|
||||
{
|
||||
m_window = static_cast<QBBWindow*>(window->handle());
|
||||
|
||||
// Extract the QPlatformOpenGLContext from the window
|
||||
QPlatformOpenGLContext *platformOpenGLContext = m_window->platformOpenGLContext();
|
||||
|
||||
// Convert this to a QGLContext
|
||||
m_glContext = QGLContext::fromOpenGLContext(platformOpenGLContext->context());
|
||||
}
|
||||
|
||||
QBBGLPaintDevice::~QBBGLPaintDevice()
|
||||
{
|
||||
// Cleanup GL context
|
||||
delete m_glContext;
|
||||
}
|
||||
|
||||
QPaintEngine *QBBGLPaintDevice::paintEngine() const
|
||||
{
|
||||
// Select a paint engine based on configued OpenGL version
|
||||
return qt_qgl_paint_engine();
|
||||
}
|
||||
|
||||
QSize QBBGLPaintDevice::size() const
|
||||
{
|
||||
// Get size of EGL surface
|
||||
return m_window->geometry().size();
|
||||
}
|
||||
|
||||
|
||||
QBBGLBackingStore::QBBGLBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window),
|
||||
m_openGLContext(0),
|
||||
m_paintDevice(0),
|
||||
m_requestedSize(),
|
||||
m_size()
|
||||
{
|
||||
#if defined(QBBGLBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBGLBackingStore::QBBGLBackingStore - w=" << window;
|
||||
#endif
|
||||
|
||||
// Create an OpenGL paint device which in turn creates a QGLContext for us
|
||||
m_paintDevice = new QBBGLPaintDevice(window);
|
||||
m_openGLContext = m_paintDevice->context()->contextHandle();
|
||||
}
|
||||
|
||||
QBBGLBackingStore::~QBBGLBackingStore()
|
||||
{
|
||||
#if defined(QBBGLBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBGLBackingStore::~QBBGLBackingStore - w=" << window();
|
||||
#endif
|
||||
|
||||
// cleanup OpenGL paint device
|
||||
delete m_paintDevice;
|
||||
}
|
||||
|
||||
void QBBGLBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
Q_UNUSED(offset);
|
||||
|
||||
#if defined(QBBGLBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBGLBackingStore::flush - w=" << window;
|
||||
#endif
|
||||
|
||||
// update the display with newly rendered content
|
||||
m_openGLContext->swapBuffers(window);
|
||||
}
|
||||
|
||||
void QBBGLBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||
{
|
||||
Q_UNUSED(staticContents);
|
||||
#if defined(QBBGLBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBGLBackingStore::resize - w=" << window() << ", s=" << size;
|
||||
#endif
|
||||
// NOTE: defer resizing window buffers until next paint as
|
||||
// resize() can be called multiple times before a paint occurs
|
||||
m_requestedSize = size;
|
||||
}
|
||||
|
||||
void QBBGLBackingStore::beginPaint(const QRegion ®ion)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
|
||||
#if defined(QBBGLBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBGLBackingStore::beginPaint - w=" << window();
|
||||
#endif
|
||||
|
||||
// resize EGL surface if window surface resized
|
||||
if (m_size != m_requestedSize) {
|
||||
resizeSurface(m_requestedSize);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBGLBackingStore::endPaint(const QRegion ®ion)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
#if defined(QBBGLBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBGLBackingStore::endPaint - w=" << window();
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBBGLBackingStore::resizeSurface(const QSize &size)
|
||||
{
|
||||
// need to destroy surface so make sure its not current
|
||||
bool restoreCurrent = false;
|
||||
QBBGLContext *platformContext = static_cast<QBBGLContext *>(m_openGLContext->handle());
|
||||
if (platformContext->isCurrent()) {
|
||||
m_openGLContext->doneCurrent();
|
||||
restoreCurrent = true;
|
||||
}
|
||||
|
||||
// destroy old EGL surface
|
||||
platformContext->destroySurface();
|
||||
|
||||
// resize window's buffers
|
||||
static_cast<QBBWindow*>(window()->handle())->setBufferSize(size);
|
||||
|
||||
// re-create EGL surface with new size
|
||||
m_size = size;
|
||||
platformContext->createSurface(window()->handle());
|
||||
|
||||
// make context current again
|
||||
if (restoreCurrent) {
|
||||
m_openGLContext->makeCurrent(window());
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
95
src/plugins/platforms/blackberry/qbbglbackingstore.h
Normal file
95
src/plugins/platforms/blackberry/qbbglbackingstore.h
Normal file
@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBGLBACKINGSTORE_H
|
||||
#define QBBGLBACKINGSTORE_H
|
||||
|
||||
#include <QtGui/qplatformbackingstore_qpa.h>
|
||||
#include <QtOpenGL/private/qglpaintdevice_p.h>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QGLContext;
|
||||
class QBBGLContext;
|
||||
class QBBScreen;
|
||||
class QBBWindow;
|
||||
|
||||
class QBBGLPaintDevice : public QGLPaintDevice
|
||||
{
|
||||
public:
|
||||
QBBGLPaintDevice(QWindow *window);
|
||||
virtual ~QBBGLPaintDevice();
|
||||
|
||||
virtual QPaintEngine *paintEngine() const;
|
||||
virtual QSize size() const;
|
||||
virtual QGLContext *context() const { return m_glContext; }
|
||||
|
||||
private:
|
||||
QBBWindow *m_window;
|
||||
QGLContext *m_glContext;
|
||||
};
|
||||
|
||||
class QBBGLBackingStore : public QPlatformBackingStore
|
||||
{
|
||||
public:
|
||||
QBBGLBackingStore(QWindow *window);
|
||||
virtual ~QBBGLBackingStore();
|
||||
|
||||
virtual QPaintDevice *paintDevice() { return m_paintDevice; }
|
||||
virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset);
|
||||
virtual void resize(const QSize &size, const QRegion &staticContents);
|
||||
virtual void beginPaint(const QRegion ®ion);
|
||||
virtual void endPaint(const QRegion ®ion);
|
||||
|
||||
void resizeSurface(const QSize &size);
|
||||
|
||||
private:
|
||||
QOpenGLContext *m_openGLContext;
|
||||
QBBGLPaintDevice *m_paintDevice;
|
||||
QSize m_requestedSize;
|
||||
QSize m_size;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBGLBACKINGSTORE_H
|
356
src/plugins/platforms/blackberry/qbbglcontext.cpp
Normal file
356
src/plugins/platforms/blackberry/qbbglcontext.cpp
Normal file
@ -0,0 +1,356 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbglcontext.h"
|
||||
#include "qbbrootwindow.h"
|
||||
#include "qbbscreen.h"
|
||||
#include "qbbwindow.h"
|
||||
|
||||
#include "private/qeglconvenience_p.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
EGLDisplay QBBGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
|
||||
|
||||
static EGLenum checkEGLError(const char *msg)
|
||||
{
|
||||
static const char *errmsg[] =
|
||||
{
|
||||
"EGL function succeeded",
|
||||
"EGL is not initialized, or could not be initialized, for the specified display",
|
||||
"EGL cannot access a requested resource",
|
||||
"EGL failed to allocate resources for the requested operation",
|
||||
"EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
|
||||
"EGLConfig argument does not name a valid EGLConfig",
|
||||
"EGLContext argument does not name a valid EGLContext",
|
||||
"EGL current surface of the calling thread is no longer valid",
|
||||
"EGLDisplay argument does not name a valid EGLDisplay",
|
||||
"EGL arguments are inconsistent",
|
||||
"EGLNativePixmapType argument does not refer to a valid native pixmap",
|
||||
"EGLNativeWindowType argument does not refer to a valid native window",
|
||||
"EGL one or more argument values are invalid",
|
||||
"EGLSurface argument does not name a valid surface configured for rendering",
|
||||
"EGL power management event has occurred",
|
||||
};
|
||||
EGLenum error = eglGetError();
|
||||
fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
|
||||
return error;
|
||||
}
|
||||
|
||||
QBBGLContext::QBBGLContext(QOpenGLContext *glContext)
|
||||
: QPlatformOpenGLContext(),
|
||||
m_glContext(glContext),
|
||||
m_eglSurface(EGL_NO_SURFACE)
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
QSurfaceFormat format = m_glContext->format();
|
||||
|
||||
// Set current rendering API
|
||||
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to set EGL API, err=%d", eglGetError());
|
||||
}
|
||||
|
||||
// Get colour channel sizes from window format
|
||||
int alphaSize = format.alphaBufferSize();
|
||||
int redSize = format.redBufferSize();
|
||||
int greenSize = format.greenBufferSize();
|
||||
int blueSize = format.blueBufferSize();
|
||||
|
||||
// Check if all channels are don't care
|
||||
if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) {
|
||||
// Set colour channels based on depth of window's screen
|
||||
QBBScreen *screen = static_cast<QBBScreen*>(QBBScreen::screens().first());
|
||||
int depth = screen->depth();
|
||||
if (depth == 32) {
|
||||
// SCREEN_FORMAT_RGBA8888
|
||||
alphaSize = 8;
|
||||
redSize = 8;
|
||||
greenSize = 8;
|
||||
blueSize = 8;
|
||||
} else {
|
||||
// SCREEN_FORMAT_RGB565
|
||||
alphaSize = 0;
|
||||
redSize = 5;
|
||||
greenSize = 6;
|
||||
blueSize = 5;
|
||||
}
|
||||
} else {
|
||||
// Choose best match based on supported pixel formats
|
||||
if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) {
|
||||
// SCREEN_FORMAT_RGB565
|
||||
alphaSize = 0;
|
||||
redSize = 5;
|
||||
greenSize = 6;
|
||||
blueSize = 5;
|
||||
} else {
|
||||
// SCREEN_FORMAT_RGBA8888
|
||||
alphaSize = 8;
|
||||
redSize = 8;
|
||||
greenSize = 8;
|
||||
blueSize = 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Update colour channel sizes in window format
|
||||
format.setAlphaBufferSize(alphaSize);
|
||||
format.setRedBufferSize(redSize);
|
||||
format.setGreenBufferSize(greenSize);
|
||||
format.setBlueBufferSize(blueSize);
|
||||
format.setSamples(2);
|
||||
|
||||
// Select EGL config based on requested window format
|
||||
m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format);
|
||||
if (m_eglConfig == 0) {
|
||||
qFatal("QBB: failed to find EGL config");
|
||||
}
|
||||
|
||||
m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs());
|
||||
if (m_eglContext == EGL_NO_CONTEXT) {
|
||||
checkEGLError("eglCreateContext");
|
||||
qFatal("QBB: failed to create EGL context, err=%d", eglGetError());
|
||||
}
|
||||
|
||||
// Query/cache window format of selected EGL config
|
||||
m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig);
|
||||
}
|
||||
|
||||
QBBGLContext::~QBBGLContext()
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
// Cleanup EGL context if it exists
|
||||
if (m_eglContext != EGL_NO_CONTEXT) {
|
||||
eglDestroyContext(ms_eglDisplay, m_eglContext);
|
||||
}
|
||||
|
||||
// Cleanup EGL surface if it exists
|
||||
destroySurface();
|
||||
}
|
||||
|
||||
void QBBGLContext::initialize()
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Initialize connection to EGL
|
||||
ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (ms_eglDisplay == EGL_NO_DISPLAY) {
|
||||
checkEGLError("eglGetDisplay");
|
||||
qFatal("QBB: failed to obtain EGL display");
|
||||
}
|
||||
|
||||
EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
checkEGLError("eglInitialize");
|
||||
qFatal("QBB: failed to initialize EGL display, err=%d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
void QBBGLContext::shutdown()
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Close connection to EGL
|
||||
eglTerminate(ms_eglDisplay);
|
||||
}
|
||||
|
||||
bool QBBGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Set current rendering API
|
||||
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to set EGL API, err=%d", eglGetError());
|
||||
}
|
||||
|
||||
if (m_eglSurface == EGL_NO_SURFACE)
|
||||
createSurface(surface);
|
||||
|
||||
eglResult = eglMakeCurrent(ms_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
checkEGLError("eglMakeCurrent");
|
||||
qFatal("QBB: failed to set current EGL context, err=%d", eglGetError());
|
||||
}
|
||||
return (eglResult == EGL_TRUE);
|
||||
}
|
||||
|
||||
void QBBGLContext::doneCurrent()
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// set current rendering API
|
||||
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to set EGL API, err=%d", eglGetError());
|
||||
}
|
||||
|
||||
// clear curent EGL context and unbind EGL surface
|
||||
eglResult = eglMakeCurrent(ms_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to clear current EGL context, err=%d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
void QBBGLContext::swapBuffers(QPlatformSurface *surface)
|
||||
{
|
||||
Q_UNUSED(surface);
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
// Set current rendering API
|
||||
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to set EGL API, err=%d", eglGetError());
|
||||
}
|
||||
|
||||
// Post EGL surface to window
|
||||
eglResult = eglSwapBuffers(ms_eglDisplay, m_eglSurface);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to swap EGL buffers, err=%d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
QFunctionPointer QBBGLContext::getProcAddress(const QByteArray &procName)
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
// Set current rendering API
|
||||
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to set EGL API, err=%d", eglGetError());
|
||||
}
|
||||
|
||||
// Lookup EGL extension function pointer
|
||||
return static_cast<QFunctionPointer>(eglGetProcAddress(procName.constData()));
|
||||
}
|
||||
|
||||
EGLint *QBBGLContext::contextAttrs()
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
// Choose EGL settings based on OpenGL version
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||
return attrs;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QBBGLContext::isCurrent() const
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
return (eglGetCurrentContext() == m_eglContext);
|
||||
}
|
||||
|
||||
void QBBGLContext::createSurface(QPlatformSurface *surface)
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Get a pointer to the corresponding platform window
|
||||
QBBWindow *platformWindow = dynamic_cast<QBBWindow*>(surface);
|
||||
if (!platformWindow) {
|
||||
qFatal("QBB: unable to create EGLSurface without a QBBWindow");
|
||||
}
|
||||
|
||||
// If the platform window does not yet have any buffers, we create
|
||||
// a temporary set of buffers with a size of 1x1 pixels. This will
|
||||
// suffice until such time as the platform window has obtained
|
||||
// buffers of the proper size
|
||||
if (!platformWindow->hasBuffers()) {
|
||||
platformWindow->setPlatformOpenGLContext(this);
|
||||
m_surfaceSize = platformWindow->geometry().size();
|
||||
platformWindow->setBufferSize(m_surfaceSize);
|
||||
}
|
||||
|
||||
// Obtain the native handle for our window
|
||||
screen_window_t handle = platformWindow->nativeHandle();
|
||||
|
||||
const EGLint eglSurfaceAttrs[] =
|
||||
{
|
||||
EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// Create EGL surface
|
||||
m_eglSurface = eglCreateWindowSurface(ms_eglDisplay, m_eglConfig, (EGLNativeWindowType) handle, eglSurfaceAttrs);
|
||||
if (m_eglSurface == EGL_NO_SURFACE) {
|
||||
checkEGLError("eglCreateWindowSurface");
|
||||
qFatal("QBB: failed to create EGL surface, err=%d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
void QBBGLContext::destroySurface()
|
||||
{
|
||||
#if defined(QBBGLCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
// Destroy EGL surface if it exists
|
||||
if (m_eglSurface != EGL_NO_SURFACE) {
|
||||
EGLBoolean eglResult = eglDestroySurface(ms_eglDisplay, m_eglSurface);
|
||||
if (eglResult != EGL_TRUE) {
|
||||
qFatal("QBB: failed to destroy EGL surface, err=%d", eglGetError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
93
src/plugins/platforms/blackberry/qbbglcontext.h
Normal file
93
src/plugins/platforms/blackberry/qbbglcontext.h
Normal file
@ -0,0 +1,93 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBGLCONTEXT_H
|
||||
#define QBBGLCONTEXT_H
|
||||
|
||||
#include <QtGui/QPlatformOpenGLContext>
|
||||
#include <QtGui/QSurfaceFormat>
|
||||
#include <QtCore/QSize>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBWindow;
|
||||
|
||||
class QBBGLContext : public QPlatformOpenGLContext
|
||||
{
|
||||
public:
|
||||
QBBGLContext(QOpenGLContext *glContext);
|
||||
virtual ~QBBGLContext();
|
||||
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
|
||||
virtual bool makeCurrent(QPlatformSurface *surface);
|
||||
virtual void doneCurrent();
|
||||
virtual void swapBuffers(QPlatformSurface *surface);
|
||||
virtual QFunctionPointer getProcAddress(const QByteArray &procName);
|
||||
|
||||
virtual QSurfaceFormat format() const { return m_windowFormat; }
|
||||
|
||||
bool isCurrent() const;
|
||||
|
||||
void createSurface(QPlatformSurface *surface);
|
||||
void destroySurface();
|
||||
|
||||
private:
|
||||
/** \todo Should this be non-static so we can use additional displays? */
|
||||
static EGLDisplay ms_eglDisplay;
|
||||
|
||||
QSurfaceFormat m_windowFormat;
|
||||
QOpenGLContext *m_glContext;
|
||||
|
||||
EGLConfig m_eglConfig;
|
||||
EGLContext m_eglContext;
|
||||
EGLSurface m_eglSurface;
|
||||
QSize m_surfaceSize;
|
||||
|
||||
static EGLint *contextAttrs();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBGLCONTEXT_H
|
1696
src/plugins/platforms/blackberry/qbbinputcontext_imf.cpp
Normal file
1696
src/plugins/platforms/blackberry/qbbinputcontext_imf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
132
src/plugins/platforms/blackberry/qbbinputcontext_imf.h
Normal file
132
src/plugins/platforms/blackberry/qbbinputcontext_imf.h
Normal file
@ -0,0 +1,132 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBINPUTCONTEXT_H
|
||||
#define QBBINPUTCONTEXT_H
|
||||
|
||||
#include <QtGui/QPlatformInputContext>
|
||||
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtGui/QPlatformIntegration>
|
||||
|
||||
#include "imf/imf_client.h"
|
||||
#include "imf/input_control.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBInputContext : public QPlatformInputContext
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QBBInputContext();
|
||||
~QBBInputContext();
|
||||
|
||||
virtual bool isValid() const;
|
||||
|
||||
virtual bool filterEvent(const QEvent *event);
|
||||
virtual void reset();
|
||||
virtual void update(Qt::InputMethodQueries);
|
||||
bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
|
||||
|
||||
virtual void showInputPanel();
|
||||
virtual void hideInputPanel();
|
||||
virtual bool isInputPanelVisible() const;
|
||||
|
||||
virtual QLocale locale() const;
|
||||
|
||||
protected:
|
||||
// Filters only for IMF events.
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void keyboardVisibilityChanged(bool visible);
|
||||
void keyboardLocaleChanged(const QLocale &locale);
|
||||
void inputItemChanged();
|
||||
|
||||
private:
|
||||
// IMF Event dispatchers
|
||||
bool dispatchFocusEvent(FocusEventId id, int hints = Qt::ImhNone);
|
||||
bool dispatchRequestSoftwareInputPanel();
|
||||
bool dispatchCloseSoftwareInputPanel();
|
||||
int32_t processEvent(event_t *event);
|
||||
|
||||
void closeSession();
|
||||
void openSession();
|
||||
bool hasSession();
|
||||
void endComposition();
|
||||
void setComposingText(QString const &composingText);
|
||||
bool hasSelectedText();
|
||||
|
||||
// IMF Event handlers - these events will come in from QCoreApplication.
|
||||
int32_t onBeginBatchEdit(input_session_t *ic);
|
||||
int32_t onClearMetaKeyStates(input_session_t *ic, int32_t states);
|
||||
int32_t onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position);
|
||||
int32_t onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length);
|
||||
int32_t onEndBatchEdit(input_session_t *ic);
|
||||
int32_t onFinishComposingText(input_session_t *ic);
|
||||
int32_t onGetCursorCapsMode(input_session_t *ic, int32_t req_modes);
|
||||
int32_t onGetCursorPosition(input_session_t *ic);
|
||||
extracted_text_t *onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags);
|
||||
spannable_string_t *onGetSelectedText(input_session_t *ic, int32_t flags);
|
||||
spannable_string_t *onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags);
|
||||
spannable_string_t *onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags);
|
||||
int32_t onPerformEditorAction(input_session_t *ic, int32_t editor_action);
|
||||
int32_t onReportFullscreenMode(input_session_t *ic, int32_t enabled);
|
||||
int32_t onSendEvent(input_session_t *ic, event_t *event);
|
||||
int32_t onSendAsyncEvent(input_session_t *ic, event_t *event);
|
||||
int32_t onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end);
|
||||
int32_t onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position);
|
||||
int32_t onSetSelection(input_session_t *ic, int32_t start, int32_t end);
|
||||
int32_t onForceUpdate();
|
||||
|
||||
int m_lastCaretPos;
|
||||
bool m_isComposing;
|
||||
QString m_composingText;
|
||||
bool m_inputPanelVisible;
|
||||
QLocale m_inputPanelLocale;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(extracted_text_t*)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBINPUTCONTEXT_H
|
187
src/plugins/platforms/blackberry/qbbinputcontext_noimf.cpp
Normal file
187
src/plugins/platforms/blackberry/qbbinputcontext_noimf.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbinputcontext_noimf.h"
|
||||
#include "qbbvirtualkeyboard.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtWidgets/QAbstractSpinBox>
|
||||
|
||||
QBBInputContext::QBBInputContext() :
|
||||
QPlatformInputContext(),
|
||||
m_inputPanelVisible(false),
|
||||
m_inputPanelLocale(QLocale::c())
|
||||
{
|
||||
QBBVirtualKeyboard &keyboard = QBBVirtualKeyboard::instance();
|
||||
connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool)));
|
||||
connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale)));
|
||||
keyboardVisibilityChanged(keyboard.isVisible());
|
||||
keyboardLocaleChanged(keyboard.locale());
|
||||
|
||||
QInputMethod *inputMethod = qApp->inputMethod();
|
||||
connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged()));
|
||||
}
|
||||
|
||||
QBBInputContext::~QBBInputContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool QBBInputContext::isValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QBBInputContext::hasPhysicalKeyboard()
|
||||
{
|
||||
// TODO: This should query the system to check if a USB keyboard is connected.
|
||||
return false;
|
||||
}
|
||||
|
||||
void QBBInputContext::reset()
|
||||
{
|
||||
}
|
||||
|
||||
bool QBBInputContext::filterEvent( const QEvent *event )
|
||||
{
|
||||
if (hasPhysicalKeyboard())
|
||||
return false;
|
||||
|
||||
if (event->type() == QEvent::CloseSoftwareInputPanel) {
|
||||
QBBVirtualKeyboard::instance().hideKeyboard();
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << "QBB: hiding virtual keyboard";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::RequestSoftwareInputPanel) {
|
||||
QBBVirtualKeyboard::instance().showKeyboard();
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << "QBB: requesting virtual keyboard";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool QBBInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
|
||||
{
|
||||
Q_UNUSED(flags);
|
||||
Q_UNUSED(sym);
|
||||
Q_UNUSED(mod);
|
||||
Q_UNUSED(scan);
|
||||
Q_UNUSED(cap);
|
||||
return false;
|
||||
}
|
||||
|
||||
void QBBInputContext::showInputPanel()
|
||||
{
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
QBBVirtualKeyboard::instance().showKeyboard();
|
||||
}
|
||||
|
||||
void QBBInputContext::hideInputPanel()
|
||||
{
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
QBBVirtualKeyboard::instance().hideKeyboard();
|
||||
}
|
||||
|
||||
bool QBBInputContext::isInputPanelVisible() const
|
||||
{
|
||||
return m_inputPanelVisible;
|
||||
}
|
||||
|
||||
QLocale QBBInputContext::locale() const
|
||||
{
|
||||
return m_inputPanelLocale;
|
||||
}
|
||||
|
||||
void QBBInputContext::keyboardVisibilityChanged(bool visible)
|
||||
{
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "visible=" << visible;
|
||||
#endif
|
||||
if (m_inputPanelVisible != visible) {
|
||||
m_inputPanelVisible = visible;
|
||||
emitInputPanelVisibleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QBBInputContext::keyboardLocaleChanged(const QLocale &locale)
|
||||
{
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "locale=" << locale;
|
||||
#endif
|
||||
if (m_inputPanelLocale != locale) {
|
||||
m_inputPanelLocale = locale;
|
||||
emitLocaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void QBBInputContext::inputItemChanged()
|
||||
{
|
||||
QInputMethod *inputMethod = qApp->inputMethod();
|
||||
QObject *inputItem = inputMethod->inputItem();
|
||||
|
||||
#if defined(QBBINPUTCONTEXT_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "input item=" << inputItem;
|
||||
#endif
|
||||
|
||||
if (!inputItem) {
|
||||
if (m_inputPanelVisible)
|
||||
hideInputPanel();
|
||||
} else {
|
||||
if (qobject_cast<QAbstractSpinBox*>(inputItem)) {
|
||||
QBBVirtualKeyboard::instance().setKeyboardMode(QBBVirtualKeyboard::NumPunc);
|
||||
} else {
|
||||
QBBVirtualKeyboard::instance().setKeyboardMode(QBBVirtualKeyboard::Default);
|
||||
}
|
||||
if (!m_inputPanelVisible)
|
||||
showInputPanel();
|
||||
}
|
||||
}
|
84
src/plugins/platforms/blackberry/qbbinputcontext_noimf.h
Normal file
84
src/plugins/platforms/blackberry/qbbinputcontext_noimf.h
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBINPUTCONTEXT_H
|
||||
#define QBBINPUTCONTEXT_H
|
||||
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtGui/QPlatformInputContext>
|
||||
#include <QtGui/QPlatformIntegration>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBInputContext : public QPlatformInputContext
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QBBInputContext();
|
||||
~QBBInputContext();
|
||||
|
||||
virtual bool isValid() const;
|
||||
|
||||
void reset();
|
||||
virtual bool filterEvent( const QEvent *event );
|
||||
bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
|
||||
|
||||
virtual void showInputPanel();
|
||||
virtual void hideInputPanel();
|
||||
virtual bool isInputPanelVisible() const;
|
||||
|
||||
virtual QLocale locale() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void keyboardVisibilityChanged(bool visible);
|
||||
void keyboardLocaleChanged(const QLocale &locale);
|
||||
void inputItemChanged();
|
||||
|
||||
private:
|
||||
bool hasPhysicalKeyboard();
|
||||
|
||||
bool m_inputPanelVisible;
|
||||
QLocale m_inputPanelLocale;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBINPUTCONTEXT_H
|
293
src/plugins/platforms/blackberry/qbbintegration.cpp
Normal file
293
src/plugins/platforms/blackberry/qbbintegration.cpp
Normal file
@ -0,0 +1,293 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbintegration.h"
|
||||
#include "qbbeventthread.h"
|
||||
#include "qbbglbackingstore.h"
|
||||
#include "qbbglcontext.h"
|
||||
#include "qbbnavigatorthread.h"
|
||||
#include "qbbrasterbackingstore.h"
|
||||
#include "qbbscreen.h"
|
||||
#include "qbbwindow.h"
|
||||
#include "qbbvirtualkeyboard.h"
|
||||
#include "qbbclipboard.h"
|
||||
#include "qbbglcontext.h"
|
||||
|
||||
#if defined(QBB_IMF)
|
||||
#include "qbbinputcontext_imf.h"
|
||||
#else
|
||||
#include "qbbinputcontext_noimf.h"
|
||||
#endif
|
||||
|
||||
#include "private/qgenericunixfontdatabase_p.h"
|
||||
#include "private/qgenericunixeventdispatcher_p.h"
|
||||
|
||||
#include <QtGui/QPlatformWindow>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QBBWindowMapper QBBIntegration::ms_windowMapper;
|
||||
QMutex QBBIntegration::ms_windowMapperMutex;
|
||||
|
||||
QBBIntegration::QBBIntegration()
|
||||
: QPlatformIntegration()
|
||||
, m_eventThread(0)
|
||||
, m_navigatorThread(0)
|
||||
, m_inputContext(0)
|
||||
, m_fontDatabase(new QGenericUnixFontDatabase())
|
||||
, m_paintUsingOpenGL(false)
|
||||
, m_eventDispatcher(createUnixEventDispatcher())
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
, m_clipboard(0)
|
||||
#endif
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Open connection to QNX composition manager
|
||||
errno = 0;
|
||||
int result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to connect to composition manager, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Create displays for all possible screens (which may not be attached)
|
||||
QBBScreen::createDisplays(m_screenContext);
|
||||
Q_FOREACH (QPlatformScreen *screen, QBBScreen::screens()) {
|
||||
screenAdded(screen);
|
||||
}
|
||||
|
||||
// Initialize global OpenGL resources
|
||||
QBBGLContext::initialize();
|
||||
|
||||
// Create/start event thread
|
||||
m_eventThread = new QBBEventThread(m_screenContext, *QBBScreen::primaryDisplay());
|
||||
m_eventThread->start();
|
||||
|
||||
// Create/start navigator thread
|
||||
m_navigatorThread = new QBBNavigatorThread(*QBBScreen::primaryDisplay());
|
||||
m_navigatorThread->start();
|
||||
|
||||
// Create/start the keyboard class.
|
||||
QBBVirtualKeyboard::instance();
|
||||
|
||||
// Set up the input context
|
||||
m_inputContext = new QBBInputContext;
|
||||
}
|
||||
|
||||
QBBIntegration::~QBBIntegration()
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << "QBB: platform plugin shutdown begin";
|
||||
#endif
|
||||
// Destroy the keyboard class.
|
||||
QBBVirtualKeyboard::destroy();
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
// Delete the clipboard
|
||||
delete m_clipboard;
|
||||
#endif
|
||||
|
||||
// Stop/destroy event thread
|
||||
delete m_eventThread;
|
||||
|
||||
// Stop/destroy navigator thread
|
||||
delete m_navigatorThread;
|
||||
|
||||
// Destroy all displays
|
||||
QBBScreen::destroyDisplays();
|
||||
|
||||
// Close connection to QNX composition manager
|
||||
screen_destroy_context(m_screenContext);
|
||||
|
||||
// Cleanup global OpenGL resources
|
||||
QBBGLContext::shutdown();
|
||||
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << "QBB: platform plugin shutdown end";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QBBIntegration::hasCapability(QPlatformIntegration::Capability cap) const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
switch (cap) {
|
||||
case ThreadedPixmaps: return true;
|
||||
#if defined(QT_OPENGL_ES)
|
||||
case OpenGL:
|
||||
return true;
|
||||
#endif
|
||||
default: return QPlatformIntegration::hasCapability(cap);
|
||||
}
|
||||
}
|
||||
|
||||
QPlatformWindow *QBBIntegration::createPlatformWindow(QWindow *window) const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// New windows are created on the primary display.
|
||||
return new QBBWindow(window, m_screenContext);
|
||||
}
|
||||
|
||||
QPlatformBackingStore *QBBIntegration::createPlatformBackingStore(QWindow *window) const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
if (paintUsingOpenGL())
|
||||
return new QBBGLBackingStore(window);
|
||||
else
|
||||
return new QBBRasterBackingStore(window);
|
||||
}
|
||||
|
||||
QPlatformOpenGLContext *QBBIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
return new QBBGLContext(context);
|
||||
}
|
||||
|
||||
QPlatformInputContext *QBBIntegration::inputContext() const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
return m_inputContext;
|
||||
}
|
||||
|
||||
void QBBIntegration::moveToScreen(QWindow *window, int screen)
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << "QBBIntegration::moveToScreen - w=" << window << ", s=" << screen;
|
||||
#endif
|
||||
|
||||
// get platform window used by widget
|
||||
QBBWindow *platformWindow = static_cast<QBBWindow *>(window->handle());
|
||||
|
||||
// lookup platform screen by index
|
||||
QBBScreen *platformScreen = static_cast<QBBScreen*>(QBBScreen::screens().at(screen));
|
||||
|
||||
// move the platform window to the platform screen
|
||||
platformWindow->setScreen(platformScreen);
|
||||
}
|
||||
|
||||
QList<QPlatformScreen *> QBBIntegration::screens() const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
return QBBScreen::screens();
|
||||
}
|
||||
|
||||
QAbstractEventDispatcher *QBBIntegration::guiThreadEventDispatcher() const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
return m_eventDispatcher;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
QPlatformClipboard *QBBIntegration::clipboard() const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
if (!m_clipboard) {
|
||||
m_clipboard = new QBBClipboard;
|
||||
}
|
||||
return m_clipboard;
|
||||
}
|
||||
#endif
|
||||
|
||||
QVariant QBBIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
if (hint == ShowIsFullScreen)
|
||||
return true;
|
||||
|
||||
return QPlatformIntegration::styleHint(hint);
|
||||
}
|
||||
|
||||
QWindow *QBBIntegration::window(screen_window_t qnxWindow)
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
QMutexLocker locker(&ms_windowMapperMutex);
|
||||
Q_UNUSED(locker);
|
||||
return ms_windowMapper.value(qnxWindow, 0);
|
||||
}
|
||||
|
||||
void QBBIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
QMutexLocker locker(&ms_windowMapperMutex);
|
||||
Q_UNUSED(locker);
|
||||
ms_windowMapper.insert(qnxWindow, window);
|
||||
}
|
||||
|
||||
void QBBIntegration::removeWindow(screen_window_t qnxWindow)
|
||||
{
|
||||
#if defined(QBBINTEGRATION_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
QMutexLocker locker(&ms_windowMapperMutex);
|
||||
Q_UNUSED(locker);
|
||||
ms_windowMapper.remove(qnxWindow);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
119
src/plugins/platforms/blackberry/qbbintegration.h
Normal file
119
src/plugins/platforms/blackberry/qbbintegration.h
Normal file
@ -0,0 +1,119 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBINTEGRATION_H
|
||||
#define QBBINTEGRATION_H
|
||||
|
||||
#include <QtGui/qplatformintegration_qpa.h>
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBEventThread;
|
||||
class QBBInputContext;
|
||||
class QBBNavigatorThread;
|
||||
class QBBWindow;
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
class QBBClipboard;
|
||||
#endif
|
||||
|
||||
template<class K, class V> class QHash;
|
||||
typedef QHash<screen_window_t, QWindow *> QBBWindowMapper;
|
||||
|
||||
class QBBIntegration : public QPlatformIntegration
|
||||
{
|
||||
public:
|
||||
QBBIntegration();
|
||||
virtual ~QBBIntegration();
|
||||
|
||||
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
|
||||
|
||||
virtual QPlatformWindow *createPlatformWindow(QWindow *window) const;
|
||||
virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
|
||||
|
||||
virtual QPlatformInputContext *inputContext() const;
|
||||
|
||||
virtual QList<QPlatformScreen *> screens() const;
|
||||
virtual void moveToScreen(QWindow *window, int screen);
|
||||
|
||||
virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const;
|
||||
|
||||
virtual QPlatformFontDatabase *fontDatabase() const { return m_fontDatabase; }
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
virtual QPlatformClipboard *clipboard() const;
|
||||
#endif
|
||||
|
||||
virtual QVariant styleHint(StyleHint hint) const;
|
||||
|
||||
bool paintUsingOpenGL() const { return m_paintUsingOpenGL; }
|
||||
|
||||
static QWindow *window(screen_window_t qnxWindow);
|
||||
|
||||
private:
|
||||
static void addWindow(screen_window_t qnxWindow, QWindow *window);
|
||||
static void removeWindow(screen_window_t qnxWindow);
|
||||
|
||||
screen_context_t m_screenContext;
|
||||
QBBEventThread *m_eventThread;
|
||||
QBBNavigatorThread *m_navigatorThread;
|
||||
QBBInputContext *m_inputContext;
|
||||
QPlatformFontDatabase *m_fontDatabase;
|
||||
bool m_paintUsingOpenGL;
|
||||
QAbstractEventDispatcher *m_eventDispatcher;
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
mutable QBBClipboard* m_clipboard;
|
||||
#endif
|
||||
|
||||
static QBBWindowMapper ms_windowMapper;
|
||||
static QMutex ms_windowMapperMutex;
|
||||
|
||||
friend class QBBWindow;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBINTEGRATION_H
|
269
src/plugins/platforms/blackberry/qbbkeytranslator.h
Normal file
269
src/plugins/platforms/blackberry/qbbkeytranslator.h
Normal file
@ -0,0 +1,269 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBKEYTRANSLATOR_H
|
||||
#define QBBKEYTRANSLATOR_H
|
||||
|
||||
#include <sys/keycodes.h>
|
||||
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
#include <QtCore/QDebug>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Qt::Key keyTranslator( int key )
|
||||
{
|
||||
switch (key) {
|
||||
case KEYCODE_PAUSE:
|
||||
return Qt::Key_Pause;
|
||||
|
||||
case KEYCODE_SCROLL_LOCK:
|
||||
return Qt::Key_ScrollLock;
|
||||
|
||||
case KEYCODE_PRINT:
|
||||
return Qt::Key_Print;
|
||||
|
||||
case KEYCODE_SYSREQ:
|
||||
return Qt::Key_SysReq;
|
||||
|
||||
// case KEYCODE_BREAK:
|
||||
|
||||
case KEYCODE_ESCAPE:
|
||||
return Qt::Key_Escape;
|
||||
|
||||
case KEYCODE_BACKSPACE:
|
||||
return Qt::Key_Backspace;
|
||||
|
||||
case KEYCODE_TAB:
|
||||
return Qt::Key_Tab;
|
||||
|
||||
case KEYCODE_BACK_TAB:
|
||||
return Qt::Key_Backtab;
|
||||
|
||||
case KEYCODE_RETURN:
|
||||
return Qt::Key_Return;
|
||||
|
||||
case KEYCODE_CAPS_LOCK:
|
||||
return Qt::Key_CapsLock;
|
||||
|
||||
case KEYCODE_LEFT_SHIFT:
|
||||
case KEYCODE_RIGHT_SHIFT:
|
||||
return Qt::Key_Shift;
|
||||
|
||||
case KEYCODE_LEFT_CTRL:
|
||||
case KEYCODE_RIGHT_CTRL:
|
||||
return Qt::Key_Control;
|
||||
|
||||
case KEYCODE_LEFT_ALT:
|
||||
case KEYCODE_RIGHT_ALT:
|
||||
return Qt::Key_Alt;
|
||||
|
||||
case KEYCODE_MENU:
|
||||
return Qt::Key_Menu;
|
||||
|
||||
case KEYCODE_LEFT_HYPER:
|
||||
return Qt::Key_Hyper_L;
|
||||
|
||||
case KEYCODE_RIGHT_HYPER:
|
||||
return Qt::Key_Hyper_R;
|
||||
|
||||
case KEYCODE_INSERT:
|
||||
return Qt::Key_Insert;
|
||||
|
||||
case KEYCODE_HOME:
|
||||
return Qt::Key_Home;
|
||||
|
||||
case KEYCODE_PG_UP:
|
||||
return Qt::Key_PageUp;
|
||||
|
||||
case KEYCODE_DELETE:
|
||||
return Qt::Key_Delete;
|
||||
|
||||
case KEYCODE_END:
|
||||
return Qt::Key_End;
|
||||
|
||||
case KEYCODE_PG_DOWN:
|
||||
return Qt::Key_PageDown;
|
||||
|
||||
case KEYCODE_LEFT:
|
||||
return Qt::Key_Left;
|
||||
|
||||
case KEYCODE_RIGHT:
|
||||
return Qt::Key_Right;
|
||||
|
||||
case KEYCODE_UP:
|
||||
return Qt::Key_Up;
|
||||
|
||||
case KEYCODE_DOWN:
|
||||
return Qt::Key_Down;
|
||||
|
||||
case KEYCODE_NUM_LOCK:
|
||||
return Qt::Key_NumLock;
|
||||
|
||||
case KEYCODE_KP_PLUS:
|
||||
return Qt::Key_Plus;
|
||||
|
||||
case KEYCODE_KP_MINUS:
|
||||
return Qt::Key_Minus;
|
||||
|
||||
case KEYCODE_KP_MULTIPLY:
|
||||
return Qt::Key_Asterisk;
|
||||
|
||||
case KEYCODE_KP_DIVIDE:
|
||||
return Qt::Key_Slash;
|
||||
|
||||
case KEYCODE_KP_ENTER:
|
||||
return Qt::Key_Enter;
|
||||
|
||||
case KEYCODE_KP_HOME:
|
||||
return Qt::Key_Home;
|
||||
|
||||
case KEYCODE_KP_UP:
|
||||
return Qt::Key_Up;
|
||||
|
||||
case KEYCODE_KP_PG_UP:
|
||||
return Qt::Key_PageUp;
|
||||
|
||||
case KEYCODE_KP_LEFT:
|
||||
return Qt::Key_Left;
|
||||
|
||||
// Is this right?
|
||||
case KEYCODE_KP_FIVE:
|
||||
return Qt::Key_5;
|
||||
|
||||
case KEYCODE_KP_RIGHT:
|
||||
return Qt::Key_Right;
|
||||
|
||||
case KEYCODE_KP_END:
|
||||
return Qt::Key_End;
|
||||
|
||||
case KEYCODE_KP_DOWN:
|
||||
return Qt::Key_Down;
|
||||
|
||||
case KEYCODE_KP_PG_DOWN:
|
||||
return Qt::Key_PageDown;
|
||||
|
||||
case KEYCODE_KP_INSERT:
|
||||
return Qt::Key_Insert;
|
||||
|
||||
case KEYCODE_KP_DELETE:
|
||||
return Qt::Key_Delete;
|
||||
|
||||
case KEYCODE_F1:
|
||||
return Qt::Key_F1;
|
||||
|
||||
case KEYCODE_F2:
|
||||
return Qt::Key_F2;
|
||||
|
||||
case KEYCODE_F3:
|
||||
return Qt::Key_F3;
|
||||
|
||||
case KEYCODE_F4:
|
||||
return Qt::Key_F4;
|
||||
|
||||
case KEYCODE_F5:
|
||||
return Qt::Key_F5;
|
||||
|
||||
case KEYCODE_F6:
|
||||
return Qt::Key_F6;
|
||||
|
||||
case KEYCODE_F7:
|
||||
return Qt::Key_F7;
|
||||
|
||||
case KEYCODE_F8:
|
||||
return Qt::Key_F8;
|
||||
|
||||
case KEYCODE_F9:
|
||||
return Qt::Key_F9;
|
||||
|
||||
case KEYCODE_F10:
|
||||
return Qt::Key_F10;
|
||||
|
||||
case KEYCODE_F11:
|
||||
return Qt::Key_F11;
|
||||
|
||||
case KEYCODE_F12:
|
||||
return Qt::Key_F12;
|
||||
|
||||
// See keycodes.h for more, but these are all the basics. And printables are already included.
|
||||
|
||||
default:
|
||||
#if defined(QBBEVENTTHREAD_DEBUG)
|
||||
qDebug() << "QBB: unknown key for translation:" << key;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return Qt::Key_Escape;
|
||||
}
|
||||
|
||||
bool isKeypadKey( int key )
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KEYCODE_KP_PLUS:
|
||||
case KEYCODE_KP_MINUS:
|
||||
case KEYCODE_KP_MULTIPLY:
|
||||
case KEYCODE_KP_DIVIDE:
|
||||
case KEYCODE_KP_ENTER:
|
||||
case KEYCODE_KP_HOME:
|
||||
case KEYCODE_KP_UP:
|
||||
case KEYCODE_KP_PG_UP:
|
||||
case KEYCODE_KP_LEFT:
|
||||
case KEYCODE_KP_FIVE:
|
||||
case KEYCODE_KP_RIGHT:
|
||||
case KEYCODE_KP_END:
|
||||
case KEYCODE_KP_DOWN:
|
||||
case KEYCODE_KP_PG_DOWN:
|
||||
case KEYCODE_KP_INSERT:
|
||||
case KEYCODE_KP_DELETE:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBKEYTRANSLATOR_H
|
279
src/plugins/platforms/blackberry/qbbnavigatorthread.cpp
Normal file
279
src/plugins/platforms/blackberry/qbbnavigatorthread.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbnavigatorthread.h"
|
||||
#include "qbbscreen.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QSocketNotifier>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static const char *navigatorControlPath = "/pps/services/navigator/control";
|
||||
static const int ppsBufferSize = 4096;
|
||||
|
||||
QBBNavigatorThread::QBBNavigatorThread(QBBScreen& primaryScreen)
|
||||
: m_primaryScreen(primaryScreen),
|
||||
m_fd(-1),
|
||||
m_readNotifier(0)
|
||||
{
|
||||
}
|
||||
|
||||
QBBNavigatorThread::~QBBNavigatorThread()
|
||||
{
|
||||
// block until thread terminates
|
||||
shutdown();
|
||||
|
||||
delete m_readNotifier;
|
||||
}
|
||||
|
||||
void QBBNavigatorThread::run()
|
||||
{
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "QBB: navigator thread started";
|
||||
#endif
|
||||
|
||||
// open connection to navigator
|
||||
errno = 0;
|
||||
m_fd = open(navigatorControlPath, O_RDWR);
|
||||
if (m_fd == -1) {
|
||||
qWarning("QBB: failed to open navigator pps, errno=%d", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read);
|
||||
// using direct connection to get the slot called in this thread's context
|
||||
connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readData()), Qt::DirectConnection);
|
||||
|
||||
exec();
|
||||
|
||||
// close connection to navigator
|
||||
close(m_fd);
|
||||
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "QBB: navigator thread stopped";
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBBNavigatorThread::shutdown()
|
||||
{
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "QBB: navigator thread shutdown begin";
|
||||
#endif
|
||||
|
||||
// signal thread to terminate
|
||||
quit();
|
||||
|
||||
// block until thread terminates
|
||||
wait();
|
||||
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "QBB: navigator thread shutdown end";
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBBNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id)
|
||||
{
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: data=" << ppsData;
|
||||
#endif
|
||||
|
||||
// tokenize pps data into lines
|
||||
QList<QByteArray> lines = ppsData.split('\n');
|
||||
|
||||
// validate pps object
|
||||
if (lines.size() == 0 || lines.at(0) != "@control") {
|
||||
qFatal("QBB: unrecognized pps object, data=%s", ppsData.constData());
|
||||
}
|
||||
|
||||
// parse pps object attributes and extract values
|
||||
for (int i = 1; i < lines.size(); i++) {
|
||||
|
||||
// tokenize current attribute
|
||||
const QByteArray &attr = lines.at(i);
|
||||
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: attr=" << attr;
|
||||
#endif
|
||||
|
||||
int firstColon = attr.indexOf(':');
|
||||
if (firstColon == -1) {
|
||||
// abort - malformed attribute
|
||||
continue;
|
||||
}
|
||||
|
||||
int secondColon = attr.indexOf(':', firstColon + 1);
|
||||
if (secondColon == -1) {
|
||||
// abort - malformed attribute
|
||||
continue;
|
||||
}
|
||||
|
||||
QByteArray key = attr.left(firstColon);
|
||||
QByteArray value = attr.mid(secondColon + 1);
|
||||
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: key=" << key;
|
||||
qDebug() << "PPS: val=" << value;
|
||||
#endif
|
||||
|
||||
// save attribute value
|
||||
if (key == "msg") {
|
||||
msg = value;
|
||||
} else if (key == "dat") {
|
||||
dat = value;
|
||||
} else if (key == "id") {
|
||||
id = value;
|
||||
} else {
|
||||
qFatal("QBB: unrecognized pps attribute, attr=%s", key.constData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QBBNavigatorThread::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat)
|
||||
{
|
||||
// construct pps message
|
||||
QByteArray ppsData = "res::";
|
||||
ppsData += res;
|
||||
ppsData += "\nid::";
|
||||
ppsData += id;
|
||||
if (!dat.isEmpty()) {
|
||||
ppsData += "\ndat::";
|
||||
ppsData += dat;
|
||||
}
|
||||
ppsData += "\n";
|
||||
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS reply=" << ppsData;
|
||||
#endif
|
||||
|
||||
// send pps message to navigator
|
||||
errno = 0;
|
||||
int bytes = write(m_fd, ppsData.constData(), ppsData.size());
|
||||
if (bytes == -1) {
|
||||
qFatal("QBB: failed to write navigator pps, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id)
|
||||
{
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: msg=" << msg << ", dat=" << dat << ", id=" << id;
|
||||
#endif
|
||||
|
||||
// check message type
|
||||
if (msg == "orientationCheck") {
|
||||
|
||||
// reply to navigator that (any) orientation is acceptable
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: orientation check, o=" << dat;
|
||||
#endif
|
||||
replyPPS(msg, id, "true");
|
||||
|
||||
} else if (msg == "orientation") {
|
||||
|
||||
// update screen geometry and reply to navigator that we're ready
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: orientation, o=" << dat;
|
||||
#endif
|
||||
m_primaryScreen.setRotation( dat.toInt() );
|
||||
QWindowSystemInterface::handleScreenGeometryChange(0, m_primaryScreen.geometry());
|
||||
replyPPS(msg, id, "");
|
||||
|
||||
} else if (msg == "SWIPE_DOWN") {
|
||||
|
||||
// simulate menu key press
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: menu";
|
||||
#endif
|
||||
QWindow *w = QGuiApplication::focusWindow();
|
||||
QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyPress, Qt::Key_Menu, Qt::NoModifier);
|
||||
QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyRelease, Qt::Key_Menu, Qt::NoModifier);
|
||||
|
||||
} else if (msg == "exit") {
|
||||
|
||||
// shutdown everything
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "PPS: exit";
|
||||
#endif
|
||||
QCoreApplication::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void QBBNavigatorThread::readData()
|
||||
{
|
||||
#if defined(QBBNAVIGATORTHREAD_DEBUG)
|
||||
qDebug() << "QBB: reading navigator data";
|
||||
#endif
|
||||
// allocate buffer for pps data
|
||||
char buffer[ppsBufferSize];
|
||||
|
||||
// attempt to read pps data
|
||||
errno = 0;
|
||||
int bytes = read(m_fd, buffer, ppsBufferSize - 1);
|
||||
if (bytes == -1) {
|
||||
qFatal("QBB: failed to read navigator pps, errno=%d", errno);
|
||||
}
|
||||
|
||||
// check if pps data was received
|
||||
if (bytes > 0) {
|
||||
|
||||
// ensure data is null terminated
|
||||
buffer[bytes] = '\0';
|
||||
|
||||
// process received message
|
||||
QByteArray ppsData(buffer);
|
||||
QByteArray msg;
|
||||
QByteArray dat;
|
||||
QByteArray id;
|
||||
parsePPS(ppsData, msg, dat, id);
|
||||
handleMessage(msg, dat, id);
|
||||
}
|
||||
}
|
78
src/plugins/platforms/blackberry/qbbnavigatorthread.h
Normal file
78
src/plugins/platforms/blackberry/qbbnavigatorthread.h
Normal file
@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBNAVIGATORTHREAD_H
|
||||
#define QBBNAVIGATORTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBScreen;
|
||||
class QSocketNotifier;
|
||||
|
||||
class QBBNavigatorThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QBBNavigatorThread(QBBScreen &primaryScreen);
|
||||
virtual ~QBBNavigatorThread();
|
||||
|
||||
protected:
|
||||
virtual void run();
|
||||
|
||||
private Q_SLOTS:
|
||||
void readData();
|
||||
|
||||
private:
|
||||
void shutdown();
|
||||
void parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id);
|
||||
void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat);
|
||||
void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id);
|
||||
|
||||
QBBScreen &m_primaryScreen;
|
||||
int m_fd;
|
||||
QSocketNotifier *m_readNotifier;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBNAVIGATORTHREAD_H
|
166
src/plugins/platforms/blackberry/qbbrasterbackingstore.cpp
Normal file
166
src/plugins/platforms/blackberry/qbbrasterbackingstore.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbrasterbackingstore.h"
|
||||
#include "qbbwindow.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QBBRasterBackingStore::QBBRasterBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
{
|
||||
#if defined(QBBRASTERBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::QBBRasterBackingStore - w=" << window;
|
||||
#endif
|
||||
|
||||
// save platform window associated with widget
|
||||
m_platformWindow = static_cast<QBBWindow*>(window->handle());
|
||||
}
|
||||
|
||||
QBBRasterBackingStore::~QBBRasterBackingStore()
|
||||
{
|
||||
#if defined(QBBRasterBackingStore_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::~QBBRasterBackingStore - w=" << window();
|
||||
#endif
|
||||
}
|
||||
|
||||
QPaintDevice *QBBRasterBackingStore::paintDevice()
|
||||
{
|
||||
return m_platformWindow->renderBuffer().image();
|
||||
}
|
||||
|
||||
void QBBRasterBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
Q_UNUSED(window);
|
||||
Q_UNUSED(offset);
|
||||
|
||||
#if defined(QBBRASTERBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::flush - w=" << this->window();
|
||||
#endif
|
||||
|
||||
// visit all pending scroll operations
|
||||
for (int i = m_scrollOpList.size() - 1; i >= 0; i--) {
|
||||
|
||||
// do the scroll operation
|
||||
ScrollOp &op = m_scrollOpList[i];
|
||||
QRegion srcArea = op.totalArea.intersected( op.totalArea.translated(-op.dx, -op.dy) );
|
||||
m_platformWindow->scroll(srcArea, op.dx, op.dy);
|
||||
}
|
||||
|
||||
// clear all pending scroll operations
|
||||
m_scrollOpList.clear();
|
||||
|
||||
// update the display with newly rendered content
|
||||
m_platformWindow->post(region);
|
||||
}
|
||||
|
||||
void QBBRasterBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||
{
|
||||
Q_UNUSED(size);
|
||||
Q_UNUSED(staticContents);
|
||||
#if defined(QBBRASTERBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::resize - w=" << window() << ", s=" << size;
|
||||
#endif
|
||||
|
||||
// NOTE: defer resizing window buffers until next paint as
|
||||
// resize() can be called multiple times before a paint occurs
|
||||
}
|
||||
|
||||
bool QBBRasterBackingStore::scroll(const QRegion &area, int dx, int dy)
|
||||
{
|
||||
#if defined(QBBRASTERBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::scroll - w=" << window();
|
||||
#endif
|
||||
|
||||
// calculate entire region affected by scroll operation (src + dst)
|
||||
QRegion totalArea = area.translated(dx, dy);
|
||||
totalArea += area;
|
||||
|
||||
// visit all pending scroll operations
|
||||
for (int i = m_scrollOpList.size() - 1; i >= 0; i--) {
|
||||
|
||||
ScrollOp &op = m_scrollOpList[i];
|
||||
if (op.totalArea == totalArea) {
|
||||
// same area is being scrolled again - update delta
|
||||
op.dx += dx;
|
||||
op.dy += dy;
|
||||
return true;
|
||||
} else if (op.totalArea.intersects(totalArea)) {
|
||||
// current scroll overlaps previous scroll but is
|
||||
// not equal in area - just paint everything
|
||||
qWarning("QBB: pending scroll operations overlap but not equal");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// create new scroll operation
|
||||
m_scrollOpList.append( ScrollOp(totalArea, dx, dy) );
|
||||
return true;
|
||||
}
|
||||
|
||||
void QBBRasterBackingStore::beginPaint(const QRegion ®ion)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
|
||||
#if defined(QBBRASTERBACKINGSTORE_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::beginPaint - w=" << window();
|
||||
#endif
|
||||
|
||||
// resize window buffers if surface resized
|
||||
QSize s = window()->size();
|
||||
if (s != m_platformWindow->bufferSize()) {
|
||||
m_platformWindow->setBufferSize(s);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBRasterBackingStore::endPaint(const QRegion ®ion)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
#if defined(QBBRasterBackingStore_DEBUG)
|
||||
qDebug() << "QBBRasterBackingStore::endPaint - w=" << window();
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
81
src/plugins/platforms/blackberry/qbbrasterbackingstore.h
Normal file
81
src/plugins/platforms/blackberry/qbbrasterbackingstore.h
Normal file
@ -0,0 +1,81 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBRASTERWINDOWSURFACE_H
|
||||
#define QBBRASTERWINDOWSURFACE_H
|
||||
|
||||
#include <QtGui/qplatformbackingstore_qpa.h>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBWindow;
|
||||
|
||||
class QBBRasterBackingStore : public QPlatformBackingStore
|
||||
{
|
||||
public:
|
||||
QBBRasterBackingStore(QWindow *window);
|
||||
virtual ~QBBRasterBackingStore();
|
||||
|
||||
virtual QPaintDevice *paintDevice();
|
||||
virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset);
|
||||
virtual void resize(const QSize &size, const QRegion &staticContents);
|
||||
virtual bool scroll(const QRegion &area, int dx, int dy);
|
||||
virtual void beginPaint(const QRegion ®ion);
|
||||
virtual void endPaint(const QRegion ®ion);
|
||||
|
||||
private:
|
||||
class ScrollOp {
|
||||
public:
|
||||
ScrollOp(const QRegion &a, int x, int y) : totalArea(a), dx(x), dy(y) {}
|
||||
QRegion totalArea;
|
||||
int dx;
|
||||
int dy;
|
||||
};
|
||||
|
||||
QBBWindow *m_platformWindow;
|
||||
QList<ScrollOp> m_scrollOpList;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBRASTERWINDOWSURFACE_H
|
257
src/plugins/platforms/blackberry/qbbrootwindow.cpp
Normal file
257
src/plugins/platforms/blackberry/qbbrootwindow.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbrootwindow.h"
|
||||
|
||||
#include "qbbscreen.h"
|
||||
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#if defined(QBBROOTWINDOW_DEBUG)
|
||||
#include <QtCore/QDebug>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static const int MAGIC_ZORDER_FOR_NO_NAV = 10;
|
||||
|
||||
QBBRootWindow::QBBRootWindow(QBBScreen *screen)
|
||||
: m_screen(screen),
|
||||
m_window(0),
|
||||
m_windowGroupName()
|
||||
{
|
||||
#if defined(QBBROOTWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Create one top-level QNX window to act as a container for child windows
|
||||
// since navigator only supports one application window
|
||||
errno = 0;
|
||||
int result = screen_create_window(&m_window, m_screen->nativeContext());
|
||||
int val[2];
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to create window, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Move window to proper display
|
||||
errno = 0;
|
||||
screen_display_t display = m_screen->nativeDisplay();
|
||||
result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window display, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Make sure window is above navigator but below keyboard if running as root
|
||||
// since navigator won't automatically set our z-order in this case
|
||||
if (getuid() == 0) {
|
||||
errno = 0;
|
||||
val[0] = MAGIC_ZORDER_FOR_NO_NAV;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window z-order, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
// Window won't be visible unless it has some buffers so make one dummy buffer that is 1x1
|
||||
errno = 0;
|
||||
val[0] = SCREEN_USAGE_NATIVE;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window buffer usage, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val[0] = m_screen->nativeFormat();
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window pixel format, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val[0] = 1;
|
||||
val[1] = 1;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window buffer size, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
result = screen_create_window_buffers(m_window, 1);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to create window buffer, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Window is always the size of the display
|
||||
errno = 0;
|
||||
QRect geometry = m_screen->geometry();
|
||||
val[0] = geometry.width();
|
||||
val[1] = geometry.height();
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Fill the window with solid black
|
||||
errno = 0;
|
||||
val[0] = 0;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_COLOR, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window colour, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Make the window opaque
|
||||
errno = 0;
|
||||
val[0] = SCREEN_TRANSPARENCY_NONE;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window transparency, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Set the swap interval to 1
|
||||
errno = 0;
|
||||
val[0] = 1;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window swap interval, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Set viewport size equal to window size but move outside buffer so the fill colour is used exclusively
|
||||
errno = 0;
|
||||
val[0] = geometry.width();
|
||||
val[1] = geometry.height();
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window source size, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val[0] = 1;
|
||||
val[1] = 0;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_POSITION, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window source position, errno=%d", errno);
|
||||
}
|
||||
|
||||
createWindowGroup();
|
||||
post();
|
||||
}
|
||||
|
||||
QBBRootWindow::~QBBRootWindow()
|
||||
{
|
||||
// Cleanup top-level QNX window
|
||||
screen_destroy_window(m_window);
|
||||
}
|
||||
|
||||
void QBBRootWindow::post() const
|
||||
{
|
||||
#if defined(QBBROOTWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
errno = 0;
|
||||
screen_buffer_t buffer;
|
||||
int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&buffer);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to query window buffer, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
int dirtyRect[] = {0, 0, 1, 1};
|
||||
result = screen_post_window(m_window, buffer, 1, dirtyRect, 0);
|
||||
if (result != 0) {
|
||||
qFatal("QBB: failed to post window buffer, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBRootWindow::flush() const
|
||||
{
|
||||
#if defined(QBBROOTWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Force immediate display update
|
||||
errno = 0;
|
||||
int result = screen_flush_context(m_screen->nativeContext(), 0);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to flush context, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBRootWindow::setRotation(int rotation)
|
||||
{
|
||||
#if defined(QBBROOTWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "angle =" << rotation;
|
||||
#endif
|
||||
errno = 0;
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window rotation, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBRootWindow::resize(const QSize &size)
|
||||
{
|
||||
errno = 0;
|
||||
int val[] = {size.width(), size.height()};
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window size, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to set window source size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// NOTE: display will update when child windows relayout and repaint
|
||||
}
|
||||
|
||||
void QBBRootWindow::createWindowGroup()
|
||||
{
|
||||
// Generate a random window group name
|
||||
m_windowGroupName = QUuid::createUuid().toString().toAscii();
|
||||
|
||||
// Create window group so child windows can be parented by container window
|
||||
errno = 0;
|
||||
int result = screen_create_window_group(m_window, m_windowGroupName.constData());
|
||||
if (result != 0) {
|
||||
qFatal("QBBRootWindow: failed to create app window group, errno=%d", errno);
|
||||
}
|
||||
}
|
81
src/plugins/platforms/blackberry/qbbrootwindow.h
Normal file
81
src/plugins/platforms/blackberry/qbbrootwindow.h
Normal file
@ -0,0 +1,81 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBROOTWINDOW_H
|
||||
#define QBBROOTWINDOW_H
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QRect>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBScreen;
|
||||
|
||||
class QBBRootWindow
|
||||
{
|
||||
public:
|
||||
QBBRootWindow(QBBScreen *screen);
|
||||
~QBBRootWindow();
|
||||
|
||||
screen_window_t nativeHandle() const { return m_window; }
|
||||
|
||||
void post() const;
|
||||
void flush() const;
|
||||
|
||||
void setRotation(int rotation);
|
||||
|
||||
void resize(const QSize &size);
|
||||
|
||||
QByteArray groupName() const { return m_windowGroupName; }
|
||||
|
||||
private:
|
||||
void createWindowGroup();
|
||||
|
||||
QBBScreen *m_screen;
|
||||
screen_window_t m_window;
|
||||
QByteArray m_windowGroupName;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBROOTWINDOW_H
|
315
src/plugins/platforms/blackberry/qbbscreen.cpp
Normal file
315
src/plugins/platforms/blackberry/qbbscreen.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbscreen.h"
|
||||
#include "qbbvirtualkeyboard.h"
|
||||
#include "qbbwindow.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QList<QPlatformScreen *> QBBScreen::ms_screens;
|
||||
QList<QBBWindow*> QBBScreen::ms_childWindows;
|
||||
|
||||
QBBScreen::QBBScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen)
|
||||
: m_screenContext(screenContext),
|
||||
m_display(display),
|
||||
m_rootWindow(),
|
||||
m_primaryScreen(primaryScreen),
|
||||
m_posted(false),
|
||||
m_platformContext(0)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Cache initial orientation of this display
|
||||
// TODO: use ORIENTATION environment variable?
|
||||
errno = 0;
|
||||
int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION, &m_initialRotation);
|
||||
if (result != 0) {
|
||||
qFatal("QBBScreen: failed to query display rotation, errno=%d", errno);
|
||||
}
|
||||
m_currentRotation = m_initialRotation;
|
||||
|
||||
// Cache size of this display in pixels
|
||||
// TODO: use WIDTH and HEIGHT environment variables?
|
||||
errno = 0;
|
||||
int val[2];
|
||||
result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBScreen: failed to query display size, errno=%d", errno);
|
||||
}
|
||||
|
||||
m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]);
|
||||
|
||||
// Cache size of this display in millimeters
|
||||
errno = 0;
|
||||
result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_PHYSICAL_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBScreen: failed to query display physical size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Peg the DPI to 96 (for now) so fonts are a reasonable size. We'll want to match
|
||||
// everything with a QStyle later, and at that point the physical size can be used
|
||||
// instead.
|
||||
{
|
||||
static const int dpi = 96;
|
||||
int width = m_currentGeometry.width() / dpi * qreal(25.4) ;
|
||||
int height = m_currentGeometry.height() / dpi * qreal(25.4) ;
|
||||
|
||||
m_currentPhysicalSize = m_initialPhysicalSize = QSize(width,height);
|
||||
}
|
||||
|
||||
// We only create the root window if we are the primary display.
|
||||
if (primaryScreen)
|
||||
m_rootWindow = QSharedPointer<QBBRootWindow>(new QBBRootWindow(this));
|
||||
}
|
||||
|
||||
QBBScreen::~QBBScreen()
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
void QBBScreen::createDisplays(screen_context_t context)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Query number of displays
|
||||
errno = 0;
|
||||
int displayCount;
|
||||
int result = screen_get_context_property_iv(context, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount);
|
||||
if (result != 0) {
|
||||
qFatal("QBBScreen: failed to query display count, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Get all displays
|
||||
errno = 0;
|
||||
screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
|
||||
result = screen_get_context_property_pv(context, SCREEN_PROPERTY_DISPLAYS, (void **)displays);
|
||||
if (result != 0) {
|
||||
qFatal("QBBScreen: failed to query displays, errno=%d", errno);
|
||||
}
|
||||
|
||||
for (int i=0; i<displayCount; i++) {
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << "QBBScreen::Creating screen for display " << i;
|
||||
#endif
|
||||
QBBScreen *screen = new QBBScreen(context, displays[i], i==0);
|
||||
ms_screens.append(screen);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void QBBScreen::destroyDisplays()
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
qDeleteAll(ms_screens);
|
||||
ms_screens.clear();
|
||||
|
||||
// We're not managing the child windows anymore so we need to clear the list.
|
||||
ms_childWindows.clear();
|
||||
}
|
||||
|
||||
/* static */
|
||||
int QBBScreen::defaultDepth()
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
static int defaultDepth = 0;
|
||||
if (defaultDepth == 0) {
|
||||
// check if display depth was specified in environment variable;
|
||||
// use default value if no valid value found
|
||||
defaultDepth = qgetenv("QBB_DISPLAY_DEPTH").toInt();
|
||||
if (defaultDepth != 16 && defaultDepth != 32) {
|
||||
defaultDepth = 32;
|
||||
}
|
||||
}
|
||||
return defaultDepth;
|
||||
}
|
||||
|
||||
QRect QBBScreen::availableGeometry() const
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// available geometry = total geometry - keyboard
|
||||
int keyboardHeight = QBBVirtualKeyboard::instance().height();
|
||||
return QRect(m_currentGeometry.x(), m_currentGeometry.y(),
|
||||
m_currentGeometry.width(), m_currentGeometry.height() - keyboardHeight);
|
||||
}
|
||||
|
||||
/*!
|
||||
Check if the supplied angles are perpendicular to each other.
|
||||
*/
|
||||
static bool isOrthogonal(int angle1, int angle2)
|
||||
{
|
||||
return ((angle1 - angle2) % 180) != 0;
|
||||
}
|
||||
|
||||
void QBBScreen::setRotation(int rotation)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "orientation =" << rotation;
|
||||
#endif
|
||||
// Check if rotation changed
|
||||
if (m_currentRotation != rotation) {
|
||||
// Update rotation of root window
|
||||
if (m_rootWindow)
|
||||
m_rootWindow->setRotation(rotation);
|
||||
|
||||
// Swap dimensions if we've rotated 90 or 270 from initial orientation
|
||||
if (isOrthogonal(m_currentRotation, rotation)) {
|
||||
m_currentGeometry = QRect(0, 0, m_initialGeometry.height(), m_initialGeometry.width());
|
||||
m_currentPhysicalSize = QSize(m_initialPhysicalSize.height(), m_initialPhysicalSize.width());
|
||||
} else {
|
||||
m_currentGeometry = QRect(0, 0, m_initialGeometry.width(), m_initialGeometry.height());
|
||||
m_currentPhysicalSize = m_initialPhysicalSize;
|
||||
}
|
||||
|
||||
// Resize root window if we've rotated 90 or 270 from previous orientation
|
||||
if (isOrthogonal(m_currentRotation, rotation)) {
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "resize, size =" << m_currentGeometry.size();
|
||||
#endif
|
||||
if (m_rootWindow)
|
||||
m_rootWindow->resize(m_currentGeometry.size());
|
||||
} else {
|
||||
// TODO: Find one global place to flush display updates
|
||||
// Force immediate display update if no geometry changes required
|
||||
if (m_rootWindow)
|
||||
m_rootWindow->flush();
|
||||
}
|
||||
|
||||
// Save new rotation
|
||||
m_currentRotation = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
void QBBScreen::addWindow(QBBWindow *window)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window;
|
||||
#endif
|
||||
|
||||
if (ms_childWindows.contains(window))
|
||||
return;
|
||||
|
||||
ms_childWindows.push_back(window);
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBScreen::removeWindow(QBBWindow *window)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window;
|
||||
#endif
|
||||
|
||||
ms_childWindows.removeAll(window);
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBScreen::raiseWindow(QBBWindow *window)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window;
|
||||
#endif
|
||||
|
||||
removeWindow(window);
|
||||
ms_childWindows.push_back(window);
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBScreen::lowerWindow(QBBWindow *window)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window;
|
||||
#endif
|
||||
|
||||
removeWindow(window);
|
||||
ms_childWindows.push_front(window);
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBScreen::updateHierarchy()
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
|
||||
QList<QBBWindow*>::iterator it;
|
||||
int topZorder = 0;
|
||||
|
||||
for (it = ms_childWindows.begin(); it != ms_childWindows.end(); it++)
|
||||
(*it)->updateZorder(topZorder);
|
||||
|
||||
// After a hierarchy update, we need to force a flush on all screens.
|
||||
// Right now, all screens share a context.
|
||||
screen_flush_context( primaryDisplay()->m_screenContext, 0 );
|
||||
}
|
||||
|
||||
void QBBScreen::onWindowPost(QBBWindow *window)
|
||||
{
|
||||
#if defined(QBBSCREEN_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
Q_UNUSED(window)
|
||||
|
||||
// post app window (so navigator will show it) after first child window
|
||||
// has posted; this only needs to happen once as the app window's content
|
||||
// never changes
|
||||
if (!m_posted && m_rootWindow) {
|
||||
m_rootWindow->post();
|
||||
m_posted = true;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
121
src/plugins/platforms/blackberry/qbbscreen.h
Normal file
121
src/plugins/platforms/blackberry/qbbscreen.h
Normal file
@ -0,0 +1,121 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBSCREEN_H
|
||||
#define QBBSCREEN_H
|
||||
|
||||
#include <QtGui/QPlatformScreen>
|
||||
|
||||
#include "qbbrootwindow.h"
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QScopedPointer>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QBBWindow;
|
||||
|
||||
class QBBScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
static QList<QPlatformScreen *> screens() { return ms_screens; }
|
||||
static void createDisplays(screen_context_t context);
|
||||
static void destroyDisplays();
|
||||
static QBBScreen *primaryDisplay() { return static_cast<QBBScreen*>(ms_screens.at(0)); }
|
||||
static int defaultDepth();
|
||||
|
||||
virtual QRect geometry() const { return m_currentGeometry; }
|
||||
virtual QRect availableGeometry() const;
|
||||
virtual int depth() const { return defaultDepth(); }
|
||||
virtual QImage::Format format() const { return (depth() == 32) ? QImage::Format_RGB32 : QImage::Format_RGB16; }
|
||||
virtual QSizeF physicalSize() const { return m_currentPhysicalSize; }
|
||||
|
||||
bool isPrimaryScreen() const { return m_primaryScreen; }
|
||||
|
||||
int rotation() const { return m_currentRotation; }
|
||||
void setRotation(int rotation);
|
||||
|
||||
int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; }
|
||||
screen_display_t nativeDisplay() const { return m_display; }
|
||||
screen_context_t nativeContext() const { return m_screenContext; }
|
||||
const char *windowGroupName() const { return m_rootWindow->groupName().constData(); }
|
||||
|
||||
/* Window hierarchy management */
|
||||
static void addWindow(QBBWindow *child);
|
||||
static void removeWindow(QBBWindow *child);
|
||||
static void raiseWindow(QBBWindow *window);
|
||||
static void lowerWindow(QBBWindow *window);
|
||||
static void updateHierarchy();
|
||||
|
||||
void onWindowPost(QBBWindow *window);
|
||||
|
||||
QSharedPointer<QBBRootWindow> rootWindow() const { return m_rootWindow; }
|
||||
|
||||
private:
|
||||
QBBScreen(screen_context_t context, screen_display_t display, bool primaryScreen);
|
||||
virtual ~QBBScreen();
|
||||
|
||||
static bool orthogonal(int rotation1, int rotation2);
|
||||
|
||||
screen_context_t m_screenContext;
|
||||
screen_display_t m_display;
|
||||
QSharedPointer<QBBRootWindow> m_rootWindow;
|
||||
bool m_primaryScreen;
|
||||
bool m_posted;
|
||||
bool m_usingOpenGL;
|
||||
|
||||
int m_initialRotation;
|
||||
int m_currentRotation;
|
||||
QSize m_initialPhysicalSize;
|
||||
QSize m_currentPhysicalSize;
|
||||
QRect m_initialGeometry;
|
||||
QRect m_currentGeometry;
|
||||
QPlatformOpenGLContext *m_platformContext;
|
||||
|
||||
static QList<QPlatformScreen *> ms_screens;
|
||||
static QList<QBBWindow *> ms_childWindows;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBSCREEN_H
|
500
src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp
Normal file
500
src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp
Normal file
@ -0,0 +1,500 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbvirtualkeyboard.h"
|
||||
#include "qbbscreen.h"
|
||||
|
||||
#include <QtGui/QPlatformScreen>
|
||||
#include <QtGui/QPlatformWindow>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/iomsg.h>
|
||||
#include <sys/pps.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *QBBVirtualKeyboard::ms_PPSPath = "/pps/services/input/control?wait";
|
||||
const size_t QBBVirtualKeyboard::ms_bufferSize = 2048;
|
||||
|
||||
static QBBVirtualKeyboard *s_instance = 0;
|
||||
|
||||
// Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP.
|
||||
#define KEYBOARD_SHADOW_HEIGHT 8
|
||||
|
||||
QBBVirtualKeyboard::QBBVirtualKeyboard() :
|
||||
m_encoder(NULL),
|
||||
m_decoder(NULL),
|
||||
m_buffer(NULL),
|
||||
m_height(0),
|
||||
m_fd(-1),
|
||||
m_keyboardMode(Default),
|
||||
m_visible(false),
|
||||
m_locale(QLatin1String("en_US"))
|
||||
{
|
||||
connect();
|
||||
}
|
||||
|
||||
QBBVirtualKeyboard::~QBBVirtualKeyboard()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
/* static */
|
||||
QBBVirtualKeyboard& QBBVirtualKeyboard::instance()
|
||||
{
|
||||
if (!s_instance) {
|
||||
s_instance = new QBBVirtualKeyboard();
|
||||
s_instance->start();
|
||||
}
|
||||
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void QBBVirtualKeyboard::destroy()
|
||||
{
|
||||
if (s_instance) {
|
||||
delete s_instance;
|
||||
s_instance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::close()
|
||||
{
|
||||
if (m_fd) {
|
||||
// any reads will fail after we close the fd, which is basically what we want.
|
||||
::close(m_fd);
|
||||
}
|
||||
|
||||
// Wait for the thread to die (should be immediate), then continue the cleanup.
|
||||
wait();
|
||||
|
||||
if (m_fd) {
|
||||
m_fd = -1;
|
||||
}
|
||||
|
||||
|
||||
if (m_decoder)
|
||||
{
|
||||
pps_decoder_cleanup(m_decoder);
|
||||
delete m_decoder;
|
||||
m_decoder = NULL;
|
||||
}
|
||||
|
||||
if (m_encoder)
|
||||
{
|
||||
pps_encoder_cleanup(m_encoder);
|
||||
delete m_encoder;
|
||||
m_encoder = NULL;
|
||||
}
|
||||
|
||||
delete [] m_buffer;
|
||||
m_buffer = NULL;
|
||||
}
|
||||
|
||||
bool QBBVirtualKeyboard::connect()
|
||||
{
|
||||
close();
|
||||
|
||||
m_encoder = new pps_encoder_t;
|
||||
m_decoder = new pps_decoder_t;
|
||||
|
||||
pps_encoder_initialize(m_encoder, false);
|
||||
pps_decoder_initialize(m_decoder, NULL);
|
||||
|
||||
errno = 0;
|
||||
m_fd = ::open(ms_PPSPath, O_RDWR);
|
||||
if (m_fd == -1)
|
||||
{
|
||||
qCritical("QBBVirtualKeyboard: Unable to open \"%s\" for keyboard: %s (%d).",
|
||||
ms_PPSPath, strerror(errno), errno);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_buffer = new char[ms_bufferSize];
|
||||
if (!m_buffer) {
|
||||
qCritical("QBBVirtualKeyboard: Unable to allocate buffer of %d bytes. Size is unavailable.", ms_bufferSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!queryPPSInfo())
|
||||
return false;
|
||||
|
||||
start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QBBVirtualKeyboard::queryPPSInfo()
|
||||
{
|
||||
// Request info, requires id to regenerate res message.
|
||||
pps_encoder_add_string(m_encoder, "msg", "info");
|
||||
pps_encoder_add_string(m_encoder, "id", "libWebView");
|
||||
|
||||
if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
pps_encoder_reset(m_encoder);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::notifyClientActiveStateChange(bool active)
|
||||
{
|
||||
if (!active)
|
||||
hideKeyboard();
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::run()
|
||||
{
|
||||
ppsDataReady();
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::ppsDataReady()
|
||||
{
|
||||
while (1) {
|
||||
ssize_t nread = read(m_fd, m_buffer, ms_bufferSize - 1);
|
||||
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: keyboardMessage size: " << nread;
|
||||
#endif
|
||||
if (nread < 0)
|
||||
break;
|
||||
|
||||
// nread is the real space necessary, not the amount read.
|
||||
if (static_cast<size_t>(nread) > ms_bufferSize - 1) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
m_buffer[nread] = 0;
|
||||
pps_decoder_parse_pps_str(m_decoder, m_buffer);
|
||||
pps_decoder_push(m_decoder, NULL);
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
pps_decoder_dump_tree(m_decoder, stderr);
|
||||
#endif
|
||||
|
||||
const char *value;
|
||||
if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) {
|
||||
if (strcmp(value, "show") == 0) {
|
||||
const bool oldVisible = m_visible;
|
||||
m_visible = true;
|
||||
handleKeyboardStateChangeMessage(true);
|
||||
if (oldVisible != m_visible)
|
||||
emit visibilityChanged(m_visible);
|
||||
} else if (strcmp(value, "hide") == 0) {
|
||||
const bool oldVisible = m_visible;
|
||||
m_visible = false;
|
||||
handleKeyboardStateChangeMessage(false);
|
||||
if (oldVisible != m_visible)
|
||||
emit visibilityChanged(m_visible);
|
||||
} else if (strcmp(value, "info") == 0)
|
||||
handleKeyboardInfoMessage();
|
||||
else if (strcmp(value, "connect") == 0) { }
|
||||
else
|
||||
qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]");
|
||||
} else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) {
|
||||
if (strcmp(value, "info") == 0)
|
||||
handleKeyboardInfoMessage();
|
||||
else
|
||||
qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]");
|
||||
} else
|
||||
qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS message type");
|
||||
}
|
||||
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: exiting keyboard thread";
|
||||
#endif
|
||||
|
||||
if (m_decoder)
|
||||
pps_decoder_cleanup(m_decoder);
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::handleKeyboardInfoMessage()
|
||||
{
|
||||
int newHeight = 0;
|
||||
const char *value;
|
||||
|
||||
if (pps_decoder_push(m_decoder, "dat") != PPS_DECODER_OK) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard PPS dat object not found");
|
||||
return;
|
||||
}
|
||||
if (pps_decoder_get_int(m_decoder, "size", &newHeight) != PPS_DECODER_OK) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard PPS size field not found");
|
||||
return;
|
||||
}
|
||||
if (pps_decoder_push(m_decoder, "locale") != PPS_DECODER_OK) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard PPS locale object not found");
|
||||
return;
|
||||
}
|
||||
if (pps_decoder_get_string(m_decoder, "languageId", &value) != PPS_DECODER_OK) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard PPS languageId field not found");
|
||||
return;
|
||||
}
|
||||
const QString languageId = QString::fromLatin1(value);
|
||||
if (pps_decoder_get_string(m_decoder, "countryId", &value) != PPS_DECODER_OK) {
|
||||
qCritical("QBBVirtualKeyboard: Keyboard PPS size countryId not found");
|
||||
return;
|
||||
}
|
||||
const QString countryId = QString::fromLatin1(value);
|
||||
|
||||
// HUGE hack, should be removed ASAP.
|
||||
newHeight -= KEYBOARD_SHADOW_HEIGHT; // We want to ignore the 8 pixel shadow above the keyboard. (PR 88400)
|
||||
|
||||
if (newHeight != m_height) {
|
||||
m_height = newHeight;
|
||||
updateAvailableScreenGeometry();
|
||||
}
|
||||
|
||||
const QLocale locale = QLocale(languageId + QLatin1Char('_') + countryId);
|
||||
if (locale != m_locale) {
|
||||
m_locale = locale;
|
||||
emit localeChanged(locale);
|
||||
}
|
||||
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: handleKeyboardInfoMessage size=" << m_height << "locale=" << m_locale;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::handleKeyboardStateChangeMessage(bool visible)
|
||||
{
|
||||
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: handleKeyboardStateChangeMessage " << visible;
|
||||
#endif
|
||||
updateAvailableScreenGeometry();
|
||||
|
||||
if (visible)
|
||||
showKeyboard();
|
||||
else
|
||||
hideKeyboard();
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::updateAvailableScreenGeometry()
|
||||
{
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: updateAvailableScreenGeometry: keyboard visible=" << m_visible << ", keyboard height=" << m_height;
|
||||
#endif
|
||||
|
||||
// TODO: What screen index should be used? I assume primaryScreen here because it works, and
|
||||
// we do it for handleScreenGeometryChange elsewhere but since we have support
|
||||
// for more than one screen, that's not going to always work.
|
||||
QBBScreen *platformScreen = QBBScreen::primaryDisplay();
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(platformScreen->screen(), platformScreen->availableGeometry());
|
||||
}
|
||||
|
||||
bool QBBVirtualKeyboard::showKeyboard()
|
||||
{
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: showKeyboard()";
|
||||
#endif
|
||||
|
||||
// Try to connect.
|
||||
if (m_fd == -1 && !connect())
|
||||
return false;
|
||||
|
||||
// NOTE: This must be done everytime the keyboard is shown even if there is no change because
|
||||
// hiding the keyboard wipes the setting.
|
||||
applyKeyboardModeOptions();
|
||||
|
||||
pps_encoder_reset(m_encoder);
|
||||
|
||||
// Send the show message.
|
||||
pps_encoder_add_string(m_encoder, "msg", "show");
|
||||
|
||||
if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
pps_encoder_reset(m_encoder);
|
||||
|
||||
// Return true if no error occurs. Sizing response will be triggered when confirmation of
|
||||
// the change arrives.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QBBVirtualKeyboard::hideKeyboard()
|
||||
{
|
||||
#ifdef QBBVIRTUALKEYBOARD_DEBUG
|
||||
qDebug() << "QBB: hideKeyboard()";
|
||||
#endif
|
||||
|
||||
if (m_fd == -1 && !connect())
|
||||
return false;
|
||||
|
||||
pps_encoder_add_string(m_encoder, "msg", "hide");
|
||||
|
||||
if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
|
||||
close();
|
||||
|
||||
//Try again.
|
||||
if (connect()) {
|
||||
if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
pps_encoder_reset(m_encoder);
|
||||
|
||||
// Return true if no error occurs. Sizing response will be triggered when confirmation of
|
||||
// the change arrives.
|
||||
return true;
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::setKeyboardMode(KeyboardMode mode)
|
||||
{
|
||||
m_keyboardMode = mode;
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::applyKeyboardModeOptions()
|
||||
{
|
||||
// Try to connect.
|
||||
if (m_fd == -1 && !connect())
|
||||
return;
|
||||
|
||||
// Send the options message.
|
||||
pps_encoder_add_string(m_encoder, "msg", "options");
|
||||
|
||||
pps_encoder_start_object(m_encoder, "dat");
|
||||
switch (m_keyboardMode) {
|
||||
case Url:
|
||||
addUrlModeOptions();
|
||||
break;
|
||||
case Email:
|
||||
addEmailModeOptions();
|
||||
break;
|
||||
case Web:
|
||||
addWebModeOptions();
|
||||
break;
|
||||
case NumPunc:
|
||||
addNumPuncModeOptions();
|
||||
break;
|
||||
case Symbol:
|
||||
addSymbolModeOptions();
|
||||
break;
|
||||
case Phone:
|
||||
addPhoneModeOptions();
|
||||
break;
|
||||
case Pin:
|
||||
addPinModeOptions();
|
||||
break;
|
||||
case Default:
|
||||
default:
|
||||
addDefaultModeOptions();
|
||||
break;
|
||||
}
|
||||
|
||||
pps_encoder_end_object(m_encoder);
|
||||
|
||||
if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
|
||||
close();
|
||||
}
|
||||
|
||||
pps_encoder_reset(m_encoder);
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addDefaultModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "default");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addUrlModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "url");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addEmailModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "email");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addWebModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "web");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addNumPuncModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "numPunc");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addPhoneModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "phone");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addPinModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "pin");
|
||||
}
|
||||
|
||||
void QBBVirtualKeyboard::addSymbolModeOptions()
|
||||
{
|
||||
pps_encoder_add_string(m_encoder, "enter", "enter.default");
|
||||
pps_encoder_add_string(m_encoder, "type", "symbol");
|
||||
}
|
130
src/plugins/platforms/blackberry/qbbvirtualkeyboard.h
Normal file
130
src/plugins/platforms/blackberry/qbbvirtualkeyboard.h
Normal file
@ -0,0 +1,130 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef VIRTUALKEYBOARD_H_
|
||||
#define VIRTUALKEYBOARD_H_
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtGui/QPlatformScreen>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sys/pps.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/* Shamelessly copied from the browser - this should be rewritten once we have a proper PPS wrapper class */
|
||||
class QBBVirtualKeyboard : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// NOTE: Not all the following keyboard modes are currently used.
|
||||
// Default - Regular Keyboard
|
||||
// Url/Email - Enhanced keys for each types.
|
||||
// Web - Regular keyboard with two blank keys, currently unused.
|
||||
// NumPunc - Numbers & Punctionation, alternate to Symbol
|
||||
// Symbol - All symbols, alternate to NumPunc, currently unused.
|
||||
// Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z
|
||||
// Pin - Keyboard for entering Pins (Hex values) currently unused.
|
||||
//
|
||||
// SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional.
|
||||
//
|
||||
enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin };
|
||||
|
||||
static QBBVirtualKeyboard& instance();
|
||||
static void destroy();
|
||||
|
||||
bool showKeyboard();
|
||||
bool hideKeyboard();
|
||||
int height() { return m_visible ? m_height : 0; }
|
||||
void setKeyboardMode(KeyboardMode);
|
||||
void notifyClientActiveStateChange(bool);
|
||||
bool isVisible() const { return m_visible; }
|
||||
QLocale locale() const { return m_locale; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void localeChanged(const QLocale &locale);
|
||||
void visibilityChanged(bool visible);
|
||||
|
||||
private:
|
||||
QBBVirtualKeyboard();
|
||||
virtual ~QBBVirtualKeyboard();
|
||||
|
||||
// Will be called internally if needed.
|
||||
bool connect();
|
||||
void close();
|
||||
void ppsDataReady();
|
||||
bool queryPPSInfo();
|
||||
void handleKeyboardInfoMessage();
|
||||
void handleKeyboardStateChangeMessage(bool visible);
|
||||
void updateAvailableScreenGeometry();
|
||||
|
||||
void applyKeyboardModeOptions();
|
||||
void addDefaultModeOptions();
|
||||
void addUrlModeOptions();
|
||||
void addEmailModeOptions();
|
||||
void addWebModeOptions();
|
||||
void addNumPuncModeOptions();
|
||||
void addSymbolModeOptions();
|
||||
void addPhoneModeOptions();
|
||||
void addPinModeOptions();
|
||||
|
||||
// QThread overrides
|
||||
virtual void run();
|
||||
|
||||
pps_encoder_t *m_encoder;
|
||||
pps_decoder_t *m_decoder;
|
||||
char *m_buffer;
|
||||
int m_height;
|
||||
int m_fd;
|
||||
KeyboardMode m_keyboardMode;
|
||||
bool m_visible;
|
||||
QLocale m_locale;
|
||||
|
||||
// Path to keyboardManager in PPS.
|
||||
static const char *ms_PPSPath;
|
||||
static const size_t ms_bufferSize;
|
||||
};
|
||||
|
||||
#endif /* VIRTUALKEYBOARD_H_ */
|
665
src/plugins/platforms/blackberry/qbbwindow.cpp
Normal file
665
src/plugins/platforms/blackberry/qbbwindow.cpp
Normal file
@ -0,0 +1,665 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qbbwindow.h"
|
||||
#include "qbbglcontext.h"
|
||||
#include "qbbintegration.h"
|
||||
#include "qbbscreen.h"
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QWindowSystemInterface>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QBBWindow::QBBWindow(QWindow *window, screen_context_t context)
|
||||
: QPlatformWindow(window),
|
||||
m_screenContext(context),
|
||||
m_window(0),
|
||||
m_currentBufferIndex(-1),
|
||||
m_previousBufferIndex(-1),
|
||||
m_platformOpenGLContext(0),
|
||||
m_screen(0),
|
||||
m_parentWindow(0),
|
||||
m_visible(true)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
|
||||
#endif
|
||||
int result;
|
||||
|
||||
// Create child QNX window
|
||||
errno = 0;
|
||||
result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to create window, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Set window buffer usage based on rendering API
|
||||
int val;
|
||||
QSurface::SurfaceType surfaceType = window->surfaceType();
|
||||
switch (surfaceType) {
|
||||
case QSurface::RasterSurface:
|
||||
val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE;
|
||||
break;
|
||||
case QSurface::OpenGLSurface:
|
||||
val = SCREEN_USAGE_OPENGL_ES2;
|
||||
break;
|
||||
default:
|
||||
qFatal("QBBWindow: unsupported window API");
|
||||
break;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, &val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window buffer usage, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Alpha channel is always pre-multiplied if present
|
||||
errno = 0;
|
||||
val = SCREEN_PRE_MULTIPLIED_ALPHA;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window alpha mode, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Make the window opaque
|
||||
errno = 0;
|
||||
val = SCREEN_TRANSPARENCY_NONE;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window transparency, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Set the window swap interval
|
||||
errno = 0;
|
||||
val = 1;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window swap interval, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Assign the window to the primary display (this is the default specified by screen).
|
||||
setScreen(QBBScreen::primaryDisplay());
|
||||
|
||||
// Add the window to the root of the hierarchy
|
||||
QBBScreen::addWindow(this);
|
||||
|
||||
// Add window to plugin's window mapper
|
||||
QBBIntegration::addWindow(m_window, window);
|
||||
}
|
||||
|
||||
QBBWindow::~QBBWindow()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
// Remove from plugin's window mapper
|
||||
QBBIntegration::removeWindow(m_window);
|
||||
|
||||
// Remove from parent's Hierarchy.
|
||||
removeFromParent();
|
||||
QBBScreen::updateHierarchy();
|
||||
|
||||
// We shouldn't allow this case unless QT allows it. Does it? Or should we send the
|
||||
// handleCloseEvent on all children when this window is deleted?
|
||||
if (m_childWindows.size() > 0)
|
||||
qFatal("QBBWindow: window destroyed before children!");
|
||||
|
||||
// Cleanup QNX window and its buffers
|
||||
screen_destroy_window(m_window);
|
||||
}
|
||||
|
||||
void QBBWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window() << ", (" << rect.x() << "," << rect.y() << "," << rect.width() << "," << rect.height() << ")";
|
||||
#endif
|
||||
|
||||
QRect oldGeometry = geometry();
|
||||
|
||||
// Call base class method
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
|
||||
// Set window geometry equal to widget geometry
|
||||
errno = 0;
|
||||
int val[2];
|
||||
val[0] = rect.x();
|
||||
val[1] = rect.y();
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window position, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val[0] = rect.width();
|
||||
val[1] = rect.height();
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Set viewport size equal to window size
|
||||
errno = 0;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window source size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Now move all children.
|
||||
QPoint offset;
|
||||
if (!oldGeometry.isEmpty()) {
|
||||
offset = rect.topLeft();
|
||||
offset -= oldGeometry.topLeft();
|
||||
|
||||
QList<QBBWindow*>::iterator it;
|
||||
for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) {
|
||||
(*it)->offset(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QBBWindow::offset(const QPoint &offset)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
// Move self and then children.
|
||||
QRect newGeometry = geometry();
|
||||
newGeometry.translate(offset);
|
||||
|
||||
// Call the base class
|
||||
QPlatformWindow::setGeometry(newGeometry);
|
||||
|
||||
int val[2];
|
||||
|
||||
errno = 0;
|
||||
val[0] = newGeometry.x();
|
||||
val[1] = newGeometry.y();
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window position, errno=%d", errno);
|
||||
}
|
||||
|
||||
QList<QBBWindow*>::iterator it;
|
||||
for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) {
|
||||
(*it)->offset(offset);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBWindow::setVisible(bool visible)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window() << "visible =" << visible;
|
||||
#endif
|
||||
|
||||
m_visible = visible;
|
||||
|
||||
QBBWindow *root = this;
|
||||
while (root->m_parentWindow)
|
||||
root = root->m_parentWindow;
|
||||
|
||||
root->updateVisibility(root->m_visible);
|
||||
|
||||
window()->requestActivateWindow();
|
||||
}
|
||||
|
||||
void QBBWindow::updateVisibility(bool parentVisible)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window();
|
||||
#endif
|
||||
// Set window visibility
|
||||
errno = 0;
|
||||
int val = (m_visible && parentVisible) ? 1 : 0;
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window visibility, errno=%d", errno);
|
||||
}
|
||||
|
||||
QList<QBBWindow *>::iterator it;
|
||||
for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) {
|
||||
(*it)->updateVisibility(m_visible && parentVisible);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBWindow::setOpacity(qreal level)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level;
|
||||
#endif
|
||||
// Set window global alpha
|
||||
errno = 0;
|
||||
int val = (int)(level * 255);
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window global alpha, errno=%d", errno);
|
||||
}
|
||||
|
||||
// TODO: How to handle children of this window? If we change all the visibilities, then
|
||||
// the transparency will look wrong...
|
||||
}
|
||||
|
||||
void QBBWindow::setBufferSize(const QSize &size)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
|
||||
#endif
|
||||
// Set window buffer size
|
||||
errno = 0;
|
||||
int val[2] = { size.width(), size.height() };
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window buffer size, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Create window buffers if they do not exist
|
||||
if (!hasBuffers()) {
|
||||
// Get pixel format from EGL config if using OpenGL;
|
||||
// otherwise inherit pixel format of window's screen
|
||||
if (m_platformOpenGLContext != 0) {
|
||||
val[0] = platformWindowFormatToNativeFormat(m_platformOpenGLContext->format());
|
||||
} else {
|
||||
val[0] = m_screen->nativeFormat();
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window pixel format, errno=%d", errno);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to create window buffers, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
// Cache new buffer size
|
||||
m_bufferSize = size;
|
||||
|
||||
// Buffers were destroyed; reacquire them
|
||||
m_currentBufferIndex = -1;
|
||||
m_previousDirty = QRegion();
|
||||
m_scrolled = QRegion();
|
||||
}
|
||||
|
||||
QBBBuffer &QBBWindow::renderBuffer()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
// Check if render buffer is invalid
|
||||
if (m_currentBufferIndex == -1) {
|
||||
// Get all buffers available for rendering
|
||||
errno = 0;
|
||||
screen_buffer_t buffers[MAX_BUFFER_COUNT];
|
||||
int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to query window buffers, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Wrap each buffer
|
||||
for (int i = 0; i < MAX_BUFFER_COUNT; ++i) {
|
||||
m_buffers[i] = QBBBuffer(buffers[i]);
|
||||
}
|
||||
|
||||
// Use the first available render buffer
|
||||
m_currentBufferIndex = 0;
|
||||
m_previousBufferIndex = -1;
|
||||
}
|
||||
|
||||
return m_buffers[m_currentBufferIndex];
|
||||
}
|
||||
|
||||
void QBBWindow::scroll(const QRegion ®ion, int dx, int dy, bool flush)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
copyBack(region, dx, dy, flush);
|
||||
m_scrolled += region;
|
||||
}
|
||||
|
||||
void QBBWindow::post(const QRegion &dirty)
|
||||
{
|
||||
// Check if render buffer exists and something was rendered
|
||||
if (m_currentBufferIndex != -1 && !dirty.isEmpty()) {
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << "QBBWindow::post - window =" << window();
|
||||
#endif
|
||||
QBBBuffer ¤tBuffer = m_buffers[m_currentBufferIndex];
|
||||
|
||||
// Copy unmodified region from old render buffer to new render buffer;
|
||||
// required to allow partial updates
|
||||
QRegion preserve = m_previousDirty - dirty - m_scrolled;
|
||||
copyBack(preserve, 0, 0);
|
||||
|
||||
// Calculate region that changed
|
||||
QRegion modified = preserve + dirty + m_scrolled;
|
||||
QRect rect = modified.boundingRect();
|
||||
int dirtyRect[4] = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() };
|
||||
|
||||
// Update the display with contents of render buffer
|
||||
errno = 0;
|
||||
int result = screen_post_window(m_window, currentBuffer.nativeBuffer(), 1, dirtyRect, 0);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to post window buffer, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Advance to next nender buffer
|
||||
m_previousBufferIndex = m_currentBufferIndex++;
|
||||
if (m_currentBufferIndex >= MAX_BUFFER_COUNT) {
|
||||
m_currentBufferIndex = 0;
|
||||
}
|
||||
|
||||
// Save modified region and clear scrolled region
|
||||
m_previousDirty = dirty;
|
||||
m_scrolled = QRegion();
|
||||
|
||||
// Notify screen that window posted
|
||||
if (m_screen != 0) {
|
||||
m_screen->onWindowPost(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QBBWindow::setScreen(QBBScreen *platformScreen)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window() << "platformScreen =" << platformScreen;
|
||||
#endif
|
||||
|
||||
if (m_screen == platformScreen)
|
||||
return;
|
||||
|
||||
m_screen = platformScreen;
|
||||
|
||||
// Move window to proper screen/display
|
||||
errno = 0;
|
||||
screen_display_t display = platformScreen->nativeDisplay();
|
||||
int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to set window display, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Add window to display's window group
|
||||
errno = 0;
|
||||
result = screen_join_window_group(m_window, platformScreen->windowGroupName());
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to join window group, errno=%d", errno);
|
||||
}
|
||||
|
||||
QList<QBBWindow*>::iterator it;
|
||||
for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) {
|
||||
// Only subwindows and tooltips need necessarily be moved to another display with the window.
|
||||
if ((window()->windowType() & Qt::WindowType_Mask) == Qt::SubWindow ||
|
||||
(window()->windowType() & Qt::WindowType_Mask) == Qt::ToolTip)
|
||||
(*it)->setScreen(platformScreen);
|
||||
}
|
||||
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBWindow::removeFromParent()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
// Remove from old Hierarchy position
|
||||
if (m_parentWindow) {
|
||||
if (m_parentWindow->m_childWindows.removeAll(this))
|
||||
m_parentWindow = 0;
|
||||
else
|
||||
qFatal("QBBWindow: Window Hierarchy broken; window has parent, but parent hasn't got child.");
|
||||
} else {
|
||||
QBBScreen::removeWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
void QBBWindow::setParent(const QPlatformWindow *window)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << this->window() << "platformWindow =" << window;
|
||||
#endif
|
||||
// Cast away the const, we need to modify the hierarchy.
|
||||
QBBWindow *newParent = 0;
|
||||
|
||||
if (window)
|
||||
newParent = static_cast<QBBWindow*>((QPlatformWindow *)window);
|
||||
|
||||
if (newParent == m_parentWindow)
|
||||
return;
|
||||
|
||||
removeFromParent();
|
||||
m_parentWindow = newParent;
|
||||
|
||||
// Add to new hierarchy position.
|
||||
if (m_parentWindow) {
|
||||
if (m_parentWindow->m_screen != m_screen)
|
||||
setScreen(m_parentWindow->m_screen);
|
||||
|
||||
m_parentWindow->m_childWindows.push_back(this);
|
||||
} else {
|
||||
QBBScreen::addWindow(this);
|
||||
}
|
||||
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBWindow::raise()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
|
||||
QBBWindow *oldParent = m_parentWindow;
|
||||
if (oldParent) {
|
||||
removeFromParent();
|
||||
oldParent->m_childWindows.push_back(this);
|
||||
} else {
|
||||
QBBScreen::raiseWindow(this);
|
||||
}
|
||||
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBWindow::lower()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
|
||||
QBBWindow *oldParent = m_parentWindow;
|
||||
if (oldParent) {
|
||||
removeFromParent();
|
||||
oldParent->m_childWindows.push_front(this);
|
||||
} else {
|
||||
QBBScreen::lowerWindow(this);
|
||||
}
|
||||
|
||||
QBBScreen::updateHierarchy();
|
||||
}
|
||||
|
||||
void QBBWindow::requestActivateWindow()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
|
||||
// TODO: Tell screen to set keyboard focus to this window.
|
||||
|
||||
// Notify that we gained focus.
|
||||
gainedFocus();
|
||||
}
|
||||
|
||||
void QBBWindow::gainedFocus()
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
|
||||
// Got focus
|
||||
QWindowSystemInterface::handleWindowActivated(window());
|
||||
}
|
||||
|
||||
void QBBWindow::setPlatformOpenGLContext(QBBGLContext *platformOpenGLContext)
|
||||
{
|
||||
// This function does not take ownership of the platform gl context.
|
||||
// It is owned by the frontend QOpenGLContext
|
||||
m_platformOpenGLContext = platformOpenGLContext;
|
||||
}
|
||||
|
||||
void QBBWindow::updateZorder(int &topZorder)
|
||||
{
|
||||
errno = 0;
|
||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder);
|
||||
topZorder++;
|
||||
|
||||
if (result != 0)
|
||||
qFatal("QBBWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window);
|
||||
|
||||
QList<QBBWindow*>::const_iterator it;
|
||||
|
||||
for (it = m_childWindows.begin(); it != m_childWindows.end(); it++)
|
||||
(*it)->updateZorder(topZorder);
|
||||
}
|
||||
|
||||
void QBBWindow::copyBack(const QRegion ®ion, int dx, int dy, bool flush)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO << "window =" << window();
|
||||
#endif
|
||||
int result;
|
||||
|
||||
// Abort if previous buffer is invalid
|
||||
if (m_previousBufferIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Abort if nothing to copy
|
||||
if (region.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QBBBuffer ¤tBuffer = m_buffers[m_currentBufferIndex];
|
||||
QBBBuffer &previousBuffer = m_buffers[m_previousBufferIndex];
|
||||
|
||||
// Break down region into non-overlapping rectangles
|
||||
QVector<QRect> rects = region.rects();
|
||||
for (int i = rects.size() - 1; i >= 0; i--) {
|
||||
// Clip rectangle to bounds of target
|
||||
QRect rect = rects[i].intersected( currentBuffer.rect() );
|
||||
|
||||
if (rect.isEmpty())
|
||||
continue;
|
||||
|
||||
// Setup blit operation
|
||||
int attribs[] = { SCREEN_BLIT_SOURCE_X, rect.x(),
|
||||
SCREEN_BLIT_SOURCE_Y, rect.y(),
|
||||
SCREEN_BLIT_SOURCE_WIDTH, rect.width(),
|
||||
SCREEN_BLIT_SOURCE_HEIGHT, rect.height(),
|
||||
SCREEN_BLIT_DESTINATION_X, rect.x() + dx,
|
||||
SCREEN_BLIT_DESTINATION_Y, rect.y() + dy,
|
||||
SCREEN_BLIT_DESTINATION_WIDTH, rect.width(),
|
||||
SCREEN_BLIT_DESTINATION_HEIGHT, rect.height(),
|
||||
SCREEN_BLIT_END };
|
||||
|
||||
// Queue blit operation
|
||||
errno = 0;
|
||||
result = screen_blit(m_screenContext, currentBuffer.nativeBuffer(), previousBuffer.nativeBuffer(), attribs);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to blit buffers, errno=%d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if flush requested
|
||||
if (flush) {
|
||||
// Wait for all blits to complete
|
||||
errno = 0;
|
||||
result = screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE);
|
||||
if (result != 0) {
|
||||
qFatal("QBBWindow: failed to flush blits, errno=%d", errno);
|
||||
}
|
||||
|
||||
// Buffer was modified outside the CPU
|
||||
currentBuffer.invalidateInCache();
|
||||
}
|
||||
}
|
||||
|
||||
int QBBWindow::platformWindowFormatToNativeFormat(const QSurfaceFormat &format)
|
||||
{
|
||||
#if defined(QBBWINDOW_DEBUG)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
#endif
|
||||
// Extract size of colour channels from window format
|
||||
int redSize = format.redBufferSize();
|
||||
if (redSize == -1) {
|
||||
qFatal("QBBWindow: red size not defined");
|
||||
}
|
||||
|
||||
int greenSize = format.greenBufferSize();
|
||||
if (greenSize == -1) {
|
||||
qFatal("QBBWindow: green size not defined");
|
||||
}
|
||||
|
||||
int blueSize = format.blueBufferSize();
|
||||
if (blueSize == -1) {
|
||||
qFatal("QBBWindow: blue size not defined");
|
||||
}
|
||||
|
||||
// select matching native format
|
||||
if (redSize == 5 && greenSize == 6 && blueSize == 5) {
|
||||
return SCREEN_FORMAT_RGB565;
|
||||
} else if (redSize == 8 && greenSize == 8 && blueSize == 8) {
|
||||
return SCREEN_FORMAT_RGBA8888;
|
||||
} else {
|
||||
qFatal("QBBWindow: unsupported pixel format");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
133
src/plugins/platforms/blackberry/qbbwindow.h
Normal file
133
src/plugins/platforms/blackberry/qbbwindow.h
Normal file
@ -0,0 +1,133 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 - 2012 Research In Motion
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QBBWINDOW_H
|
||||
#define QBBWINDOW_H
|
||||
|
||||
#include <QtGui/QPlatformWindow>
|
||||
|
||||
#include "qbbbuffer.h"
|
||||
|
||||
#include <QtGui/QImage>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <screen/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// all surfaces double buffered
|
||||
#define MAX_BUFFER_COUNT 2
|
||||
|
||||
class QBBGLContext;
|
||||
class QBBScreen;
|
||||
|
||||
class QPlatformGLContext;
|
||||
class QSurfaceFormat;
|
||||
|
||||
class QBBWindow : public QPlatformWindow
|
||||
{
|
||||
friend class QBBScreen;
|
||||
public:
|
||||
QBBWindow(QWindow *window, screen_context_t context);
|
||||
virtual ~QBBWindow();
|
||||
|
||||
virtual void setGeometry(const QRect &rect);
|
||||
virtual void setVisible(bool visible);
|
||||
virtual void setOpacity(qreal level);
|
||||
|
||||
virtual WId winId() const { return (WId)m_window; }
|
||||
screen_window_t nativeHandle() const { return m_window; }
|
||||
|
||||
void setBufferSize(const QSize &size);
|
||||
QSize bufferSize() const { return m_bufferSize; }
|
||||
bool hasBuffers() const { return !m_bufferSize.isEmpty(); }
|
||||
|
||||
QBBBuffer &renderBuffer();
|
||||
void scroll(const QRegion ®ion, int dx, int dy, bool flush=false);
|
||||
void post(const QRegion &dirty);
|
||||
|
||||
void setScreen(QBBScreen *platformScreen);
|
||||
|
||||
virtual void setParent(const QPlatformWindow *window);
|
||||
virtual void raise();
|
||||
virtual void lower();
|
||||
virtual void requestActivateWindow();
|
||||
|
||||
void gainedFocus();
|
||||
|
||||
QBBScreen *screen() const { return m_screen; }
|
||||
const QList<QBBWindow*>& children() const { return m_childWindows; }
|
||||
|
||||
void setPlatformOpenGLContext(QBBGLContext *platformOpenGLContext);
|
||||
QBBGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; }
|
||||
|
||||
private:
|
||||
void removeFromParent();
|
||||
void offset(const QPoint &offset);
|
||||
void updateVisibility(bool parentVisible);
|
||||
void updateZorder(int &topZorder);
|
||||
|
||||
void fetchBuffers();
|
||||
|
||||
void copyBack(const QRegion ®ion, int dx, int dy, bool flush=false);
|
||||
|
||||
static int platformWindowFormatToNativeFormat(const QSurfaceFormat &format);
|
||||
|
||||
screen_context_t m_screenContext;
|
||||
screen_window_t m_window;
|
||||
QSize m_bufferSize;
|
||||
QBBBuffer m_buffers[MAX_BUFFER_COUNT];
|
||||
int m_currentBufferIndex;
|
||||
int m_previousBufferIndex;
|
||||
QRegion m_previousDirty;
|
||||
QRegion m_scrolled;
|
||||
|
||||
QBBGLContext *m_platformOpenGLContext;
|
||||
QBBScreen *m_screen;
|
||||
QList<QBBWindow*> m_childWindows;
|
||||
QBBWindow *m_parentWindow;
|
||||
bool m_visible;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QBBWINDOW_H
|
@ -11,3 +11,7 @@ mac {
|
||||
}
|
||||
|
||||
win32: SUBDIRS += windows
|
||||
|
||||
blackberry-armv7le-qcc {
|
||||
SUBDIRS += blackberry
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user