summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmintegration.cpp
diff options
context:
space:
mode:
authorLorn Potter <[email protected]>2018-06-30 08:48:52 +1000
committerLorn Potter <[email protected]>2018-07-16 08:18:17 +0000
commit51a614a419e9745d275793e36b6aab295bf1e8e3 (patch)
tree7ad6238bf1801d39bfb67d7d6823543d04d48dea /src/plugins/platforms/wasm/qwasmintegration.cpp
parent95e9cbb3eef695aa7b1192678c75d4be166b93a0 (diff)
wasm: rename platform, refactor files and other things
Task-number: QTBUG-69168 Change-Id: I78a3ad5e16fbb1046eedf2056583c022f7a27d5b Reviewed-by: Eskil Abrahamsen Blomfeldt <[email protected]>
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmintegration.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
new file mode 100644
index 00000000000..196b2c65754
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmintegration.h"
+#include "qwasmeventtranslator.h"
+#include "qwasmeventdispatcher.h"
+#include "qwasmcompositor.h"
+#include "qwasmopenglcontext.h"
+#include "qwasmtheme.h"
+
+#include "qwasmwindow.h"
+#ifndef QT_NO_OPENGL
+# include "qwasmbackingstore.h"
+#endif
+#include "qwasmfontdatabase.h"
+#if defined(Q_OS_UNIX)
+#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
+#endif
+#include <qpa/qplatformwindow.h>
+#include <QtGui/QScreen>
+#include <qpa/qwindowsysteminterface.h>
+#include <QCoreApplication>
+
+#include <emscripten/bind.h>
+
+// this is where EGL headers are pulled in, make sure it is last
+#include "qwasmscreen.h"
+
+using namespace emscripten;
+QT_BEGIN_NAMESPACE
+
+void browserBeforeUnload() {
+ QWasmIntegration::QWasmBrowserExit();
+}
+
+EMSCRIPTEN_BINDINGS(my_module) {
+ function("browserBeforeUnload", &browserBeforeUnload);
+}
+
+static QWasmIntegration *globalHtml5Integration;
+QWasmIntegration *QWasmIntegration::get() { return globalHtml5Integration; }
+
+void emscriptenOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ int emOutputFlags = (EM_LOG_CONSOLE | EM_LOG_DEMANGLE);
+ QByteArray localMsg = msg.toLocal8Bit();
+
+ switch (type) {
+ case QtDebugMsg:
+ emscripten_log(emOutputFlags, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
+ break;
+ case QtInfoMsg:
+ emscripten_log(emOutputFlags, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
+ break;
+ case QtWarningMsg:
+ emOutputFlags |= EM_LOG_WARN;
+ emscripten_log(emOutputFlags, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
+ break;
+ case QtCriticalMsg:
+ emOutputFlags |= EM_LOG_ERROR;
+ emscripten_log(emOutputFlags, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
+ break;
+ case QtFatalMsg:
+ emOutputFlags |= EM_LOG_ERROR;
+ emscripten_log(emOutputFlags, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
+ abort();
+ }
+}
+
+QWasmIntegration::QWasmIntegration()
+ : mFontDb(nullptr),
+ mCompositor(new QWasmCompositor),
+ mScreen(new QWasmScreen(mCompositor)),
+ m_eventDispatcher(nullptr)
+{
+ qSetMessagePattern(QString("(%{function}:%{line}) - %{message}"));
+ qInstallMessageHandler(emscriptenOutput);
+
+ globalHtml5Integration = this;
+
+ updateQScreenAndCanvasRenderSize();
+ screenAdded(mScreen);
+ emscripten_set_resize_callback(0, (void *)this, 1, uiEvent_cb);
+
+ m_eventTranslator = new QWasmEventTranslator();
+
+ EM_ASM(// exit app if browser closes
+ window.onbeforeunload = function () {
+ Module.browserBeforeUnload();
+ };
+ );
+}
+
+QWasmIntegration::~QWasmIntegration()
+{
+ delete mCompositor;
+ destroyScreen(mScreen);
+ delete mFontDb;
+ delete m_eventTranslator;
+}
+
+void QWasmIntegration::QWasmBrowserExit()
+{
+ QCoreApplication *app = QCoreApplication::instance();
+ app->quit();
+}
+
+bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ case RasterGLSurface: return true;
+ case MultipleWindows: return true;
+ case WindowManagement: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformWindow *QWasmIntegration::createPlatformWindow(QWindow *window) const
+{
+ QWasmWindow *w = new QWasmWindow(window, mCompositor, m_backingStores.value(window));
+ w->create();
+
+ return w;
+}
+
+QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *window) const
+{
+#ifndef QT_NO_OPENGL
+ QWasmBackingStore *backingStore = new QWasmBackingStore(mCompositor, window);
+ m_backingStores.insert(window, backingStore);
+ return backingStore;
+#else
+ return nullptr;
+#endif
+}
+
+#ifndef QT_NO_OPENGL
+QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ return new QWasmOpenGLContext(context->format());
+}
+#endif
+
+QPlatformFontDatabase *QWasmIntegration::fontDatabase() const
+{
+ if (mFontDb == 0)
+ mFontDb = new QWasmFontDatabase();
+
+ return mFontDb;
+}
+
+QAbstractEventDispatcher *QWasmIntegration::createEventDispatcher() const
+{
+ return new QWasmEventDispatcher();
+}
+
+QVariant QWasmIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
+{
+ return QPlatformIntegration::styleHint(hint);
+}
+
+QStringList QWasmIntegration::themeNames() const
+{
+ return QStringList() << QLatin1String("webassembly");
+}
+
+QPlatformTheme *QWasmIntegration::createPlatformTheme(const QString &name) const
+{
+ if (name == QLatin1String("webassembly"))
+ return new QWasmTheme();
+ return QPlatformIntegration::createPlatformTheme(name);
+}
+
+int QWasmIntegration::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
+{
+ Q_UNUSED(e)
+ Q_UNUSED(userData)
+
+ if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
+ // This resize event is called when the HTML window is resized. Depending
+ // on the page layout the the canvas might also have been resized, so we
+ // update the Qt screen size (and canvas render size).
+ updateQScreenAndCanvasRenderSize();
+ }
+
+ return 0;
+}
+
+static void set_canvas_size(double width, double height)
+{
+ EM_ASM_({
+ var canvas = Module.canvas;
+ canvas.width = $0;
+ canvas.height = $1;
+ }, width, height);
+}
+
+void QWasmIntegration::updateQScreenAndCanvasRenderSize()
+{
+ // The HTML canvas has two sizes: the CSS size and the canvas render size.
+ // The CSS size is determined according to standard CSS rules, while the
+ // render size is set using the "width" and "height" attributes. The render
+ // size must be set manually and is not auto-updated on CSS size change.
+ // Setting the render size to a value larger than the CSS size enables high-dpi
+ // rendering.
+
+ double css_width;
+ double css_height;
+ emscripten_get_element_css_size(0, &css_width, &css_height);
+ QSizeF cssSize(css_width, css_height);
+
+ QWasmScreen *screen = QWasmIntegration::get()->mScreen;
+ QSizeF canvasSize = cssSize * screen->devicePixelRatio();
+
+ set_canvas_size(canvasSize.width(), canvasSize.height());
+ screen->setGeometry(QRect(QPoint(0, 0), cssSize.toSize()));
+ QWasmIntegration::get()->mCompositor->redrawWindowContent();
+}
+
+QT_END_NAMESPACE