diff options
Diffstat (limited to 'tests/auto/client/shared/coreprotocol.h')
-rw-r--r-- | tests/auto/client/shared/coreprotocol.h | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h new file mode 100644 index 000000000..2fbe9b139 --- /dev/null +++ b/tests/auto/client/shared/coreprotocol.h @@ -0,0 +1,313 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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$ +** +****************************************************************************/ + +#ifndef MOCKCOMPOSITOR_COREPROTOCOL_H +#define MOCKCOMPOSITOR_COREPROTOCOL_H + +#include "corecompositor.h" + +#include <qwayland-server-wayland.h> + +namespace MockCompositor { + +class WlCompositor; +class Output; +class Pointer; +class CursorRole; +class ShmPool; +class ShmBuffer; + +class Buffer : public QObject, public QtWaylandServer::wl_buffer +{ + Q_OBJECT +public: + explicit Buffer(wl_client *client, int id, int version) + : QtWaylandServer::wl_buffer(client, id, version) + { + } + virtual QSize size() const = 0; + bool m_destroyed = false; + +protected: + void buffer_destroy_resource(Resource *resource) override + { + Q_UNUSED(resource); + m_destroyed = true; + // The client side resource has been destroyed, but we keep this object because it may be + // be used as a reference by e.g. surface for the currently committed buffer so it's not + // yet safe to free it. + + //TODO: The memory should be freed by its factory + } + void buffer_destroy(Resource *resource) override { wl_resource_destroy(resource->handle); } +}; + +class Callback : public QObject, public QtWaylandServer::wl_callback +{ + Q_OBJECT +public: + explicit Callback(wl_client *client, int id, int version = 1) + : QtWaylandServer::wl_callback(client, id, version) + { + } + ~Callback() override { if (!m_destroyed) wl_resource_destroy(resource()->handle); } + void send_done(uint32_t data) = delete; // use state-tracking method below instead + void sendDone(uint data) { Q_ASSERT(!m_done); QtWaylandServer::wl_callback::send_done(data); m_done = true; } + void sendDoneAndDestroy(uint data) { sendDone(data); wl_resource_destroy(resource()->handle); } + bool m_done = false; + bool m_destroyed = false; +protected: + void callback_destroy_resource(Resource *resource) override { Q_UNUSED(resource); m_destroyed = true; } +}; + +class SurfaceRole : public QObject { + Q_OBJECT +}; + +class Surface : public QObject, public QtWaylandServer::wl_surface +{ + Q_OBJECT +public: + explicit Surface(WlCompositor *wlCompositor, wl_client *client, int id, int version) + : QtWaylandServer::wl_surface(client, id, version) + , m_wlCompositor(wlCompositor) + { + } + ~Surface() override { qDeleteAll(m_commits); } // TODO: maybe make sure buffers are released? + void sendFrameCallbacks(); + void sendEnter(Output *output); + void send_enter(::wl_resource *output) = delete; + void sendLeave(Output *output); + void send_leave(::wl_resource *output) = delete; + + WlCompositor *m_wlCompositor; + struct PerCommitData { + Callback *frame = nullptr; + QPoint attachOffset; + bool attached = false; + }; + struct DoubleBufferedState { + PerCommitData commitSpecific; + Buffer *buffer = nullptr; + uint configureSerial = 0; + int bufferScale = 1; + } m_pending, m_committed; + QVector<DoubleBufferedState *> m_commits; + QVector<Callback *> m_waitingFrameCallbacks; + QVector<Output *> m_outputs; + SurfaceRole *m_role = nullptr; + +signals: + void attach(void *buffer, QPoint offset); + void commit(); + void bufferCommitted(); + +protected: + void surface_destroy_resource(Resource *resource) override; + void surface_destroy(Resource *resource) override { wl_resource_destroy(resource->handle); } + void surface_attach(Resource *resource, wl_resource *buffer, int32_t x, int32_t y) override; + void surface_set_buffer_scale(Resource *resource, int32_t scale) override; + void surface_commit(Resource *resource) override; + void surface_frame(Resource *resource, uint32_t callback) override; +}; + +class WlCompositor : public Global, public QtWaylandServer::wl_compositor +{ + Q_OBJECT +public: + explicit WlCompositor(CoreCompositor *compositor, int version = 3) + : QtWaylandServer::wl_compositor(compositor->m_display, version) + , m_compositor(compositor) + {} + bool isClean() override; + QString dirtyMessage() override; + QVector<Surface *> m_surfaces; + CoreCompositor *m_compositor = nullptr; + +signals: + void surfaceCreated(Surface *surface); + +protected: + void compositor_create_surface(Resource *resource, uint32_t id) override + { + auto *surface = new Surface(this, resource->client(), id, resource->version()); + m_surfaces.append(surface); + emit surfaceCreated(surface); + } +}; + +class SubCompositor : public Global, public QtWaylandServer::wl_subcompositor +{ + Q_OBJECT +public: + explicit SubCompositor(CoreCompositor *compositor, int version = 1) + : QtWaylandServer::wl_subcompositor(compositor->m_display, version) + {} + // TODO +}; + +class Output : public Global, public QtWaylandServer::wl_output +{ + Q_OBJECT +public: + explicit Output(CoreCompositor *compositor, int scale = 1, int version = 2) + : QtWaylandServer::wl_output(compositor->m_display, version) + , m_scale(scale) + , m_version(version) + {} + void sendScale(int factor); + void send_scale(int32_t factor) = delete; + void send_scale(struct ::wl_resource *resource, int32_t factor) = delete; + void sendDone(); + int m_scale = 1; + int m_version = 1; // TODO: remove on libwayland upgrade + +protected: + void output_bind_resource(Resource *resource) override; +}; + +class Seat : public Global, public QtWaylandServer::wl_seat +{ + Q_OBJECT +public: + explicit Seat(CoreCompositor *compositor, uint capabilities, int version = 4); + ~Seat() override; + void send_capabilities(Resource *resource, uint capabilities) = delete; // Use wrapper instead + void send_capabilities(uint capabilities) = delete; // Use wrapper instead + void setCapabilities(uint capabilities); + + CoreCompositor *m_compositor = nullptr; + + Pointer* m_pointer = nullptr; + QVector<Pointer *> m_oldPointers; + + uint m_capabilities = 0; + +protected: + void seat_bind_resource(Resource *resource) override + { + wl_seat::send_capabilities(resource->handle, m_capabilities); + } + + void seat_get_pointer(Resource *resource, uint32_t id) override; +// void seat_get_keyboard(Resource *resource, uint32_t id) override; +// void seat_get_touch(Resource *resource, uint32_t id) override; + +// void seat_release(Resource *resource) override; +}; + +class Pointer : public QObject, public QtWaylandServer::wl_pointer +{ + Q_OBJECT +public: + explicit Pointer(Seat *seat) : m_seat(seat) {} + Surface *cursorSurface(); + CursorRole* m_cursorRole = nullptr; //TODO: cleanup + uint sendEnter(Surface *surface, const QPointF &position); + void sendMotion(wl_client *client, const QPointF &position); + uint sendButton(wl_client *client, uint button, uint state); + void sendAxis(wl_client *client, axis axis, qreal value); + + Seat *m_seat = nullptr; + uint m_enterSerial = 0; + +signals: + void setCursor(uint serial); //TODO: add arguments? + +protected: + void pointer_set_cursor(Resource *resource, uint32_t serial, ::wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) override; + //TODO +}; + +class CursorRole : public SurfaceRole { + Q_OBJECT +public: + explicit CursorRole(Surface *surface) // TODO: needs some more args + : m_surface(surface) + { + } + static CursorRole *fromSurface(Surface *surface) { return qobject_cast<CursorRole *>(surface->m_role); } + Surface *m_surface = nullptr; +}; + +class Shm : public Global, public QtWaylandServer::wl_shm +{ + Q_OBJECT +public: + explicit Shm(CoreCompositor *compositor, QVector<format> formats = {format_argb8888, format_xrgb8888, format_rgb888}, int version = 1); + bool isClean() override; + CoreCompositor *m_compositor = nullptr; + QVector<ShmPool *> m_pools; + const QVector<format> m_formats; + +protected: + void shm_create_pool(Resource *resource, uint32_t id, int32_t fd, int32_t size) override; + void shm_bind_resource(Resource *resource) override + { + for (auto format : qAsConst(m_formats)) + send_format(resource->handle, format); + } +}; + +class ShmPool : QObject, public QtWaylandServer::wl_shm_pool +{ + Q_OBJECT +public: + explicit ShmPool(Shm *shm, wl_client *client, int id, int version = 1); + Shm *m_shm = nullptr; + QVector<ShmBuffer *> m_buffers; + +protected: + void shm_pool_create_buffer(Resource *resource, uint32_t id, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format) override; + void shm_pool_destroy_resource(Resource *resource) override; + void shm_pool_destroy(Resource *resource) override { wl_resource_destroy(resource->handle); } +}; + +class ShmBuffer : public Buffer +{ + Q_OBJECT +public: + static ShmBuffer *fromBuffer(Buffer *buffer) { return qobject_cast<ShmBuffer *>(buffer); } + explicit ShmBuffer(int offset, const QSize &size, int stride, Shm::format format, wl_client *client, int id, int version = 1) + : Buffer(client, id, version) + , m_offset(offset) + , m_size(size) + , m_stride(stride) + , m_format(format) + { + } + QSize size() const override { return m_size; } + const int m_offset; + const QSize m_size; + const int m_stride; + const Shm::format m_format; +}; + +} // namespace MockCompositor + +#endif // MOCKCOMPOSITOR_COREPROTOCOL_H |