/*
* Copyright (C) 2013-2015 Canonical, Ltd.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#include "mirserverintegration.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Mir
#include
#include
// local
#include "clipboard.h"
#include "display.h"
#include "displaywindow.h"
#include "miropenglcontext.h"
#include "nativeinterface.h"
#include "qmirserver.h"
#include "services.h"
#include "ubuntutheme.h"
namespace mg = mir::graphics;
using qtmir::Clipboard;
MirServerIntegration::MirServerIntegration()
: m_accessibility(new QPlatformAccessibility())
, m_fontDb(new QGenericUnixFontDatabase())
, m_services(new Services)
, m_mirServer(new QMirServer(QCoreApplication::arguments()))
, m_display(nullptr)
, m_nativeInterface(nullptr)
, m_clipboard(new Clipboard)
{
// For access to sensors, qtmir uses qtubuntu-sensors. qtubuntu-sensors reads the
// UBUNTU_PLATFORM_API_BACKEND variable to decide if to load a valid sensor backend or not.
// For it to function we need to ensure a valid backend has been specified
if (qEnvironmentVariableIsEmpty("UBUNTU_PLATFORM_API_BACKEND")) {
if (qgetenv("DESKTOP_SESSION").contains("mir") || !qEnvironmentVariableIsSet("ANDROID_DATA")) {
qputenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient");
} else {
qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient");
}
}
// If Mir shuts down, quit.
QObject::connect(m_mirServer.data(), &QMirServer::stopped,
QCoreApplication::instance(), &QCoreApplication::quit);
m_inputContext = QPlatformInputContextFactory::create();
}
MirServerIntegration::~MirServerIntegration()
{
delete m_nativeInterface;
delete m_display;
}
bool MirServerIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
case OpenGL: return true;
case ThreadedOpenGL: return true;
case BufferQueueingOpenGL: return true;
case MultipleWindows: return false; // multi-monitor support
case WindowManagement: return false; // platform has no WM, as this implements the WM!
case NonFullScreenWindows: return false;
default: return QPlatformIntegration::hasCapability(cap);
}
}
QPlatformWindow *MirServerIntegration::createPlatformWindow(QWindow *window) const
{
QWindowSystemInterface::flushWindowSystemEvents();
DisplayWindow* displayWindow = nullptr;
auto const mirServer = m_mirServer->mirServer().lock();
mg::DisplayBuffer* first_buffer{nullptr};
mg::DisplaySyncGroup* first_group{nullptr};
if (mirServer) {
mirServer->the_display()->for_each_display_sync_group([&](mg::DisplaySyncGroup &group) {
if (!first_group) {
first_group = &group;
}
group.for_each_display_buffer([&](mg::DisplayBuffer &buffer) {
if (!first_buffer) {
first_buffer = &buffer;
}
});
});
}
// FIXME(gerry) this will go very bad for >1 display buffer
if (first_group && first_buffer)
displayWindow = new DisplayWindow(window, first_group, first_buffer);
if (!displayWindow)
return nullptr;
//displayWindow->requestActivateWindow();
return displayWindow;
}
QPlatformBackingStore *MirServerIntegration::createPlatformBackingStore(QWindow *window) const
{
qDebug() << "createPlatformBackingStore" << window;
return nullptr;
}
QPlatformOpenGLContext *MirServerIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
qDebug() << "createPlatformOpenGLContext" << context;
return new MirOpenGLContext(m_mirServer->mirServer(), context->format());
}
QAbstractEventDispatcher *MirServerIntegration::createEventDispatcher() const
{
return createUnixEventDispatcher();
}
void MirServerIntegration::initialize()
{
// Creates instance of and start the Mir server in a separate thread
if (!m_mirServer->start()) {
exit(2);
}
m_display = new Display(m_mirServer->mirServer().data()->the_display()->configuration());
m_nativeInterface = new NativeInterface(m_mirServer->mirServer());
for (QPlatformScreen *screen : m_display->screens())
screenAdded(screen);
m_clipboard->setupDBusService();
}
QPlatformAccessibility *MirServerIntegration::accessibility() const
{
return m_accessibility.data();
}
QPlatformFontDatabase *MirServerIntegration::fontDatabase() const
{
return m_fontDb.data();
}
QStringList MirServerIntegration::themeNames() const
{
return QStringList(UbuntuTheme::name);
}
QPlatformTheme *MirServerIntegration::createPlatformTheme(const QString& name) const
{
Q_UNUSED(name);
return new UbuntuTheme;
}
QPlatformServices *MirServerIntegration::services() const
{
return m_services.data();
}
QPlatformNativeInterface *MirServerIntegration::nativeInterface() const
{
return m_nativeInterface;
}
QPlatformClipboard *MirServerIntegration::clipboard() const
{
return m_clipboard.data();
}