2
* Copyright (C) 2013-2016 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
#include "mirserverintegration.h"
19
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
20
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
21
#include <QtPlatformSupport/private/qgenericunixservices_p.h>
23
#include <qpa/qplatformwindow.h>
24
#include <qpa/qplatformaccessibility.h>
25
#include <qpa/qplatforminputcontext.h>
26
#include <qpa/qplatforminputcontextfactory_p.h>
27
#include <qpa/qwindowsysteminterface.h>
29
#include <QGuiApplication>
30
#include <QStringList>
34
#include <mir/graphics/display.h>
35
#include <mir/graphics/display_configuration.h>
38
#include "clipboard.h"
39
#include "miropenglcontext.h"
40
#include "nativeinterface.h"
41
#include "offscreensurface.h"
42
#include "qmirserver.h"
44
#include "screensmodel.h"
45
#include "screenwindow.h"
47
#include "ubuntutheme.h"
50
namespace mg = mir::graphics;
51
using qtmir::Clipboard;
53
MirServerIntegration::MirServerIntegration(int &argc, char **argv)
54
: m_accessibility(new QPlatformAccessibility())
55
, m_fontDb(new QGenericUnixFontDatabase())
56
, m_services(new Services)
57
, m_mirServer(new QMirServer(argc, argv))
58
, m_nativeInterface(nullptr)
60
// For access to sensors, qtmir uses qtubuntu-sensors. qtubuntu-sensors reads the
61
// UBUNTU_PLATFORM_API_BACKEND variable to decide if to load a valid sensor backend or not.
62
// For it to function we need to ensure a valid backend has been specified
63
if (qEnvironmentVariableIsEmpty("UBUNTU_PLATFORM_API_BACKEND")) {
64
if (qgetenv("DESKTOP_SESSION").contains("mir") || !qEnvironmentVariableIsSet("ANDROID_DATA")) {
65
qputenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient");
67
qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient");
71
// If Mir shuts down, quit.
72
QObject::connect(m_mirServer.data(), &QMirServer::stopped,
73
QCoreApplication::instance(), &QCoreApplication::quit);
75
m_inputContext = QPlatformInputContextFactory::create();
77
// Default Qt behaviour doesn't match a shell's intentions, so customize:
78
qGuiApp->setQuitOnLastWindowClosed(false);
81
MirServerIntegration::~MirServerIntegration()
83
delete m_nativeInterface;
86
bool MirServerIntegration::hasCapability(QPlatformIntegration::Capability cap) const
89
case ThreadedPixmaps: return true;
90
case OpenGL: return true;
91
case ThreadedOpenGL: return true;
92
case BufferQueueingOpenGL: return true;
93
case MultipleWindows: return true; // multi-monitor support
94
case WindowManagement: return false; // platform has no WM, as this implements the WM!
95
case NonFullScreenWindows: return false;
96
default: return QPlatformIntegration::hasCapability(cap);
100
QPlatformWindow *MirServerIntegration::createPlatformWindow(QWindow *window) const
102
QWindowSystemInterface::flushWindowSystemEvents();
104
auto screens = m_mirServer->screensModel();
106
qCritical("Screens are not initialized, unable to create a new QWindow/ScreenWindow");
110
auto platformWindow = new ScreenWindow(window);
111
if (screens->compositing()) {
112
platformWindow->setExposed(true);
115
qCDebug(QTMIR_SCREENS) << "QWindow" << window << "with geom" << window->geometry()
116
<< "is backed by a" << static_cast<Screen *>(window->screen()->handle())
117
<< "with geometry" << window->screen()->geometry();
118
return platformWindow;
121
QPlatformBackingStore *MirServerIntegration::createPlatformBackingStore(QWindow */*window*/) const
126
QPlatformOpenGLContext *MirServerIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
128
return m_mirServer->createPlatformOpenGLContext(context);
131
QAbstractEventDispatcher *MirServerIntegration::createEventDispatcher() const
133
return createUnixEventDispatcher();
136
void MirServerIntegration::initialize()
138
// Creates instance of and start the Mir server in a separate thread
139
if (!m_mirServer->start()) {
143
auto screens = m_mirServer->screensModel();
145
qFatal("ScreensModel not initialized");
147
QObject::connect(screens.data(), &ScreensModel::screenAdded,
148
[this](Screen *screen) { this->screenAdded(screen); });
149
QObject::connect(screens.data(), &ScreensModel::screenRemoved,
150
[this](Screen *screen) {
151
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
154
this->destroyScreen(screen);
158
Q_FOREACH(auto screen, screens->screens()) {
162
m_nativeInterface = new NativeInterface(m_mirServer.data());
165
QPlatformAccessibility *MirServerIntegration::accessibility() const
167
return m_accessibility.data();
170
QPlatformFontDatabase *MirServerIntegration::fontDatabase() const
172
return m_fontDb.data();
175
QStringList MirServerIntegration::themeNames() const
177
return QStringList(UbuntuTheme::name);
180
QPlatformTheme *MirServerIntegration::createPlatformTheme(const QString& name) const
183
return new UbuntuTheme;
186
QPlatformServices *MirServerIntegration::services() const
188
return m_services.data();
191
QPlatformNativeInterface *MirServerIntegration::nativeInterface() const
193
return m_nativeInterface;
196
QPlatformClipboard *MirServerIntegration::clipboard() const
198
static QPlatformClipboard *clipboard = nullptr;
200
clipboard = new Clipboard;
205
QPlatformOffscreenSurface *MirServerIntegration::createPlatformOffscreenSurface(
206
QOffscreenSurface *surface) const
208
return new OffscreenSurface(surface);