summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel d'Andrada <daniel.dandrada@canonical.com>2015-07-24 19:00:22 -0300
committerDaniel d'Andrada <daniel.dandrada@canonical.com>2015-07-24 19:00:22 -0300
commit038c0514e8d12fa5f067f336a0e26a5d3417b29b (patch)
tree2b0ec28271424825b1adde3db9de84e66a1b4dc9 /src
parent0669f32d7b6112561458df8888845a4e26eb9167 (diff)
parent5435c2d8e18affc57d03d0742029edadba6f48fa (diff)
Merge trunk
[ Andreas Pokorny ] * Release in step with Mir 0.14.0 [ CI Train Bot ] * New rebuild forced. [ Gerry Boland ] * [qpa] refactor QMirServer to clean up its API, and fix strange thread design. [ MichaƂ Sawicz ] * Depend on same-version qtmir-{desktop,android} * No-change rebuild against Qt 5.4.2.
Diffstat (limited to 'src')
-rw-r--r--src/common/debughelpers.h2
-rw-r--r--src/modules/Unity/Application/mirsurfaceitem.cpp30
-rw-r--r--src/platforms/mirserver/CMakeLists.txt1
-rw-r--r--src/platforms/mirserver/display.cpp7
-rw-r--r--src/platforms/mirserver/display.h12
-rw-r--r--src/platforms/mirserver/miropenglcontext.cpp5
-rw-r--r--src/platforms/mirserver/miropenglcontext.h1
-rw-r--r--src/platforms/mirserver/mirserverintegration.cpp59
-rw-r--r--src/platforms/mirserver/mirserverintegration.h7
-rw-r--r--src/platforms/mirserver/nativeinterface.cpp23
-rw-r--r--src/platforms/mirserver/nativeinterface.h6
-rw-r--r--src/platforms/mirserver/qmirserver.cpp101
-rw-r--r--src/platforms/mirserver/qmirserver.h60
-rw-r--r--src/platforms/mirserver/qmirserver_p.cpp53
-rw-r--r--src/platforms/mirserver/qmirserver_p.h67
-rw-r--r--src/platforms/mirserver/qteventfeeder.cpp17
-rw-r--r--src/platforms/mirserver/qteventfeeder.h4
17 files changed, 258 insertions, 197 deletions
diff --git a/src/common/debughelpers.h b/src/common/debughelpers.h
index 7990598..d4e5253 100644
--- a/src/common/debughelpers.h
+++ b/src/common/debughelpers.h
@@ -20,7 +20,7 @@
#include <QString>
#include <mir_toolkit/common.h>
-#include <mir_toolkit/events/input/input_event.h>
+#include <mir_toolkit/event.h>
class QTouchEvent;
diff --git a/src/modules/Unity/Application/mirsurfaceitem.cpp b/src/modules/Unity/Application/mirsurfaceitem.cpp
index d140f7e..3c98329 100644
--- a/src/modules/Unity/Application/mirsurfaceitem.cpp
+++ b/src/modules/Unity/Application/mirsurfaceitem.cpp
@@ -73,16 +73,16 @@ getMirModifiersFromQt(Qt::KeyboardModifiers mods)
mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerAction action)
{
- auto timestamp = qtEvent->timestamp() * 1000000;
+ auto timestamp = std::chrono::milliseconds(qtEvent->timestamp());
auto modifiers = getMirModifiersFromQt(qtEvent->modifiers());
- std::vector<MirPointerButton> buttons;
+ MirPointerButtons buttons = 0;
if (qtEvent->buttons() & Qt::LeftButton)
- buttons.push_back(mir_pointer_button_primary);
+ buttons |= mir_pointer_button_primary;
if (qtEvent->buttons() & Qt::RightButton)
- buttons.push_back(mir_pointer_button_secondary);
+ buttons |= mir_pointer_button_secondary;
if (qtEvent->buttons() & Qt::MidButton)
- buttons.push_back(mir_pointer_button_tertiary);
+ buttons |= mir_pointer_button_tertiary;
return mir::events::make_event(0 /*DeviceID */, timestamp, modifiers, action,
buttons, qtEvent->x(), qtEvent->y(), 0, 0);
@@ -90,9 +90,9 @@ mir::EventUPtr makeMirEvent(QMouseEvent *qtEvent, MirPointerAction action)
mir::EventUPtr makeMirEvent(QHoverEvent *qtEvent, MirPointerAction action)
{
- auto timestamp = qtEvent->timestamp() * 1000000;
+ auto timestamp = std::chrono::milliseconds(qtEvent->timestamp());
- std::vector<MirPointerButton> buttons;
+ MirPointerButtons buttons = 0;
return mir::events::make_event(0 /*DeviceID */, timestamp, mir_input_event_modifier_none, action,
buttons, qtEvent->posF().x(), qtEvent->posF().y(), 0, 0);
@@ -115,7 +115,7 @@ mir::EventUPtr makeMirEvent(QKeyEvent *qtEvent)
if (qtEvent->isAutoRepeat())
action = mir_keyboard_action_repeat;
- return mir::events::make_event(0 /* DeviceID */, qtEvent->timestamp() * 1000000,
+ return mir::events::make_event(0 /* DeviceID */, std::chrono::milliseconds(qtEvent->timestamp()),
action, qtEvent->nativeVirtualKey(),
qtEvent->nativeScanCode(),
qtEvent->nativeModifiers());
@@ -127,7 +127,7 @@ mir::EventUPtr makeMirEvent(Qt::KeyboardModifiers qmods,
ulong qtTimestamp)
{
auto modifiers = getMirModifiersFromQt(qmods);
- auto ev = mir::events::make_event(0, static_cast<int64_t>(qtTimestamp) * 1000000,
+ auto ev = mir::events::make_event(0, std::chrono::milliseconds(qtTimestamp),
modifiers);
for (int i = 0; i < qtTouchPoints.count(); ++i) {
@@ -388,17 +388,16 @@ bool MirSurfaceItem::updateTexture() // called by rendering thread (scene gra
bool textureUpdated = false;
const void* const userId = (void*)123;
- std::unique_ptr<mg::Renderable> renderable =
- m_surface->compositor_snapshot(userId);
+ auto renderables = m_surface->generate_renderables(userId);
- if (m_surface->buffers_ready_for_compositor(userId) > 0) {
+ if (m_surface->buffers_ready_for_compositor(userId) > 0 && renderables.size() > 0) {
if (!m_textureProvider->t) {
- m_textureProvider->t = new MirBufferSGTexture(renderable->buffer());
+ m_textureProvider->t = new MirBufferSGTexture(renderables[0]->buffer());
} else {
// Avoid holding two buffers for the compositor at the same time. Thus free the current
// before acquiring the next
m_textureProvider->t->freeBuffer();
- m_textureProvider->t->setBuffer(renderable->buffer());
+ m_textureProvider->t->setBuffer(renderables[0]->buffer());
}
textureUpdated = true;
}
@@ -746,7 +745,8 @@ void MirSurfaceItem::dropPendingBuffers()
// The line below looks like an innocent, effect-less, getter. But as this
// method returns a unique_pointer, not holding its reference causes the
// buffer to be destroyed/released straight away.
- m_surface->compositor_snapshot(userId)->buffer();
+ for (auto const & item : m_surface->generate_renderables(userId))
+ item->buffer();
qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::dropPendingBuffers()"
<< "surface =" << this
<< "buffer dropped."
diff --git a/src/platforms/mirserver/CMakeLists.txt b/src/platforms/mirserver/CMakeLists.txt
index 13c643a..7397ad1 100644
--- a/src/platforms/mirserver/CMakeLists.txt
+++ b/src/platforms/mirserver/CMakeLists.txt
@@ -46,6 +46,7 @@ set(MIRSERVER_QPA_PLUGIN_SRC
qteventfeeder.cpp
plugin.cpp
qmirserver.cpp
+ qmirserver_p.cpp
sessionauthorizer.cpp
sessionlistener.cpp
surfaceobserver.cpp
diff --git a/src/platforms/mirserver/display.cpp b/src/platforms/mirserver/display.cpp
index 70a6b15..7228f6e 100644
--- a/src/platforms/mirserver/display.cpp
+++ b/src/platforms/mirserver/display.cpp
@@ -23,18 +23,13 @@
#include <mir/graphics/display.h>
#include <mir/graphics/display_configuration.h>
-#include <QDebug>
namespace mg = mir::graphics;
// TODO: Listen for display changes and update the list accordingly
-Display::Display(const QSharedPointer<MirServer> &server, QObject *parent)
- : QObject(parent)
- , m_mirServer(server)
+Display::Display(const std::shared_ptr<mir::graphics::DisplayConfiguration> &displayConfig)
{
- std::shared_ptr<mir::graphics::DisplayConfiguration> displayConfig = m_mirServer->the_display()->configuration();
-
displayConfig->for_each_output([this](mg::DisplayConfigurationOutput const& output) {
if (output.used) {
auto screen = new Screen(output);
diff --git a/src/platforms/mirserver/display.h b/src/platforms/mirserver/display.h
index 21c7767..bc77381 100644
--- a/src/platforms/mirserver/display.h
+++ b/src/platforms/mirserver/display.h
@@ -19,23 +19,21 @@
#ifndef DISPLAY_H
#define DISPLAY_H
-#include <QObject>
#include <qpa/qplatformscreen.h>
+#include <memory>
-class MirServer;
+namespace mir { namespace graphics { class DisplayConfiguration; }}
-class Display : public QObject
+class Display
{
- Q_OBJECT
public:
- Display(const QSharedPointer<MirServer> &server, QObject *parent = 0);
- ~Display();
+ Display(const std::shared_ptr<mir::graphics::DisplayConfiguration> &displayConfig);
+ virtual ~Display();
QList<QPlatformScreen *> screens() const { return m_screens; }
private:
QList<QPlatformScreen *> m_screens;
- const QSharedPointer<MirServer> m_mirServer;
};
#endif // DISPLAY_H
diff --git a/src/platforms/mirserver/miropenglcontext.cpp b/src/platforms/mirserver/miropenglcontext.cpp
index cf5ef9d..cb84666 100644
--- a/src/platforms/mirserver/miropenglcontext.cpp
+++ b/src/platforms/mirserver/miropenglcontext.cpp
@@ -36,12 +36,11 @@
// (i.e. individual display output buffers) to use as a common base context.
MirOpenGLContext::MirOpenGLContext(const QSharedPointer<MirServer> &server, const QSurfaceFormat &format)
- : m_mirServer(server)
#if GL_DEBUG
- , m_logger(new QOpenGLDebugLogger(this))
+ : m_logger(new QOpenGLDebugLogger(this))
#endif
{
- std::shared_ptr<mir::graphics::Display> display = m_mirServer->the_display();
+ std::shared_ptr<mir::graphics::Display> display = server->the_display();
// create a temporary GL context to fetch the EGL display and config, so Qt can determine the surface format
std::unique_ptr<mir::graphics::GLContext> mirContext = display->create_gl_context();
diff --git a/src/platforms/mirserver/miropenglcontext.h b/src/platforms/mirserver/miropenglcontext.h
index e09a992..de3ec9c 100644
--- a/src/platforms/mirserver/miropenglcontext.h
+++ b/src/platforms/mirserver/miropenglcontext.h
@@ -52,7 +52,6 @@ public:
#endif
private:
- const QSharedPointer<MirServer> m_mirServer;
QSurfaceFormat m_format;
#if GL_DEBUG
QOpenGLDebugLogger *m_logger;
diff --git a/src/platforms/mirserver/mirserverintegration.cpp b/src/platforms/mirserver/mirserverintegration.cpp
index 2292831..ad33caa 100644
--- a/src/platforms/mirserver/mirserverintegration.cpp
+++ b/src/platforms/mirserver/mirserverintegration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Canonical, Ltd.
+ * 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
@@ -30,7 +30,6 @@
#include <qpa/qwindowsysteminterface.h>
#include <QCoreApplication>
-#include <QStringList>
#include <QOpenGLContext>
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
@@ -41,10 +40,7 @@
// Mir
#include <mir/graphics/display.h>
-#include <mir/graphics/display_buffer.h>
-
-// std
-#include <csignal>
+#include <mir/graphics/display_configuration.h>
// local
#include "clipboard.h"
@@ -66,36 +62,25 @@ MirServerIntegration::MirServerIntegration()
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
, m_eventDispatcher(createUnixEventDispatcher())
#endif
+ , m_mirServer(new QMirServer(QCoreApplication::arguments()))
, m_display(nullptr)
- , m_qmirServer(nullptr)
, m_nativeInterface(nullptr)
, m_clipboard(new Clipboard)
{
- // Start Mir server only once Qt has initialized its event dispatcher, see initialize()
-
- QStringList args = QCoreApplication::arguments();
- // convert arguments back into argc-argv form that Mir wants
- char **argv;
- argv = new char*[args.size() + 1];
- for (int i = 0; i < args.size(); i++) {
- argv[i] = new char[strlen(args.at(i).toStdString().c_str())+1];
- memcpy(argv[i], args.at(i).toStdString().c_str(), strlen(args.at(i).toStdString().c_str())+1);
- }
- argv[args.size()] = '\0';
-
// 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")) {
+ if (qgetenv("DESKTOP_SESSION").contains("mir") || !qEnvironmentVariableIsSet("ANDROID_DATA")) {
qputenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient");
} else {
qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient");
}
}
- m_mirServer = QSharedPointer<MirServer>(
- new MirServer(args.length(), const_cast<const char**>(argv)));
+ // If Mir shuts down, quit.
+ QObject::connect(m_mirServer.data(), &QMirServer::stopped,
+ QCoreApplication::instance(), &QCoreApplication::quit);
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
QGuiApplicationPrivate::instance()->setEventDispatcher(eventDispatcher_);
@@ -109,7 +94,6 @@ MirServerIntegration::~MirServerIntegration()
{
delete m_nativeInterface;
delete m_display;
- delete m_qmirServer;
}
bool MirServerIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -135,18 +119,21 @@ QPlatformWindow *MirServerIntegration::createPlatformWindow(QWindow *window) con
DisplayWindow* displayWindow = nullptr;
+ auto const mirServer = m_mirServer->mirServer().lock();
mg::DisplayBuffer* first_buffer{nullptr};
mg::DisplaySyncGroup* first_group{nullptr};
- m_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;
+ 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)
@@ -168,7 +155,7 @@ QPlatformBackingStore *MirServerIntegration::createPlatformBackingStore(QWindow
QPlatformOpenGLContext *MirServerIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
qDebug() << "createPlatformOpenGLContext" << context;
- return new MirOpenGLContext(m_mirServer, context->format());
+ return new MirOpenGLContext(m_mirServer->mirServer(), context->format());
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
@@ -181,10 +168,12 @@ QAbstractEventDispatcher *MirServerIntegration::createEventDispatcher() const
void MirServerIntegration::initialize()
{
// Creates instance of and start the Mir server in a separate thread
- m_qmirServer = new QMirServer(m_mirServer);
+ if (!m_mirServer->start()) {
+ exit(2);
+ }
- m_display = new Display(m_mirServer);
- m_nativeInterface = new NativeInterface(m_mirServer);
+ 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);
diff --git a/src/platforms/mirserver/mirserverintegration.h b/src/platforms/mirserver/mirserverintegration.h
index 37e0dc0..a02405e 100644
--- a/src/platforms/mirserver/mirserverintegration.h
+++ b/src/platforms/mirserver/mirserverintegration.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Canonical, Ltd.
+ * 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
@@ -69,8 +69,6 @@ public:
QPlatformNativeInterface *nativeInterface() const override;
private:
- QSharedPointer<MirServer> m_mirServer;
-
QScopedPointer<QPlatformAccessibility> m_accessibility;
QScopedPointer<QPlatformFontDatabase> m_fontDb;
QScopedPointer<QPlatformServices> m_services;
@@ -78,8 +76,9 @@ private:
QScopedPointer<QAbstractEventDispatcher> m_eventDispatcher;
#endif
+ QScopedPointer<QMirServer> m_mirServer;
+
Display *m_display;
- QMirServer *m_qmirServer;
NativeInterface *m_nativeInterface;
QPlatformInputContext* m_inputContext;
QScopedPointer<qtmir::Clipboard> m_clipboard;
diff --git a/src/platforms/mirserver/nativeinterface.cpp b/src/platforms/mirserver/nativeinterface.cpp
index b013345..6cc4c0d 100644
--- a/src/platforms/mirserver/nativeinterface.cpp
+++ b/src/platforms/mirserver/nativeinterface.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Canonical, Ltd.
+ * 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
@@ -18,7 +18,7 @@
#include "nativeinterface.h"
-NativeInterface::NativeInterface(const QSharedPointer<MirServer> &server)
+NativeInterface::NativeInterface(const QWeakPointer<MirServer> &server)
: m_mirServer(server)
{
}
@@ -27,14 +27,17 @@ void *NativeInterface::nativeResourceForIntegration(const QByteArray &resource)
{
void *result = nullptr;
- if (resource == "SessionAuthorizer")
- result = m_mirServer->sessionAuthorizer();
- else if (resource == "Shell")
- result = m_mirServer->shell();
- else if (resource == "SessionListener")
- result = m_mirServer->sessionListener();
- else if (resource == "PromptSessionListener")
- result = m_mirServer->promptSessionListener();
+ auto const server = m_mirServer.lock();
+ if (server) {
+ if (resource == "SessionAuthorizer")
+ result = server->sessionAuthorizer();
+ else if (resource == "Shell")
+ result = server->shell();
+ else if (resource == "SessionListener")
+ result = server->sessionListener();
+ else if (resource == "PromptSessionListener")
+ result = server->promptSessionListener();
+ }
return result;
}
diff --git a/src/platforms/mirserver/nativeinterface.h b/src/platforms/mirserver/nativeinterface.h
index 5a5c377..da97663 100644
--- a/src/platforms/mirserver/nativeinterface.h
+++ b/src/platforms/mirserver/nativeinterface.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Canonical, Ltd.
+ * 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
@@ -29,11 +29,11 @@
class NativeInterface : public QPlatformNativeInterface
{
public:
- NativeInterface(const QSharedPointer<MirServer> &);
+ NativeInterface(const QWeakPointer<MirServer> &);
virtual void *nativeResourceForIntegration(const QByteArray &resource);
- QSharedPointer<MirServer> m_mirServer;
+ QWeakPointer<MirServer> m_mirServer;
};
#endif // NATIVEINTEGRATION_H
diff --git a/src/platforms/mirserver/qmirserver.cpp b/src/platforms/mirserver/qmirserver.cpp
index f28393a..c7dc580 100644
--- a/src/platforms/mirserver/qmirserver.cpp
+++ b/src/platforms/mirserver/qmirserver.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Canonical, Ltd.
+ * 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
@@ -19,80 +19,77 @@
#include <QCoreApplication>
#include <QDebug>
-#include <mir/main_loop.h>
-
// local
+#include "mirserver.h"
#include "qmirserver.h"
+#include "qmirserver_p.h"
-void MirServerWorker::run()
+QMirServer::QMirServer(const QStringList &arguments, QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QMirServerPrivate())
{
- auto const main_loop = server->the_main_loop();
- // By enqueuing the notification code in the main loop, we are
- // ensuring that the server has really and fully started before
- // leaving wait_for_startup().
- main_loop->enqueue(
- this,
- [&]
- {
- std::lock_guard<std::mutex> lock(mutex);
- mir_running = true;
- started_cv.notify_one();
- });
-
- server->run();
- Q_EMIT stopped();
+ Q_D(QMirServer);
+
+ // convert arguments back into argc-argv form that Mir wants
+ int argc = arguments.size();
+ char **argv = new char*[argc + 1];
+ for (int i = 0; i < argc; i++) {
+ argv[i] = new char[strlen(arguments.at(i).toStdString().c_str())+1];
+ memcpy(argv[i], arguments.at(i).toStdString().c_str(), strlen(arguments.at(i).toStdString().c_str())+1);
+ }
+ argv[argc] = '\0';
+
+ d->server = QSharedPointer<MirServer>(new MirServer(argc, const_cast<const char**>(argv)));
+
+ d->serverThread = new MirServerThread(d->server);
+
+ connect(d->serverThread, &MirServerThread::stopped, this, &QMirServer::stopped);
}
-bool MirServerWorker::wait_for_mir_startup()
+QMirServer::~QMirServer()
{
- std::unique_lock<decltype(mutex)> lock(mutex);
- started_cv.wait_for(lock, std::chrono::seconds{10}, [&]{ return mir_running; });
- return mir_running;
+ stop();
}
-QMirServer::QMirServer(const QSharedPointer<MirServer> &server, QObject *parent)
- : QObject(parent)
- , m_mirServer(new MirServerWorker(server))
+bool QMirServer::start()
{
- m_mirServer->moveToThread(&m_mirThread);
+ Q_D(QMirServer);
- connect(this, &QMirServer::run, m_mirServer, &MirServerWorker::run);
- connect(this, &QMirServer::stop, m_mirServer, &MirServerWorker::stop);
+ d->serverThread->start(QThread::TimeCriticalPriority);
- connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QMirServer::shutDownMirServer);
- connect(m_mirServer, &MirServerWorker::stopped, this, &QMirServer::shutDownQApplication, Qt::DirectConnection); // since no event loop
-
- m_mirThread.start(QThread::TimeCriticalPriority);
- Q_EMIT run();
-
- if (!m_mirServer->wait_for_mir_startup())
+ if (!d->serverThread->waitForMirStartup())
{
qCritical() << "ERROR: QMirServer - Mir failed to start";
- exit(2);
+ return false;
}
-}
-QMirServer::~QMirServer()
-{
- shutDownMirServer();
+ Q_EMIT started();
+ return true;
}
-void QMirServer::shutDownMirServer()
+void QMirServer::stop()
{
- if (m_mirThread.isRunning()) {
- m_mirServer->stop();
- m_mirThread.wait();
+ Q_D(QMirServer);
+
+ if (d->serverThread->isRunning()) {
+ d->serverThread->stop();
+ if (!d->serverThread->wait(10000)) {
+ // do something to indicate fail during shutdown
+ qCritical() << "ERROR: QMirServer - Mir failed to shut down correctly, terminating it";
+ d->serverThread->terminate();
+ }
}
}
-void QMirServer::shutDownQApplication()
+bool QMirServer::isRunning() const
{
- if (m_mirThread.isRunning())
- m_mirThread.quit();
+ Q_D(const QMirServer);
+ return d->serverThread->isRunning();
+}
- // if unexpected mir server stop, better quit the QApplication
- if (!QCoreApplication::closingDown()) {
- QCoreApplication::quit();
- }
+QWeakPointer<MirServer> QMirServer::mirServer() const
+{
+ Q_D(const QMirServer);
+ return d->server.toWeakRef();
}
diff --git a/src/platforms/mirserver/qmirserver.h b/src/platforms/mirserver/qmirserver.h
index be74149..ecb943b 100644
--- a/src/platforms/mirserver/qmirserver.h
+++ b/src/platforms/mirserver/qmirserver.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Canonical, Ltd.
+ * 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
@@ -19,63 +19,35 @@
// Qt
#include <QObject>
-#include <QThread>
-#include <QSharedPointer>
+#include <QWeakPointer>
-// local
-#include "mirserver.h"
+class QMirServerPrivate;
+class MirServer;
-#include <condition_variable>
-#include <mutex>
-
-// Wrap mir::Server with QObject, so it can be controlled via QThread
-class MirServerWorker : public QObject
+class QMirServer: public QObject
{
Q_OBJECT
public:
- MirServerWorker(const QSharedPointer<MirServer> &server)
- : server(server)
- {}
-
- bool wait_for_mir_startup();
+ QMirServer(const QStringList &arguments, QObject* parent=0);
+ virtual ~QMirServer();
-Q_SIGNALS:
- void stopped();
+ bool start();
+ Q_SLOT void stop();
+ bool isRunning() const;
-public Q_SLOTS:
- void run();
- void stop() { server->stop(); }
-
-private:
- std::mutex mutex;
- std::condition_variable started_cv;
- bool mir_running{false};
-
- const QSharedPointer<MirServer> server;
-};
-
-
-class QMirServer: public QObject
-{
- Q_OBJECT
-
-public:
- QMirServer(const QSharedPointer<MirServer> &config, QObject* parent=0);
- ~QMirServer();
+ QWeakPointer<MirServer> mirServer() const;
Q_SIGNALS:
- void run();
- void stop();
+ void started();
+ void stopped();
-protected Q_SLOTS:
- void shutDownMirServer();
- void shutDownQApplication();
+protected:
+ QMirServerPrivate * const d_ptr;
private:
- QThread m_mirThread;
- MirServerWorker *m_mirServer;
Q_DISABLE_COPY(QMirServer)
+ Q_DECLARE_PRIVATE(QMirServer)
};
#endif // QMIRSERVER_H
diff --git a/src/platforms/mirserver/qmirserver_p.cpp b/src/platforms/mirserver/qmirserver_p.cpp
new file mode 100644
index 0000000..d784a46
--- /dev/null
+++ b/src/platforms/mirserver/qmirserver_p.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+// Mir
+#include <mir/main_loop.h>
+
+// local
+#include "qmirserver_p.h"
+
+
+void MirServerThread::run()
+{
+ auto const main_loop = server->the_main_loop();
+ // By enqueuing the notification code in the main loop, we are
+ // ensuring that the server has really and fully started before
+ // leaving wait_for_startup().
+ main_loop->enqueue(
+ this,
+ [&]
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ mir_running = true;
+ started_cv.notify_one();
+ });
+
+ server->run(); // blocks until Mir server stopped
+ Q_EMIT stopped();
+}
+
+void MirServerThread::stop()
+{
+ server->stop();
+}
+
+bool MirServerThread::waitForMirStartup()
+{
+ std::unique_lock<decltype(mutex)> lock(mutex);
+ started_cv.wait_for(lock, std::chrono::seconds{10}, [&]{ return mir_running; });
+ return mir_running;
+}
diff --git a/src/platforms/mirserver/qmirserver_p.h b/src/platforms/mirserver/qmirserver_p.h
new file mode 100644
index 0000000..6e86d8d
--- /dev/null
+++ b/src/platforms/mirserver/qmirserver_p.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QMIRSERVER_P_H
+#define QMIRSERVER_P_H
+
+// Qt
+#include <QThread>
+#include <QSharedPointer>
+
+// std
+#include <condition_variable>
+#include <mutex>
+
+// local
+#include "mirserver.h"
+
+class QMirServer;
+class MirServerThread;
+
+struct QMirServerPrivate
+{
+ QSharedPointer<MirServer> server;
+ MirServerThread *serverThread;
+};
+
+
+class MirServerThread : public QThread
+{
+ Q_OBJECT
+
+public:
+ MirServerThread(const QSharedPointer<MirServer> &server)
+ : server(server)
+ {}
+
+ bool waitForMirStartup();
+
+Q_SIGNALS:
+ void stopped();
+
+public Q_SLOTS:
+ void run() override;
+ void stop();
+
+private:
+ std::mutex mutex;
+ std::condition_variable started_cv;
+ bool mir_running{false};
+
+ const QSharedPointer<MirServer> server;
+};
+
+#endif // QMIRSERVER_P_H
diff --git a/src/platforms/mirserver/qteventfeeder.cpp b/src/platforms/mirserver/qteventfeeder.cpp
index 6c6dfa6..5490096 100644
--- a/src/platforms/mirserver/qteventfeeder.cpp
+++ b/src/platforms/mirserver/qteventfeeder.cpp
@@ -219,11 +219,11 @@ QtEventFeeder::~QtEventFeeder()
delete mQtWindowSystem;
}
-void QtEventFeeder::dispatch(MirEvent const& event)
+bool QtEventFeeder::dispatch(MirEvent const& event)
{
auto type = mir_event_get_type(&event);
if (type != mir_event_type_input)
- return;
+ return false;
auto iev = mir_event_get_input_event(&event);
switch (mir_input_event_get_type(iev)) {
@@ -238,6 +238,8 @@ void QtEventFeeder::dispatch(MirEvent const& event)
default:
break;
}
+
+ return true;
}
namespace
@@ -423,17 +425,6 @@ void QtEventFeeder::stop()
// not used
}
-void QtEventFeeder::configuration_changed(std::chrono::nanoseconds when)
-{
- Q_UNUSED(when);
-}
-
-void QtEventFeeder::device_reset(int32_t device_id, std::chrono::nanoseconds when)
-{
- Q_UNUSED(device_id);
- Q_UNUSED(when);
-}
-
void QtEventFeeder::validateTouches(ulong timestamp,
QList<QWindowSystemInterface::TouchPoint> &touchPoints)
{
diff --git a/src/platforms/mirserver/qteventfeeder.h b/src/platforms/mirserver/qteventfeeder.h
index 48113bf..d786715 100644
--- a/src/platforms/mirserver/qteventfeeder.h
+++ b/src/platforms/mirserver/qteventfeeder.h
@@ -61,9 +61,7 @@ public:
static const int MirEventActionPointerIndexMask;
static const int MirEventActionPointerIndexShift;
- void configuration_changed(std::chrono::nanoseconds when) override;
- void device_reset(int32_t device_id, std::chrono::nanoseconds when) override;
- void dispatch(MirEvent const& event) override;
+ bool dispatch(MirEvent const& event) override;
void start() override;
void stop() override;