Add Mir client platform plugin
Contributed by Canonical, Ltd. Change-Id: I77752a1fd56641342be6c84e01b013d3df36ad73 Reviewed-by: Paul Olav Tvete <paul.tvete@theqtcompany.com>
This commit is contained in:
parent
26b4ec448c
commit
f08e1ecdc8
47
config.tests/qpa/mirclient/mirclient.cpp
Normal file
47
config.tests/qpa/mirclient/mirclient.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the config.tests of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL21$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** As a special exception, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
#include <ubuntu/application/lifecycle_delegate.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
static void surfaceCreateCallback(MirSurface*, void*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int, char **)
|
||||||
|
{
|
||||||
|
u_application_lifecycle_delegate_new();
|
||||||
|
mir_surface_create(0, surfaceCreateCallback, 0);
|
||||||
|
}
|
4
config.tests/qpa/mirclient/mirclient.pro
Normal file
4
config.tests/qpa/mirclient/mirclient.pro
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
SOURCES = mirclient.cpp
|
||||||
|
CONFIG += link_pkgconfig
|
||||||
|
PKGCONFIG += egl mirclient ubuntu-platform-api
|
||||||
|
CONFIG -= qt
|
34
configure
vendored
34
configure
vendored
@ -689,6 +689,7 @@ CFG_EGLFS_VIV=no
|
|||||||
CFG_DIRECTFB=auto
|
CFG_DIRECTFB=auto
|
||||||
CFG_LINUXFB=auto
|
CFG_LINUXFB=auto
|
||||||
CFG_KMS=auto
|
CFG_KMS=auto
|
||||||
|
CFG_MIRCLIENT=auto
|
||||||
CFG_LIBUDEV=auto
|
CFG_LIBUDEV=auto
|
||||||
CFG_LIBINPUT=auto
|
CFG_LIBINPUT=auto
|
||||||
CFG_OBSOLETE_WAYLAND=no
|
CFG_OBSOLETE_WAYLAND=no
|
||||||
@ -1850,6 +1851,13 @@ while [ "$#" -gt 0 ]; do
|
|||||||
UNKNOWN_OPT=yes
|
UNKNOWN_OPT=yes
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
mirclient)
|
||||||
|
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||||
|
CFG_MIRCLIENT="$VAL"
|
||||||
|
else
|
||||||
|
UNKNOWN_OPT=yes
|
||||||
|
fi
|
||||||
|
;;
|
||||||
libudev)
|
libudev)
|
||||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||||
CFG_LIBUDEV="$VAL"
|
CFG_LIBUDEV="$VAL"
|
||||||
@ -2650,6 +2658,9 @@ Additional options:
|
|||||||
-no-kms ............ Do not compile KMS support.
|
-no-kms ............ Do not compile KMS support.
|
||||||
* -kms ............... Compile KMS support (Requires EGL).
|
* -kms ............... Compile KMS support (Requires EGL).
|
||||||
|
|
||||||
|
* -no-mirclient....... Do not compile Mir client support.
|
||||||
|
-mirclient.......... Compile Mir client support.
|
||||||
|
|
||||||
-qpa <name> ......... Sets the default QPA platform (e.g xcb, cocoa, windows).
|
-qpa <name> ......... Sets the default QPA platform (e.g xcb, cocoa, windows).
|
||||||
|
|
||||||
-xplatform target ... The target platform when cross-compiling.
|
-xplatform target ... The target platform when cross-compiling.
|
||||||
@ -5269,6 +5280,7 @@ ORIG_CFG_EGLFS="$CFG_EGLFS"
|
|||||||
ORIG_CFG_DIRECTFB="$CFG_DIRECTFB"
|
ORIG_CFG_DIRECTFB="$CFG_DIRECTFB"
|
||||||
ORIG_CFG_LINUXFB="$CFG_LINUXFB"
|
ORIG_CFG_LINUXFB="$CFG_LINUXFB"
|
||||||
ORIG_CFG_KMS="$CFG_KMS"
|
ORIG_CFG_KMS="$CFG_KMS"
|
||||||
|
ORIG_CFG_MIRCLIENT="$CFG_MIRCLIENT"
|
||||||
|
|
||||||
if [ "$CFG_LIBUDEV" != "no" ]; then
|
if [ "$CFG_LIBUDEV" != "no" ]; then
|
||||||
if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists libudev 2>/dev/null; then
|
if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists libudev 2>/dev/null; then
|
||||||
@ -5551,6 +5563,20 @@ if [ "$CFG_KMS" != "no" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$CFG_MIRCLIENT" != "no" ]; then
|
||||||
|
if compileTest qpa/mirclient "Mir client"; then
|
||||||
|
CFG_MIRCLIENT=yes
|
||||||
|
elif [ "$CFG_MIRCLIENT" = "yes" ]; then
|
||||||
|
echo " Mir client support cannot be enabled due to functionality tests!"
|
||||||
|
echo " Turn on verbose messaging (-v) to $0 to see the final report."
|
||||||
|
echo " If you believe this message is in error you may use the continue"
|
||||||
|
echo " switch (-continue) to $0 to continue."
|
||||||
|
exit 101
|
||||||
|
else
|
||||||
|
CFG_MIRCLIENT=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Detect libxkbcommon
|
# Detect libxkbcommon
|
||||||
MIN_REQ_XKBCOMMON="0.4.1"
|
MIN_REQ_XKBCOMMON="0.4.1"
|
||||||
# currently only xcb platform plugin supports building xkbcommon
|
# currently only xcb platform plugin supports building xkbcommon
|
||||||
@ -5721,11 +5747,14 @@ fi
|
|||||||
if [ "$CFG_KMS" = "yes" ]; then
|
if [ "$CFG_KMS" = "yes" ]; then
|
||||||
QT_CONFIG="$QT_CONFIG kms"
|
QT_CONFIG="$QT_CONFIG kms"
|
||||||
fi
|
fi
|
||||||
|
if [ "$CFG_MIRCLIENT" = "yes" ]; then
|
||||||
|
QT_CONFIG="$QT_CONFIG mirclient"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$XPLATFORM_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ] && [ "$XPLATFORM_QNX" = "no" ] && [ "$XPLATFORM_ANDROID" = "no" ] && [ "$XPLATFORM_HAIKU" = "no" ]; then
|
if [ "$XPLATFORM_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ] && [ "$XPLATFORM_QNX" = "no" ] && [ "$XPLATFORM_ANDROID" = "no" ] && [ "$XPLATFORM_HAIKU" = "no" ]; then
|
||||||
if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ] && [ "$CFG_DIRECTFB" = "no" ] && [ "$CFG_LINUXFB" = "no" ] && [ "$CFG_KMS" = "no" ]; then
|
if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ] && [ "$CFG_DIRECTFB" = "no" ] && [ "$CFG_LINUXFB" = "no" ] && [ "$CFG_KMS" = "no" ] && [ "$CFG_MIRCLIENT" = "no" ]; then
|
||||||
if [ "$QPA_PLATFORM_GUARD" = "yes" ] &&
|
if [ "$QPA_PLATFORM_GUARD" = "yes" ] &&
|
||||||
( [ "$ORIG_CFG_XCB" = "auto" ] || [ "$ORIG_CFG_EGLFS" = "auto" ] || [ "$ORIG_CFG_DIRECTFB" = "auto" ] || [ "$ORIG_CFG_LINUXFB" = "auto" ] || [ "$ORIG_CFG_KMS" = "auto" ] ); then
|
( [ "$ORIG_CFG_XCB" = "auto" ] || [ "$ORIG_CFG_EGLFS" = "auto" ] || [ "$ORIG_CFG_DIRECTFB" = "auto" ] || [ "$ORIG_CFG_LINUXFB" = "auto" ] || [ "$ORIG_CFG_KMS" = "auto" ] || [ "$ORIG_CFG_MIRCLIENT" = "auto" ] ); then
|
||||||
echo "No QPA platform plugin enabled!"
|
echo "No QPA platform plugin enabled!"
|
||||||
echo " If you really want to build without a QPA platform plugin you must pass"
|
echo " If you really want to build without a QPA platform plugin you must pass"
|
||||||
echo " -no-qpa-platform-guard to configure. Doing this will"
|
echo " -no-qpa-platform-guard to configure. Doing this will"
|
||||||
@ -7142,6 +7171,7 @@ report_support " EGLFS Mali ........." "$CFG_EGLFS_MALI"
|
|||||||
report_support " EGLFS Raspberry Pi ." "$CFG_EGLFS_BRCM"
|
report_support " EGLFS Raspberry Pi ." "$CFG_EGLFS_BRCM"
|
||||||
report_support " EGLFS X11 .........." "$CFG_EGL_X"
|
report_support " EGLFS X11 .........." "$CFG_EGL_X"
|
||||||
report_support " LinuxFB .............." "$CFG_LINUXFB"
|
report_support " LinuxFB .............." "$CFG_LINUXFB"
|
||||||
|
report_support " Mir client............" "$CFG_MIRCLIENT"
|
||||||
report_support " XCB .................." "$CFG_XCB" system "system library" qt "bundled copy"
|
report_support " XCB .................." "$CFG_XCB" system "system library" qt "bundled copy"
|
||||||
if [ "$CFG_XCB" != "no" ]; then
|
if [ "$CFG_XCB" != "no" ]; then
|
||||||
report_support " EGL on X ..........." "$CFG_EGL_X"
|
report_support " EGL on X ..........." "$CFG_EGL_X"
|
||||||
|
3
src/plugins/platforms/mirclient/mirclient.json
Normal file
3
src/plugins/platforms/mirclient/mirclient.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Keys": [ "mirclient" ]
|
||||||
|
}
|
47
src/plugins/platforms/mirclient/mirclient.pro
Normal file
47
src/plugins/platforms/mirclient/mirclient.pro
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
TARGET = mirclient
|
||||||
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
PLUGIN_TYPE = platforms
|
||||||
|
PLUGIN_CLASS_NAME = MirServerIntegrationPlugin
|
||||||
|
!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
|
||||||
|
load(qt_plugin)
|
||||||
|
|
||||||
|
QT += core-private gui-private platformsupport-private dbus
|
||||||
|
|
||||||
|
CONFIG += qpa/genericunixfontdatabase
|
||||||
|
|
||||||
|
DEFINES += MESA_EGL_NO_X11_HEADERS
|
||||||
|
# CONFIG += c++11 # only enables C++0x
|
||||||
|
QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall
|
||||||
|
QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
|
||||||
|
|
||||||
|
CONFIG += link_pkgconfig
|
||||||
|
PKGCONFIG += egl mirclient ubuntu-platform-api
|
||||||
|
|
||||||
|
SOURCES = \
|
||||||
|
qmirclientbackingstore.cpp \
|
||||||
|
qmirclientclipboard.cpp \
|
||||||
|
qmirclientglcontext.cpp \
|
||||||
|
qmirclientinput.cpp \
|
||||||
|
qmirclientintegration.cpp \
|
||||||
|
qmirclientnativeinterface.cpp \
|
||||||
|
qmirclientplatformservices.cpp \
|
||||||
|
qmirclientplugin.cpp \
|
||||||
|
qmirclientscreen.cpp \
|
||||||
|
qmirclienttheme.cpp \
|
||||||
|
qmirclientwindow.cpp
|
||||||
|
|
||||||
|
HEADERS = \
|
||||||
|
qmirclientbackingstore.h \
|
||||||
|
qmirclientclipboard.h \
|
||||||
|
qmirclientglcontext.h \
|
||||||
|
qmirclientinput.h \
|
||||||
|
qmirclientintegration.h \
|
||||||
|
qmirclientlogging.h \
|
||||||
|
qmirclientnativeinterface.h \
|
||||||
|
qmirclientorientationchangeevent_p.h \
|
||||||
|
qmirclientplatformservices.h \
|
||||||
|
qmirclientplugin.h \
|
||||||
|
qmirclientscreen.h \
|
||||||
|
qmirclienttheme.h \
|
||||||
|
qmirclientwindow.h
|
146
src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
Normal file
146
src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qmirclientbackingstore.h"
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
#include <QtGui/QOpenGLContext>
|
||||||
|
#include <QtGui/QOpenGLTexture>
|
||||||
|
#include <QtGui/QMatrix4x4>
|
||||||
|
#include <QtGui/private/qopengltextureblitter_p.h>
|
||||||
|
#include <QtGui/qopenglfunctions.h>
|
||||||
|
|
||||||
|
QMirClientBackingStore::QMirClientBackingStore(QWindow* window)
|
||||||
|
: QPlatformBackingStore(window)
|
||||||
|
, mContext(new QOpenGLContext)
|
||||||
|
, mTexture(new QOpenGLTexture(QOpenGLTexture::Target2D))
|
||||||
|
, mBlitter(new QOpenGLTextureBlitter)
|
||||||
|
{
|
||||||
|
mContext->setFormat(window->requestedFormat());
|
||||||
|
mContext->setScreen(window->screen());
|
||||||
|
mContext->create();
|
||||||
|
|
||||||
|
window->setSurfaceType(QSurface::OpenGLSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientBackingStore::~QMirClientBackingStore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset)
|
||||||
|
{
|
||||||
|
Q_UNUSED(region);
|
||||||
|
Q_UNUSED(offset);
|
||||||
|
mContext->makeCurrent(window);
|
||||||
|
glViewport(0, 0, window->width(), window->height());
|
||||||
|
|
||||||
|
updateTexture();
|
||||||
|
|
||||||
|
if (!mBlitter->isCreated())
|
||||||
|
mBlitter->create();
|
||||||
|
|
||||||
|
mBlitter->bind();
|
||||||
|
mBlitter->setSwizzleRB(true);
|
||||||
|
mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft);
|
||||||
|
mBlitter->release();
|
||||||
|
|
||||||
|
mContext->swapBuffers(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientBackingStore::updateTexture()
|
||||||
|
{
|
||||||
|
if (mDirty.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!mTexture->isCreated()) {
|
||||||
|
mTexture->setMinificationFilter(QOpenGLTexture::Nearest);
|
||||||
|
mTexture->setMagnificationFilter(QOpenGLTexture::Nearest);
|
||||||
|
mTexture->setWrapMode(QOpenGLTexture::ClampToEdge);
|
||||||
|
mTexture->setData(mImage, QOpenGLTexture::DontGenerateMipMaps);
|
||||||
|
mTexture->create();
|
||||||
|
}
|
||||||
|
mTexture->bind();
|
||||||
|
|
||||||
|
QRegion fixed;
|
||||||
|
QRect imageRect = mImage.rect();
|
||||||
|
|
||||||
|
Q_FOREACH (const QRect &rect, mDirty.rects()) {
|
||||||
|
// intersect with image rect to be sure
|
||||||
|
QRect r = imageRect & rect;
|
||||||
|
|
||||||
|
// if the rect is wide enough it is cheaper to just extend it instead of doing an image copy
|
||||||
|
if (r.width() >= imageRect.width() / 2) {
|
||||||
|
r.setX(0);
|
||||||
|
r.setWidth(imageRect.width());
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed |= r;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH (const QRect &rect, fixed.rects()) {
|
||||||
|
// if the sub-rect is full-width we can pass the image data directly to
|
||||||
|
// OpenGL instead of copying, since there is no gap between scanlines
|
||||||
|
if (rect.width() == imageRect.width()) {
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
|
mImage.constScanLine(rect.y()));
|
||||||
|
} else {
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
|
mImage.copy(rect).constBits());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* End of code taken from QEGLPlatformBackingStore */
|
||||||
|
|
||||||
|
mDirty = QRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QMirClientBackingStore::beginPaint(const QRegion& region)
|
||||||
|
{
|
||||||
|
mDirty |= region;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/)
|
||||||
|
{
|
||||||
|
mImage = QImage(size, QImage::Format_RGB32);
|
||||||
|
|
||||||
|
if (mTexture->isCreated())
|
||||||
|
mTexture->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPaintDevice* QMirClientBackingStore::paintDevice()
|
||||||
|
{
|
||||||
|
return &mImage;
|
||||||
|
}
|
70
src/plugins/platforms/mirclient/qmirclientbackingstore.h
Normal file
70
src/plugins/platforms/mirclient/qmirclientbackingstore.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTBACKINGSTORE_H
|
||||||
|
#define QMIRCLIENTBACKINGSTORE_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformbackingstore.h>
|
||||||
|
|
||||||
|
class QOpenGLContext;
|
||||||
|
class QOpenGLTexture;
|
||||||
|
class QOpenGLTextureBlitter;
|
||||||
|
|
||||||
|
class QMirClientBackingStore : public QPlatformBackingStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMirClientBackingStore(QWindow* window);
|
||||||
|
virtual ~QMirClientBackingStore();
|
||||||
|
|
||||||
|
// QPlatformBackingStore methods.
|
||||||
|
void beginPaint(const QRegion&) override;
|
||||||
|
void flush(QWindow* window, const QRegion& region, const QPoint& offset) override;
|
||||||
|
void resize(const QSize& size, const QRegion& staticContents) override;
|
||||||
|
QPaintDevice* paintDevice() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateTexture();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<QOpenGLContext> mContext;
|
||||||
|
QScopedPointer<QOpenGLTexture> mTexture;
|
||||||
|
QScopedPointer<QOpenGLTextureBlitter> mBlitter;
|
||||||
|
QImage mImage;
|
||||||
|
QRegion mDirty;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTBACKINGSTORE_H
|
305
src/plugins/platforms/mirclient/qmirclientclipboard.cpp
Normal file
305
src/plugins/platforms/mirclient/qmirclientclipboard.cpp
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qmirclientclipboard.h"
|
||||||
|
|
||||||
|
#include <QtCore/QMimeData>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QDBusPendingCallWatcher>
|
||||||
|
#include <QDBusPendingReply>
|
||||||
|
|
||||||
|
// FIXME(loicm) The clipboard data format is not defined by Ubuntu Platform API
|
||||||
|
// which makes it impossible to have non-Qt applications communicate with Qt
|
||||||
|
// applications through the clipboard API. The solution would be to have
|
||||||
|
// Ubuntu Platform define the data format or propose an API that supports
|
||||||
|
// embedding different mime types in the clipboard.
|
||||||
|
|
||||||
|
// Data format:
|
||||||
|
// number of mime types (sizeof(int))
|
||||||
|
// data layout ((4 * sizeof(int)) * number of mime types)
|
||||||
|
// mime type string offset (sizeof(int))
|
||||||
|
// mime type string size (sizeof(int))
|
||||||
|
// data offset (sizeof(int))
|
||||||
|
// data size (sizeof(int))
|
||||||
|
// data (n bytes)
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int maxFormatsCount = 16;
|
||||||
|
const int maxBufferSize = 4 * 1024 * 1024; // 4 Mb
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientClipboard::QMirClientClipboard()
|
||||||
|
: mMimeData(new QMimeData)
|
||||||
|
, mIsOutdated(true)
|
||||||
|
, mUpdatesDisabled(false)
|
||||||
|
, mDBusSetupDone(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientClipboard::~QMirClientClipboard()
|
||||||
|
{
|
||||||
|
delete mMimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::requestDBusClipboardContents()
|
||||||
|
{
|
||||||
|
if (!mDBusSetupDone) {
|
||||||
|
setupDBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mPendingGetContentsCall.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QDBusPendingCall pendingCall = mDBusClipboard->asyncCall("GetContents");
|
||||||
|
|
||||||
|
mPendingGetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
|
||||||
|
|
||||||
|
QObject::connect(mPendingGetContentsCall.data(), SIGNAL(finished(QDBusPendingCallWatcher*)),
|
||||||
|
this, SLOT(onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher* call)
|
||||||
|
{
|
||||||
|
Q_ASSERT(call == mPendingGetContentsCall.data());
|
||||||
|
|
||||||
|
QDBusPendingReply<QByteArray> reply = *call;
|
||||||
|
if (reply.isError()) {
|
||||||
|
qCritical("QMirClientClipboard - Failed to get system clipboard contents via D-Bus. %s, %s",
|
||||||
|
qPrintable(reply.error().name()), qPrintable(reply.error().message()));
|
||||||
|
// TODO: Might try again later a number of times...
|
||||||
|
} else {
|
||||||
|
QByteArray serializedMimeData = reply.argumentAt<0>();
|
||||||
|
updateMimeData(serializedMimeData);
|
||||||
|
}
|
||||||
|
call->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher *call)
|
||||||
|
{
|
||||||
|
QDBusPendingReply<void> reply = *call;
|
||||||
|
if (reply.isError()) {
|
||||||
|
qCritical("QMirClientClipboard - Failed to set the system clipboard contents via D-Bus. %s, %s",
|
||||||
|
qPrintable(reply.error().name()), qPrintable(reply.error().message()));
|
||||||
|
// TODO: Might try again later a number of times...
|
||||||
|
}
|
||||||
|
call->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::updateMimeData(const QByteArray &serializedMimeData)
|
||||||
|
{
|
||||||
|
if (mUpdatesDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMimeData *newMimeData = deserializeMimeData(serializedMimeData);
|
||||||
|
if (newMimeData) {
|
||||||
|
delete mMimeData;
|
||||||
|
mMimeData = newMimeData;
|
||||||
|
mIsOutdated = false;
|
||||||
|
emitChanged(QClipboard::Clipboard);
|
||||||
|
} else {
|
||||||
|
qWarning("QMirClientClipboard - Got invalid serialized mime data. Ignoring it.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::setupDBus()
|
||||||
|
{
|
||||||
|
QDBusConnection dbusConnection = QDBusConnection::sessionBus();
|
||||||
|
|
||||||
|
bool ok = dbusConnection.connect(
|
||||||
|
"com.canonical.QtMir",
|
||||||
|
"/com/canonical/QtMir/Clipboard",
|
||||||
|
"com.canonical.QtMir.Clipboard",
|
||||||
|
"ContentsChanged",
|
||||||
|
this, SLOT(updateMimeData(QByteArray)));
|
||||||
|
if (!ok) {
|
||||||
|
qCritical("QMirClientClipboard - Failed to connect to ContentsChanged signal form the D-Bus system clipboard.");
|
||||||
|
}
|
||||||
|
|
||||||
|
mDBusClipboard = new QDBusInterface("com.canonical.QtMir",
|
||||||
|
"/com/canonical/QtMir/Clipboard",
|
||||||
|
"com.canonical.QtMir.Clipboard",
|
||||||
|
dbusConnection);
|
||||||
|
|
||||||
|
mDBusSetupDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray QMirClientClipboard::serializeMimeData(QMimeData *mimeData) const
|
||||||
|
{
|
||||||
|
const QStringList formats = mimeData->formats();
|
||||||
|
const int formatCount = qMin(formats.size(), maxFormatsCount);
|
||||||
|
const int headerSize = sizeof(int) + (formatCount * 4 * sizeof(int));
|
||||||
|
int bufferSize = headerSize;
|
||||||
|
|
||||||
|
for (int i = 0; i < formatCount; i++)
|
||||||
|
bufferSize += formats[i].size() + mimeData->data(formats[i]).size();
|
||||||
|
|
||||||
|
QByteArray serializedMimeData;
|
||||||
|
if (bufferSize <= maxBufferSize) {
|
||||||
|
// Serialize data.
|
||||||
|
serializedMimeData.resize(bufferSize);
|
||||||
|
{
|
||||||
|
char *buffer = serializedMimeData.data();
|
||||||
|
int* header = reinterpret_cast<int*>(serializedMimeData.data());
|
||||||
|
int offset = headerSize;
|
||||||
|
header[0] = formatCount;
|
||||||
|
for (int i = 0; i < formatCount; i++) {
|
||||||
|
const int formatOffset = offset;
|
||||||
|
const int formatSize = formats[i].size();
|
||||||
|
const int dataOffset = offset + formatSize;
|
||||||
|
const int dataSize = mimeData->data(formats[i]).size();
|
||||||
|
memcpy(&buffer[formatOffset], formats[i].toLatin1().data(), formatSize);
|
||||||
|
memcpy(&buffer[dataOffset], mimeData->data(formats[i]).data(), dataSize);
|
||||||
|
header[i*4+1] = formatOffset;
|
||||||
|
header[i*4+2] = formatSize;
|
||||||
|
header[i*4+3] = dataOffset;
|
||||||
|
header[i*4+4] = dataSize;
|
||||||
|
offset += formatSize + dataSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning("QMirClientClipboard: Not sending contents (%d bytes) to the global clipboard as it's"
|
||||||
|
" bigger than the maximum allowed size of %d bytes", bufferSize, maxBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return serializedMimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData *QMirClientClipboard::deserializeMimeData(const QByteArray &serializedMimeData) const
|
||||||
|
{
|
||||||
|
if (static_cast<std::size_t>(serializedMimeData.size()) < sizeof(int)) {
|
||||||
|
// Data is invalid
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData *mimeData = new QMimeData;
|
||||||
|
|
||||||
|
const char* const buffer = serializedMimeData.constData();
|
||||||
|
const int* const header = reinterpret_cast<const int*>(serializedMimeData.constData());
|
||||||
|
|
||||||
|
const int count = qMin(header[0], maxFormatsCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
const int formatOffset = header[i*4+1];
|
||||||
|
const int formatSize = header[i*4+2];
|
||||||
|
const int dataOffset = header[i*4+3];
|
||||||
|
const int dataSize = header[i*4+4];
|
||||||
|
|
||||||
|
if (formatOffset + formatSize <= serializedMimeData.size()
|
||||||
|
&& dataOffset + dataSize <= serializedMimeData.size()) {
|
||||||
|
|
||||||
|
QString mimeType = QString::fromLatin1(&buffer[formatOffset], formatSize);
|
||||||
|
QByteArray mimeDataBytes(&buffer[dataOffset], dataSize);
|
||||||
|
|
||||||
|
mimeData->setData(mimeType, mimeDataBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode)
|
||||||
|
{
|
||||||
|
if (mode != QClipboard::Clipboard)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (mIsOutdated && mPendingGetContentsCall.isNull()) {
|
||||||
|
requestDBusClipboardContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whatever we have at the moment instead of blocking until we have something.
|
||||||
|
//
|
||||||
|
// This might be called during app startup just for the sake of checking if some
|
||||||
|
// "Paste" UI control should be enabled or not.
|
||||||
|
// We will emit QClipboard::changed() once we finally have something.
|
||||||
|
return mMimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
|
||||||
|
{
|
||||||
|
if (mode != QClipboard::Clipboard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!mPendingGetContentsCall.isNull()) {
|
||||||
|
// Ignore whatever comes from the system clipboard as we are going to change it anyway
|
||||||
|
QObject::disconnect(mPendingGetContentsCall.data(), 0, this, 0);
|
||||||
|
mUpdatesDisabled = true;
|
||||||
|
mPendingGetContentsCall->waitForFinished();
|
||||||
|
mUpdatesDisabled = false;
|
||||||
|
delete mPendingGetContentsCall.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray serializedMimeData = serializeMimeData(mimeData);
|
||||||
|
if (!serializedMimeData.isEmpty()) {
|
||||||
|
setDBusClipboardContents(serializedMimeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
mMimeData = mimeData;
|
||||||
|
emitChanged(QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const
|
||||||
|
{
|
||||||
|
return mode == QClipboard::Clipboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(mode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClipboard::setDBusClipboardContents(const QByteArray &clipboardContents)
|
||||||
|
{
|
||||||
|
if (!mPendingSetContentsCall.isNull()) {
|
||||||
|
// Ignore any previous set call as we are going to overwrite it anyway
|
||||||
|
QObject::disconnect(mPendingSetContentsCall.data(), 0, this, 0);
|
||||||
|
mUpdatesDisabled = true;
|
||||||
|
mPendingSetContentsCall->waitForFinished();
|
||||||
|
mUpdatesDisabled = false;
|
||||||
|
delete mPendingSetContentsCall.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusPendingCall pendingCall = mDBusClipboard->asyncCall("SetContents", clipboardContents);
|
||||||
|
|
||||||
|
mPendingSetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
|
||||||
|
|
||||||
|
QObject::connect(mPendingSetContentsCall.data(), SIGNAL(finished(QDBusPendingCallWatcher*)),
|
||||||
|
this, SLOT(onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*)));
|
||||||
|
}
|
88
src/plugins/platforms/mirclient/qmirclientclipboard.h
Normal file
88
src/plugins/platforms/mirclient/qmirclientclipboard.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTCLIPBOARD_H
|
||||||
|
#define QMIRCLIENTCLIPBOARD_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformclipboard.h>
|
||||||
|
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QPointer>
|
||||||
|
class QDBusInterface;
|
||||||
|
class QDBusPendingCallWatcher;
|
||||||
|
|
||||||
|
class QMirClientClipboard : public QObject, public QPlatformClipboard
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QMirClientClipboard();
|
||||||
|
virtual ~QMirClientClipboard();
|
||||||
|
|
||||||
|
// QPlatformClipboard methods.
|
||||||
|
QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override;
|
||||||
|
void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override;
|
||||||
|
bool supportsMode(QClipboard::Mode mode) const override;
|
||||||
|
bool ownsMode(QClipboard::Mode mode) const override;
|
||||||
|
|
||||||
|
void requestDBusClipboardContents();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*);
|
||||||
|
void onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*);
|
||||||
|
void updateMimeData(const QByteArray &serializedMimeData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupDBus();
|
||||||
|
|
||||||
|
QByteArray serializeMimeData(QMimeData *mimeData) const;
|
||||||
|
QMimeData *deserializeMimeData(const QByteArray &serializedMimeData) const;
|
||||||
|
|
||||||
|
void setDBusClipboardContents(const QByteArray &clipboardContents);
|
||||||
|
|
||||||
|
QMimeData *mMimeData;
|
||||||
|
bool mIsOutdated;
|
||||||
|
|
||||||
|
QPointer<QDBusInterface> mDBusClipboard;
|
||||||
|
|
||||||
|
QPointer<QDBusPendingCallWatcher> mPendingGetContentsCall;
|
||||||
|
QPointer<QDBusPendingCallWatcher> mPendingSetContentsCall;
|
||||||
|
|
||||||
|
bool mUpdatesDisabled;
|
||||||
|
bool mDBusSetupDone;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTCLIPBOARD_H
|
156
src/plugins/platforms/mirclient/qmirclientglcontext.cpp
Normal file
156
src/plugins/platforms/mirclient/qmirclientglcontext.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qmirclientglcontext.h"
|
||||||
|
#include "qmirclientwindow.h"
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
#include <QtPlatformSupport/private/qeglconvenience_p.h>
|
||||||
|
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
static void printOpenGLESConfig() {
|
||||||
|
static bool once = true;
|
||||||
|
if (once) {
|
||||||
|
const char* string = (const char*) glGetString(GL_VENDOR);
|
||||||
|
LOG("OpenGL ES vendor: %s", string);
|
||||||
|
string = (const char*) glGetString(GL_RENDERER);
|
||||||
|
LOG("OpenGL ES renderer: %s", string);
|
||||||
|
string = (const char*) glGetString(GL_VERSION);
|
||||||
|
LOG("OpenGL ES version: %s", string);
|
||||||
|
string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||||
|
LOG("OpenGL ES Shading Language version: %s", string);
|
||||||
|
string = (const char*) glGetString(GL_EXTENSIONS);
|
||||||
|
LOG("OpenGL ES extensions: %s", string);
|
||||||
|
once = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static EGLenum api_in_use()
|
||||||
|
{
|
||||||
|
#ifdef QTUBUNTU_USE_OPENGL
|
||||||
|
return EGL_OPENGL_API;
|
||||||
|
#else
|
||||||
|
return EGL_OPENGL_ES_API;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientOpenGLContext::QMirClientOpenGLContext(QMirClientScreen* screen, QMirClientOpenGLContext* share)
|
||||||
|
{
|
||||||
|
ASSERT(screen != NULL);
|
||||||
|
mEglDisplay = screen->eglDisplay();
|
||||||
|
mScreen = screen;
|
||||||
|
|
||||||
|
// Create an OpenGL ES 2 context.
|
||||||
|
QVector<EGLint> attribs;
|
||||||
|
attribs.append(EGL_CONTEXT_CLIENT_VERSION);
|
||||||
|
attribs.append(2);
|
||||||
|
attribs.append(EGL_NONE);
|
||||||
|
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
|
||||||
|
|
||||||
|
mEglContext = eglCreateContext(mEglDisplay, screen->eglConfig(), share ? share->eglContext() : EGL_NO_CONTEXT,
|
||||||
|
attribs.constData());
|
||||||
|
DASSERT(mEglContext != EGL_NO_CONTEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientOpenGLContext::~QMirClientOpenGLContext()
|
||||||
|
{
|
||||||
|
ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface)
|
||||||
|
{
|
||||||
|
DASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
|
||||||
|
EGLSurface eglSurface = static_cast<QMirClientWindow*>(surface)->eglSurface();
|
||||||
|
#if defined(QT_NO_DEBUG)
|
||||||
|
eglBindAPI(api_in_use());
|
||||||
|
eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
|
||||||
|
#else
|
||||||
|
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
|
||||||
|
ASSERT(eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext) == EGL_TRUE);
|
||||||
|
printOpenGLESConfig();
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientOpenGLContext::doneCurrent()
|
||||||
|
{
|
||||||
|
#if defined(QT_NO_DEBUG)
|
||||||
|
eglBindAPI(api_in_use());
|
||||||
|
eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
#else
|
||||||
|
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
|
||||||
|
ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientOpenGLContext::swapBuffers(QPlatformSurface* surface)
|
||||||
|
{
|
||||||
|
QMirClientWindow *ubuntuWindow = static_cast<QMirClientWindow*>(surface);
|
||||||
|
|
||||||
|
EGLSurface eglSurface = ubuntuWindow->eglSurface();
|
||||||
|
#if defined(QT_NO_DEBUG)
|
||||||
|
eglBindAPI(api_in_use());
|
||||||
|
eglSwapBuffers(mEglDisplay, eglSurface);
|
||||||
|
#else
|
||||||
|
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
|
||||||
|
ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// "Technique" copied from mir, in examples/eglapp.c around line 96
|
||||||
|
EGLint newBufferWidth = -1;
|
||||||
|
EGLint newBufferHeight = -1;
|
||||||
|
/*
|
||||||
|
* Querying the surface (actually the current buffer) dimensions here is
|
||||||
|
* the only truly safe way to be sure that the dimensions we think we
|
||||||
|
* have are those of the buffer being rendered to. But this should be
|
||||||
|
* improved in future; https://bugs.launchpad.net/mir/+bug/1194384
|
||||||
|
*/
|
||||||
|
eglQuerySurface(mEglDisplay, eglSurface, EGL_WIDTH, &newBufferWidth);
|
||||||
|
eglQuerySurface(mEglDisplay, eglSurface, EGL_HEIGHT, &newBufferHeight);
|
||||||
|
|
||||||
|
ubuntuWindow->onBuffersSwapped_threadSafe(newBufferWidth, newBufferHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*QMirClientOpenGLContext::getProcAddress(const QByteArray& procName)) ()
|
||||||
|
{
|
||||||
|
#if defined(QT_NO_DEBUG)
|
||||||
|
eglBindAPI(api_in_use());
|
||||||
|
#else
|
||||||
|
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
|
||||||
|
#endif
|
||||||
|
return eglGetProcAddress(procName.constData());
|
||||||
|
}
|
66
src/plugins/platforms/mirclient/qmirclientglcontext.h
Normal file
66
src/plugins/platforms/mirclient/qmirclientglcontext.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTGLCONTEXT_H
|
||||||
|
#define QMIRCLIENTGLCONTEXT_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformopenglcontext.h>
|
||||||
|
#include "qmirclientscreen.h"
|
||||||
|
|
||||||
|
class QMirClientOpenGLContext : public QPlatformOpenGLContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMirClientOpenGLContext(QMirClientScreen* screen, QMirClientOpenGLContext* share);
|
||||||
|
virtual ~QMirClientOpenGLContext();
|
||||||
|
|
||||||
|
// QPlatformOpenGLContext methods.
|
||||||
|
QSurfaceFormat format() const override { return mScreen->surfaceFormat(); }
|
||||||
|
void swapBuffers(QPlatformSurface* surface) override;
|
||||||
|
bool makeCurrent(QPlatformSurface* surface) override;
|
||||||
|
void doneCurrent() override;
|
||||||
|
bool isValid() const override { return mEglContext != EGL_NO_CONTEXT; }
|
||||||
|
void (*getProcAddress(const QByteArray& procName)) ();
|
||||||
|
|
||||||
|
EGLContext eglContext() const { return mEglContext; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMirClientScreen* mScreen;
|
||||||
|
EGLContext mEglContext;
|
||||||
|
EGLDisplay mEglDisplay;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTGLCONTEXT_H
|
520
src/plugins/platforms/mirclient/qmirclientinput.cpp
Normal file
520
src/plugins/platforms/mirclient/qmirclientinput.cpp
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014-2015 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Local
|
||||||
|
#include "qmirclientinput.h"
|
||||||
|
#include "qmirclientintegration.h"
|
||||||
|
#include "qmirclientnativeinterface.h"
|
||||||
|
#include "qmirclientscreen.h"
|
||||||
|
#include "qmirclientwindow.h"
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
#include "qmirclientorientationchangeevent_p.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
#endif
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <private/qguiapplication_p.h>
|
||||||
|
#include <qpa/qplatforminputcontext.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||||
|
|
||||||
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
|
||||||
|
#define LOG_EVENTS 0
|
||||||
|
|
||||||
|
// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
|
||||||
|
static const uint32_t KeyTable[] = {
|
||||||
|
XKB_KEY_Escape, Qt::Key_Escape,
|
||||||
|
XKB_KEY_Tab, Qt::Key_Tab,
|
||||||
|
XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab,
|
||||||
|
XKB_KEY_BackSpace, Qt::Key_Backspace,
|
||||||
|
XKB_KEY_Return, Qt::Key_Return,
|
||||||
|
XKB_KEY_Insert, Qt::Key_Insert,
|
||||||
|
XKB_KEY_Delete, Qt::Key_Delete,
|
||||||
|
XKB_KEY_Clear, Qt::Key_Delete,
|
||||||
|
XKB_KEY_Pause, Qt::Key_Pause,
|
||||||
|
XKB_KEY_Print, Qt::Key_Print,
|
||||||
|
|
||||||
|
XKB_KEY_Home, Qt::Key_Home,
|
||||||
|
XKB_KEY_End, Qt::Key_End,
|
||||||
|
XKB_KEY_Left, Qt::Key_Left,
|
||||||
|
XKB_KEY_Up, Qt::Key_Up,
|
||||||
|
XKB_KEY_Right, Qt::Key_Right,
|
||||||
|
XKB_KEY_Down, Qt::Key_Down,
|
||||||
|
XKB_KEY_Prior, Qt::Key_PageUp,
|
||||||
|
XKB_KEY_Next, Qt::Key_PageDown,
|
||||||
|
|
||||||
|
XKB_KEY_Shift_L, Qt::Key_Shift,
|
||||||
|
XKB_KEY_Shift_R, Qt::Key_Shift,
|
||||||
|
XKB_KEY_Shift_Lock, Qt::Key_Shift,
|
||||||
|
XKB_KEY_Control_L, Qt::Key_Control,
|
||||||
|
XKB_KEY_Control_R, Qt::Key_Control,
|
||||||
|
XKB_KEY_Meta_L, Qt::Key_Meta,
|
||||||
|
XKB_KEY_Meta_R, Qt::Key_Meta,
|
||||||
|
XKB_KEY_Alt_L, Qt::Key_Alt,
|
||||||
|
XKB_KEY_Alt_R, Qt::Key_Alt,
|
||||||
|
XKB_KEY_Caps_Lock, Qt::Key_CapsLock,
|
||||||
|
XKB_KEY_Num_Lock, Qt::Key_NumLock,
|
||||||
|
XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock,
|
||||||
|
XKB_KEY_Super_L, Qt::Key_Super_L,
|
||||||
|
XKB_KEY_Super_R, Qt::Key_Super_R,
|
||||||
|
XKB_KEY_Menu, Qt::Key_Menu,
|
||||||
|
XKB_KEY_Hyper_L, Qt::Key_Hyper_L,
|
||||||
|
XKB_KEY_Hyper_R, Qt::Key_Hyper_R,
|
||||||
|
XKB_KEY_Help, Qt::Key_Help,
|
||||||
|
|
||||||
|
XKB_KEY_KP_Space, Qt::Key_Space,
|
||||||
|
XKB_KEY_KP_Tab, Qt::Key_Tab,
|
||||||
|
XKB_KEY_KP_Enter, Qt::Key_Enter,
|
||||||
|
XKB_KEY_KP_Home, Qt::Key_Home,
|
||||||
|
XKB_KEY_KP_Left, Qt::Key_Left,
|
||||||
|
XKB_KEY_KP_Up, Qt::Key_Up,
|
||||||
|
XKB_KEY_KP_Right, Qt::Key_Right,
|
||||||
|
XKB_KEY_KP_Down, Qt::Key_Down,
|
||||||
|
XKB_KEY_KP_Prior, Qt::Key_PageUp,
|
||||||
|
XKB_KEY_KP_Next, Qt::Key_PageDown,
|
||||||
|
XKB_KEY_KP_End, Qt::Key_End,
|
||||||
|
XKB_KEY_KP_Begin, Qt::Key_Clear,
|
||||||
|
XKB_KEY_KP_Insert, Qt::Key_Insert,
|
||||||
|
XKB_KEY_KP_Delete, Qt::Key_Delete,
|
||||||
|
XKB_KEY_KP_Equal, Qt::Key_Equal,
|
||||||
|
XKB_KEY_KP_Multiply, Qt::Key_Asterisk,
|
||||||
|
XKB_KEY_KP_Add, Qt::Key_Plus,
|
||||||
|
XKB_KEY_KP_Separator, Qt::Key_Comma,
|
||||||
|
XKB_KEY_KP_Subtract, Qt::Key_Minus,
|
||||||
|
XKB_KEY_KP_Decimal, Qt::Key_Period,
|
||||||
|
XKB_KEY_KP_Divide, Qt::Key_Slash,
|
||||||
|
|
||||||
|
XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr,
|
||||||
|
XKB_KEY_Multi_key, Qt::Key_Multi_key,
|
||||||
|
XKB_KEY_Codeinput, Qt::Key_Codeinput,
|
||||||
|
XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate,
|
||||||
|
XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
|
||||||
|
XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
|
||||||
|
|
||||||
|
XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
|
||||||
|
XKB_KEY_script_switch, Qt::Key_Mode_switch,
|
||||||
|
XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
|
||||||
|
XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown,
|
||||||
|
XKB_KEY_XF86PowerOff, Qt::Key_PowerOff,
|
||||||
|
XKB_KEY_XF86PowerDown, Qt::Key_PowerDown,
|
||||||
|
|
||||||
|
0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
class QMirClientEvent : public QEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMirClientEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type)
|
||||||
|
: QEvent(type), window(window) {
|
||||||
|
nativeEvent = mir_event_ref(event);
|
||||||
|
}
|
||||||
|
~QMirClientEvent()
|
||||||
|
{
|
||||||
|
mir_event_unref(nativeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointer<QMirClientWindow> window;
|
||||||
|
const MirEvent *nativeEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
QMirClientInput::QMirClientInput(QMirClientClientIntegration* integration)
|
||||||
|
: QObject(nullptr)
|
||||||
|
, mIntegration(integration)
|
||||||
|
, mEventFilterType(static_cast<QMirClientNativeInterface*>(
|
||||||
|
integration->nativeInterface())->genericEventFilterType())
|
||||||
|
, mEventType(static_cast<QEvent::Type>(QEvent::registerEventType()))
|
||||||
|
{
|
||||||
|
// Initialize touch device.
|
||||||
|
mTouchDevice = new QTouchDevice;
|
||||||
|
mTouchDevice->setType(QTouchDevice::TouchScreen);
|
||||||
|
mTouchDevice->setCapabilities(
|
||||||
|
QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure |
|
||||||
|
QTouchDevice::NormalizedPosition);
|
||||||
|
QWindowSystemInterface::registerTouchDevice(mTouchDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientInput::~QMirClientInput()
|
||||||
|
{
|
||||||
|
// Qt will take care of deleting mTouchDevice.
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (LOG_EVENTS != 0)
|
||||||
|
static const char* nativeEventTypeToStr(MirEventType t)
|
||||||
|
{
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case mir_event_type_key:
|
||||||
|
return "mir_event_type_key";
|
||||||
|
case mir_event_type_motion:
|
||||||
|
return "mir_event_type_motion";
|
||||||
|
case mir_event_type_surface:
|
||||||
|
return "mir_event_type_surface";
|
||||||
|
case mir_event_type_resize:
|
||||||
|
return "mir_event_type_resize";
|
||||||
|
case mir_event_type_prompt_session_state_change:
|
||||||
|
return "mir_event_type_prompt_session_state_change";
|
||||||
|
case mir_event_type_orientation:
|
||||||
|
return "mir_event_type_orientation";
|
||||||
|
case mir_event_type_close_surface:
|
||||||
|
return "mir_event_type_close_surface";
|
||||||
|
case mir_event_type_input:
|
||||||
|
return "mir_event_type_input";
|
||||||
|
default:
|
||||||
|
DLOG("Invalid event type %d", t);
|
||||||
|
return "invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // LOG_EVENTS != 0
|
||||||
|
|
||||||
|
void QMirClientInput::customEvent(QEvent* event)
|
||||||
|
{
|
||||||
|
DASSERT(QThread::currentThread() == thread());
|
||||||
|
QMirClientEvent* ubuntuEvent = static_cast<QMirClientEvent*>(event);
|
||||||
|
const MirEvent *nativeEvent = ubuntuEvent->nativeEvent;
|
||||||
|
|
||||||
|
if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) {
|
||||||
|
qWarning() << "Attempted to deliver an event to a non-existent window, ignoring.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event filtering.
|
||||||
|
long result;
|
||||||
|
if (QWindowSystemInterface::handleNativeEvent(
|
||||||
|
ubuntuEvent->window->window(), mEventFilterType,
|
||||||
|
const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) {
|
||||||
|
DLOG("event filtered out by native interface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (LOG_EVENTS != 0)
|
||||||
|
LOG("QMirClientInput::customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Event dispatching.
|
||||||
|
switch (mir_event_get_type(nativeEvent))
|
||||||
|
{
|
||||||
|
case mir_event_type_input:
|
||||||
|
dispatchInputEvent(ubuntuEvent->window->window(), mir_event_get_input_event(nativeEvent));
|
||||||
|
break;
|
||||||
|
case mir_event_type_resize:
|
||||||
|
{
|
||||||
|
Q_ASSERT(ubuntuEvent->window->screen() == mIntegration->screen());
|
||||||
|
|
||||||
|
auto resizeEvent = mir_event_get_resize_event(nativeEvent);
|
||||||
|
|
||||||
|
mIntegration->screen()->handleWindowSurfaceResize(
|
||||||
|
mir_resize_event_get_width(resizeEvent),
|
||||||
|
mir_resize_event_get_height(resizeEvent));
|
||||||
|
|
||||||
|
ubuntuEvent->window->handleSurfaceResize(mir_resize_event_get_width(resizeEvent),
|
||||||
|
mir_resize_event_get_height(resizeEvent));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case mir_event_type_surface:
|
||||||
|
{
|
||||||
|
auto surfaceEvent = mir_event_get_surface_event(nativeEvent);
|
||||||
|
if (mir_surface_event_get_attribute(surfaceEvent) == mir_surface_attrib_focus) {
|
||||||
|
ubuntuEvent->window->handleSurfaceFocusChange(mir_surface_event_get_attribute_value(surfaceEvent) ==
|
||||||
|
mir_surface_focused);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case mir_event_type_orientation:
|
||||||
|
dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent));
|
||||||
|
break;
|
||||||
|
case mir_event_type_close_surface:
|
||||||
|
QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DLOG("unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientInput::postEvent(QMirClientWindow *platformWindow, const MirEvent *event)
|
||||||
|
{
|
||||||
|
QWindow *window = platformWindow->window();
|
||||||
|
|
||||||
|
QCoreApplication::postEvent(this, new QMirClientEvent(
|
||||||
|
platformWindow, event, mEventType));
|
||||||
|
|
||||||
|
if ((window->flags().testFlag(Qt::WindowTransparentForInput)) && window->parent()) {
|
||||||
|
QCoreApplication::postEvent(this, new QMirClientEvent(
|
||||||
|
static_cast<QMirClientWindow*>(platformWindow->QPlatformWindow::parent()),
|
||||||
|
event, mEventType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientInput::dispatchInputEvent(QWindow *window, const MirInputEvent *ev)
|
||||||
|
{
|
||||||
|
switch (mir_input_event_get_type(ev))
|
||||||
|
{
|
||||||
|
case mir_input_event_type_key:
|
||||||
|
dispatchKeyEvent(window, ev);
|
||||||
|
break;
|
||||||
|
case mir_input_event_type_touch:
|
||||||
|
dispatchTouchEvent(window, ev);
|
||||||
|
break;
|
||||||
|
case mir_input_event_type_pointer:
|
||||||
|
dispatchPointerEvent(window, ev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientInput::dispatchTouchEvent(QWindow *window, const MirInputEvent *ev)
|
||||||
|
{
|
||||||
|
const MirTouchEvent *tev = mir_input_event_get_touch_event(ev);
|
||||||
|
|
||||||
|
// FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
|
||||||
|
// needs to be fixed as soon as the compat input lib adds query support.
|
||||||
|
const float kMaxPressure = 1.28;
|
||||||
|
const QRect kWindowGeometry = window->geometry();
|
||||||
|
QList<QWindowSystemInterface::TouchPoint> touchPoints;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
|
||||||
|
// as Qt::TouchPointMoved
|
||||||
|
const unsigned int kPointerCount = mir_touch_event_point_count(tev);
|
||||||
|
for (unsigned int i = 0; i < kPointerCount; ++i) {
|
||||||
|
QWindowSystemInterface::TouchPoint touchPoint;
|
||||||
|
|
||||||
|
const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x();
|
||||||
|
const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere
|
||||||
|
const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
|
||||||
|
const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
|
||||||
|
const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
|
||||||
|
touchPoint.id = mir_touch_event_id(tev, i);
|
||||||
|
touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
|
||||||
|
touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
|
||||||
|
touchPoint.pressure = kP / kMaxPressure;
|
||||||
|
|
||||||
|
MirTouchAction touch_action = mir_touch_event_action(tev, i);
|
||||||
|
switch (touch_action)
|
||||||
|
{
|
||||||
|
case mir_touch_action_down:
|
||||||
|
touchPoint.state = Qt::TouchPointPressed;
|
||||||
|
break;
|
||||||
|
case mir_touch_action_up:
|
||||||
|
touchPoint.state = Qt::TouchPointReleased;
|
||||||
|
break;
|
||||||
|
case mir_touch_action_change:
|
||||||
|
default:
|
||||||
|
touchPoint.state = Qt::TouchPointMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
touchPoints.append(touchPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong timestamp = mir_input_event_get_event_time(ev) / 1000000;
|
||||||
|
QWindowSystemInterface::handleTouchEvent(window, timestamp,
|
||||||
|
mTouchDevice, touchPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t translateKeysym(uint32_t sym, char *string, size_t size)
|
||||||
|
{
|
||||||
|
Q_UNUSED(size);
|
||||||
|
string[0] = '\0';
|
||||||
|
|
||||||
|
if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35)
|
||||||
|
return Qt::Key_F1 + (int(sym) - XKB_KEY_F1);
|
||||||
|
|
||||||
|
for (int i = 0; KeyTable[i]; i += 2) {
|
||||||
|
if (sym == KeyTable[i])
|
||||||
|
return KeyTable[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
string[0] = sym;
|
||||||
|
string[1] = '\0';
|
||||||
|
return toupper(sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers)
|
||||||
|
{
|
||||||
|
Qt::KeyboardModifiers q_modifiers = Qt::NoModifier;
|
||||||
|
if (modifiers & mir_input_event_modifier_shift) {
|
||||||
|
q_modifiers |= Qt::ShiftModifier;
|
||||||
|
}
|
||||||
|
if (modifiers & mir_input_event_modifier_ctrl) {
|
||||||
|
q_modifiers |= Qt::ControlModifier;
|
||||||
|
}
|
||||||
|
if (modifiers & mir_input_event_modifier_alt) {
|
||||||
|
q_modifiers |= Qt::AltModifier;
|
||||||
|
}
|
||||||
|
if (modifiers & mir_input_event_modifier_meta) {
|
||||||
|
q_modifiers |= Qt::MetaModifier;
|
||||||
|
}
|
||||||
|
return q_modifiers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientInput::dispatchKeyEvent(QWindow *window, const MirInputEvent *event)
|
||||||
|
{
|
||||||
|
const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event);
|
||||||
|
|
||||||
|
ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
|
||||||
|
xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event);
|
||||||
|
|
||||||
|
// Key modifier and unicode index mapping.
|
||||||
|
auto modifiers = qt_modifiers_from_mir(mir_keyboard_event_modifiers(key_event));
|
||||||
|
|
||||||
|
MirKeyboardAction action = mir_keyboard_event_action(key_event);
|
||||||
|
QEvent::Type keyType = action == mir_keyboard_action_up
|
||||||
|
? QEvent::KeyRelease : QEvent::KeyPress;
|
||||||
|
|
||||||
|
char s[2];
|
||||||
|
int sym = translateKeysym(xk_sym, s, sizeof(s));
|
||||||
|
QString text = QString::fromLatin1(s);
|
||||||
|
|
||||||
|
bool is_auto_rep = action == mir_keyboard_action_repeat;
|
||||||
|
|
||||||
|
QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||||
|
if (context) {
|
||||||
|
QKeyEvent qKeyEvent(keyType, sym, modifiers, text, is_auto_rep);
|
||||||
|
qKeyEvent.setTimestamp(timestamp);
|
||||||
|
if (context->filterEvent(&qKeyEvent)) {
|
||||||
|
DLOG("key event filtered out by input context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWindowSystemInterface::handleKeyEvent(window, timestamp, keyType, sym, modifiers, text, is_auto_rep);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
Qt::MouseButtons extract_buttons(const MirPointerEvent *pev)
|
||||||
|
{
|
||||||
|
Qt::MouseButtons buttons = Qt::NoButton;
|
||||||
|
if (mir_pointer_event_button_state(pev, mir_pointer_button_primary))
|
||||||
|
buttons |= Qt::LeftButton;
|
||||||
|
if (mir_pointer_event_button_state(pev, mir_pointer_button_secondary))
|
||||||
|
buttons |= Qt::RightButton;
|
||||||
|
if (mir_pointer_event_button_state(pev, mir_pointer_button_tertiary))
|
||||||
|
buttons |= Qt::MidButton;
|
||||||
|
|
||||||
|
// TODO: Should mir back and forward buttons exist?
|
||||||
|
// should they be Qt::X button 1 and 2?
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientInput::dispatchPointerEvent(QWindow *window, const MirInputEvent *ev)
|
||||||
|
{
|
||||||
|
auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
|
||||||
|
|
||||||
|
auto pev = mir_input_event_get_pointer_event(ev);
|
||||||
|
auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
|
||||||
|
auto buttons = extract_buttons(pev);
|
||||||
|
|
||||||
|
auto local_point = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
|
||||||
|
mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
|
||||||
|
|
||||||
|
QWindowSystemInterface::handleMouseEvent(window, timestamp, local_point, local_point /* Should we omit global point instead? */,
|
||||||
|
buttons, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (LOG_EVENTS != 0)
|
||||||
|
static const char* nativeOrientationDirectionToStr(MirOrientation orientation)
|
||||||
|
{
|
||||||
|
switch (orientation) {
|
||||||
|
case mir_orientation_normal:
|
||||||
|
return "Normal";
|
||||||
|
break;
|
||||||
|
case mir_orientation_left:
|
||||||
|
return "Left";
|
||||||
|
break;
|
||||||
|
case mir_orientation_inverted:
|
||||||
|
return "Inverted";
|
||||||
|
break;
|
||||||
|
case mir_orientation_right:
|
||||||
|
return "Right";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "INVALID!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event)
|
||||||
|
{
|
||||||
|
MirOrientation mir_orientation = mir_orientation_event_get_direction(event);
|
||||||
|
#if (LOG_EVENTS != 0)
|
||||||
|
// Orientation event logging.
|
||||||
|
LOG("ORIENTATION direction: %s", nativeOrientationDirectionToStr(mir_orientation));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!window->screen()) {
|
||||||
|
DLOG("Window has no associated screen, dropping orientation event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrientationChangeEvent::Orientation orientation;
|
||||||
|
switch (mir_orientation) {
|
||||||
|
case mir_orientation_normal:
|
||||||
|
orientation = OrientationChangeEvent::TopUp;
|
||||||
|
break;
|
||||||
|
case mir_orientation_left:
|
||||||
|
orientation = OrientationChangeEvent::LeftUp;
|
||||||
|
break;
|
||||||
|
case mir_orientation_inverted:
|
||||||
|
orientation = OrientationChangeEvent::TopDown;
|
||||||
|
break;
|
||||||
|
case mir_orientation_right:
|
||||||
|
orientation = OrientationChangeEvent::RightUp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DLOG("No such orientation %d", mir_orientation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch orientation event to [Platform]Screen, as that is where Qt reads it. Screen will handle
|
||||||
|
// notifying Qt of the actual orientation change - done to prevent multiple Windows each creating
|
||||||
|
// an identical orientation change event and passing it directly to Qt.
|
||||||
|
// [Platform]Screen can also factor in the native orientation.
|
||||||
|
QCoreApplication::postEvent(static_cast<QMirClientScreen*>(window->screen()->handle()),
|
||||||
|
new OrientationChangeEvent(OrientationChangeEvent::mType, orientation));
|
||||||
|
}
|
||||||
|
|
78
src/plugins/platforms/mirclient/qmirclientinput.h
Normal file
78
src/plugins/platforms/mirclient/qmirclientinput.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014-2015 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTINPUT_H
|
||||||
|
#define QMIRCLIENTINPUT_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
|
||||||
|
class QMirClientClientIntegration;
|
||||||
|
class QMirClientWindow;
|
||||||
|
|
||||||
|
class QMirClientInput : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QMirClientInput(QMirClientClientIntegration* integration);
|
||||||
|
virtual ~QMirClientInput();
|
||||||
|
|
||||||
|
// QObject methods.
|
||||||
|
void customEvent(QEvent* event) override;
|
||||||
|
|
||||||
|
void postEvent(QMirClientWindow* window, const MirEvent *event);
|
||||||
|
QMirClientClientIntegration* integration() const { return mIntegration; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dispatchKeyEvent(QWindow *window, const MirInputEvent *event);
|
||||||
|
void dispatchPointerEvent(QWindow *window, const MirInputEvent *event);
|
||||||
|
void dispatchTouchEvent(QWindow *window, const MirInputEvent *event);
|
||||||
|
void dispatchInputEvent(QWindow *window, const MirInputEvent *event);
|
||||||
|
|
||||||
|
void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMirClientClientIntegration* mIntegration;
|
||||||
|
QTouchDevice* mTouchDevice;
|
||||||
|
const QByteArray mEventFilterType;
|
||||||
|
const QEvent::Type mEventType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTINPUT_H
|
264
src/plugins/platforms/mirclient/qmirclientintegration.cpp
Normal file
264
src/plugins/platforms/mirclient/qmirclientintegration.cpp
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014-2015 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <private/qguiapplication_p.h>
|
||||||
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
|
#include <qpa/qplatforminputcontext.h>
|
||||||
|
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
|
||||||
|
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
|
||||||
|
// Local
|
||||||
|
#include "qmirclientbackingstore.h"
|
||||||
|
#include "qmirclientclipboard.h"
|
||||||
|
#include "qmirclientglcontext.h"
|
||||||
|
#include "qmirclientinput.h"
|
||||||
|
#include "qmirclientintegration.h"
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
#include "qmirclientnativeinterface.h"
|
||||||
|
#include "qmirclientscreen.h"
|
||||||
|
#include "qmirclienttheme.h"
|
||||||
|
#include "qmirclientwindow.h"
|
||||||
|
|
||||||
|
// platform-api
|
||||||
|
#include <ubuntu/application/lifecycle_delegate.h>
|
||||||
|
#include <ubuntu/application/id.h>
|
||||||
|
#include <ubuntu/application/options.h>
|
||||||
|
|
||||||
|
static void resumedCallback(const UApplicationOptions *options, void* context)
|
||||||
|
{
|
||||||
|
Q_UNUSED(options)
|
||||||
|
Q_UNUSED(context)
|
||||||
|
DASSERT(context != NULL);
|
||||||
|
QCoreApplication::postEvent(QCoreApplication::instance(),
|
||||||
|
new QEvent(QEvent::ApplicationActivate));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aboutToStopCallback(UApplicationArchive *archive, void* context)
|
||||||
|
{
|
||||||
|
Q_UNUSED(archive)
|
||||||
|
DASSERT(context != NULL);
|
||||||
|
QMirClientClientIntegration* integration = static_cast<QMirClientClientIntegration*>(context);
|
||||||
|
integration->inputContext()->hideInputPanel();
|
||||||
|
QCoreApplication::postEvent(QCoreApplication::instance(),
|
||||||
|
new QEvent(QEvent::ApplicationDeactivate));
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientClientIntegration::QMirClientClientIntegration()
|
||||||
|
: QPlatformIntegration()
|
||||||
|
, mNativeInterface(new QMirClientNativeInterface)
|
||||||
|
, mFontDb(new QGenericUnixFontDatabase)
|
||||||
|
, mServices(new QMirClientPlatformServices)
|
||||||
|
, mClipboard(new QMirClientClipboard)
|
||||||
|
, mScaleFactor(1.0)
|
||||||
|
{
|
||||||
|
setupOptions();
|
||||||
|
setupDescription();
|
||||||
|
|
||||||
|
// Create new application instance
|
||||||
|
mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions);
|
||||||
|
|
||||||
|
if (mInstance == nullptr)
|
||||||
|
qFatal("QMirClientClientIntegration: connection to Mir server failed. Check that a Mir server is\n"
|
||||||
|
"running, and the correct socket is being used and is accessible. The shell may have\n"
|
||||||
|
"rejected the incoming connection, so check its log file");
|
||||||
|
|
||||||
|
// Create default screen.
|
||||||
|
mScreen = new QMirClientScreen(u_application_instance_get_mir_connection(mInstance));
|
||||||
|
screenAdded(mScreen);
|
||||||
|
|
||||||
|
// Initialize input.
|
||||||
|
if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_INPUT")) {
|
||||||
|
mInput = new QMirClientInput(this);
|
||||||
|
mInputContext = QPlatformInputContextFactory::create();
|
||||||
|
} else {
|
||||||
|
mInput = nullptr;
|
||||||
|
mInputContext = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the scale factor
|
||||||
|
const int defaultGridUnit = 8;
|
||||||
|
int gridUnit = defaultGridUnit;
|
||||||
|
QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
|
||||||
|
if (!gridUnitString.isEmpty()) {
|
||||||
|
bool ok;
|
||||||
|
gridUnit = gridUnitString.toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
gridUnit = defaultGridUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mScaleFactor = static_cast<qreal>(gridUnit) / defaultGridUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientClientIntegration::~QMirClientClientIntegration()
|
||||||
|
{
|
||||||
|
delete mInput;
|
||||||
|
delete mInputContext;
|
||||||
|
delete mScreen;
|
||||||
|
delete mServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformServices *QMirClientClientIntegration::services() const
|
||||||
|
{
|
||||||
|
return mServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClientIntegration::setupOptions()
|
||||||
|
{
|
||||||
|
QStringList args = QCoreApplication::arguments();
|
||||||
|
int argc = args.size() + 1;
|
||||||
|
char **argv = new char*[argc];
|
||||||
|
for (int i = 0; i < argc - 1; i++)
|
||||||
|
argv[i] = qstrdup(args.at(i).toLocal8Bit());
|
||||||
|
argv[argc - 1] = nullptr;
|
||||||
|
|
||||||
|
mOptions = u_application_options_new_from_cmd_line(argc - 1, argv);
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
delete [] argv[i];
|
||||||
|
delete [] argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientClientIntegration::setupDescription()
|
||||||
|
{
|
||||||
|
mDesc = u_application_description_new();
|
||||||
|
UApplicationId* id = u_application_id_new_from_stringn("QtUbuntu", 8);
|
||||||
|
u_application_description_set_application_id(mDesc, id);
|
||||||
|
|
||||||
|
UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new();
|
||||||
|
u_application_lifecycle_delegate_set_application_resumed_cb(delegate, &resumedCallback);
|
||||||
|
u_application_lifecycle_delegate_set_application_about_to_stop_cb(delegate, &aboutToStopCallback);
|
||||||
|
u_application_lifecycle_delegate_set_context(delegate, this);
|
||||||
|
u_application_description_set_application_lifecycle_delegate(mDesc, delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
|
||||||
|
{
|
||||||
|
return const_cast<QMirClientClientIntegration*>(this)->createPlatformWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window)
|
||||||
|
{
|
||||||
|
QPlatformWindow* platformWindow = new QMirClientWindow(
|
||||||
|
window, mClipboard, static_cast<QMirClientScreen*>(mScreen), mInput, u_application_instance_get_mir_connection(mInstance));
|
||||||
|
platformWindow->requestActivateWindow();
|
||||||
|
return platformWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
|
||||||
|
{
|
||||||
|
switch (cap) {
|
||||||
|
case ThreadedPixmaps:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpenGL:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ThreadedOpenGL:
|
||||||
|
if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
DLOG("ubuntumirclient: disabled threaded OpenGL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QPlatformIntegration::hasCapability(cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractEventDispatcher *QMirClientClientIntegration::createEventDispatcher() const
|
||||||
|
{
|
||||||
|
return createUnixEventDispatcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(QWindow* window) const
|
||||||
|
{
|
||||||
|
return new QMirClientBackingStore(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
|
||||||
|
QOpenGLContext* context) const
|
||||||
|
{
|
||||||
|
return const_cast<QMirClientClientIntegration*>(this)->createPlatformOpenGLContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
|
||||||
|
QOpenGLContext* context)
|
||||||
|
{
|
||||||
|
return new QMirClientOpenGLContext(static_cast<QMirClientScreen*>(context->screen()->handle()),
|
||||||
|
static_cast<QMirClientOpenGLContext*>(context->shareHandle()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QMirClientClientIntegration::themeNames() const
|
||||||
|
{
|
||||||
|
return QStringList(QMirClientTheme::name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformTheme* QMirClientClientIntegration::createPlatformTheme(const QString& name) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(name);
|
||||||
|
return new QMirClientTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const
|
||||||
|
{
|
||||||
|
switch (hint) {
|
||||||
|
case QPlatformIntegration::StartDragDistance: {
|
||||||
|
// default is 10 pixels (see QPlatformTheme::defaultThemeHint)
|
||||||
|
return 10.0 * mScaleFactor;
|
||||||
|
}
|
||||||
|
case QPlatformIntegration::PasswordMaskDelay: {
|
||||||
|
// return time in milliseconds - 1 second
|
||||||
|
return QVariant(1000);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QPlatformIntegration::styleHint(hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformClipboard* QMirClientClientIntegration::clipboard() const
|
||||||
|
{
|
||||||
|
return mClipboard.data();
|
||||||
|
}
|
99
src/plugins/platforms/mirclient/qmirclientintegration.h
Normal file
99
src/plugins/platforms/mirclient/qmirclientintegration.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTINTEGRATION_H
|
||||||
|
#define QMIRCLIENTINTEGRATION_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformintegration.h>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
|
#include "qmirclientplatformservices.h"
|
||||||
|
|
||||||
|
// platform-api
|
||||||
|
#include <ubuntu/application/description.h>
|
||||||
|
#include <ubuntu/application/instance.h>
|
||||||
|
|
||||||
|
class QMirClientClipboard;
|
||||||
|
class QMirClientInput;
|
||||||
|
class QMirClientScreen;
|
||||||
|
|
||||||
|
class QMirClientClientIntegration : public QPlatformIntegration {
|
||||||
|
public:
|
||||||
|
QMirClientClientIntegration();
|
||||||
|
virtual ~QMirClientClientIntegration();
|
||||||
|
|
||||||
|
// QPlatformIntegration methods.
|
||||||
|
bool hasCapability(QPlatformIntegration::Capability cap) const override;
|
||||||
|
QAbstractEventDispatcher *createEventDispatcher() const override;
|
||||||
|
QPlatformNativeInterface* nativeInterface() const override { return mNativeInterface; }
|
||||||
|
QPlatformBackingStore* createPlatformBackingStore(QWindow* window) const override;
|
||||||
|
QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context) const override;
|
||||||
|
QPlatformFontDatabase* fontDatabase() const override { return mFontDb; }
|
||||||
|
QStringList themeNames() const override;
|
||||||
|
QPlatformTheme* createPlatformTheme(const QString& name) const override;
|
||||||
|
QVariant styleHint(StyleHint hint) const override;
|
||||||
|
QPlatformServices *services() const override;
|
||||||
|
QPlatformWindow* createPlatformWindow(QWindow* window) const override;
|
||||||
|
QPlatformInputContext* inputContext() const override { return mInputContext; }
|
||||||
|
QPlatformClipboard* clipboard() const override;
|
||||||
|
|
||||||
|
QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context);
|
||||||
|
QPlatformWindow* createPlatformWindow(QWindow* window);
|
||||||
|
QMirClientScreen* screen() const { return mScreen; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupOptions();
|
||||||
|
void setupDescription();
|
||||||
|
|
||||||
|
QPlatformNativeInterface* mNativeInterface;
|
||||||
|
QPlatformFontDatabase* mFontDb;
|
||||||
|
|
||||||
|
QMirClientPlatformServices* mServices;
|
||||||
|
|
||||||
|
QMirClientScreen* mScreen;
|
||||||
|
QMirClientInput* mInput;
|
||||||
|
QPlatformInputContext* mInputContext;
|
||||||
|
QSharedPointer<QMirClientClipboard> mClipboard;
|
||||||
|
qreal mScaleFactor;
|
||||||
|
|
||||||
|
// Platform API stuff
|
||||||
|
UApplicationOptions* mOptions;
|
||||||
|
UApplicationDescription* mDesc;
|
||||||
|
UApplicationInstance* mInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTINTEGRATION_H
|
60
src/plugins/platforms/mirclient/qmirclientlogging.h
Normal file
60
src/plugins/platforms/mirclient/qmirclientlogging.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTLOGGING_H
|
||||||
|
#define QMIRCLIENTLOGGING_H
|
||||||
|
|
||||||
|
// Logging and assertion macros.
|
||||||
|
#define LOG(...) qDebug(__VA_ARGS__)
|
||||||
|
#define LOG_IF(cond,...) do { if (cond) qDebug(__VA_ARGS__); } while (0)
|
||||||
|
#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
|
||||||
|
#define NOT_REACHED() qt_assert("Not reached!",__FILE__,__LINE__)
|
||||||
|
|
||||||
|
// Logging and assertion macros are compiled out for release builds.
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
#define DLOG(...) LOG(__VA_ARGS__)
|
||||||
|
#define DLOG_IF(cond,...) LOG_IF((cond), __VA_ARGS__)
|
||||||
|
#define DASSERT(cond) ASSERT((cond))
|
||||||
|
#define DNOT_REACHED() NOT_REACHED()
|
||||||
|
#else
|
||||||
|
#define DLOG(...) qt_noop()
|
||||||
|
#define DLOG_IF(cond,...) qt_noop()
|
||||||
|
#define DASSERT(cond) qt_noop()
|
||||||
|
#define DNOT_REACHED() qt_noop()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTLOGGING_H
|
134
src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
Normal file
134
src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <private/qguiapplication_p.h>
|
||||||
|
#include <QtGui/qopenglcontext.h>
|
||||||
|
#include <QtGui/qscreen.h>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
|
||||||
|
// Local
|
||||||
|
#include "qmirclientnativeinterface.h"
|
||||||
|
#include "qmirclientscreen.h"
|
||||||
|
#include "qmirclientglcontext.h"
|
||||||
|
|
||||||
|
class QMirClientResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMirClientResourceMap()
|
||||||
|
: QMap<QByteArray, QMirClientNativeInterface::ResourceType>() {
|
||||||
|
insert("egldisplay", QMirClientNativeInterface::EglDisplay);
|
||||||
|
insert("eglcontext", QMirClientNativeInterface::EglContext);
|
||||||
|
insert("nativeorientation", QMirClientNativeInterface::NativeOrientation);
|
||||||
|
insert("display", QMirClientNativeInterface::Display);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(QMirClientResourceMap, ubuntuResourceMap)
|
||||||
|
|
||||||
|
QMirClientNativeInterface::QMirClientNativeInterface()
|
||||||
|
: mGenericEventFilterType(QByteArrayLiteral("Event"))
|
||||||
|
, mNativeOrientation(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientNativeInterface::~QMirClientNativeInterface()
|
||||||
|
{
|
||||||
|
delete mNativeOrientation;
|
||||||
|
mNativeOrientation = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* QMirClientNativeInterface::nativeResourceForContext(
|
||||||
|
const QByteArray& resourceString, QOpenGLContext* context)
|
||||||
|
{
|
||||||
|
if (!context)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const QByteArray kLowerCaseResource = resourceString.toLower();
|
||||||
|
|
||||||
|
if (!ubuntuResourceMap()->contains(kLowerCaseResource))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
|
||||||
|
|
||||||
|
if (kResourceType == QMirClientNativeInterface::EglContext)
|
||||||
|
return static_cast<QMirClientOpenGLContext*>(context->handle())->eglContext();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resourceString, QWindow* window)
|
||||||
|
{
|
||||||
|
const QByteArray kLowerCaseResource = resourceString.toLower();
|
||||||
|
if (!ubuntuResourceMap()->contains(kLowerCaseResource))
|
||||||
|
return NULL;
|
||||||
|
const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
|
||||||
|
if (kResourceType == QMirClientNativeInterface::EglDisplay) {
|
||||||
|
if (window) {
|
||||||
|
return static_cast<QMirClientScreen*>(window->screen()->handle())->eglDisplay();
|
||||||
|
} else {
|
||||||
|
return static_cast<QMirClientScreen*>(
|
||||||
|
QGuiApplication::primaryScreen()->handle())->eglDisplay();
|
||||||
|
}
|
||||||
|
} else if (kResourceType == QMirClientNativeInterface::NativeOrientation) {
|
||||||
|
// Return the device's native screen orientation.
|
||||||
|
if (window) {
|
||||||
|
QMirClientScreen *ubuntuScreen = static_cast<QMirClientScreen*>(window->screen()->handle());
|
||||||
|
mNativeOrientation = new Qt::ScreenOrientation(ubuntuScreen->nativeOrientation());
|
||||||
|
} else {
|
||||||
|
QPlatformScreen *platformScreen = QGuiApplication::primaryScreen()->handle();
|
||||||
|
mNativeOrientation = new Qt::ScreenOrientation(platformScreen->nativeOrientation());
|
||||||
|
}
|
||||||
|
return mNativeOrientation;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* QMirClientNativeInterface::nativeResourceForScreen(const QByteArray& resourceString, QScreen* screen)
|
||||||
|
{
|
||||||
|
const QByteArray kLowerCaseResource = resourceString.toLower();
|
||||||
|
if (!ubuntuResourceMap()->contains(kLowerCaseResource))
|
||||||
|
return NULL;
|
||||||
|
const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
|
||||||
|
if (kResourceType == QMirClientNativeInterface::Display) {
|
||||||
|
if (!screen)
|
||||||
|
screen = QGuiApplication::primaryScreen();
|
||||||
|
return static_cast<QMirClientScreen*>(screen->handle())->eglNativeDisplay();
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
|
}
|
66
src/plugins/platforms/mirclient/qmirclientnativeinterface.h
Normal file
66
src/plugins/platforms/mirclient/qmirclientnativeinterface.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTNATIVEINTERFACE_H
|
||||||
|
#define QMIRCLIENTNATIVEINTERFACE_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
|
||||||
|
class QMirClientNativeInterface : public QPlatformNativeInterface {
|
||||||
|
public:
|
||||||
|
enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display };
|
||||||
|
|
||||||
|
QMirClientNativeInterface();
|
||||||
|
~QMirClientNativeInterface();
|
||||||
|
|
||||||
|
// QPlatformNativeInterface methods.
|
||||||
|
void* nativeResourceForContext(const QByteArray& resourceString,
|
||||||
|
QOpenGLContext* context) override;
|
||||||
|
void* nativeResourceForWindow(const QByteArray& resourceString,
|
||||||
|
QWindow* window) override;
|
||||||
|
void* nativeResourceForScreen(const QByteArray& resourceString,
|
||||||
|
QScreen* screen) override;
|
||||||
|
|
||||||
|
// New methods.
|
||||||
|
const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QByteArray mGenericEventFilterType;
|
||||||
|
Qt::ScreenOrientation* mNativeOrientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTNATIVEINTERFACE_H
|
@ -0,0 +1,66 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
|
||||||
|
#define QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
|
||||||
|
class OrientationChangeEvent : public QEvent {
|
||||||
|
public:
|
||||||
|
enum Orientation {
|
||||||
|
Undefined = 0,
|
||||||
|
TopUp,
|
||||||
|
TopDown,
|
||||||
|
LeftUp,
|
||||||
|
RightUp,
|
||||||
|
FaceUp,
|
||||||
|
FaceDown
|
||||||
|
};
|
||||||
|
|
||||||
|
OrientationChangeEvent(QEvent::Type type, Orientation orientation)
|
||||||
|
: QEvent(type)
|
||||||
|
, mOrientation(orientation)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QEvent::Type mType;
|
||||||
|
Orientation mOrientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
|
@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qmirclientplatformservices.h"
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <ubuntu/application/url_dispatcher/service.h>
|
||||||
|
#include <ubuntu/application/url_dispatcher/session.h>
|
||||||
|
|
||||||
|
bool QMirClientPlatformServices::openUrl(const QUrl &url)
|
||||||
|
{
|
||||||
|
return callDispatcher(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMirClientPlatformServices::openDocument(const QUrl &url)
|
||||||
|
{
|
||||||
|
return callDispatcher(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMirClientPlatformServices::callDispatcher(const QUrl &url)
|
||||||
|
{
|
||||||
|
UAUrlDispatcherSession* session = ua_url_dispatcher_session();
|
||||||
|
if (!session)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL);
|
||||||
|
|
||||||
|
free(session);
|
||||||
|
|
||||||
|
// We are returning true here because the other option
|
||||||
|
// is spawning a nested event loop and wait for the
|
||||||
|
// callback. But there is no guarantee on how fast
|
||||||
|
// the callback is going to be so we prefer to avoid the
|
||||||
|
// nested event loop. Long term plan is improve Qt API
|
||||||
|
// to support an async openUrl
|
||||||
|
return true;
|
||||||
|
}
|
54
src/plugins/platforms/mirclient/qmirclientplatformservices.h
Normal file
54
src/plugins/platforms/mirclient/qmirclientplatformservices.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTPLATFORMSERVICES_H
|
||||||
|
#define QMIRCLIENTPLATFORMSERVICES_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformservices.h>
|
||||||
|
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
|
||||||
|
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
|
||||||
|
|
||||||
|
class QMirClientPlatformServices : public QPlatformServices {
|
||||||
|
public:
|
||||||
|
bool openUrl(const QUrl &url) override;
|
||||||
|
bool openDocument(const QUrl &url) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool callDispatcher(const QUrl &url);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTPLATFORMSERVICES_H
|
61
src/plugins/platforms/mirclient/qmirclientplugin.cpp
Normal file
61
src/plugins/platforms/mirclient/qmirclientplugin.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qmirclientplugin.h"
|
||||||
|
#include "qmirclientintegration.h"
|
||||||
|
|
||||||
|
QStringList QMirClientIntegrationPlugin::keys() const
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
list << "mirclient";
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system,
|
||||||
|
const QStringList &)
|
||||||
|
{
|
||||||
|
if (system.toLower() == "mirclient") {
|
||||||
|
#ifdef PLATFORM_API_TOUCH
|
||||||
|
setenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient", 1);
|
||||||
|
#else
|
||||||
|
setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1);
|
||||||
|
#endif
|
||||||
|
return new QMirClientClientIntegration;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
53
src/plugins/platforms/mirclient/qmirclientplugin.h
Normal file
53
src/plugins/platforms/mirclient/qmirclientplugin.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTPLUGIN_H
|
||||||
|
#define QMIRCLIENTPLUGIN_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformintegrationplugin.h>
|
||||||
|
|
||||||
|
class QMirClientIntegrationPlugin : public QPlatformIntegrationPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "mirclient.json")
|
||||||
|
|
||||||
|
public:
|
||||||
|
QStringList keys() const;
|
||||||
|
QPlatformIntegration* create(const QString&, const QStringList&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTPLUGIN_H
|
296
src/plugins/platforms/mirclient/qmirclientscreen.cpp
Normal file
296
src/plugins/platforms/mirclient/qmirclientscreen.cpp
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QtCore/qmath.h>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QThread>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
#include <QtPlatformSupport/private/qeglconvenience_p.h>
|
||||||
|
|
||||||
|
// local
|
||||||
|
#include "qmirclientscreen.h"
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
#include "qmirclientorientationchangeevent_p.h"
|
||||||
|
|
||||||
|
#include "memory"
|
||||||
|
|
||||||
|
static const int kSwapInterval = 1;
|
||||||
|
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
|
||||||
|
static const char *orientationToStr(Qt::ScreenOrientation orientation) {
|
||||||
|
switch (orientation) {
|
||||||
|
case Qt::PrimaryOrientation:
|
||||||
|
return "primary";
|
||||||
|
case Qt::PortraitOrientation:
|
||||||
|
return "portrait";
|
||||||
|
case Qt::LandscapeOrientation:
|
||||||
|
return "landscape";
|
||||||
|
case Qt::InvertedPortraitOrientation:
|
||||||
|
return "inverted portrait";
|
||||||
|
case Qt::InvertedLandscapeOrientation:
|
||||||
|
return "inverted landscape";
|
||||||
|
default:
|
||||||
|
return "INVALID!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printEglConfig(EGLDisplay display, EGLConfig config) {
|
||||||
|
DASSERT(display != EGL_NO_DISPLAY);
|
||||||
|
DASSERT(config != nullptr);
|
||||||
|
static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
|
||||||
|
{ EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
|
||||||
|
{ EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
|
||||||
|
{ EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
|
||||||
|
{ EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
|
||||||
|
{ EGL_RED_SIZE, "EGL_RED_SIZE" },
|
||||||
|
{ EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
|
||||||
|
{ EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
|
||||||
|
{ EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
|
||||||
|
{ EGL_CONFIG_ID, "EGL_CONFIG_ID" },
|
||||||
|
{ EGL_LEVEL, "EGL_LEVEL" },
|
||||||
|
{ EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
|
||||||
|
{ EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
|
||||||
|
{ EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
|
||||||
|
{ EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
|
||||||
|
{ EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
|
||||||
|
{ EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
|
||||||
|
{ EGL_SAMPLES, "EGL_SAMPLES" },
|
||||||
|
{ EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
|
||||||
|
{ EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
|
||||||
|
{ EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
|
||||||
|
{ EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
|
||||||
|
{ EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
|
||||||
|
{ EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
|
||||||
|
{ EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
|
||||||
|
{ EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
|
||||||
|
{ EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
|
||||||
|
{ EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
|
||||||
|
{ -1, NULL }
|
||||||
|
};
|
||||||
|
const char* string = eglQueryString(display, EGL_VENDOR);
|
||||||
|
LOG("EGL vendor: %s", string);
|
||||||
|
string = eglQueryString(display, EGL_VERSION);
|
||||||
|
LOG("EGL version: %s", string);
|
||||||
|
string = eglQueryString(display, EGL_EXTENSIONS);
|
||||||
|
LOG("EGL extensions: %s", string);
|
||||||
|
LOG("EGL configuration attibutes:");
|
||||||
|
for (int index = 0; kAttribs[index].attrib != -1; index++) {
|
||||||
|
EGLint value;
|
||||||
|
if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
|
||||||
|
LOG(" %s: %d", kAttribs[index].name, static_cast<int>(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
const QEvent::Type OrientationChangeEvent::mType =
|
||||||
|
static_cast<QEvent::Type>(QEvent::registerEventType());
|
||||||
|
|
||||||
|
static const MirDisplayOutput *find_active_output(
|
||||||
|
const MirDisplayConfiguration *conf)
|
||||||
|
{
|
||||||
|
const MirDisplayOutput *output = NULL;
|
||||||
|
for (uint32_t d = 0; d < conf->num_outputs; d++)
|
||||||
|
{
|
||||||
|
const MirDisplayOutput *out = conf->outputs + d;
|
||||||
|
|
||||||
|
if (out->used &&
|
||||||
|
out->connected &&
|
||||||
|
out->num_modes &&
|
||||||
|
out->current_mode < out->num_modes)
|
||||||
|
{
|
||||||
|
output = out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientScreen::QMirClientScreen(MirConnection *connection)
|
||||||
|
: mFormat(QImage::Format_RGB32)
|
||||||
|
, mDepth(32)
|
||||||
|
, mSurfaceFormat()
|
||||||
|
, mEglDisplay(EGL_NO_DISPLAY)
|
||||||
|
, mEglConfig(nullptr)
|
||||||
|
{
|
||||||
|
// Initialize EGL.
|
||||||
|
ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
|
||||||
|
|
||||||
|
mEglNativeDisplay = mir_connection_get_egl_native_display(connection);
|
||||||
|
ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
|
||||||
|
ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
|
||||||
|
|
||||||
|
// Configure EGL buffers format.
|
||||||
|
mSurfaceFormat.setRedBufferSize(8);
|
||||||
|
mSurfaceFormat.setGreenBufferSize(8);
|
||||||
|
mSurfaceFormat.setBlueBufferSize(8);
|
||||||
|
mSurfaceFormat.setAlphaBufferSize(8);
|
||||||
|
mSurfaceFormat.setDepthBufferSize(24);
|
||||||
|
mSurfaceFormat.setStencilBufferSize(8);
|
||||||
|
if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
|
||||||
|
mSurfaceFormat.setSamples(4);
|
||||||
|
DLOG("ubuntumirclient: setting MSAA to 4 samples");
|
||||||
|
}
|
||||||
|
#ifdef QTUBUNTU_USE_OPENGL
|
||||||
|
mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
|
||||||
|
#else
|
||||||
|
mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||||
|
#endif
|
||||||
|
mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
|
||||||
|
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
printEglConfig(mEglDisplay, mEglConfig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set vblank swap interval.
|
||||||
|
int swapInterval = kSwapInterval;
|
||||||
|
QByteArray swapIntervalString = qgetenv("QTUBUNTU_SWAPINTERVAL");
|
||||||
|
if (!swapIntervalString.isEmpty()) {
|
||||||
|
bool ok;
|
||||||
|
swapInterval = swapIntervalString.toInt(&ok);
|
||||||
|
if (!ok)
|
||||||
|
swapInterval = kSwapInterval;
|
||||||
|
}
|
||||||
|
DLOG("ubuntumirclient: setting swap interval to %d", swapInterval);
|
||||||
|
eglSwapInterval(mEglDisplay, swapInterval);
|
||||||
|
|
||||||
|
// Get screen resolution.
|
||||||
|
auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); };
|
||||||
|
using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>;
|
||||||
|
configUp displayConfig(mir_connection_create_display_config(connection), configDeleter);
|
||||||
|
ASSERT(displayConfig != nullptr);
|
||||||
|
|
||||||
|
auto const displayOutput = find_active_output(displayConfig.get());
|
||||||
|
ASSERT(displayOutput != nullptr);
|
||||||
|
|
||||||
|
const MirDisplayMode *mode = &displayOutput->modes[displayOutput->current_mode];
|
||||||
|
const int kScreenWidth = mode->horizontal_resolution;
|
||||||
|
const int kScreenHeight = mode->vertical_resolution;
|
||||||
|
DASSERT(kScreenWidth > 0 && kScreenHeight > 0);
|
||||||
|
|
||||||
|
DLOG("ubuntumirclient: screen resolution: %dx%d", kScreenWidth, kScreenHeight);
|
||||||
|
|
||||||
|
mGeometry = QRect(0, 0, kScreenWidth, kScreenHeight);
|
||||||
|
|
||||||
|
DLOG("QQMirClientScreen::QQMirClientScreen (this=%p)", this);
|
||||||
|
|
||||||
|
// Set the default orientation based on the initial screen dimmensions.
|
||||||
|
mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
|
||||||
|
|
||||||
|
// If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
|
||||||
|
mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientScreen::~QMirClientScreen()
|
||||||
|
{
|
||||||
|
eglTerminate(mEglDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientScreen::customEvent(QEvent* event) {
|
||||||
|
DASSERT(QThread::currentThread() == thread());
|
||||||
|
|
||||||
|
OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event);
|
||||||
|
switch (oReadingEvent->mOrientation) {
|
||||||
|
case OrientationChangeEvent::LeftUp: {
|
||||||
|
mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
|
||||||
|
Qt::InvertedPortraitOrientation : Qt::LandscapeOrientation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OrientationChangeEvent::TopUp: {
|
||||||
|
mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
|
||||||
|
Qt::LandscapeOrientation : Qt::PortraitOrientation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OrientationChangeEvent::RightUp: {
|
||||||
|
mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
|
||||||
|
Qt::PortraitOrientation : Qt::InvertedLandscapeOrientation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OrientationChangeEvent::TopDown: {
|
||||||
|
mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
|
||||||
|
Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
DLOG("QMirClientScreen::customEvent - Unknown orientation.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raise the event signal so that client apps know the orientation changed
|
||||||
|
DLOG("QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
|
||||||
|
QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeight)
|
||||||
|
{
|
||||||
|
if ((windowWidth > windowHeight && mGeometry.width() < mGeometry.height())
|
||||||
|
|| (windowWidth < windowHeight && mGeometry.width() > mGeometry.height())) {
|
||||||
|
|
||||||
|
// The window aspect ratio differ's from the screen one. This means that
|
||||||
|
// unity8 has rotated the window in its scene.
|
||||||
|
// As there's no way to express window rotation in Qt's API, we have
|
||||||
|
// Flip QScreen's dimensions so that orientation properties match
|
||||||
|
// (primaryOrientation particularly).
|
||||||
|
// FIXME: This assumes a phone scenario. Won't work, or make sense,
|
||||||
|
// on the desktop
|
||||||
|
|
||||||
|
QRect currGeometry = mGeometry;
|
||||||
|
mGeometry.setWidth(currGeometry.height());
|
||||||
|
mGeometry.setHeight(currGeometry.width());
|
||||||
|
|
||||||
|
DLOG("QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
|
||||||
|
mGeometry.width(), mGeometry.height());
|
||||||
|
QWindowSystemInterface::handleScreenGeometryChange(screen(),
|
||||||
|
mGeometry /* newGeometry */,
|
||||||
|
mGeometry /* newAvailableGeometry */);
|
||||||
|
|
||||||
|
if (mGeometry.width() < mGeometry.height()) {
|
||||||
|
mCurrentOrientation = Qt::PortraitOrientation;
|
||||||
|
} else {
|
||||||
|
mCurrentOrientation = Qt::LandscapeOrientation;
|
||||||
|
}
|
||||||
|
DLOG("QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
|
||||||
|
QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
|
||||||
|
}
|
||||||
|
}
|
84
src/plugins/platforms/mirclient/qmirclientscreen.h
Normal file
84
src/plugins/platforms/mirclient/qmirclientscreen.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTSCREEN_H
|
||||||
|
#define QMIRCLIENTSCREEN_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformscreen.h>
|
||||||
|
#include <QSurfaceFormat>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
struct MirConnection;
|
||||||
|
|
||||||
|
class QMirClientScreen : public QObject, public QPlatformScreen
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QMirClientScreen(MirConnection *connection);
|
||||||
|
virtual ~QMirClientScreen();
|
||||||
|
|
||||||
|
// QPlatformScreen methods.
|
||||||
|
QImage::Format format() const override { return mFormat; }
|
||||||
|
int depth() const override { return mDepth; }
|
||||||
|
QRect geometry() const override { return mGeometry; }
|
||||||
|
QRect availableGeometry() const override { return mGeometry; }
|
||||||
|
Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; }
|
||||||
|
Qt::ScreenOrientation orientation() const override { return mNativeOrientation; }
|
||||||
|
|
||||||
|
// New methods.
|
||||||
|
QSurfaceFormat surfaceFormat() const { return mSurfaceFormat; }
|
||||||
|
EGLDisplay eglDisplay() const { return mEglDisplay; }
|
||||||
|
EGLConfig eglConfig() const { return mEglConfig; }
|
||||||
|
EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
|
||||||
|
void handleWindowSurfaceResize(int width, int height);
|
||||||
|
|
||||||
|
// QObject methods.
|
||||||
|
void customEvent(QEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QRect mGeometry;
|
||||||
|
Qt::ScreenOrientation mNativeOrientation;
|
||||||
|
Qt::ScreenOrientation mCurrentOrientation;
|
||||||
|
QImage::Format mFormat;
|
||||||
|
int mDepth;
|
||||||
|
QSurfaceFormat mSurfaceFormat;
|
||||||
|
EGLDisplay mEglDisplay;
|
||||||
|
EGLConfig mEglConfig;
|
||||||
|
EGLNativeDisplayType mEglNativeDisplay;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTSCREEN_H
|
64
src/plugins/platforms/mirclient/qmirclienttheme.cpp
Normal file
64
src/plugins/platforms/mirclient/qmirclienttheme.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qmirclienttheme.h"
|
||||||
|
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
|
||||||
|
const char *QMirClientTheme::name = "ubuntu";
|
||||||
|
|
||||||
|
QMirClientTheme::QMirClientTheme()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientTheme::~QMirClientTheme()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QMirClientTheme::themeHint(ThemeHint hint) const
|
||||||
|
{
|
||||||
|
if (hint == QPlatformTheme::SystemIconThemeName) {
|
||||||
|
QByteArray iconTheme = qgetenv("QTUBUNTU_ICON_THEME");
|
||||||
|
if (iconTheme.isEmpty()) {
|
||||||
|
return QVariant(QStringLiteral("ubuntu-mobile"));
|
||||||
|
} else {
|
||||||
|
return QVariant(QString(iconTheme));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return QGenericUnixTheme::themeHint(hint);
|
||||||
|
}
|
||||||
|
}
|
54
src/plugins/platforms/mirclient/qmirclienttheme.h
Normal file
54
src/plugins/platforms/mirclient/qmirclienttheme.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTTHEME_H
|
||||||
|
#define QMIRCLIENTTHEME_H
|
||||||
|
|
||||||
|
#include <QtPlatformSupport/private/qgenericunixthemes_p.h>
|
||||||
|
|
||||||
|
class QMirClientTheme : public QGenericUnixTheme
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char* name;
|
||||||
|
QMirClientTheme();
|
||||||
|
virtual ~QMirClientTheme();
|
||||||
|
|
||||||
|
// From QPlatformTheme
|
||||||
|
QVariant themeHint(ThemeHint hint) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTTHEME_H
|
452
src/plugins/platforms/mirclient/qmirclientwindow.cpp
Normal file
452
src/plugins/platforms/mirclient/qmirclientwindow.cpp
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014-2015 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Local
|
||||||
|
#include "qmirclientclipboard.h"
|
||||||
|
#include "qmirclientinput.h"
|
||||||
|
#include "qmirclientwindow.h"
|
||||||
|
#include "qmirclientscreen.h"
|
||||||
|
#include "qmirclientlogging.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
|
// Platform API
|
||||||
|
#include <ubuntu/application/instance.h>
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
#define IS_OPAQUE_FLAG 1
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case Qt::WindowNoState:
|
||||||
|
return mir_surface_state_restored;
|
||||||
|
|
||||||
|
case Qt::WindowFullScreen:
|
||||||
|
return mir_surface_state_fullscreen;
|
||||||
|
|
||||||
|
case Qt::WindowMaximized:
|
||||||
|
return mir_surface_state_maximized;
|
||||||
|
|
||||||
|
case Qt::WindowMinimized:
|
||||||
|
return mir_surface_state_minimized;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG("Unexpected Qt::WindowState: %d", state);
|
||||||
|
return mir_surface_state_restored;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
const char *qtWindowStateToStr(Qt::WindowState state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case Qt::WindowNoState:
|
||||||
|
return "NoState";
|
||||||
|
|
||||||
|
case Qt::WindowFullScreen:
|
||||||
|
return "FullScreen";
|
||||||
|
|
||||||
|
case Qt::WindowMaximized:
|
||||||
|
return "Maximized";
|
||||||
|
|
||||||
|
case Qt::WindowMinimized:
|
||||||
|
return "Minimized";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "!?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
class QMirClientWindowPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void createEGLSurface(EGLNativeWindowType nativeWindow);
|
||||||
|
void destroyEGLSurface();
|
||||||
|
int panelHeight();
|
||||||
|
|
||||||
|
QMirClientScreen* screen;
|
||||||
|
EGLSurface eglSurface;
|
||||||
|
WId id;
|
||||||
|
QMirClientInput* input;
|
||||||
|
Qt::WindowState state;
|
||||||
|
MirConnection *connection;
|
||||||
|
MirSurface* surface;
|
||||||
|
QSize bufferSize;
|
||||||
|
QMutex mutex;
|
||||||
|
QSharedPointer<QMirClientClipboard> clipboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void eventCallback(MirSurface* surface, const MirEvent *event, void* context)
|
||||||
|
{
|
||||||
|
(void) surface;
|
||||||
|
DASSERT(context != NULL);
|
||||||
|
QMirClientWindow* platformWindow = static_cast<QMirClientWindow*>(context);
|
||||||
|
platformWindow->priv()->input->postEvent(platformWindow, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void surfaceCreateCallback(MirSurface* surface, void* context)
|
||||||
|
{
|
||||||
|
DASSERT(context != NULL);
|
||||||
|
QMirClientWindow* platformWindow = static_cast<QMirClientWindow*>(context);
|
||||||
|
platformWindow->priv()->surface = surface;
|
||||||
|
|
||||||
|
mir_surface_set_event_handler(surface, eventCallback, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientWindow::QMirClientWindow(QWindow* w, QSharedPointer<QMirClientClipboard> clipboard, QMirClientScreen* screen,
|
||||||
|
QMirClientInput* input, MirConnection* connection)
|
||||||
|
: QObject(nullptr), QPlatformWindow(w)
|
||||||
|
{
|
||||||
|
DASSERT(screen != NULL);
|
||||||
|
|
||||||
|
d = new QMirClientWindowPrivate;
|
||||||
|
d->screen = screen;
|
||||||
|
d->eglSurface = EGL_NO_SURFACE;
|
||||||
|
d->input = input;
|
||||||
|
d->state = window()->windowState();
|
||||||
|
d->connection = connection;
|
||||||
|
d->clipboard = clipboard;
|
||||||
|
|
||||||
|
static int id = 1;
|
||||||
|
d->id = id++;
|
||||||
|
|
||||||
|
// Use client geometry if set explicitly, use available screen geometry otherwise.
|
||||||
|
QPlatformWindow::setGeometry(window()->geometry() != screen->geometry() ?
|
||||||
|
window()->geometry() : screen->availableGeometry());
|
||||||
|
createWindow();
|
||||||
|
DLOG("QMirClientWindow::QMirClientWindow (this=%p, w=%p, screen=%p, input=%p)", this, w, screen, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMirClientWindow::~QMirClientWindow()
|
||||||
|
{
|
||||||
|
DLOG("QMirClientWindow::~QMirClientWindow");
|
||||||
|
d->destroyEGLSurface();
|
||||||
|
|
||||||
|
mir_surface_release_sync(d->surface);
|
||||||
|
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindowPrivate::createEGLSurface(EGLNativeWindowType nativeWindow)
|
||||||
|
{
|
||||||
|
DLOG("QMirClientWindowPrivate::createEGLSurface (this=%p, nativeWindow=%p)",
|
||||||
|
this, reinterpret_cast<void*>(nativeWindow));
|
||||||
|
|
||||||
|
eglSurface = eglCreateWindowSurface(screen->eglDisplay(), screen->eglConfig(),
|
||||||
|
nativeWindow, nullptr);
|
||||||
|
|
||||||
|
DASSERT(eglSurface != EGL_NO_SURFACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindowPrivate::destroyEGLSurface()
|
||||||
|
{
|
||||||
|
DLOG("QMirClientWindowPrivate::destroyEGLSurface (this=%p)", this);
|
||||||
|
if (eglSurface != EGL_NO_SURFACE) {
|
||||||
|
eglDestroySurface(screen->eglDisplay(), eglSurface);
|
||||||
|
eglSurface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
|
||||||
|
// we need to guess the panel height (3GU + 2DP)
|
||||||
|
int QMirClientWindowPrivate::panelHeight()
|
||||||
|
{
|
||||||
|
const int defaultGridUnit = 8;
|
||||||
|
int gridUnit = defaultGridUnit;
|
||||||
|
QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
|
||||||
|
if (!gridUnitString.isEmpty()) {
|
||||||
|
bool ok;
|
||||||
|
gridUnit = gridUnitString.toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
gridUnit = defaultGridUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qreal densityPixelRatio = static_cast<qreal>(gridUnit) / defaultGridUnit;
|
||||||
|
return gridUnit * 3 + qFloor(densityPixelRatio) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static MirPixelFormat
|
||||||
|
mir_choose_default_pixel_format(MirConnection *connection)
|
||||||
|
{
|
||||||
|
MirPixelFormat format[mir_pixel_formats];
|
||||||
|
unsigned int nformats;
|
||||||
|
|
||||||
|
mir_connection_get_available_surface_formats(connection,
|
||||||
|
format, mir_pixel_formats, &nformats);
|
||||||
|
|
||||||
|
return format[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::createWindow()
|
||||||
|
{
|
||||||
|
DLOG("QMirClientWindow::createWindow (this=%p)", this);
|
||||||
|
|
||||||
|
// FIXME: remove this remnant of an old platform-api enum - needs ubuntu-keyboard update
|
||||||
|
const int SCREEN_KEYBOARD_ROLE = 7;
|
||||||
|
// Get surface role and flags.
|
||||||
|
QVariant roleVariant = window()->property("role");
|
||||||
|
int role = roleVariant.isValid() ? roleVariant.toUInt() : 1; // 1 is the default role for apps.
|
||||||
|
QVariant opaqueVariant = window()->property("opaque");
|
||||||
|
uint flags = opaqueVariant.isValid() ?
|
||||||
|
opaqueVariant.toUInt() ? static_cast<uint>(IS_OPAQUE_FLAG) : 0 : 0;
|
||||||
|
|
||||||
|
// FIXME(loicm) Opaque flag is forced for now for non-system sessions (applications) for
|
||||||
|
// performance reasons.
|
||||||
|
flags |= static_cast<uint>(IS_OPAQUE_FLAG);
|
||||||
|
|
||||||
|
const QByteArray title = (!window()->title().isNull()) ? window()->title().toUtf8() : "Window 1"; // legacy title
|
||||||
|
const int panelHeight = d->panelHeight();
|
||||||
|
|
||||||
|
#if !defined(QT_NO_DEBUG)
|
||||||
|
LOG("panelHeight: '%d'", panelHeight);
|
||||||
|
LOG("role: '%d'", role);
|
||||||
|
LOG("flags: '%s'", (flags & static_cast<uint>(1)) ? "Opaque" : "NotOpaque");
|
||||||
|
LOG("title: '%s'", title.constData());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get surface geometry.
|
||||||
|
QRect geometry;
|
||||||
|
if (d->state == Qt::WindowFullScreen) {
|
||||||
|
printf("QMirClientWindow - fullscreen geometry\n");
|
||||||
|
geometry = screen()->geometry();
|
||||||
|
} else if (d->state == Qt::WindowMaximized) {
|
||||||
|
printf("QMirClientWindow - maximized geometry\n");
|
||||||
|
geometry = screen()->availableGeometry();
|
||||||
|
/*
|
||||||
|
* FIXME: Autopilot relies on being able to convert coordinates relative of the window
|
||||||
|
* into absolute screen coordinates. Mir does not allow this, see bug lp:1346633
|
||||||
|
* Until there's a correct way to perform this transformation agreed, this horrible hack
|
||||||
|
* guesses the transformation heuristically.
|
||||||
|
*
|
||||||
|
* Assumption: this method only used on phone devices!
|
||||||
|
*/
|
||||||
|
geometry.setY(panelHeight);
|
||||||
|
} else {
|
||||||
|
printf("QMirClientWindow - regular geometry\n");
|
||||||
|
geometry = this->geometry();
|
||||||
|
geometry.setY(panelHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOG("[ubuntumirclient QPA] creating surface at (%d, %d) with size (%d, %d) with title '%s'\n",
|
||||||
|
geometry.x(), geometry.y(), geometry.width(), geometry.height(), title.data());
|
||||||
|
|
||||||
|
MirSurfaceSpec *spec;
|
||||||
|
if (role == SCREEN_KEYBOARD_ROLE)
|
||||||
|
{
|
||||||
|
spec = mir_connection_create_spec_for_input_method(d->connection, geometry.width(),
|
||||||
|
geometry.height(), mir_choose_default_pixel_format(d->connection));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spec = mir_connection_create_spec_for_normal_surface(d->connection, geometry.width(),
|
||||||
|
geometry.height(), mir_choose_default_pixel_format(d->connection));
|
||||||
|
}
|
||||||
|
mir_surface_spec_set_name(spec, title.data());
|
||||||
|
|
||||||
|
// Create platform window
|
||||||
|
mir_wait_for(mir_surface_create(spec, surfaceCreateCallback, this));
|
||||||
|
mir_surface_spec_release(spec);
|
||||||
|
|
||||||
|
DASSERT(d->surface != NULL);
|
||||||
|
d->createEGLSurface((EGLNativeWindowType)mir_buffer_stream_get_egl_native_window(mir_surface_get_buffer_stream(d->surface)));
|
||||||
|
|
||||||
|
if (d->state == Qt::WindowFullScreen) {
|
||||||
|
// TODO: We could set this on creation once surface spec supports it (mps already up)
|
||||||
|
mir_wait_for(mir_surface_set_state(d->surface, mir_surface_state_fullscreen));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window manager can give us a final size different from what we asked for
|
||||||
|
// so let's check what we ended up getting
|
||||||
|
{
|
||||||
|
MirSurfaceParameters parameters;
|
||||||
|
mir_surface_get_parameters(d->surface, ¶meters);
|
||||||
|
|
||||||
|
geometry.setWidth(parameters.width);
|
||||||
|
geometry.setHeight(parameters.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOG("[ubuntumirclient QPA] created surface has size (%d, %d)",
|
||||||
|
geometry.width(), geometry.height());
|
||||||
|
|
||||||
|
// Assume that the buffer size matches the surface size at creation time
|
||||||
|
d->bufferSize = geometry.size();
|
||||||
|
|
||||||
|
// Tell Qt about the geometry.
|
||||||
|
QWindowSystemInterface::handleGeometryChange(window(), geometry);
|
||||||
|
QPlatformWindow::setGeometry(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::moveResize(const QRect& rect)
|
||||||
|
{
|
||||||
|
(void) rect;
|
||||||
|
// TODO: Not yet supported by mir.
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::handleSurfaceResize(int width, int height)
|
||||||
|
{
|
||||||
|
QMutexLocker(&d->mutex);
|
||||||
|
LOG("QMirClientWindow::handleSurfaceResize(width=%d, height=%d)", width, height);
|
||||||
|
|
||||||
|
// The current buffer size hasn't actually changed. so just render on it and swap
|
||||||
|
// buffers in the hope that the next buffer will match the surface size advertised
|
||||||
|
// in this event.
|
||||||
|
// But since this event is processed by a thread different from the one that swaps
|
||||||
|
// buffers, you can never know if this information is already outdated as there's
|
||||||
|
// no synchronicity whatsoever between the processing of resize events and the
|
||||||
|
// consumption of buffers.
|
||||||
|
if (d->bufferSize.width() != width || d->bufferSize.height() != height) {
|
||||||
|
QWindowSystemInterface::handleExposeEvent(window(), geometry());
|
||||||
|
QWindowSystemInterface::flushWindowSystemEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::handleSurfaceFocusChange(bool focused)
|
||||||
|
{
|
||||||
|
LOG("QMirClientWindow::handleSurfaceFocusChange(focused=%s)", focused ? "true" : "false");
|
||||||
|
QWindow *activatedWindow = focused ? window() : nullptr;
|
||||||
|
|
||||||
|
// System clipboard contents might have changed while this window was unfocused and wihtout
|
||||||
|
// this process getting notified about it because it might have been suspended (due to
|
||||||
|
// application lifecycle policies), thus unable to listen to any changes notified through
|
||||||
|
// D-Bus.
|
||||||
|
// Therefore let's ensure we are up to date with the system clipboard now that we are getting
|
||||||
|
// focused again.
|
||||||
|
if (focused) {
|
||||||
|
d->clipboard->requestDBusClipboardContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWindowSystemInterface::handleWindowActivated(activatedWindow, Qt::ActiveWindowFocusReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::setWindowState(Qt::WindowState state)
|
||||||
|
{
|
||||||
|
QMutexLocker(&d->mutex);
|
||||||
|
DLOG("QMirClientWindow::setWindowState (this=%p, %s)", this, qtWindowStateToStr(state));
|
||||||
|
|
||||||
|
if (state == d->state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: Perhaps we should check if the states are applied?
|
||||||
|
mir_wait_for(mir_surface_set_state(d->surface, qtWindowStateToMirSurfaceState(state)));
|
||||||
|
d->state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::setGeometry(const QRect& rect)
|
||||||
|
{
|
||||||
|
DLOG("QMirClientWindow::setGeometry (this=%p)", this);
|
||||||
|
|
||||||
|
bool doMoveResize;
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker(&d->mutex);
|
||||||
|
QPlatformWindow::setGeometry(rect);
|
||||||
|
doMoveResize = d->state != Qt::WindowFullScreen && d->state != Qt::WindowMaximized;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doMoveResize) {
|
||||||
|
moveResize(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::setVisible(bool visible)
|
||||||
|
{
|
||||||
|
QMutexLocker(&d->mutex);
|
||||||
|
DLOG("QMirClientWindow::setVisible (this=%p, visible=%s)", this, visible ? "true" : "false");
|
||||||
|
|
||||||
|
if (visible) {
|
||||||
|
mir_wait_for(mir_surface_set_state(d->surface, qtWindowStateToMirSurfaceState(d->state)));
|
||||||
|
|
||||||
|
QWindowSystemInterface::handleExposeEvent(window(), QRect());
|
||||||
|
QWindowSystemInterface::flushWindowSystemEvents();
|
||||||
|
} else {
|
||||||
|
// TODO: Use the new mir_surface_state_hidden state instead of mir_surface_state_minimized.
|
||||||
|
// Will have to change qtmir and unity8 for that.
|
||||||
|
mir_wait_for(mir_surface_set_state(d->surface, mir_surface_state_minimized));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* QMirClientWindow::eglSurface() const
|
||||||
|
{
|
||||||
|
return d->eglSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
WId QMirClientWindow::winId() const
|
||||||
|
{
|
||||||
|
return d->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMirClientWindow::onBuffersSwapped_threadSafe(int newBufferWidth, int newBufferHeight)
|
||||||
|
{
|
||||||
|
QMutexLocker(&d->mutex);
|
||||||
|
|
||||||
|
bool sizeKnown = newBufferWidth > 0 && newBufferHeight > 0;
|
||||||
|
|
||||||
|
if (sizeKnown && (d->bufferSize.width() != newBufferWidth ||
|
||||||
|
d->bufferSize.height() != newBufferHeight)) {
|
||||||
|
|
||||||
|
DLOG("QMirClientWindow::onBuffersSwapped_threadSafe - buffer size changed from (%d,%d) to (%d,%d)",
|
||||||
|
d->bufferSize.width(), d->bufferSize.height(), newBufferWidth, newBufferHeight);
|
||||||
|
|
||||||
|
d->bufferSize.rwidth() = newBufferWidth;
|
||||||
|
d->bufferSize.rheight() = newBufferHeight;
|
||||||
|
|
||||||
|
QRect newGeometry;
|
||||||
|
|
||||||
|
newGeometry = geometry();
|
||||||
|
newGeometry.setWidth(d->bufferSize.width());
|
||||||
|
newGeometry.setHeight(d->bufferSize.height());
|
||||||
|
|
||||||
|
QPlatformWindow::setGeometry(newGeometry);
|
||||||
|
QWindowSystemInterface::handleGeometryChange(window(), newGeometry, QRect());
|
||||||
|
}
|
||||||
|
}
|
80
src/plugins/platforms/mirclient/qmirclientwindow.h
Normal file
80
src/plugins/platforms/mirclient/qmirclientwindow.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014-2015 Canonical, Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL3$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QMIRCLIENTWINDOW_H
|
||||||
|
#define QMIRCLIENTWINDOW_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformwindow.h>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
|
||||||
|
class QMirClientClipboard;
|
||||||
|
class QMirClientInput;
|
||||||
|
class QMirClientScreen;
|
||||||
|
class QMirClientWindowPrivate;
|
||||||
|
|
||||||
|
class QMirClientWindow : public QObject, public QPlatformWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QMirClientWindow(QWindow *w, QSharedPointer<QMirClientClipboard> clipboard, QMirClientScreen *screen,
|
||||||
|
QMirClientInput *input, MirConnection *mir_connection);
|
||||||
|
virtual ~QMirClientWindow();
|
||||||
|
|
||||||
|
// QPlatformWindow methods.
|
||||||
|
WId winId() const override;
|
||||||
|
void setGeometry(const QRect&) override;
|
||||||
|
void setWindowState(Qt::WindowState state) override;
|
||||||
|
void setVisible(bool visible) override;
|
||||||
|
|
||||||
|
// New methods.
|
||||||
|
void* eglSurface() const;
|
||||||
|
void handleSurfaceResize(int width, int height);
|
||||||
|
void handleSurfaceFocusChange(bool focused);
|
||||||
|
void onBuffersSwapped_threadSafe(int newBufferWidth, int newBufferHeight);
|
||||||
|
|
||||||
|
QMirClientWindowPrivate* priv() { return d; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createWindow();
|
||||||
|
void moveResize(const QRect& rect);
|
||||||
|
|
||||||
|
QMirClientWindowPrivate *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMIRCLIENTWINDOW_H
|
@ -40,3 +40,5 @@ contains(QT_CONFIG, linuxfb): SUBDIRS += linuxfb
|
|||||||
haiku {
|
haiku {
|
||||||
SUBDIRS += haiku
|
SUBDIRS += haiku
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contains(QT_CONFIG, mirclient): SUBDIRS += mirclient
|
||||||
|
Loading…
x
Reference in New Issue
Block a user