From 2cc758045e322873ad58f675a70c8d8366b5c318 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 5 Aug 2016 11:53:43 +0200 Subject: Fix autotest directory structure The client and server parts are separate modules, so they need separate top-level directories under tests/auto. This also makes it easier to add new tests later. Change-Id: I393341b6f4e8fc3afa480653f3482192e002e425 Reviewed-by: Giulio Camuffo --- tests/auto/client/client.pro | 26 +- tests/auto/client/client/client.pro | 28 ++ tests/auto/client/client/mockcompositor.cpp | 377 +++++++++++++++++ tests/auto/client/client/mockcompositor.h | 208 +++++++++ tests/auto/client/client/mockinput.cpp | 467 +++++++++++++++++++++ tests/auto/client/client/mockinput.h | 175 ++++++++ tests/auto/client/client/mockoutput.cpp | 74 ++++ tests/auto/client/client/mockshell.cpp | 184 ++++++++ tests/auto/client/client/mocksurface.cpp | 143 +++++++ tests/auto/client/client/mocksurface.h | 76 ++++ tests/auto/client/client/tst_client.cpp | 360 ++++++++++++++++ tests/auto/client/mockcompositor.cpp | 377 ----------------- tests/auto/client/mockcompositor.h | 208 --------- tests/auto/client/mockinput.cpp | 467 --------------------- tests/auto/client/mockinput.h | 175 -------- tests/auto/client/mockoutput.cpp | 74 ---- tests/auto/client/mockshell.cpp | 184 -------- tests/auto/client/mocksurface.cpp | 143 ------- tests/auto/client/mocksurface.h | 76 ---- tests/auto/client/tst_client.cpp | 360 ---------------- tests/auto/compositor/BLACKLIST | 2 - tests/auto/compositor/compositor.pro | 35 +- tests/auto/compositor/compositor/BLACKLIST | 2 + tests/auto/compositor/compositor/compositor.pro | 36 ++ tests/auto/compositor/compositor/mockclient.cpp | 207 +++++++++ tests/auto/compositor/compositor/mockclient.h | 110 +++++ tests/auto/compositor/compositor/mockseat.cpp | 48 +++ tests/auto/compositor/compositor/mockseat.h | 50 +++ .../auto/compositor/compositor/testcompositor.cpp | 52 +++ tests/auto/compositor/compositor/testcompositor.h | 47 +++ .../auto/compositor/compositor/testinputdevice.cpp | 62 +++ tests/auto/compositor/compositor/testinputdevice.h | 59 +++ .../compositor/compositor/testkeyboardgrabber.cpp | 65 +++ .../compositor/compositor/testkeyboardgrabber.h | 57 +++ .../auto/compositor/compositor/tst_compositor.cpp | 395 +++++++++++++++++ tests/auto/compositor/mockclient.cpp | 207 --------- tests/auto/compositor/mockclient.h | 110 ----- tests/auto/compositor/mockseat.cpp | 48 --- tests/auto/compositor/mockseat.h | 50 --- tests/auto/compositor/testcompositor.cpp | 52 --- tests/auto/compositor/testcompositor.h | 47 --- tests/auto/compositor/testinputdevice.cpp | 62 --- tests/auto/compositor/testinputdevice.h | 59 --- tests/auto/compositor/testkeyboardgrabber.cpp | 65 --- tests/auto/compositor/testkeyboardgrabber.h | 57 --- tests/auto/compositor/tst_compositor.cpp | 395 ----------------- tests/global/.gitignore | 1 + 47 files changed, 3287 insertions(+), 3275 deletions(-) create mode 100644 tests/auto/client/client/client.pro create mode 100644 tests/auto/client/client/mockcompositor.cpp create mode 100644 tests/auto/client/client/mockcompositor.h create mode 100644 tests/auto/client/client/mockinput.cpp create mode 100644 tests/auto/client/client/mockinput.h create mode 100644 tests/auto/client/client/mockoutput.cpp create mode 100644 tests/auto/client/client/mockshell.cpp create mode 100644 tests/auto/client/client/mocksurface.cpp create mode 100644 tests/auto/client/client/mocksurface.h create mode 100644 tests/auto/client/client/tst_client.cpp delete mode 100644 tests/auto/client/mockcompositor.cpp delete mode 100644 tests/auto/client/mockcompositor.h delete mode 100644 tests/auto/client/mockinput.cpp delete mode 100644 tests/auto/client/mockinput.h delete mode 100644 tests/auto/client/mockoutput.cpp delete mode 100644 tests/auto/client/mockshell.cpp delete mode 100644 tests/auto/client/mocksurface.cpp delete mode 100644 tests/auto/client/mocksurface.h delete mode 100644 tests/auto/client/tst_client.cpp delete mode 100644 tests/auto/compositor/BLACKLIST create mode 100644 tests/auto/compositor/compositor/BLACKLIST create mode 100644 tests/auto/compositor/compositor/compositor.pro create mode 100644 tests/auto/compositor/compositor/mockclient.cpp create mode 100644 tests/auto/compositor/compositor/mockclient.h create mode 100644 tests/auto/compositor/compositor/mockseat.cpp create mode 100644 tests/auto/compositor/compositor/mockseat.h create mode 100644 tests/auto/compositor/compositor/testcompositor.cpp create mode 100644 tests/auto/compositor/compositor/testcompositor.h create mode 100644 tests/auto/compositor/compositor/testinputdevice.cpp create mode 100644 tests/auto/compositor/compositor/testinputdevice.h create mode 100644 tests/auto/compositor/compositor/testkeyboardgrabber.cpp create mode 100644 tests/auto/compositor/compositor/testkeyboardgrabber.h create mode 100644 tests/auto/compositor/compositor/tst_compositor.cpp delete mode 100644 tests/auto/compositor/mockclient.cpp delete mode 100644 tests/auto/compositor/mockclient.h delete mode 100644 tests/auto/compositor/mockseat.cpp delete mode 100644 tests/auto/compositor/mockseat.h delete mode 100644 tests/auto/compositor/testcompositor.cpp delete mode 100644 tests/auto/compositor/testcompositor.h delete mode 100644 tests/auto/compositor/testinputdevice.cpp delete mode 100644 tests/auto/compositor/testinputdevice.h delete mode 100644 tests/auto/compositor/testkeyboardgrabber.cpp delete mode 100644 tests/auto/compositor/testkeyboardgrabber.h delete mode 100644 tests/auto/compositor/tst_compositor.cpp create mode 100644 tests/global/.gitignore diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro index eaf6c6e95..916b3abe4 100644 --- a/tests/auto/client/client.pro +++ b/tests/auto/client/client.pro @@ -1,25 +1,3 @@ -CONFIG += testcase link_pkgconfig -TARGET = tst_client +TEMPLATE=subdirs -QT += testlib -QT += core-private gui-private - -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += wayland-client wayland-server -} else { - LIBS += -lwayland-client -lwayland-server -} - -CONFIG += wayland-scanner -WAYLANDSERVERSOURCES += \ - ../../../src/3rdparty/protocol/wayland.xml - -SOURCES += tst_client.cpp \ - mockcompositor.cpp \ - mockinput.cpp \ - mockshell.cpp \ - mocksurface.cpp \ - mockoutput.cpp -HEADERS += mockcompositor.h \ - mockinput.h \ - mocksurface.h \ +SUBDIRS += client diff --git a/tests/auto/client/client/client.pro b/tests/auto/client/client/client.pro new file mode 100644 index 000000000..006d130a0 --- /dev/null +++ b/tests/auto/client/client/client.pro @@ -0,0 +1,28 @@ +CONFIG += testcase link_pkgconfig +TARGET = tst_client + +QT += testlib +QT += core-private gui-private + +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += wayland-client wayland-server +} else { + LIBS += -lwayland-client -lwayland-server +} + +CONFIG += wayland-scanner +WAYLANDSERVERSOURCES += \ + ../../../../src/3rdparty/protocol/wayland.xml + +SOURCES += \ + tst_client.cpp \ + mockcompositor.cpp \ + mockinput.cpp \ + mockshell.cpp \ + mocksurface.cpp \ + mockoutput.cpp + +HEADERS += \ + mockcompositor.h \ + mockinput.h \ + mocksurface.h diff --git a/tests/auto/client/client/mockcompositor.cpp b/tests/auto/client/client/mockcompositor.cpp new file mode 100644 index 000000000..83dd52ba2 --- /dev/null +++ b/tests/auto/client/client/mockcompositor.cpp @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" +#include "mockinput.h" +#include "mocksurface.h" + +#include +MockCompositor::MockCompositor() + : m_alive(true) + , m_ready(false) + , m_compositor(0) +{ + pthread_create(&m_thread, 0, run, this); + + m_mutex.lock(); + m_waitCondition.wait(&m_mutex); + m_mutex.unlock(); +} + +MockCompositor::~MockCompositor() +{ + m_alive = false; + m_waitCondition.wakeOne(); + pthread_join(m_thread, 0); +} + +void MockCompositor::lock() +{ + m_mutex.lock(); +} + +void MockCompositor::unlock() +{ + m_mutex.unlock(); +} + +void MockCompositor::applicationInitialized() +{ + m_ready = true; +} + +int MockCompositor::waylandFileDescriptor() const +{ + return m_compositor->fileDescriptor(); +} + +void MockCompositor::processWaylandEvents() +{ + m_waitCondition.wakeOne(); +} + +void MockCompositor::setOutputGeometry(const QRect &rect) +{ + Command command = makeCommand(Impl::Compositor::setOutputGeometry, m_compositor); + command.parameters << rect; + processCommand(command); +} + +void MockCompositor::setKeyboardFocus(const QSharedPointer &surface) +{ + Command command = makeCommand(Impl::Compositor::setKeyboardFocus, m_compositor); + command.parameters << QVariant::fromValue(surface); + processCommand(command); +} + +void MockCompositor::sendMousePress(const QSharedPointer &surface, const QPoint &pos) +{ + Command command = makeCommand(Impl::Compositor::sendMousePress, m_compositor); + command.parameters << QVariant::fromValue(surface) << pos; + processCommand(command); +} + +void MockCompositor::sendMouseRelease(const QSharedPointer &surface) +{ + Command command = makeCommand(Impl::Compositor::sendMouseRelease, m_compositor); + command.parameters << QVariant::fromValue(surface); + processCommand(command); +} + +void MockCompositor::sendKeyPress(const QSharedPointer &surface, uint code) +{ + Command command = makeCommand(Impl::Compositor::sendKeyPress, m_compositor); + command.parameters << QVariant::fromValue(surface) << code; + processCommand(command); +} + +void MockCompositor::sendKeyRelease(const QSharedPointer &surface, uint code) +{ + Command command = makeCommand(Impl::Compositor::sendKeyRelease, m_compositor); + command.parameters << QVariant::fromValue(surface) << code; + processCommand(command); +} + +void MockCompositor::sendTouchDown(const QSharedPointer &surface, const QPoint &position, int id) +{ + Command command = makeCommand(Impl::Compositor::sendTouchDown, m_compositor); + command.parameters << QVariant::fromValue(surface) << position << id; + processCommand(command); +} + +void MockCompositor::sendTouchMotion(const QSharedPointer &surface, const QPoint &position, int id) +{ + Command command = makeCommand(Impl::Compositor::sendTouchMotion, m_compositor); + command.parameters << QVariant::fromValue(surface) << position << id; + processCommand(command); +} + +void MockCompositor::sendTouchUp(const QSharedPointer &surface, int id) +{ + Command command = makeCommand(Impl::Compositor::sendTouchUp, m_compositor); + command.parameters << QVariant::fromValue(surface) << id; + processCommand(command); +} + +void MockCompositor::sendTouchFrame(const QSharedPointer &surface) +{ + Command command = makeCommand(Impl::Compositor::sendTouchFrame, m_compositor); + command.parameters << QVariant::fromValue(surface); + processCommand(command); +} + +void MockCompositor::sendDataDeviceDataOffer(const QSharedPointer &surface) +{ + Command command = makeCommand(Impl::Compositor::sendDataDeviceDataOffer, m_compositor); + command.parameters << QVariant::fromValue(surface); + processCommand(command); +} + +void MockCompositor::sendDataDeviceEnter(const QSharedPointer &surface, const QPoint& position) +{ + Command command = makeCommand(Impl::Compositor::sendDataDeviceEnter, m_compositor); + command.parameters << QVariant::fromValue(surface) << QVariant::fromValue(position); + processCommand(command); +} + +void MockCompositor::sendDataDeviceMotion(const QPoint &position) +{ + Command command = makeCommand(Impl::Compositor::sendDataDeviceMotion, m_compositor); + command.parameters << QVariant::fromValue(position); + processCommand(command); +} + +void MockCompositor::sendDataDeviceDrop(const QSharedPointer &surface) +{ + Command command = makeCommand(Impl::Compositor::sendDataDeviceDrop, m_compositor); + command.parameters << QVariant::fromValue(surface); + processCommand(command); +} + +void MockCompositor::sendDataDeviceLeave(const QSharedPointer &surface) +{ + Command command = makeCommand(Impl::Compositor::sendDataDeviceLeave, m_compositor); + command.parameters << QVariant::fromValue(surface); + processCommand(command); +} + +void MockCompositor::waitForStartDrag() +{ + Command command = makeCommand(Impl::Compositor::waitForStartDrag, m_compositor); + processCommand(command); +} + +QSharedPointer MockCompositor::surface() +{ + QSharedPointer result; + lock(); + QVector surfaces = m_compositor->surfaces(); + foreach (Impl::Surface *surface, surfaces) { + // we don't want to mistake the cursor surface for a window surface + if (surface->isMapped()) { + result = surface->mockSurface(); + break; + } + } + unlock(); + return result; +} + +MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target) +{ + Command command; + command.callback = callback; + command.target = target; + return command; +} + +void MockCompositor::processCommand(const Command &command) +{ + lock(); + m_commandQueue << command; + unlock(); + + m_waitCondition.wakeOne(); +} + +void MockCompositor::dispatchCommands() +{ + lock(); + int count = m_commandQueue.length(); + unlock(); + + for (int i = 0; i < count; ++i) { + lock(); + const Command command = m_commandQueue.takeFirst(); + unlock(); + command.callback(command.target, command.parameters); + } +} + +void *MockCompositor::run(void *data) +{ + MockCompositor *controller = static_cast(data); + + Impl::Compositor compositor; + + controller->m_compositor = &compositor; + controller->m_waitCondition.wakeOne(); + + while (!controller->m_ready) { + controller->dispatchCommands(); + compositor.dispatchEvents(20); + } + + while (controller->m_alive) { + { + QMutexLocker locker(&controller->m_mutex); + if (controller->m_commandQueue.isEmpty()) + controller->m_waitCondition.wait(&controller->m_mutex); + } + controller->dispatchCommands(); + compositor.dispatchEvents(20); + } + + return 0; +} + +namespace Impl { + +Compositor::Compositor() + : m_display(wl_display_create()) + , m_startDragSeen(false) + , m_time(0) +{ + wl_list_init(&m_outputResources); + + if (wl_display_add_socket(m_display, 0)) { + fprintf(stderr, "Fatal: Failed to open server socket\n"); + exit(EXIT_FAILURE); + } + + wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor); + + m_data_device_manager.reset(new DataDeviceManager(this, m_display)); + + wl_display_init_shm(m_display); + + m_seat.reset(new Seat(this, m_display)); + m_pointer = m_seat->pointer(); + m_keyboard = m_seat->keyboard(); + m_touch = m_seat->touch(); + + wl_display_add_global(m_display, &wl_output_interface, this, bindOutput); + wl_display_add_global(m_display, &wl_shell_interface, this, bindShell); + + m_loop = wl_display_get_event_loop(m_display); + m_fd = wl_event_loop_get_fd(m_loop); +} + +Compositor::~Compositor() +{ + wl_display_destroy(m_display); +} + +void Compositor::dispatchEvents(int timeout) +{ + wl_display_flush_clients(m_display); + wl_event_loop_dispatch(m_loop, timeout); +} + +static void compositor_create_surface(wl_client *client, wl_resource *compositorResource, uint32_t id) +{ + Compositor *compositor = static_cast(compositorResource->data); + compositor->addSurface(new Surface(client, id, wl_resource_get_version(compositorResource), compositor)); +} + +static void compositor_create_region(wl_client *client, wl_resource *compositorResource, uint32_t id) +{ + Q_UNUSED(client); + Q_UNUSED(compositorResource); + Q_UNUSED(id); +} + +void Compositor::bindCompositor(wl_client *client, void *compositorData, uint32_t version, uint32_t id) +{ + static const struct wl_compositor_interface compositorInterface = { + compositor_create_surface, + compositor_create_region + }; + + Q_UNUSED(version); + wl_client_add_object(client, &wl_compositor_interface, &compositorInterface, id, compositorData); +} + +static void unregisterResourceCallback(wl_listener *listener, void *data) +{ + struct wl_resource *resource = reinterpret_cast(data); + wl_list_remove(&resource->link); + delete listener; +} + +void registerResource(wl_list *list, wl_resource *resource) +{ + wl_list_insert(list, &resource->link); + + wl_listener *listener = new wl_listener; + listener->notify = unregisterResourceCallback; + + wl_signal_add(&resource->destroy_signal, listener); +} + +QVector Compositor::surfaces() const +{ + return m_surfaces; +} + +uint32_t Compositor::nextSerial() +{ + return wl_display_next_serial(m_display); +} + +void Compositor::addSurface(Surface *surface) +{ + m_surfaces << surface; +} + +void Compositor::removeSurface(Surface *surface) +{ + m_surfaces.removeOne(surface); + if (m_keyboard->focus() == surface) + m_keyboard->setFocus(0); + if (m_pointer->focus() == surface) + m_pointer->setFocus(0, QPoint()); +} + +} + diff --git a/tests/auto/client/client/mockcompositor.h b/tests/auto/client/client/mockcompositor.h new file mode 100644 index 000000000..2f0df4a0f --- /dev/null +++ b/tests/auto/client/client/mockcompositor.h @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOCKCOMPOSITOR_H +#define MOCKCOMPOSITOR_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Impl { + +typedef void (**Implementation)(void); + +class Keyboard; +class Pointer; +class Touch; +class Seat; +class DataDeviceManager; +class Surface; + +class Compositor +{ +public: + Compositor(); + ~Compositor(); + + int fileDescriptor() const { return m_fd; } + void dispatchEvents(int timeout = 0); + + uint32_t nextSerial(); + uint32_t time() { return ++m_time; } + + static void setOutputGeometry(void *compositor, const QList ¶meters); + + QVector surfaces() const; + + void addSurface(Surface *surface); + void removeSurface(Surface *surface); + + static void setKeyboardFocus(void *data, const QList ¶meters); + static void sendMousePress(void *data, const QList ¶meters); + static void sendMouseRelease(void *data, const QList ¶meters); + static void sendKeyPress(void *data, const QList ¶meters); + static void sendKeyRelease(void *data, const QList ¶meters); + static void sendTouchDown(void *data, const QList ¶meters); + static void sendTouchUp(void *data, const QList ¶meters); + static void sendTouchMotion(void *data, const QList ¶meters); + static void sendTouchFrame(void *data, const QList ¶meters); + static void sendDataDeviceDataOffer(void *data, const QList ¶meters); + static void sendDataDeviceEnter(void *data, const QList ¶meters); + static void sendDataDeviceMotion(void *data, const QList ¶meters); + static void sendDataDeviceDrop(void *data, const QList ¶meters); + static void sendDataDeviceLeave(void *data, const QList ¶meters); + static void waitForStartDrag(void *data, const QList ¶meters); + +public: + bool m_startDragSeen; + +private: + static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id); + static void bindOutput(wl_client *client, void *data, uint32_t version, uint32_t id); + static void bindShell(wl_client *client, void *data, uint32_t version, uint32_t id); + + void initShm(); + + void sendOutputGeometry(wl_resource *resource); + void sendOutputMode(wl_resource *resource); + + QRect m_outputGeometry; + + wl_display *m_display; + wl_event_loop *m_loop; + wl_shm *m_shm; + int m_fd; + + wl_list m_outputResources; + uint32_t m_time; + + QScopedPointer m_seat; + Pointer *m_pointer; + Keyboard *m_keyboard; + Touch *m_touch; + QScopedPointer m_data_device_manager; + QVector m_surfaces; +}; + +void registerResource(wl_list *list, wl_resource *resource); + +} + +class MockSurface +{ +public: + Impl::Surface *handle() const { return m_surface; } + + QImage image; + +private: + MockSurface(Impl::Surface *surface); + friend class Impl::Compositor; + friend class Impl::Surface; + + Impl::Surface *m_surface; +}; + +Q_DECLARE_METATYPE(QSharedPointer) + +class MockCompositor +{ +public: + MockCompositor(); + ~MockCompositor(); + + void applicationInitialized(); + + int waylandFileDescriptor() const; + void processWaylandEvents(); + + void setOutputGeometry(const QRect &rect); + void setKeyboardFocus(const QSharedPointer &surface); + void sendMousePress(const QSharedPointer &surface, const QPoint &pos); + void sendMouseRelease(const QSharedPointer &surface); + void sendKeyPress(const QSharedPointer &surface, uint code); + void sendKeyRelease(const QSharedPointer &surface, uint code); + void sendTouchDown(const QSharedPointer &surface, const QPoint &position, int id); + void sendTouchMotion(const QSharedPointer &surface, const QPoint &position, int id); + void sendTouchUp(const QSharedPointer &surface, int id); + void sendTouchFrame(const QSharedPointer &surface); + void sendDataDeviceDataOffer(const QSharedPointer &surface); + void sendDataDeviceEnter(const QSharedPointer &surface, const QPoint &position); + void sendDataDeviceMotion(const QPoint &position); + void sendDataDeviceDrop(const QSharedPointer &surface); + void sendDataDeviceLeave(const QSharedPointer &surface); + void waitForStartDrag(); + + QSharedPointer surface(); + + void lock(); + void unlock(); + +private: + struct Command + { + typedef void (*Callback)(void *target, const QList ¶meters); + + Callback callback; + void *target; + QList parameters; + }; + + static Command makeCommand(Command::Callback callback, void *target); + + void processCommand(const Command &command); + void dispatchCommands(); + + static void *run(void *data); + + bool m_alive; + bool m_ready; + pthread_t m_thread; + QMutex m_mutex; + QWaitCondition m_waitCondition; + + Impl::Compositor *m_compositor; + + QList m_commandQueue; +}; + +#endif diff --git a/tests/auto/client/client/mockinput.cpp b/tests/auto/client/client/mockinput.cpp new file mode 100644 index 000000000..05df8604b --- /dev/null +++ b/tests/auto/client/client/mockinput.cpp @@ -0,0 +1,467 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" +#include "mockinput.h" +#include "mocksurface.h" + +namespace Impl { + +static Surface *resolveSurface(const QVariant &v) +{ + QSharedPointer mockSurface = v.value >(); + return mockSurface ? mockSurface->handle() : 0; +} + +void Compositor::setKeyboardFocus(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + compositor->m_keyboard->setFocus(resolveSurface(parameters.first())); +} + +void Compositor::sendMousePress(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + if (!surface) + return; + + QPoint pos = parameters.last().toPoint(); + compositor->m_pointer->setFocus(surface, pos); + compositor->m_pointer->sendMotion(pos); + compositor->m_pointer->sendButton(0x110, 1); +} + +void Compositor::sendMouseRelease(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + if (!surface) + return; + + compositor->m_pointer->sendButton(0x110, 0); +} + +void Compositor::sendKeyPress(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + if (!surface) + return; + + compositor->m_keyboard->sendKey(parameters.last().toUInt() - 8, 1); +} + +void Compositor::sendKeyRelease(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + if (!surface) + return; + + compositor->m_keyboard->sendKey(parameters.last().toUInt() - 8, 0); +} + +void Compositor::sendTouchDown(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + QPoint position = parameters.at(1).toPoint(); + int id = parameters.at(2).toInt(); + + compositor->m_touch->sendDown(surface, position, id); +} + +void Compositor::sendTouchUp(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + int id = parameters.at(1).toInt(); + + compositor->m_touch->sendUp(surface, id); +} + +void Compositor::sendTouchMotion(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + QPoint position = parameters.at(1).toPoint(); + int id = parameters.at(2).toInt(); + + compositor->m_touch->sendMotion(surface, position, id); +} + +void Compositor::sendTouchFrame(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + compositor->m_touch->sendFrame(surface); +} + +void Compositor::sendDataDeviceDataOffer(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + compositor->m_data_device_manager->dataDevice()->sendDataOffer(surface->resource()->client()); +} + +void Compositor::sendDataDeviceEnter(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + QPoint position = parameters.at(1).toPoint(); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + compositor->m_data_device_manager->dataDevice()->sendEnter(surface, position); +} + +void Compositor::sendDataDeviceMotion(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Q_ASSERT(compositor); + QPoint position = parameters.first().toPoint(); + compositor->m_data_device_manager->dataDevice()->sendMotion(position); +} + +void Compositor::sendDataDeviceDrop(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + compositor->m_data_device_manager->dataDevice()->sendDrop(surface); +} + +void Compositor::sendDataDeviceLeave(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Surface *surface = resolveSurface(parameters.first()); + + Q_ASSERT(compositor); + Q_ASSERT(surface); + + compositor->m_data_device_manager->dataDevice()->sendLeave(surface); +} + +void Compositor::waitForStartDrag(void *data, const QList ¶meters) +{ + Compositor *compositor = static_cast(data); + Q_ASSERT(compositor); + while (!compositor->m_startDragSeen) { + wl_display_flush_clients(compositor->m_display); + wl_event_loop_dispatch(compositor->m_loop, 100); + } + compositor->m_startDragSeen = false; +} + +Seat::Seat(Compositor *compositor, struct ::wl_display *display) + : wl_seat(display, 2) + , m_compositor(compositor) + , m_keyboard(new Keyboard(compositor)) + , m_pointer(new Pointer(compositor)) + , m_touch(new Touch(compositor)) +{ +} + +Seat::~Seat() +{ +} + +void Seat::seat_bind_resource(Resource *resource) +{ + send_capabilities(resource->handle, capability_keyboard | capability_pointer | capability_touch); +} + +void Seat::seat_get_keyboard(Resource *resource, uint32_t id) +{ + m_keyboard->add(resource->client(), id, resource->version()); +} + +void Seat::seat_get_pointer(Resource *resource, uint32_t id) +{ + m_pointer->add(resource->client(), id, resource->version()); +} + +void Seat::seat_get_touch(Resource *resource, uint32_t id) +{ + m_touch->add(resource->client(), id, resource->version()); +} + +Keyboard::Keyboard(Compositor *compositor) + : wl_keyboard() + , m_compositor(compositor) + , m_focusResource(Q_NULLPTR) + , m_focus(Q_NULLPTR) +{ +} + +Keyboard::~Keyboard() +{ +} + +void Keyboard::setFocus(Surface *surface) +{ + if (m_focusResource && m_focus != surface) { + uint32_t serial = m_compositor->nextSerial(); + send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); + } + + Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; + + if (resource && (m_focus != surface || m_focusResource != resource)) { + uint32_t serial = m_compositor->nextSerial(); + send_modifiers(resource->handle, serial, 0, 0, 0, 0); + send_enter(resource->handle, serial, surface->resource()->handle, QByteArray()); + } + + m_focusResource = resource; + m_focus = surface; +} + +void Keyboard::sendKey(uint32_t key, uint32_t state) +{ + if (m_focusResource) { + uint32_t serial = m_compositor->nextSerial(); + send_key(m_focusResource->handle, serial, m_compositor->time(), key, state); + } +} + + +void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource) +{ + if (m_focusResource == resource) + m_focusResource = 0; +} + +Pointer::Pointer(Compositor *compositor) + : wl_pointer() + , m_compositor(compositor) + , m_focusResource(Q_NULLPTR) + , m_focus(Q_NULLPTR) +{ +} + +Pointer::~Pointer() +{ + +} + +void Pointer::setFocus(Surface *surface, const QPoint &pos) +{ + if (m_focusResource && m_focus != surface) { + uint32_t serial = m_compositor->nextSerial(); + send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); + } + + Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; + + if (resource && (m_focus != surface || resource != m_focusResource)) { + uint32_t serial = m_compositor->nextSerial(); + send_enter(resource->handle, serial, surface->resource()->handle, + wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); + } + + m_focusResource = resource; + m_focus = surface; +} + +void Pointer::sendMotion(const QPoint &pos) +{ + if (m_focusResource) + send_motion(m_focusResource->handle, m_compositor->time(), + wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); +} + +void Pointer::sendButton(uint32_t button, uint32_t state) +{ + if (m_focusResource) { + uint32_t serial = m_compositor->nextSerial(); + send_button(m_focusResource->handle, serial, m_compositor->time(), + button, state); + } +} + +void Pointer::pointer_destroy_resource(wl_pointer::Resource *resource) +{ + if (m_focusResource == resource) + m_focusResource = 0; +} + +Touch::Touch(Compositor *compositor) + : wl_touch() + , m_compositor(compositor) +{ +} + +void Touch::sendDown(Surface *surface, const QPoint &position, int id) +{ + uint32_t serial = m_compositor->nextSerial(); + uint32_t time = m_compositor->time(); + Q_ASSERT(surface); + Resource *resource = resourceMap().value(surface->resource()->client()); + Q_ASSERT(resource); + wl_touch_send_down(resource->handle, serial, time, surface->resource()->handle, id, position.x(), position.y()); +} + +void Touch::sendUp(Surface *surface, int id) +{ + Resource *resource = resourceMap().value(surface->resource()->client()); + wl_touch_send_up(resource->handle, m_compositor->nextSerial(), m_compositor->time(), id); +} + +void Touch::sendMotion(Surface *surface, const QPoint &position, int id) +{ + Resource *resource = resourceMap().value(surface->resource()->client()); + uint32_t time = m_compositor->time(); + wl_touch_send_motion(resource->handle, time, id, position.x(), position.y()); +} + +void Touch::sendFrame(Surface *surface) +{ + Resource *resource = resourceMap().value(surface->resource()->client()); + wl_touch_send_frame(resource->handle); +} + +DataOffer::DataOffer() + : wl_data_offer() +{ + +} + +DataDevice::DataDevice(Compositor *compositor) + : wl_data_device() + , m_compositor(compositor) + , m_dataOffer(nullptr) + , m_focus(nullptr) +{ + +} + +void DataDevice::sendDataOffer(wl_client *client) +{ + m_dataOffer = new QtWaylandServer::wl_data_offer(client, 0, 1); + Resource *resource = resourceMap().value(client); + send_data_offer(resource->handle, m_dataOffer->resource()->handle); +} + +void DataDevice::sendEnter(Surface *surface, const QPoint& position) +{ + uint serial = m_compositor->nextSerial(); + m_focus = surface; + Resource *resource = resourceMap().value(surface->resource()->client()); + send_enter(resource->handle, serial, surface->resource()->handle, position.x(), position.y(), m_dataOffer->resource()->handle); +} + +void DataDevice::sendMotion(const QPoint &position) +{ + uint32_t time = m_compositor->time(); + Resource *resource = resourceMap().value(m_focus->resource()->client()); + send_motion(resource->handle, time, position.x(), position.y()); +} + +void DataDevice::sendDrop(Surface *surface) +{ + Resource *resource = resourceMap().value(surface->resource()->client()); + send_drop(resource->handle); +} + +void DataDevice::sendLeave(Surface *surface) +{ + Resource *resource = resourceMap().value(surface->resource()->client()); + send_leave(resource->handle); +} + +DataDevice::~DataDevice() +{ + +} + +void DataDevice::data_device_start_drag(QtWaylandServer::wl_data_device::Resource *resource, wl_resource *source, wl_resource *origin, wl_resource *icon, uint32_t serial) +{ + m_compositor->m_startDragSeen = true; +} + +DataDeviceManager::DataDeviceManager(Compositor *compositor, wl_display *display) + : wl_data_device_manager(display, 1) + , m_compositor(compositor) +{ + +} + +DataDeviceManager::~DataDeviceManager() +{ + +} + +DataDevice *DataDeviceManager::dataDevice() const +{ + return m_data_device.data(); +} + +void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) +{ + if (!m_data_device) + m_data_device.reset(new DataDevice(m_compositor)); + m_data_device->add(resource->client(), id, 1); +} + +void DataDeviceManager::data_device_manager_create_data_source(QtWaylandServer::wl_data_device_manager::Resource *resource, uint32_t id) +{ + new QtWaylandServer::wl_data_source(resource->client(), id, 1); +} + +} diff --git a/tests/auto/client/client/mockinput.h b/tests/auto/client/client/mockinput.h new file mode 100644 index 000000000..d98328a66 --- /dev/null +++ b/tests/auto/client/client/mockinput.h @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOCKINPUT_H +#define MOCKINPUT_H + +#include + +#include "qwayland-server-wayland.h" + +#include "mockcompositor.h" + +namespace Impl { + +class Keyboard; +class Pointer; + +class Seat : public QtWaylandServer::wl_seat +{ +public: + Seat(Compositor *compositor, struct ::wl_display *display); + ~Seat(); + + Compositor *compositor() const { return m_compositor; } + + Keyboard *keyboard() const { return m_keyboard.data(); } + Pointer *pointer() const { return m_pointer.data(); } + Touch *touch() const { return m_touch.data(); } + +protected: + void seat_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void seat_get_keyboard(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + void seat_get_pointer(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + void seat_get_touch(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + +private: + Compositor *m_compositor; + + QScopedPointer m_keyboard; + QScopedPointer m_pointer; + QScopedPointer m_touch; +}; + +class Keyboard : public QtWaylandServer::wl_keyboard +{ +public: + Keyboard(Compositor *compositor); + ~Keyboard(); + + Surface *focus() const { return m_focus; } + void setFocus(Surface *surface); + + void sendKey(uint32_t key, uint32_t state); + +protected: + void keyboard_destroy_resource(wl_keyboard::Resource *resource) Q_DECL_OVERRIDE; + +private: + Compositor *m_compositor; + + Resource *m_focusResource; + Surface *m_focus; +}; + +class Pointer : public QtWaylandServer::wl_pointer +{ +public: + Pointer(Compositor *compositor); + ~Pointer(); + + Surface *focus() const { return m_focus; } + + void setFocus(Surface *surface, const QPoint &pos); + void sendMotion(const QPoint &pos); + void sendButton(uint32_t button, uint32_t state); + +protected: + void pointer_destroy_resource(wl_pointer::Resource *resource) Q_DECL_OVERRIDE; + +private: + Compositor *m_compositor; + + Resource *m_focusResource; + Surface *m_focus; +}; + +class Touch : public QtWaylandServer::wl_touch +{ +public: + Touch(Compositor *compositor); + void sendDown(Surface *surface, const QPoint &position, int id); + void sendUp(Surface *surface, int id); + void sendMotion(Surface *surface, const QPoint &position, int id); + void sendFrame(Surface *surface); +private: + Compositor *m_compositor; +}; + +class DataOffer : public QtWaylandServer::wl_data_offer +{ +public: + DataOffer(); +}; + +class DataDevice : public QtWaylandServer::wl_data_device +{ +public: + DataDevice(Compositor *compositor); + void sendDataOffer(wl_client *client); + void sendEnter(Surface *surface, const QPoint &position); + void sendMotion(const QPoint &position); + void sendDrop(Surface *surface); + void sendLeave(Surface *surface); + ~DataDevice(); + +protected: + void data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) override; + +private: + Compositor *m_compositor; + QtWaylandServer::wl_data_offer *m_dataOffer; + Surface* m_focus; +}; + +class DataDeviceManager : public QtWaylandServer::wl_data_device_manager +{ +public: + DataDeviceManager(Compositor *compositor, struct ::wl_display *display); + ~DataDeviceManager(); + DataDevice *dataDevice() const; + +protected: + void data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; + void data_device_manager_create_data_source(Resource *resource, uint32_t id) override; + +private: + Compositor *m_compositor; + + QScopedPointer m_data_device; +}; + +} + +#endif // MOCKINPUT_H diff --git a/tests/auto/client/client/mockoutput.cpp b/tests/auto/client/client/mockoutput.cpp new file mode 100644 index 000000000..573de90b9 --- /dev/null +++ b/tests/auto/client/client/mockoutput.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" + +namespace Impl { + +void Compositor::bindOutput(wl_client *client, void *compositorData, uint32_t version, uint32_t id) +{ + Q_UNUSED(version); + + wl_resource *resource = wl_client_add_object(client, &wl_output_interface, 0, id, compositorData); + + Compositor *compositor = static_cast(compositorData); + registerResource(&compositor->m_outputResources, resource); + + compositor->sendOutputGeometry(resource); + compositor->sendOutputMode(resource); +} + +void Compositor::sendOutputGeometry(wl_resource *resource) +{ + const QRect &r = m_outputGeometry; + wl_output_send_geometry(resource, r.x(), r.y(), r.width(), r.height(), 0, "", "",0); +} + +void Compositor::sendOutputMode(wl_resource *resource) +{ + const QRect &r = m_outputGeometry; + wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, r.width(), r.height(), 60); +} + +void Compositor::setOutputGeometry(void *c, const QList ¶meters) +{ + Compositor *compositor = static_cast(c); + compositor->m_outputGeometry = parameters.first().toRect(); + + wl_resource *resource; + wl_list_for_each(resource, &compositor->m_outputResources, link) + compositor->sendOutputGeometry(resource); +} + +} + diff --git a/tests/auto/client/client/mockshell.cpp b/tests/auto/client/client/mockshell.cpp new file mode 100644 index 000000000..dfc39e5e4 --- /dev/null +++ b/tests/auto/client/client/mockshell.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" +#include "mocksurface.h" + +namespace Impl { + +void shell_surface_pong(wl_client *client, + wl_resource *surface_resource, + uint32_t serial) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(serial); +} + +void shell_surface_move(wl_client *client, + wl_resource *surface_resource, + wl_resource *input_device_resource, + uint32_t time) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(input_device_resource); + Q_UNUSED(time); +} + +void shell_surface_resize(wl_client *client, + wl_resource *surface_resource, + wl_resource *input_device_resource, + uint32_t time, + uint32_t edges) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(input_device_resource); + Q_UNUSED(time); + Q_UNUSED(edges); + +} + +void shell_surface_set_toplevel(wl_client *client, + wl_resource *surface_resource) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); +} + +void shell_surface_set_transient(wl_client *client, + wl_resource *surface_resource, + wl_resource *parent_surface_resource, + int x, + int y, + uint32_t flags) +{ + + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(parent_surface_resource); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(flags); +} + +void shell_surface_set_fullscreen(wl_client *client, + wl_resource *surface_resource, + uint32_t method, + uint32_t framerate, + wl_resource *output) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(method); + Q_UNUSED(framerate); + Q_UNUSED(output); +} + +void shell_surface_set_popup(wl_client *client, wl_resource *resource, + wl_resource *input_device, uint32_t time, + wl_resource *parent, + int32_t x, int32_t y, + uint32_t flags) +{ + Q_UNUSED(client); + Q_UNUSED(resource); + Q_UNUSED(input_device); + Q_UNUSED(time); + Q_UNUSED(parent); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(flags); +} + +void shell_surface_set_maximized(wl_client *client, + wl_resource *surface_resource, + wl_resource *output) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(output); +} + +void shell_surface_set_title(wl_client *client, + wl_resource *surface_resource, + const char *title) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(title); +} + +void shell_surface_set_class(wl_client *client, + wl_resource *surface_resource, + const char *class_) +{ + Q_UNUSED(client); + Q_UNUSED(surface_resource); + Q_UNUSED(class_); +} + +static void get_shell_surface(wl_client *client, wl_resource *compositorResource, uint32_t id, wl_resource *surfaceResource) +{ + static const struct wl_shell_surface_interface shellSurfaceInterface = { + shell_surface_pong, + shell_surface_move, + shell_surface_resize, + shell_surface_set_toplevel, + shell_surface_set_transient, + shell_surface_set_fullscreen, + shell_surface_set_popup, + shell_surface_set_maximized, + shell_surface_set_title, + shell_surface_set_class + }; + + Q_UNUSED(compositorResource); + wl_client_add_object(client, &wl_shell_surface_interface, &shellSurfaceInterface, id, surfaceResource->data); + Surface *surf = Surface::fromResource(surfaceResource); + surf->map(); +} + +void Compositor::bindShell(wl_client *client, void *compositorData, uint32_t version, uint32_t id) +{ + static const struct wl_shell_interface shellInterface = { + get_shell_surface + }; + + Q_UNUSED(version); + wl_client_add_object(client, &wl_shell_interface, &shellInterface, id, compositorData); +} + +} + diff --git a/tests/auto/client/client/mocksurface.cpp b/tests/auto/client/client/mocksurface.cpp new file mode 100644 index 000000000..b6d338b29 --- /dev/null +++ b/tests/auto/client/client/mocksurface.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mocksurface.h" +#include "mockcompositor.h" + +namespace Impl { + +Surface::Surface(wl_client *client, uint32_t id, int v, Compositor *compositor) + : QtWaylandServer::wl_surface(client, id, v) + , m_buffer(Q_NULLPTR) + , m_compositor(compositor) + , m_mockSurface(new MockSurface(this)) + , m_mapped(false) +{ +} + +Surface::~Surface() +{ + m_mockSurface->m_surface = 0; +} + +void Surface::map() +{ + m_mapped = true; +} + +bool Surface::isMapped() const +{ + return m_mapped; +} + +Surface *Surface::fromResource(struct ::wl_resource *resource) +{ + return static_cast(Resource::fromResource(resource)->surface_object); +} + +void Surface::surface_destroy_resource(Resource *) +{ + compositor()->removeSurface(this); + delete this; +} + +void Surface::surface_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void Surface::surface_attach(Resource *resource, + struct wl_resource *buffer, int x, int y) +{ + Q_UNUSED(resource); + Q_UNUSED(x); + Q_UNUSED(y); + m_buffer = buffer; + + if (!buffer) + m_mockSurface->image = QImage(); +} + +void Surface::surface_damage(Resource *resource, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + Q_UNUSED(resource); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(width); + Q_UNUSED(height); +} + +void Surface::surface_frame(Resource *resource, + uint32_t callback) +{ + wl_resource *frameCallback = wl_client_add_object(resource->client(), &wl_callback_interface, 0, callback, this); + m_frameCallbackList << frameCallback; +} + +void Surface::surface_commit(Resource *resource) +{ + Q_UNUSED(resource); + + if (m_buffer) { +#if WAYLAND_VERSION_CHECK(1, 2, 0) + struct ::wl_shm_buffer *shm_buffer = wl_shm_buffer_get(m_buffer); +#else + struct ::wl_buffer *shm_buffer = 0; + if (wl_buffer_is_shm(static_cast(m_buffer->data))) + shm_buffer = static_cast(m_buffer->data); +#endif + + if (shm_buffer) { + int stride = wl_shm_buffer_get_stride(shm_buffer); + uint format = wl_shm_buffer_get_format(shm_buffer); + Q_UNUSED(format); + void *data = wl_shm_buffer_get_data(shm_buffer); + const uchar *char_data = static_cast(data); + QImage img(char_data, wl_shm_buffer_get_width(shm_buffer), wl_shm_buffer_get_height(shm_buffer), stride, QImage::Format_ARGB32_Premultiplied); + m_mockSurface->image = img; + } + } + + foreach (wl_resource *frameCallback, m_frameCallbackList) { + wl_callback_send_done(frameCallback, m_compositor->time()); + wl_resource_destroy(frameCallback); + } + m_frameCallbackList.clear(); +} + +} +MockSurface::MockSurface(Impl::Surface *surface) + : m_surface(surface) +{ +} diff --git a/tests/auto/client/client/mocksurface.h b/tests/auto/client/client/mocksurface.h new file mode 100644 index 000000000..821d49f54 --- /dev/null +++ b/tests/auto/client/client/mocksurface.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qwayland-server-wayland.h" + +#include "mockcompositor.h" + +namespace Impl { + +class Surface : public QtWaylandServer::wl_surface +{ +public: + Surface(wl_client *client, uint32_t id, int v, Compositor *compositor); + ~Surface(); + + Compositor *compositor() const { return m_compositor; } + static Surface *fromResource(struct ::wl_resource *resource); + void map(); + bool isMapped() const; + + QSharedPointer mockSurface() const { return m_mockSurface; } + +protected: + + void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void surface_destroy(Resource *resource) Q_DECL_OVERRIDE; + void surface_attach(Resource *resource, + struct wl_resource *buffer, int x, int y) Q_DECL_OVERRIDE; + void surface_damage(Resource *resource, + int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; + void surface_frame(Resource *resource, + uint32_t callback) Q_DECL_OVERRIDE; + void surface_commit(Resource *resource) Q_DECL_OVERRIDE; +private: + wl_resource *m_buffer; + + Compositor *m_compositor; + QSharedPointer m_mockSurface; + QList m_frameCallbackList; + bool m_mapped; +}; + +} diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp new file mode 100644 index 000000000..5a1143220 --- /dev/null +++ b/tests/auto/client/client/tst_client.cpp @@ -0,0 +1,360 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +static const QSize screenSize(1600, 1200); + +class TestWindow : public QWindow +{ +public: + TestWindow() + : focusInEventCount(0) + , focusOutEventCount(0) + , keyPressEventCount(0) + , keyReleaseEventCount(0) + , mousePressEventCount(0) + , mouseReleaseEventCount(0) + , touchEventCount(0) + , keyCode(0) + { + setSurfaceType(QSurface::RasterSurface); + setGeometry(0, 0, 32, 32); + create(); + } + + void focusInEvent(QFocusEvent *) + { + ++focusInEventCount; + } + + void focusOutEvent(QFocusEvent *) + { + ++focusOutEventCount; + } + + void keyPressEvent(QKeyEvent *event) + { + ++keyPressEventCount; + keyCode = event->nativeScanCode(); + } + + void keyReleaseEvent(QKeyEvent *event) + { + ++keyReleaseEventCount; + keyCode = event->nativeScanCode(); + } + + void mousePressEvent(QMouseEvent *event) + { + ++mousePressEventCount; + mousePressPos = event->pos(); + } + + void mouseReleaseEvent(QMouseEvent *) + { + ++mouseReleaseEventCount; + } + + void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE + { + ++touchEventCount; + } + + int focusInEventCount; + int focusOutEventCount; + int keyPressEventCount; + int keyReleaseEventCount; + int mousePressEventCount; + int mouseReleaseEventCount; + int touchEventCount; + + uint keyCode; + QPoint mousePressPos; +}; + +class tst_WaylandClient : public QObject +{ + Q_OBJECT +public: + tst_WaylandClient(MockCompositor *c) + : compositor(c) + { + QSocketNotifier *notifier = new QSocketNotifier(compositor->waylandFileDescriptor(), QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(processWaylandEvents())); + // connect to the event dispatcher to make sure to flush out the outgoing message queue + connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, &tst_WaylandClient::processWaylandEvents); + connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &tst_WaylandClient::processWaylandEvents); + } + +public slots: + void processWaylandEvents() + { + compositor->processWaylandEvents(); + } + + void cleanup() + { + // make sure the surfaces from the last test are properly cleaned up + // and don't show up as false positives in the next test + QTRY_VERIFY(!compositor->surface()); + } + +private slots: + void screen(); + void createDestroyWindow(); + void events(); + void backingStore(); + void touchDrag(); + void mouseDrag(); + +private: + MockCompositor *compositor; +}; + +void tst_WaylandClient::screen() +{ + QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize); +} + +void tst_WaylandClient::createDestroyWindow() +{ + TestWindow window; + window.show(); + + QTRY_VERIFY(compositor->surface()); + + window.destroy(); + QTRY_VERIFY(!compositor->surface()); +} + +void tst_WaylandClient::events() +{ + TestWindow window; + window.show(); + + QSharedPointer surface; + QTRY_VERIFY(surface = compositor->surface()); + + QCOMPARE(window.focusInEventCount, 0); + compositor->setKeyboardFocus(surface); + QTRY_COMPARE(window.focusInEventCount, 1); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); + + QCOMPARE(window.focusOutEventCount, 0); + compositor->setKeyboardFocus(QSharedPointer(0)); + QTRY_COMPARE(window.focusOutEventCount, 1); + QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast(0)); + + compositor->setKeyboardFocus(surface); + QTRY_COMPARE(window.focusInEventCount, 2); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); + + uint keyCode = 80; // arbitrarily chosen + QCOMPARE(window.keyPressEventCount, 0); + compositor->sendKeyPress(surface, keyCode); + QTRY_COMPARE(window.keyPressEventCount, 1); + QTRY_COMPARE(window.keyCode, keyCode); + + QCOMPARE(window.keyReleaseEventCount, 0); + compositor->sendKeyRelease(surface, keyCode); + QTRY_COMPARE(window.keyReleaseEventCount, 1); + QCOMPARE(window.keyCode, keyCode); + + QPoint mousePressPos(16, 16); + QCOMPARE(window.mousePressEventCount, 0); + compositor->sendMousePress(surface, mousePressPos); + QTRY_COMPARE(window.mousePressEventCount, 1); + QTRY_COMPARE(window.mousePressPos, mousePressPos); + + QCOMPARE(window.mouseReleaseEventCount, 0); + compositor->sendMouseRelease(surface); + QTRY_COMPARE(window.mouseReleaseEventCount, 1); + + const int touchId = 0; + compositor->sendTouchDown(surface, QPoint(10, 10), touchId); + compositor->sendTouchFrame(surface); + QTRY_COMPARE(window.touchEventCount, 1); + + compositor->sendTouchUp(surface, touchId); + compositor->sendTouchFrame(surface); + QTRY_COMPARE(window.touchEventCount, 2); +} + +void tst_WaylandClient::backingStore() +{ + TestWindow window; + window.show(); + + QSharedPointer surface; + QTRY_VERIFY(surface = compositor->surface()); + + QRect rect(QPoint(), window.size()); + + QBackingStore backingStore(&window); + backingStore.resize(rect.size()); + + backingStore.beginPaint(rect); + + QColor color = Qt::magenta; + + QPainter p(backingStore.paintDevice()); + p.fillRect(rect, color); + p.end(); + + backingStore.endPaint(); + + QVERIFY(surface->image.isNull()); + + backingStore.flush(rect); + + QTRY_COMPARE(surface->image.size(), window.frameGeometry().size()); + QTRY_COMPARE(surface->image.pixel(window.frameMargins().left(), window.frameMargins().top()), color.rgba()); + + window.hide(); + + // hiding the window should detach the buffer + QTRY_VERIFY(surface->image.isNull()); +} + +class DndWindow : public QWindow +{ + Q_OBJECT + +public: + DndWindow(QWindow *parent = 0) + : QWindow(parent) + , dragStarted(false) + { + QImage cursorImage(64,64,QImage::Format_ARGB32); + cursorImage.fill(Qt::blue); + m_dragIcon = QPixmap::fromImage(cursorImage); + } + ~DndWindow(){} + bool dragStarted; + +protected: + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE + { + if (dragStarted) + return; + dragStarted = true; + + QByteArray dataBytes; + QMimeData *mimeData = new QMimeData; + mimeData->setData("application/x-dnditemdata", dataBytes); + QDrag *drag = new QDrag(this); + drag->setMimeData(mimeData); + drag->setPixmap(m_dragIcon); + drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); + } +private: + QPixmap m_dragIcon; +}; + +void tst_WaylandClient::touchDrag() +{ + DndWindow window; + window.show(); + + QSharedPointer surface; + QTRY_VERIFY(surface = compositor->surface()); + + compositor->setKeyboardFocus(surface); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); + + const int id = 0; + compositor->sendTouchDown(surface, QPoint(10, 10), id); + compositor->sendTouchMotion(surface, QPoint(20, 20), id); + compositor->sendTouchFrame(surface); + compositor->waitForStartDrag(); + compositor->sendDataDeviceDataOffer(surface); + compositor->sendDataDeviceEnter(surface, QPoint(20, 20)); + compositor->sendDataDeviceMotion( QPoint(21, 21)); + compositor->sendDataDeviceDrop(surface); + compositor->sendDataDeviceLeave(surface); + QTRY_VERIFY(window.dragStarted); +} + +void tst_WaylandClient::mouseDrag() +{ + DndWindow window; + window.show(); + + QSharedPointer surface; + QTRY_VERIFY(surface = compositor->surface()); + + compositor->setKeyboardFocus(surface); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); + + compositor->sendMousePress(surface, QPoint(10, 10)); + compositor->sendDataDeviceDataOffer(surface); + compositor->sendDataDeviceEnter(surface, QPoint(20, 20)); + compositor->sendDataDeviceMotion( QPoint(21, 21)); + compositor->waitForStartDrag(); + compositor->sendDataDeviceDrop(surface); + compositor->sendDataDeviceLeave(surface); + QTRY_VERIFY(window.dragStarted); +} + +int main(int argc, char **argv) +{ + setenv("XDG_RUNTIME_DIR", ".", 1); + setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin + + // wayland-egl hangs in the test setup when we try to initialize. Until it gets + // figured out, avoid clientBufferIntegration() from being called in + // QWaylandWindow::createDecorations(). + setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1); + + MockCompositor compositor; + compositor.setOutputGeometry(QRect(QPoint(), screenSize)); + + QGuiApplication app(argc, argv); + compositor.applicationInitialized(); + + tst_WaylandClient tc(&compositor); + return QTest::qExec(&tc, argc, argv); +} + +#include diff --git a/tests/auto/client/mockcompositor.cpp b/tests/auto/client/mockcompositor.cpp deleted file mode 100644 index 83dd52ba2..000000000 --- a/tests/auto/client/mockcompositor.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockcompositor.h" -#include "mockinput.h" -#include "mocksurface.h" - -#include -MockCompositor::MockCompositor() - : m_alive(true) - , m_ready(false) - , m_compositor(0) -{ - pthread_create(&m_thread, 0, run, this); - - m_mutex.lock(); - m_waitCondition.wait(&m_mutex); - m_mutex.unlock(); -} - -MockCompositor::~MockCompositor() -{ - m_alive = false; - m_waitCondition.wakeOne(); - pthread_join(m_thread, 0); -} - -void MockCompositor::lock() -{ - m_mutex.lock(); -} - -void MockCompositor::unlock() -{ - m_mutex.unlock(); -} - -void MockCompositor::applicationInitialized() -{ - m_ready = true; -} - -int MockCompositor::waylandFileDescriptor() const -{ - return m_compositor->fileDescriptor(); -} - -void MockCompositor::processWaylandEvents() -{ - m_waitCondition.wakeOne(); -} - -void MockCompositor::setOutputGeometry(const QRect &rect) -{ - Command command = makeCommand(Impl::Compositor::setOutputGeometry, m_compositor); - command.parameters << rect; - processCommand(command); -} - -void MockCompositor::setKeyboardFocus(const QSharedPointer &surface) -{ - Command command = makeCommand(Impl::Compositor::setKeyboardFocus, m_compositor); - command.parameters << QVariant::fromValue(surface); - processCommand(command); -} - -void MockCompositor::sendMousePress(const QSharedPointer &surface, const QPoint &pos) -{ - Command command = makeCommand(Impl::Compositor::sendMousePress, m_compositor); - command.parameters << QVariant::fromValue(surface) << pos; - processCommand(command); -} - -void MockCompositor::sendMouseRelease(const QSharedPointer &surface) -{ - Command command = makeCommand(Impl::Compositor::sendMouseRelease, m_compositor); - command.parameters << QVariant::fromValue(surface); - processCommand(command); -} - -void MockCompositor::sendKeyPress(const QSharedPointer &surface, uint code) -{ - Command command = makeCommand(Impl::Compositor::sendKeyPress, m_compositor); - command.parameters << QVariant::fromValue(surface) << code; - processCommand(command); -} - -void MockCompositor::sendKeyRelease(const QSharedPointer &surface, uint code) -{ - Command command = makeCommand(Impl::Compositor::sendKeyRelease, m_compositor); - command.parameters << QVariant::fromValue(surface) << code; - processCommand(command); -} - -void MockCompositor::sendTouchDown(const QSharedPointer &surface, const QPoint &position, int id) -{ - Command command = makeCommand(Impl::Compositor::sendTouchDown, m_compositor); - command.parameters << QVariant::fromValue(surface) << position << id; - processCommand(command); -} - -void MockCompositor::sendTouchMotion(const QSharedPointer &surface, const QPoint &position, int id) -{ - Command command = makeCommand(Impl::Compositor::sendTouchMotion, m_compositor); - command.parameters << QVariant::fromValue(surface) << position << id; - processCommand(command); -} - -void MockCompositor::sendTouchUp(const QSharedPointer &surface, int id) -{ - Command command = makeCommand(Impl::Compositor::sendTouchUp, m_compositor); - command.parameters << QVariant::fromValue(surface) << id; - processCommand(command); -} - -void MockCompositor::sendTouchFrame(const QSharedPointer &surface) -{ - Command command = makeCommand(Impl::Compositor::sendTouchFrame, m_compositor); - command.parameters << QVariant::fromValue(surface); - processCommand(command); -} - -void MockCompositor::sendDataDeviceDataOffer(const QSharedPointer &surface) -{ - Command command = makeCommand(Impl::Compositor::sendDataDeviceDataOffer, m_compositor); - command.parameters << QVariant::fromValue(surface); - processCommand(command); -} - -void MockCompositor::sendDataDeviceEnter(const QSharedPointer &surface, const QPoint& position) -{ - Command command = makeCommand(Impl::Compositor::sendDataDeviceEnter, m_compositor); - command.parameters << QVariant::fromValue(surface) << QVariant::fromValue(position); - processCommand(command); -} - -void MockCompositor::sendDataDeviceMotion(const QPoint &position) -{ - Command command = makeCommand(Impl::Compositor::sendDataDeviceMotion, m_compositor); - command.parameters << QVariant::fromValue(position); - processCommand(command); -} - -void MockCompositor::sendDataDeviceDrop(const QSharedPointer &surface) -{ - Command command = makeCommand(Impl::Compositor::sendDataDeviceDrop, m_compositor); - command.parameters << QVariant::fromValue(surface); - processCommand(command); -} - -void MockCompositor::sendDataDeviceLeave(const QSharedPointer &surface) -{ - Command command = makeCommand(Impl::Compositor::sendDataDeviceLeave, m_compositor); - command.parameters << QVariant::fromValue(surface); - processCommand(command); -} - -void MockCompositor::waitForStartDrag() -{ - Command command = makeCommand(Impl::Compositor::waitForStartDrag, m_compositor); - processCommand(command); -} - -QSharedPointer MockCompositor::surface() -{ - QSharedPointer result; - lock(); - QVector surfaces = m_compositor->surfaces(); - foreach (Impl::Surface *surface, surfaces) { - // we don't want to mistake the cursor surface for a window surface - if (surface->isMapped()) { - result = surface->mockSurface(); - break; - } - } - unlock(); - return result; -} - -MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target) -{ - Command command; - command.callback = callback; - command.target = target; - return command; -} - -void MockCompositor::processCommand(const Command &command) -{ - lock(); - m_commandQueue << command; - unlock(); - - m_waitCondition.wakeOne(); -} - -void MockCompositor::dispatchCommands() -{ - lock(); - int count = m_commandQueue.length(); - unlock(); - - for (int i = 0; i < count; ++i) { - lock(); - const Command command = m_commandQueue.takeFirst(); - unlock(); - command.callback(command.target, command.parameters); - } -} - -void *MockCompositor::run(void *data) -{ - MockCompositor *controller = static_cast(data); - - Impl::Compositor compositor; - - controller->m_compositor = &compositor; - controller->m_waitCondition.wakeOne(); - - while (!controller->m_ready) { - controller->dispatchCommands(); - compositor.dispatchEvents(20); - } - - while (controller->m_alive) { - { - QMutexLocker locker(&controller->m_mutex); - if (controller->m_commandQueue.isEmpty()) - controller->m_waitCondition.wait(&controller->m_mutex); - } - controller->dispatchCommands(); - compositor.dispatchEvents(20); - } - - return 0; -} - -namespace Impl { - -Compositor::Compositor() - : m_display(wl_display_create()) - , m_startDragSeen(false) - , m_time(0) -{ - wl_list_init(&m_outputResources); - - if (wl_display_add_socket(m_display, 0)) { - fprintf(stderr, "Fatal: Failed to open server socket\n"); - exit(EXIT_FAILURE); - } - - wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor); - - m_data_device_manager.reset(new DataDeviceManager(this, m_display)); - - wl_display_init_shm(m_display); - - m_seat.reset(new Seat(this, m_display)); - m_pointer = m_seat->pointer(); - m_keyboard = m_seat->keyboard(); - m_touch = m_seat->touch(); - - wl_display_add_global(m_display, &wl_output_interface, this, bindOutput); - wl_display_add_global(m_display, &wl_shell_interface, this, bindShell); - - m_loop = wl_display_get_event_loop(m_display); - m_fd = wl_event_loop_get_fd(m_loop); -} - -Compositor::~Compositor() -{ - wl_display_destroy(m_display); -} - -void Compositor::dispatchEvents(int timeout) -{ - wl_display_flush_clients(m_display); - wl_event_loop_dispatch(m_loop, timeout); -} - -static void compositor_create_surface(wl_client *client, wl_resource *compositorResource, uint32_t id) -{ - Compositor *compositor = static_cast(compositorResource->data); - compositor->addSurface(new Surface(client, id, wl_resource_get_version(compositorResource), compositor)); -} - -static void compositor_create_region(wl_client *client, wl_resource *compositorResource, uint32_t id) -{ - Q_UNUSED(client); - Q_UNUSED(compositorResource); - Q_UNUSED(id); -} - -void Compositor::bindCompositor(wl_client *client, void *compositorData, uint32_t version, uint32_t id) -{ - static const struct wl_compositor_interface compositorInterface = { - compositor_create_surface, - compositor_create_region - }; - - Q_UNUSED(version); - wl_client_add_object(client, &wl_compositor_interface, &compositorInterface, id, compositorData); -} - -static void unregisterResourceCallback(wl_listener *listener, void *data) -{ - struct wl_resource *resource = reinterpret_cast(data); - wl_list_remove(&resource->link); - delete listener; -} - -void registerResource(wl_list *list, wl_resource *resource) -{ - wl_list_insert(list, &resource->link); - - wl_listener *listener = new wl_listener; - listener->notify = unregisterResourceCallback; - - wl_signal_add(&resource->destroy_signal, listener); -} - -QVector Compositor::surfaces() const -{ - return m_surfaces; -} - -uint32_t Compositor::nextSerial() -{ - return wl_display_next_serial(m_display); -} - -void Compositor::addSurface(Surface *surface) -{ - m_surfaces << surface; -} - -void Compositor::removeSurface(Surface *surface) -{ - m_surfaces.removeOne(surface); - if (m_keyboard->focus() == surface) - m_keyboard->setFocus(0); - if (m_pointer->focus() == surface) - m_pointer->setFocus(0, QPoint()); -} - -} - diff --git a/tests/auto/client/mockcompositor.h b/tests/auto/client/mockcompositor.h deleted file mode 100644 index 2f0df4a0f..000000000 --- a/tests/auto/client/mockcompositor.h +++ /dev/null @@ -1,208 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MOCKCOMPOSITOR_H -#define MOCKCOMPOSITOR_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace Impl { - -typedef void (**Implementation)(void); - -class Keyboard; -class Pointer; -class Touch; -class Seat; -class DataDeviceManager; -class Surface; - -class Compositor -{ -public: - Compositor(); - ~Compositor(); - - int fileDescriptor() const { return m_fd; } - void dispatchEvents(int timeout = 0); - - uint32_t nextSerial(); - uint32_t time() { return ++m_time; } - - static void setOutputGeometry(void *compositor, const QList ¶meters); - - QVector surfaces() const; - - void addSurface(Surface *surface); - void removeSurface(Surface *surface); - - static void setKeyboardFocus(void *data, const QList ¶meters); - static void sendMousePress(void *data, const QList ¶meters); - static void sendMouseRelease(void *data, const QList ¶meters); - static void sendKeyPress(void *data, const QList ¶meters); - static void sendKeyRelease(void *data, const QList ¶meters); - static void sendTouchDown(void *data, const QList ¶meters); - static void sendTouchUp(void *data, const QList ¶meters); - static void sendTouchMotion(void *data, const QList ¶meters); - static void sendTouchFrame(void *data, const QList ¶meters); - static void sendDataDeviceDataOffer(void *data, const QList ¶meters); - static void sendDataDeviceEnter(void *data, const QList ¶meters); - static void sendDataDeviceMotion(void *data, const QList ¶meters); - static void sendDataDeviceDrop(void *data, const QList ¶meters); - static void sendDataDeviceLeave(void *data, const QList ¶meters); - static void waitForStartDrag(void *data, const QList ¶meters); - -public: - bool m_startDragSeen; - -private: - static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id); - static void bindOutput(wl_client *client, void *data, uint32_t version, uint32_t id); - static void bindShell(wl_client *client, void *data, uint32_t version, uint32_t id); - - void initShm(); - - void sendOutputGeometry(wl_resource *resource); - void sendOutputMode(wl_resource *resource); - - QRect m_outputGeometry; - - wl_display *m_display; - wl_event_loop *m_loop; - wl_shm *m_shm; - int m_fd; - - wl_list m_outputResources; - uint32_t m_time; - - QScopedPointer m_seat; - Pointer *m_pointer; - Keyboard *m_keyboard; - Touch *m_touch; - QScopedPointer m_data_device_manager; - QVector m_surfaces; -}; - -void registerResource(wl_list *list, wl_resource *resource); - -} - -class MockSurface -{ -public: - Impl::Surface *handle() const { return m_surface; } - - QImage image; - -private: - MockSurface(Impl::Surface *surface); - friend class Impl::Compositor; - friend class Impl::Surface; - - Impl::Surface *m_surface; -}; - -Q_DECLARE_METATYPE(QSharedPointer) - -class MockCompositor -{ -public: - MockCompositor(); - ~MockCompositor(); - - void applicationInitialized(); - - int waylandFileDescriptor() const; - void processWaylandEvents(); - - void setOutputGeometry(const QRect &rect); - void setKeyboardFocus(const QSharedPointer &surface); - void sendMousePress(const QSharedPointer &surface, const QPoint &pos); - void sendMouseRelease(const QSharedPointer &surface); - void sendKeyPress(const QSharedPointer &surface, uint code); - void sendKeyRelease(const QSharedPointer &surface, uint code); - void sendTouchDown(const QSharedPointer &surface, const QPoint &position, int id); - void sendTouchMotion(const QSharedPointer &surface, const QPoint &position, int id); - void sendTouchUp(const QSharedPointer &surface, int id); - void sendTouchFrame(const QSharedPointer &surface); - void sendDataDeviceDataOffer(const QSharedPointer &surface); - void sendDataDeviceEnter(const QSharedPointer &surface, const QPoint &position); - void sendDataDeviceMotion(const QPoint &position); - void sendDataDeviceDrop(const QSharedPointer &surface); - void sendDataDeviceLeave(const QSharedPointer &surface); - void waitForStartDrag(); - - QSharedPointer surface(); - - void lock(); - void unlock(); - -private: - struct Command - { - typedef void (*Callback)(void *target, const QList ¶meters); - - Callback callback; - void *target; - QList parameters; - }; - - static Command makeCommand(Command::Callback callback, void *target); - - void processCommand(const Command &command); - void dispatchCommands(); - - static void *run(void *data); - - bool m_alive; - bool m_ready; - pthread_t m_thread; - QMutex m_mutex; - QWaitCondition m_waitCondition; - - Impl::Compositor *m_compositor; - - QList m_commandQueue; -}; - -#endif diff --git a/tests/auto/client/mockinput.cpp b/tests/auto/client/mockinput.cpp deleted file mode 100644 index 05df8604b..000000000 --- a/tests/auto/client/mockinput.cpp +++ /dev/null @@ -1,467 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockcompositor.h" -#include "mockinput.h" -#include "mocksurface.h" - -namespace Impl { - -static Surface *resolveSurface(const QVariant &v) -{ - QSharedPointer mockSurface = v.value >(); - return mockSurface ? mockSurface->handle() : 0; -} - -void Compositor::setKeyboardFocus(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - compositor->m_keyboard->setFocus(resolveSurface(parameters.first())); -} - -void Compositor::sendMousePress(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - if (!surface) - return; - - QPoint pos = parameters.last().toPoint(); - compositor->m_pointer->setFocus(surface, pos); - compositor->m_pointer->sendMotion(pos); - compositor->m_pointer->sendButton(0x110, 1); -} - -void Compositor::sendMouseRelease(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - if (!surface) - return; - - compositor->m_pointer->sendButton(0x110, 0); -} - -void Compositor::sendKeyPress(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - if (!surface) - return; - - compositor->m_keyboard->sendKey(parameters.last().toUInt() - 8, 1); -} - -void Compositor::sendKeyRelease(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - if (!surface) - return; - - compositor->m_keyboard->sendKey(parameters.last().toUInt() - 8, 0); -} - -void Compositor::sendTouchDown(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - QPoint position = parameters.at(1).toPoint(); - int id = parameters.at(2).toInt(); - - compositor->m_touch->sendDown(surface, position, id); -} - -void Compositor::sendTouchUp(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - int id = parameters.at(1).toInt(); - - compositor->m_touch->sendUp(surface, id); -} - -void Compositor::sendTouchMotion(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - QPoint position = parameters.at(1).toPoint(); - int id = parameters.at(2).toInt(); - - compositor->m_touch->sendMotion(surface, position, id); -} - -void Compositor::sendTouchFrame(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - compositor->m_touch->sendFrame(surface); -} - -void Compositor::sendDataDeviceDataOffer(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - compositor->m_data_device_manager->dataDevice()->sendDataOffer(surface->resource()->client()); -} - -void Compositor::sendDataDeviceEnter(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - QPoint position = parameters.at(1).toPoint(); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - compositor->m_data_device_manager->dataDevice()->sendEnter(surface, position); -} - -void Compositor::sendDataDeviceMotion(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Q_ASSERT(compositor); - QPoint position = parameters.first().toPoint(); - compositor->m_data_device_manager->dataDevice()->sendMotion(position); -} - -void Compositor::sendDataDeviceDrop(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - compositor->m_data_device_manager->dataDevice()->sendDrop(surface); -} - -void Compositor::sendDataDeviceLeave(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Surface *surface = resolveSurface(parameters.first()); - - Q_ASSERT(compositor); - Q_ASSERT(surface); - - compositor->m_data_device_manager->dataDevice()->sendLeave(surface); -} - -void Compositor::waitForStartDrag(void *data, const QList ¶meters) -{ - Compositor *compositor = static_cast(data); - Q_ASSERT(compositor); - while (!compositor->m_startDragSeen) { - wl_display_flush_clients(compositor->m_display); - wl_event_loop_dispatch(compositor->m_loop, 100); - } - compositor->m_startDragSeen = false; -} - -Seat::Seat(Compositor *compositor, struct ::wl_display *display) - : wl_seat(display, 2) - , m_compositor(compositor) - , m_keyboard(new Keyboard(compositor)) - , m_pointer(new Pointer(compositor)) - , m_touch(new Touch(compositor)) -{ -} - -Seat::~Seat() -{ -} - -void Seat::seat_bind_resource(Resource *resource) -{ - send_capabilities(resource->handle, capability_keyboard | capability_pointer | capability_touch); -} - -void Seat::seat_get_keyboard(Resource *resource, uint32_t id) -{ - m_keyboard->add(resource->client(), id, resource->version()); -} - -void Seat::seat_get_pointer(Resource *resource, uint32_t id) -{ - m_pointer->add(resource->client(), id, resource->version()); -} - -void Seat::seat_get_touch(Resource *resource, uint32_t id) -{ - m_touch->add(resource->client(), id, resource->version()); -} - -Keyboard::Keyboard(Compositor *compositor) - : wl_keyboard() - , m_compositor(compositor) - , m_focusResource(Q_NULLPTR) - , m_focus(Q_NULLPTR) -{ -} - -Keyboard::~Keyboard() -{ -} - -void Keyboard::setFocus(Surface *surface) -{ - if (m_focusResource && m_focus != surface) { - uint32_t serial = m_compositor->nextSerial(); - send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); - } - - Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; - - if (resource && (m_focus != surface || m_focusResource != resource)) { - uint32_t serial = m_compositor->nextSerial(); - send_modifiers(resource->handle, serial, 0, 0, 0, 0); - send_enter(resource->handle, serial, surface->resource()->handle, QByteArray()); - } - - m_focusResource = resource; - m_focus = surface; -} - -void Keyboard::sendKey(uint32_t key, uint32_t state) -{ - if (m_focusResource) { - uint32_t serial = m_compositor->nextSerial(); - send_key(m_focusResource->handle, serial, m_compositor->time(), key, state); - } -} - - -void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource) -{ - if (m_focusResource == resource) - m_focusResource = 0; -} - -Pointer::Pointer(Compositor *compositor) - : wl_pointer() - , m_compositor(compositor) - , m_focusResource(Q_NULLPTR) - , m_focus(Q_NULLPTR) -{ -} - -Pointer::~Pointer() -{ - -} - -void Pointer::setFocus(Surface *surface, const QPoint &pos) -{ - if (m_focusResource && m_focus != surface) { - uint32_t serial = m_compositor->nextSerial(); - send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); - } - - Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; - - if (resource && (m_focus != surface || resource != m_focusResource)) { - uint32_t serial = m_compositor->nextSerial(); - send_enter(resource->handle, serial, surface->resource()->handle, - wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); - } - - m_focusResource = resource; - m_focus = surface; -} - -void Pointer::sendMotion(const QPoint &pos) -{ - if (m_focusResource) - send_motion(m_focusResource->handle, m_compositor->time(), - wl_fixed_from_int(pos.x()), wl_fixed_from_int(pos.y())); -} - -void Pointer::sendButton(uint32_t button, uint32_t state) -{ - if (m_focusResource) { - uint32_t serial = m_compositor->nextSerial(); - send_button(m_focusResource->handle, serial, m_compositor->time(), - button, state); - } -} - -void Pointer::pointer_destroy_resource(wl_pointer::Resource *resource) -{ - if (m_focusResource == resource) - m_focusResource = 0; -} - -Touch::Touch(Compositor *compositor) - : wl_touch() - , m_compositor(compositor) -{ -} - -void Touch::sendDown(Surface *surface, const QPoint &position, int id) -{ - uint32_t serial = m_compositor->nextSerial(); - uint32_t time = m_compositor->time(); - Q_ASSERT(surface); - Resource *resource = resourceMap().value(surface->resource()->client()); - Q_ASSERT(resource); - wl_touch_send_down(resource->handle, serial, time, surface->resource()->handle, id, position.x(), position.y()); -} - -void Touch::sendUp(Surface *surface, int id) -{ - Resource *resource = resourceMap().value(surface->resource()->client()); - wl_touch_send_up(resource->handle, m_compositor->nextSerial(), m_compositor->time(), id); -} - -void Touch::sendMotion(Surface *surface, const QPoint &position, int id) -{ - Resource *resource = resourceMap().value(surface->resource()->client()); - uint32_t time = m_compositor->time(); - wl_touch_send_motion(resource->handle, time, id, position.x(), position.y()); -} - -void Touch::sendFrame(Surface *surface) -{ - Resource *resource = resourceMap().value(surface->resource()->client()); - wl_touch_send_frame(resource->handle); -} - -DataOffer::DataOffer() - : wl_data_offer() -{ - -} - -DataDevice::DataDevice(Compositor *compositor) - : wl_data_device() - , m_compositor(compositor) - , m_dataOffer(nullptr) - , m_focus(nullptr) -{ - -} - -void DataDevice::sendDataOffer(wl_client *client) -{ - m_dataOffer = new QtWaylandServer::wl_data_offer(client, 0, 1); - Resource *resource = resourceMap().value(client); - send_data_offer(resource->handle, m_dataOffer->resource()->handle); -} - -void DataDevice::sendEnter(Surface *surface, const QPoint& position) -{ - uint serial = m_compositor->nextSerial(); - m_focus = surface; - Resource *resource = resourceMap().value(surface->resource()->client()); - send_enter(resource->handle, serial, surface->resource()->handle, position.x(), position.y(), m_dataOffer->resource()->handle); -} - -void DataDevice::sendMotion(const QPoint &position) -{ - uint32_t time = m_compositor->time(); - Resource *resource = resourceMap().value(m_focus->resource()->client()); - send_motion(resource->handle, time, position.x(), position.y()); -} - -void DataDevice::sendDrop(Surface *surface) -{ - Resource *resource = resourceMap().value(surface->resource()->client()); - send_drop(resource->handle); -} - -void DataDevice::sendLeave(Surface *surface) -{ - Resource *resource = resourceMap().value(surface->resource()->client()); - send_leave(resource->handle); -} - -DataDevice::~DataDevice() -{ - -} - -void DataDevice::data_device_start_drag(QtWaylandServer::wl_data_device::Resource *resource, wl_resource *source, wl_resource *origin, wl_resource *icon, uint32_t serial) -{ - m_compositor->m_startDragSeen = true; -} - -DataDeviceManager::DataDeviceManager(Compositor *compositor, wl_display *display) - : wl_data_device_manager(display, 1) - , m_compositor(compositor) -{ - -} - -DataDeviceManager::~DataDeviceManager() -{ - -} - -DataDevice *DataDeviceManager::dataDevice() const -{ - return m_data_device.data(); -} - -void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) -{ - if (!m_data_device) - m_data_device.reset(new DataDevice(m_compositor)); - m_data_device->add(resource->client(), id, 1); -} - -void DataDeviceManager::data_device_manager_create_data_source(QtWaylandServer::wl_data_device_manager::Resource *resource, uint32_t id) -{ - new QtWaylandServer::wl_data_source(resource->client(), id, 1); -} - -} diff --git a/tests/auto/client/mockinput.h b/tests/auto/client/mockinput.h deleted file mode 100644 index d98328a66..000000000 --- a/tests/auto/client/mockinput.h +++ /dev/null @@ -1,175 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MOCKINPUT_H -#define MOCKINPUT_H - -#include - -#include "qwayland-server-wayland.h" - -#include "mockcompositor.h" - -namespace Impl { - -class Keyboard; -class Pointer; - -class Seat : public QtWaylandServer::wl_seat -{ -public: - Seat(Compositor *compositor, struct ::wl_display *display); - ~Seat(); - - Compositor *compositor() const { return m_compositor; } - - Keyboard *keyboard() const { return m_keyboard.data(); } - Pointer *pointer() const { return m_pointer.data(); } - Touch *touch() const { return m_touch.data(); } - -protected: - void seat_bind_resource(Resource *resource) Q_DECL_OVERRIDE; - void seat_get_keyboard(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; - void seat_get_pointer(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; - void seat_get_touch(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; - - QScopedPointer m_keyboard; - QScopedPointer m_pointer; - QScopedPointer m_touch; -}; - -class Keyboard : public QtWaylandServer::wl_keyboard -{ -public: - Keyboard(Compositor *compositor); - ~Keyboard(); - - Surface *focus() const { return m_focus; } - void setFocus(Surface *surface); - - void sendKey(uint32_t key, uint32_t state); - -protected: - void keyboard_destroy_resource(wl_keyboard::Resource *resource) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; - - Resource *m_focusResource; - Surface *m_focus; -}; - -class Pointer : public QtWaylandServer::wl_pointer -{ -public: - Pointer(Compositor *compositor); - ~Pointer(); - - Surface *focus() const { return m_focus; } - - void setFocus(Surface *surface, const QPoint &pos); - void sendMotion(const QPoint &pos); - void sendButton(uint32_t button, uint32_t state); - -protected: - void pointer_destroy_resource(wl_pointer::Resource *resource) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; - - Resource *m_focusResource; - Surface *m_focus; -}; - -class Touch : public QtWaylandServer::wl_touch -{ -public: - Touch(Compositor *compositor); - void sendDown(Surface *surface, const QPoint &position, int id); - void sendUp(Surface *surface, int id); - void sendMotion(Surface *surface, const QPoint &position, int id); - void sendFrame(Surface *surface); -private: - Compositor *m_compositor; -}; - -class DataOffer : public QtWaylandServer::wl_data_offer -{ -public: - DataOffer(); -}; - -class DataDevice : public QtWaylandServer::wl_data_device -{ -public: - DataDevice(Compositor *compositor); - void sendDataOffer(wl_client *client); - void sendEnter(Surface *surface, const QPoint &position); - void sendMotion(const QPoint &position); - void sendDrop(Surface *surface); - void sendLeave(Surface *surface); - ~DataDevice(); - -protected: - void data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) override; - -private: - Compositor *m_compositor; - QtWaylandServer::wl_data_offer *m_dataOffer; - Surface* m_focus; -}; - -class DataDeviceManager : public QtWaylandServer::wl_data_device_manager -{ -public: - DataDeviceManager(Compositor *compositor, struct ::wl_display *display); - ~DataDeviceManager(); - DataDevice *dataDevice() const; - -protected: - void data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; - void data_device_manager_create_data_source(Resource *resource, uint32_t id) override; - -private: - Compositor *m_compositor; - - QScopedPointer m_data_device; -}; - -} - -#endif // MOCKINPUT_H diff --git a/tests/auto/client/mockoutput.cpp b/tests/auto/client/mockoutput.cpp deleted file mode 100644 index 573de90b9..000000000 --- a/tests/auto/client/mockoutput.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockcompositor.h" - -namespace Impl { - -void Compositor::bindOutput(wl_client *client, void *compositorData, uint32_t version, uint32_t id) -{ - Q_UNUSED(version); - - wl_resource *resource = wl_client_add_object(client, &wl_output_interface, 0, id, compositorData); - - Compositor *compositor = static_cast(compositorData); - registerResource(&compositor->m_outputResources, resource); - - compositor->sendOutputGeometry(resource); - compositor->sendOutputMode(resource); -} - -void Compositor::sendOutputGeometry(wl_resource *resource) -{ - const QRect &r = m_outputGeometry; - wl_output_send_geometry(resource, r.x(), r.y(), r.width(), r.height(), 0, "", "",0); -} - -void Compositor::sendOutputMode(wl_resource *resource) -{ - const QRect &r = m_outputGeometry; - wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, r.width(), r.height(), 60); -} - -void Compositor::setOutputGeometry(void *c, const QList ¶meters) -{ - Compositor *compositor = static_cast(c); - compositor->m_outputGeometry = parameters.first().toRect(); - - wl_resource *resource; - wl_list_for_each(resource, &compositor->m_outputResources, link) - compositor->sendOutputGeometry(resource); -} - -} - diff --git a/tests/auto/client/mockshell.cpp b/tests/auto/client/mockshell.cpp deleted file mode 100644 index dfc39e5e4..000000000 --- a/tests/auto/client/mockshell.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockcompositor.h" -#include "mocksurface.h" - -namespace Impl { - -void shell_surface_pong(wl_client *client, - wl_resource *surface_resource, - uint32_t serial) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(serial); -} - -void shell_surface_move(wl_client *client, - wl_resource *surface_resource, - wl_resource *input_device_resource, - uint32_t time) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(input_device_resource); - Q_UNUSED(time); -} - -void shell_surface_resize(wl_client *client, - wl_resource *surface_resource, - wl_resource *input_device_resource, - uint32_t time, - uint32_t edges) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(input_device_resource); - Q_UNUSED(time); - Q_UNUSED(edges); - -} - -void shell_surface_set_toplevel(wl_client *client, - wl_resource *surface_resource) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); -} - -void shell_surface_set_transient(wl_client *client, - wl_resource *surface_resource, - wl_resource *parent_surface_resource, - int x, - int y, - uint32_t flags) -{ - - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(parent_surface_resource); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(flags); -} - -void shell_surface_set_fullscreen(wl_client *client, - wl_resource *surface_resource, - uint32_t method, - uint32_t framerate, - wl_resource *output) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(method); - Q_UNUSED(framerate); - Q_UNUSED(output); -} - -void shell_surface_set_popup(wl_client *client, wl_resource *resource, - wl_resource *input_device, uint32_t time, - wl_resource *parent, - int32_t x, int32_t y, - uint32_t flags) -{ - Q_UNUSED(client); - Q_UNUSED(resource); - Q_UNUSED(input_device); - Q_UNUSED(time); - Q_UNUSED(parent); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(flags); -} - -void shell_surface_set_maximized(wl_client *client, - wl_resource *surface_resource, - wl_resource *output) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(output); -} - -void shell_surface_set_title(wl_client *client, - wl_resource *surface_resource, - const char *title) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(title); -} - -void shell_surface_set_class(wl_client *client, - wl_resource *surface_resource, - const char *class_) -{ - Q_UNUSED(client); - Q_UNUSED(surface_resource); - Q_UNUSED(class_); -} - -static void get_shell_surface(wl_client *client, wl_resource *compositorResource, uint32_t id, wl_resource *surfaceResource) -{ - static const struct wl_shell_surface_interface shellSurfaceInterface = { - shell_surface_pong, - shell_surface_move, - shell_surface_resize, - shell_surface_set_toplevel, - shell_surface_set_transient, - shell_surface_set_fullscreen, - shell_surface_set_popup, - shell_surface_set_maximized, - shell_surface_set_title, - shell_surface_set_class - }; - - Q_UNUSED(compositorResource); - wl_client_add_object(client, &wl_shell_surface_interface, &shellSurfaceInterface, id, surfaceResource->data); - Surface *surf = Surface::fromResource(surfaceResource); - surf->map(); -} - -void Compositor::bindShell(wl_client *client, void *compositorData, uint32_t version, uint32_t id) -{ - static const struct wl_shell_interface shellInterface = { - get_shell_surface - }; - - Q_UNUSED(version); - wl_client_add_object(client, &wl_shell_interface, &shellInterface, id, compositorData); -} - -} - diff --git a/tests/auto/client/mocksurface.cpp b/tests/auto/client/mocksurface.cpp deleted file mode 100644 index b6d338b29..000000000 --- a/tests/auto/client/mocksurface.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mocksurface.h" -#include "mockcompositor.h" - -namespace Impl { - -Surface::Surface(wl_client *client, uint32_t id, int v, Compositor *compositor) - : QtWaylandServer::wl_surface(client, id, v) - , m_buffer(Q_NULLPTR) - , m_compositor(compositor) - , m_mockSurface(new MockSurface(this)) - , m_mapped(false) -{ -} - -Surface::~Surface() -{ - m_mockSurface->m_surface = 0; -} - -void Surface::map() -{ - m_mapped = true; -} - -bool Surface::isMapped() const -{ - return m_mapped; -} - -Surface *Surface::fromResource(struct ::wl_resource *resource) -{ - return static_cast(Resource::fromResource(resource)->surface_object); -} - -void Surface::surface_destroy_resource(Resource *) -{ - compositor()->removeSurface(this); - delete this; -} - -void Surface::surface_destroy(Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void Surface::surface_attach(Resource *resource, - struct wl_resource *buffer, int x, int y) -{ - Q_UNUSED(resource); - Q_UNUSED(x); - Q_UNUSED(y); - m_buffer = buffer; - - if (!buffer) - m_mockSurface->image = QImage(); -} - -void Surface::surface_damage(Resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - Q_UNUSED(resource); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(width); - Q_UNUSED(height); -} - -void Surface::surface_frame(Resource *resource, - uint32_t callback) -{ - wl_resource *frameCallback = wl_client_add_object(resource->client(), &wl_callback_interface, 0, callback, this); - m_frameCallbackList << frameCallback; -} - -void Surface::surface_commit(Resource *resource) -{ - Q_UNUSED(resource); - - if (m_buffer) { -#if WAYLAND_VERSION_CHECK(1, 2, 0) - struct ::wl_shm_buffer *shm_buffer = wl_shm_buffer_get(m_buffer); -#else - struct ::wl_buffer *shm_buffer = 0; - if (wl_buffer_is_shm(static_cast(m_buffer->data))) - shm_buffer = static_cast(m_buffer->data); -#endif - - if (shm_buffer) { - int stride = wl_shm_buffer_get_stride(shm_buffer); - uint format = wl_shm_buffer_get_format(shm_buffer); - Q_UNUSED(format); - void *data = wl_shm_buffer_get_data(shm_buffer); - const uchar *char_data = static_cast(data); - QImage img(char_data, wl_shm_buffer_get_width(shm_buffer), wl_shm_buffer_get_height(shm_buffer), stride, QImage::Format_ARGB32_Premultiplied); - m_mockSurface->image = img; - } - } - - foreach (wl_resource *frameCallback, m_frameCallbackList) { - wl_callback_send_done(frameCallback, m_compositor->time()); - wl_resource_destroy(frameCallback); - } - m_frameCallbackList.clear(); -} - -} -MockSurface::MockSurface(Impl::Surface *surface) - : m_surface(surface) -{ -} diff --git a/tests/auto/client/mocksurface.h b/tests/auto/client/mocksurface.h deleted file mode 100644 index 821d49f54..000000000 --- a/tests/auto/client/mocksurface.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "qwayland-server-wayland.h" - -#include "mockcompositor.h" - -namespace Impl { - -class Surface : public QtWaylandServer::wl_surface -{ -public: - Surface(wl_client *client, uint32_t id, int v, Compositor *compositor); - ~Surface(); - - Compositor *compositor() const { return m_compositor; } - static Surface *fromResource(struct ::wl_resource *resource); - void map(); - bool isMapped() const; - - QSharedPointer mockSurface() const { return m_mockSurface; } - -protected: - - void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - - void surface_destroy(Resource *resource) Q_DECL_OVERRIDE; - void surface_attach(Resource *resource, - struct wl_resource *buffer, int x, int y) Q_DECL_OVERRIDE; - void surface_damage(Resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; - void surface_frame(Resource *resource, - uint32_t callback) Q_DECL_OVERRIDE; - void surface_commit(Resource *resource) Q_DECL_OVERRIDE; -private: - wl_resource *m_buffer; - - Compositor *m_compositor; - QSharedPointer m_mockSurface; - QList m_frameCallbackList; - bool m_mapped; -}; - -} diff --git a/tests/auto/client/tst_client.cpp b/tests/auto/client/tst_client.cpp deleted file mode 100644 index 5a1143220..000000000 --- a/tests/auto/client/tst_client.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockcompositor.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -static const QSize screenSize(1600, 1200); - -class TestWindow : public QWindow -{ -public: - TestWindow() - : focusInEventCount(0) - , focusOutEventCount(0) - , keyPressEventCount(0) - , keyReleaseEventCount(0) - , mousePressEventCount(0) - , mouseReleaseEventCount(0) - , touchEventCount(0) - , keyCode(0) - { - setSurfaceType(QSurface::RasterSurface); - setGeometry(0, 0, 32, 32); - create(); - } - - void focusInEvent(QFocusEvent *) - { - ++focusInEventCount; - } - - void focusOutEvent(QFocusEvent *) - { - ++focusOutEventCount; - } - - void keyPressEvent(QKeyEvent *event) - { - ++keyPressEventCount; - keyCode = event->nativeScanCode(); - } - - void keyReleaseEvent(QKeyEvent *event) - { - ++keyReleaseEventCount; - keyCode = event->nativeScanCode(); - } - - void mousePressEvent(QMouseEvent *event) - { - ++mousePressEventCount; - mousePressPos = event->pos(); - } - - void mouseReleaseEvent(QMouseEvent *) - { - ++mouseReleaseEventCount; - } - - void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE - { - ++touchEventCount; - } - - int focusInEventCount; - int focusOutEventCount; - int keyPressEventCount; - int keyReleaseEventCount; - int mousePressEventCount; - int mouseReleaseEventCount; - int touchEventCount; - - uint keyCode; - QPoint mousePressPos; -}; - -class tst_WaylandClient : public QObject -{ - Q_OBJECT -public: - tst_WaylandClient(MockCompositor *c) - : compositor(c) - { - QSocketNotifier *notifier = new QSocketNotifier(compositor->waylandFileDescriptor(), QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), this, SLOT(processWaylandEvents())); - // connect to the event dispatcher to make sure to flush out the outgoing message queue - connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, &tst_WaylandClient::processWaylandEvents); - connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &tst_WaylandClient::processWaylandEvents); - } - -public slots: - void processWaylandEvents() - { - compositor->processWaylandEvents(); - } - - void cleanup() - { - // make sure the surfaces from the last test are properly cleaned up - // and don't show up as false positives in the next test - QTRY_VERIFY(!compositor->surface()); - } - -private slots: - void screen(); - void createDestroyWindow(); - void events(); - void backingStore(); - void touchDrag(); - void mouseDrag(); - -private: - MockCompositor *compositor; -}; - -void tst_WaylandClient::screen() -{ - QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize); -} - -void tst_WaylandClient::createDestroyWindow() -{ - TestWindow window; - window.show(); - - QTRY_VERIFY(compositor->surface()); - - window.destroy(); - QTRY_VERIFY(!compositor->surface()); -} - -void tst_WaylandClient::events() -{ - TestWindow window; - window.show(); - - QSharedPointer surface; - QTRY_VERIFY(surface = compositor->surface()); - - QCOMPARE(window.focusInEventCount, 0); - compositor->setKeyboardFocus(surface); - QTRY_COMPARE(window.focusInEventCount, 1); - QTRY_COMPARE(QGuiApplication::focusWindow(), &window); - - QCOMPARE(window.focusOutEventCount, 0); - compositor->setKeyboardFocus(QSharedPointer(0)); - QTRY_COMPARE(window.focusOutEventCount, 1); - QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast(0)); - - compositor->setKeyboardFocus(surface); - QTRY_COMPARE(window.focusInEventCount, 2); - QTRY_COMPARE(QGuiApplication::focusWindow(), &window); - - uint keyCode = 80; // arbitrarily chosen - QCOMPARE(window.keyPressEventCount, 0); - compositor->sendKeyPress(surface, keyCode); - QTRY_COMPARE(window.keyPressEventCount, 1); - QTRY_COMPARE(window.keyCode, keyCode); - - QCOMPARE(window.keyReleaseEventCount, 0); - compositor->sendKeyRelease(surface, keyCode); - QTRY_COMPARE(window.keyReleaseEventCount, 1); - QCOMPARE(window.keyCode, keyCode); - - QPoint mousePressPos(16, 16); - QCOMPARE(window.mousePressEventCount, 0); - compositor->sendMousePress(surface, mousePressPos); - QTRY_COMPARE(window.mousePressEventCount, 1); - QTRY_COMPARE(window.mousePressPos, mousePressPos); - - QCOMPARE(window.mouseReleaseEventCount, 0); - compositor->sendMouseRelease(surface); - QTRY_COMPARE(window.mouseReleaseEventCount, 1); - - const int touchId = 0; - compositor->sendTouchDown(surface, QPoint(10, 10), touchId); - compositor->sendTouchFrame(surface); - QTRY_COMPARE(window.touchEventCount, 1); - - compositor->sendTouchUp(surface, touchId); - compositor->sendTouchFrame(surface); - QTRY_COMPARE(window.touchEventCount, 2); -} - -void tst_WaylandClient::backingStore() -{ - TestWindow window; - window.show(); - - QSharedPointer surface; - QTRY_VERIFY(surface = compositor->surface()); - - QRect rect(QPoint(), window.size()); - - QBackingStore backingStore(&window); - backingStore.resize(rect.size()); - - backingStore.beginPaint(rect); - - QColor color = Qt::magenta; - - QPainter p(backingStore.paintDevice()); - p.fillRect(rect, color); - p.end(); - - backingStore.endPaint(); - - QVERIFY(surface->image.isNull()); - - backingStore.flush(rect); - - QTRY_COMPARE(surface->image.size(), window.frameGeometry().size()); - QTRY_COMPARE(surface->image.pixel(window.frameMargins().left(), window.frameMargins().top()), color.rgba()); - - window.hide(); - - // hiding the window should detach the buffer - QTRY_VERIFY(surface->image.isNull()); -} - -class DndWindow : public QWindow -{ - Q_OBJECT - -public: - DndWindow(QWindow *parent = 0) - : QWindow(parent) - , dragStarted(false) - { - QImage cursorImage(64,64,QImage::Format_ARGB32); - cursorImage.fill(Qt::blue); - m_dragIcon = QPixmap::fromImage(cursorImage); - } - ~DndWindow(){} - bool dragStarted; - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE - { - if (dragStarted) - return; - dragStarted = true; - - QByteArray dataBytes; - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-dnditemdata", dataBytes); - QDrag *drag = new QDrag(this); - drag->setMimeData(mimeData); - drag->setPixmap(m_dragIcon); - drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); - } -private: - QPixmap m_dragIcon; -}; - -void tst_WaylandClient::touchDrag() -{ - DndWindow window; - window.show(); - - QSharedPointer surface; - QTRY_VERIFY(surface = compositor->surface()); - - compositor->setKeyboardFocus(surface); - QTRY_COMPARE(QGuiApplication::focusWindow(), &window); - - const int id = 0; - compositor->sendTouchDown(surface, QPoint(10, 10), id); - compositor->sendTouchMotion(surface, QPoint(20, 20), id); - compositor->sendTouchFrame(surface); - compositor->waitForStartDrag(); - compositor->sendDataDeviceDataOffer(surface); - compositor->sendDataDeviceEnter(surface, QPoint(20, 20)); - compositor->sendDataDeviceMotion( QPoint(21, 21)); - compositor->sendDataDeviceDrop(surface); - compositor->sendDataDeviceLeave(surface); - QTRY_VERIFY(window.dragStarted); -} - -void tst_WaylandClient::mouseDrag() -{ - DndWindow window; - window.show(); - - QSharedPointer surface; - QTRY_VERIFY(surface = compositor->surface()); - - compositor->setKeyboardFocus(surface); - QTRY_COMPARE(QGuiApplication::focusWindow(), &window); - - compositor->sendMousePress(surface, QPoint(10, 10)); - compositor->sendDataDeviceDataOffer(surface); - compositor->sendDataDeviceEnter(surface, QPoint(20, 20)); - compositor->sendDataDeviceMotion( QPoint(21, 21)); - compositor->waitForStartDrag(); - compositor->sendDataDeviceDrop(surface); - compositor->sendDataDeviceLeave(surface); - QTRY_VERIFY(window.dragStarted); -} - -int main(int argc, char **argv) -{ - setenv("XDG_RUNTIME_DIR", ".", 1); - setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin - - // wayland-egl hangs in the test setup when we try to initialize. Until it gets - // figured out, avoid clientBufferIntegration() from being called in - // QWaylandWindow::createDecorations(). - setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1); - - MockCompositor compositor; - compositor.setOutputGeometry(QRect(QPoint(), screenSize)); - - QGuiApplication app(argc, argv); - compositor.applicationInitialized(); - - tst_WaylandClient tc(&compositor); - return QTest::qExec(&tc, argc, argv); -} - -#include diff --git a/tests/auto/compositor/BLACKLIST b/tests/auto/compositor/BLACKLIST deleted file mode 100644 index df4672be3..000000000 --- a/tests/auto/compositor/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[keyboardGrab] -ubuntu-14.04 diff --git a/tests/auto/compositor/compositor.pro b/tests/auto/compositor/compositor.pro index 035beeb41..6bf2aef6c 100644 --- a/tests/auto/compositor/compositor.pro +++ b/tests/auto/compositor/compositor.pro @@ -1,34 +1,3 @@ -CONFIG += testcase link_pkgconfig -TARGET = tst_compositor +TEMPLATE=subdirs -QT += testlib -QT += core-private gui-private compositor compositor-private - -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += wayland-client wayland-server -} else { - LIBS += -lwayland-client -lwayland-server -} - -config_xkbcommon { - !contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG_PRIVATE += xkbcommon - } else { - LIBS_PRIVATE += -lxkbcommon - } -} else { - DEFINES += QT_NO_WAYLAND_XKB -} - -SOURCES += tst_compositor.cpp \ - testcompositor.cpp \ - testkeyboardgrabber.cpp \ - mockclient.cpp \ - mockseat.cpp \ - testinputdevice.cpp - -HEADERS += testcompositor.h \ - testkeyboardgrabber.h \ - mockclient.h \ - mockseat.h \ - testinputdevice.h +SUBDIRS += compositor diff --git a/tests/auto/compositor/compositor/BLACKLIST b/tests/auto/compositor/compositor/BLACKLIST new file mode 100644 index 000000000..df4672be3 --- /dev/null +++ b/tests/auto/compositor/compositor/BLACKLIST @@ -0,0 +1,2 @@ +[keyboardGrab] +ubuntu-14.04 diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro new file mode 100644 index 000000000..39d2179ad --- /dev/null +++ b/tests/auto/compositor/compositor/compositor.pro @@ -0,0 +1,36 @@ +CONFIG += testcase link_pkgconfig +TARGET = tst_compositor + +QT += testlib +QT += core-private gui-private compositor compositor-private + +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += wayland-client wayland-server +} else { + LIBS += -lwayland-client -lwayland-server +} + +config_xkbcommon { + !contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG_PRIVATE += xkbcommon + } else { + LIBS_PRIVATE += -lxkbcommon + } +} else { + DEFINES += QT_NO_WAYLAND_XKB +} + +SOURCES += \ + tst_compositor.cpp \ + testcompositor.cpp \ + testkeyboardgrabber.cpp \ + mockclient.cpp \ + mockseat.cpp \ + testinputdevice.cpp + +HEADERS += \ + testcompositor.h \ + testkeyboardgrabber.h \ + mockclient.h \ + mockseat.h \ + testinputdevice.h diff --git a/tests/auto/compositor/compositor/mockclient.cpp b/tests/auto/compositor/compositor/mockclient.cpp new file mode 100644 index 000000000..33847da7d --- /dev/null +++ b/tests/auto/compositor/compositor/mockclient.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockclient.h" +#include "mockseat.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +const struct wl_registry_listener MockClient::registryListener = { + MockClient::handleGlobal +}; + +MockClient::MockClient() + : display(wl_display_connect(0)) + , compositor(0) + , output(0) + , registry(0) + , wlshell(0) +{ + if (!display) + qFatal("MockClient(): wl_display_connect() failed"); + + registry = wl_display_get_registry(display); + wl_registry_add_listener(registry, ®istryListener, this); + + fd = wl_display_get_fd(display); + + QSocketNotifier *readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); + connect(readNotifier, SIGNAL(activated(int)), this, SLOT(readEvents())); + + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; + connect(dispatcher, SIGNAL(awake()), this, SLOT(flushDisplay())); + + QElapsedTimer timeout; + timeout.start(); + do { + QCoreApplication::processEvents(); + } while (!(compositor && output) && timeout.elapsed() < 1000); + + if (!compositor || !output) + qFatal("MockClient(): failed to receive globals from display"); +} + +const wl_output_listener MockClient::outputListener = { + MockClient::outputGeometryEvent, + MockClient::outputModeEvent, + MockClient::outputDone, + MockClient::outputScale +}; + +MockClient::~MockClient() +{ + wl_display_disconnect(display); +} + +void MockClient::outputGeometryEvent(void *data, wl_output *, + int32_t x, int32_t y, + int32_t width, int32_t height, + int, const char *, const char *, + int32_t ) +{ + resolve(data)->geometry.moveTopLeft(QPoint(x, y)); +} + +void MockClient::outputModeEvent(void *data, wl_output *, uint32_t, + int w, int h, int) +{ + resolve(data)->geometry.setSize(QSize(w, h)); +} + +void MockClient::outputDone(void *, wl_output *) +{ + +} + +void MockClient::outputScale(void *, wl_output *, int) +{ + +} + +void MockClient::readEvents() +{ + wl_display_dispatch(display); +} + +void MockClient::flushDisplay() +{ + wl_display_dispatch_pending(display); + wl_display_flush(display); +} + +void MockClient::handleGlobal(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) +{ + resolve(data)->handleGlobal(id, QByteArray(interface)); +} + +void MockClient::handleGlobal(uint32_t id, const QByteArray &interface) +{ + if (interface == "wl_compositor") { + compositor = static_cast(wl_registry_bind(registry, id, &wl_compositor_interface, 1)); + } else if (interface == "wl_output") { + output = static_cast(wl_registry_bind(registry, id, &wl_output_interface, 2)); + wl_output_add_listener(output, &outputListener, this); + } else if (interface == "wl_shm") { + shm = static_cast(wl_registry_bind(registry, id, &wl_shm_interface, 1)); + } else if (interface == "wl_shell") { + wlshell = static_cast(wl_registry_bind(registry, id, &wl_shell_interface, 1)); + } else if (interface == "wl_seat") { + wl_seat *s = static_cast(wl_registry_bind(registry, id, &wl_seat_interface, 1)); + m_seats << new MockSeat(s); + } +} + +wl_surface *MockClient::createSurface() +{ + flushDisplay(); + return wl_compositor_create_surface(compositor); +} + +wl_shell_surface *MockClient::createShellSurface(wl_surface *surface) +{ + flushDisplay(); + return wl_shell_get_shell_surface(wlshell, surface); +} + +ShmBuffer::ShmBuffer(const QSize &size, wl_shm *shm) + : handle(0) +{ + int stride = size.width() * 4; + int alloc = stride * size.height(); + + char filename[] = "/tmp/wayland-shm-XXXXXX"; + + int fd = mkstemp(filename); + if (fd < 0) { + qWarning("open %s failed: %s", filename, strerror(errno)); + return; + } + + if (ftruncate(fd, alloc) < 0) { + qWarning("ftruncate failed: %s", strerror(errno)); + close(fd); + return; + } + + void *data = mmap(0, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + unlink(filename); + + if (data == MAP_FAILED) { + qWarning("mmap failed: %s", strerror(errno)); + close(fd); + return; + } + + image = QImage(static_cast(data), size.width(), size.height(), stride, QImage::Format_ARGB32); + shm_pool = wl_shm_create_pool(shm,fd,alloc); + handle = wl_shm_pool_create_buffer(shm_pool,0, size.width(), size.height(), + stride, WL_SHM_FORMAT_ARGB8888); + close(fd); +} + +ShmBuffer::~ShmBuffer() +{ + munmap(image.bits(), image.byteCount()); + wl_buffer_destroy(handle); + wl_shm_pool_destroy(shm_pool); +} + diff --git a/tests/auto/compositor/compositor/mockclient.h b/tests/auto/compositor/compositor/mockclient.h new file mode 100644 index 000000000..8647205f2 --- /dev/null +++ b/tests/auto/compositor/compositor/mockclient.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include +#include + +class MockSeat; + +class ShmBuffer +{ +public: + ShmBuffer(const QSize &size, wl_shm *shm); + ~ShmBuffer(); + + struct wl_buffer *handle; + struct wl_shm_pool *shm_pool; + QImage image; +}; + +class MockClient : public QObject +{ + Q_OBJECT + +public: + MockClient(); + ~MockClient(); + + wl_surface *createSurface(); + wl_shell_surface *createShellSurface(wl_surface *surface); + + wl_display *display; + wl_compositor *compositor; + wl_output *output; + wl_shm *shm; + wl_registry *registry; + wl_shell *wlshell; + + QList m_seats; + + QRect geometry; + + int fd; + +private slots: + void readEvents(); + void flushDisplay(); + +private: + static MockClient *resolve(void *data) { return static_cast(data); } + static const struct wl_registry_listener registryListener; + static void handleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version); + static int sourceUpdate(uint32_t mask, void *data); + + static void outputGeometryEvent(void *data, + wl_output *output, + int32_t x, int32_t y, + int32_t width, int32_t height, + int subpixel, + const char *make, + const char *model, + int32_t transform); + + static void outputModeEvent(void *data, + wl_output *wl_output, + uint32_t flags, + int width, + int height, + int refresh); + static void outputDone(void *data, wl_output *output); + static void outputScale(void *data, wl_output *output, int factor); + + void handleGlobal(uint32_t id, const QByteArray &interface); + + static const wl_output_listener outputListener; +}; + diff --git a/tests/auto/compositor/compositor/mockseat.cpp b/tests/auto/compositor/compositor/mockseat.cpp new file mode 100644 index 000000000..ebf387f94 --- /dev/null +++ b/tests/auto/compositor/compositor/mockseat.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2014 LG Electronics Ltd., author: +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockseat.h" + +MockSeat::MockSeat(wl_seat *seat) + : m_seat(seat) +{ + // Bind to the keyboard interface so that the compositor has + // the right resource associations + m_keyboard = wl_seat_get_keyboard(seat); +} + +MockSeat::~MockSeat() +{ + wl_keyboard_destroy(m_keyboard); + wl_seat_destroy(m_seat); +} diff --git a/tests/auto/compositor/compositor/mockseat.h b/tests/auto/compositor/compositor/mockseat.h new file mode 100644 index 000000000..24399a448 --- /dev/null +++ b/tests/auto/compositor/compositor/mockseat.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2014 LG Electronics Ltd., author: +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef MOCKSEAT +#define MOCKSEAT + +#include +#include + +class MockSeat : public QObject +{ + Q_OBJECT + +public: + MockSeat(wl_seat *seat); + ~MockSeat(); + + wl_seat *m_seat; + wl_keyboard *m_keyboard; +}; +#endif diff --git a/tests/auto/compositor/compositor/testcompositor.cpp b/tests/auto/compositor/compositor/testcompositor.cpp new file mode 100644 index 000000000..95dd87e3c --- /dev/null +++ b/tests/auto/compositor/compositor/testcompositor.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testcompositor.h" + +TestCompositor::TestCompositor(QWaylandCompositor::ExtensionFlag flags) : QWaylandCompositor(0, flags) +{ + createOutput(0, "", ""); + addDefaultShell(); +} + +void TestCompositor::surfaceCreated(QWaylandSurface *surface) +{ + surfaces << surface; +} + +void TestCompositor::surfaceAboutToBeDestroyed(QWaylandSurface *surface) +{ + surfaces.removeOne(surface); +} + + diff --git a/tests/auto/compositor/compositor/testcompositor.h b/tests/auto/compositor/compositor/testcompositor.h new file mode 100644 index 000000000..c7d571d23 --- /dev/null +++ b/tests/auto/compositor/compositor/testcompositor.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandcompositor.h" +#include "qwaylandsurface.h" + +class TestCompositor : public QWaylandCompositor +{ +public: + TestCompositor(QWaylandCompositor::ExtensionFlag flags = QWaylandCompositor::DefaultExtensions); + + void surfaceCreated(QWaylandSurface *surface); + void surfaceAboutToBeDestroyed(QWaylandSurface *surface); + + QList surfaces; +}; + diff --git a/tests/auto/compositor/compositor/testinputdevice.cpp b/tests/auto/compositor/compositor/testinputdevice.cpp new file mode 100644 index 000000000..db2d1d706 --- /dev/null +++ b/tests/auto/compositor/compositor/testinputdevice.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2014 LG Electronics, Inc., author: +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testinputdevice.h" + +#include + +TestInputDevice::TestInputDevice(QWaylandCompositor *compositor, QWaylandInputDevice::CapabilityFlags caps) + : QWaylandInputDevice(compositor, caps) +{ + m_queryCount = 0; +} + +TestInputDevice::~TestInputDevice() +{ +} + +bool TestInputDevice::isOwner(QInputEvent *event) +{ + m_queryCount++; + QMouseEvent *me = dynamic_cast(event); + return m_events.contains(me); +} + +QList TestInputDevice::createMouseEvents(int count) +{ + for (int i = 0; i < count; i++) { + m_events.append(new QMouseEvent(QEvent::MouseMove, QPointF(10 + i, 10 + i), Qt::NoButton, Qt::NoButton, Qt::NoModifier)); + } + return m_events; +} + diff --git a/tests/auto/compositor/compositor/testinputdevice.h b/tests/auto/compositor/compositor/testinputdevice.h new file mode 100644 index 000000000..df5c646d1 --- /dev/null +++ b/tests/auto/compositor/compositor/testinputdevice.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2014 LG Electronics, Inc., author: +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +QT_BEGIN_NAMESPACE +class QInputEvent; +class QMouseEvent; +QT_END_NAMESPACE + +class TestInputDevice : public QWaylandInputDevice +{ + +public: + + TestInputDevice(QWaylandCompositor *compositor, QWaylandInputDevice::CapabilityFlags caps); + ~TestInputDevice(); + + bool isOwner(QInputEvent *event); + + QList createMouseEvents(int count); + + int queryCount() { return m_queryCount; } + +private: + int m_queryCount; + QList m_events; +}; diff --git a/tests/auto/compositor/compositor/testkeyboardgrabber.cpp b/tests/auto/compositor/compositor/testkeyboardgrabber.cpp new file mode 100644 index 000000000..da2f467d9 --- /dev/null +++ b/tests/auto/compositor/compositor/testkeyboardgrabber.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2014 LG Electronics, Inc., author: +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testkeyboardgrabber.h" + +namespace QtWayland { + KeyboardGrabber::~KeyboardGrabber() {} +} + +void TestKeyboardGrabber::focused(QtWayland::Surface *surface) +{ + Q_UNUSED(surface); + Q_EMIT focusedCalled(); +} + +void TestKeyboardGrabber::key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + Q_UNUSED(serial); + Q_UNUSED(time); + Q_UNUSED(key); + Q_UNUSED(state); + Q_EMIT keyCalled(); +} + +void TestKeyboardGrabber::modifiers(uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + Q_UNUSED(serial); + Q_UNUSED(mods_depressed); + Q_UNUSED(mods_latched); + Q_UNUSED(mods_locked); + Q_UNUSED(group); + Q_EMIT modifiersCalled(); +} + diff --git a/tests/auto/compositor/compositor/testkeyboardgrabber.h b/tests/auto/compositor/compositor/testkeyboardgrabber.h new file mode 100644 index 000000000..0ce56b1a7 --- /dev/null +++ b/tests/auto/compositor/compositor/testkeyboardgrabber.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2014 LG Electronics, Inc., author: +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "QtCompositor/private/qwlkeyboard_p.h" +#include "QtCompositor/private/qwlsurface_p.h" + +class TestKeyboardGrabber : public QObject, public QtWayland::KeyboardGrabber +{ + Q_OBJECT + +public: + + TestKeyboardGrabber() {} + ~TestKeyboardGrabber() {} + + void focused(QtWayland::Surface *surface); + void key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state); + void modifiers(uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group); + +signals: + void focusedCalled(); + void keyCalled(); + void modifiersCalled(); +}; + + diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp new file mode 100644 index 000000000..c30ebc02b --- /dev/null +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockclient.h" +#include "testcompositor.h" +#include "testkeyboardgrabber.h" + +#include "QtCompositor/private/qwlkeyboard_p.h" +#include "QtCompositor/private/qwlinputdevice_p.h" +#include "QtCompositor/private/qwlcompositor_p.h" +#include "testinputdevice.h" + +#include "qwaylandbufferref.h" + +#include + +#include + +class tst_WaylandCompositor : public QObject +{ + Q_OBJECT + +public: + tst_WaylandCompositor() { + setenv("XDG_RUNTIME_DIR", ".", 1); + } + +private slots: + void inputDeviceCapabilities(); + void keyboardGrab(); + void inputDeviceCreation(); + void inputDeviceKeyboardFocus(); + void singleClient(); + void multipleClients(); + void geometry(); + void mapSurface(); + void frameCallback(); +}; + +void tst_WaylandCompositor::singleClient() +{ + TestCompositor compositor; + + MockClient client; + + wl_surface *sa = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + wl_surface *sb = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 2); + + QWaylandClient *ca = compositor.surfaces.at(0)->client(); + QWaylandClient *cb = compositor.surfaces.at(1)->client(); + + QCOMPARE(ca, cb); + QVERIFY(ca != 0); + + QList surfaces = compositor.surfacesForClient(ca); + QCOMPARE(surfaces.size(), 2); + QVERIFY((surfaces.at(0) == compositor.surfaces.at(0) && surfaces.at(1) == compositor.surfaces.at(1)) + || (surfaces.at(0) == compositor.surfaces.at(1) && surfaces.at(1) == compositor.surfaces.at(0))); + + wl_surface_destroy(sa); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + wl_surface_destroy(sb); + QTRY_COMPARE(compositor.surfaces.size(), 0); +} + +void tst_WaylandCompositor::multipleClients() +{ + TestCompositor compositor; + + MockClient a; + MockClient b; + MockClient c; + + wl_surface *sa = a.createSurface(); + wl_surface *sb = b.createSurface(); + wl_surface *sc = c.createSurface(); + + QTRY_COMPARE(compositor.surfaces.size(), 3); + + QWaylandClient *ca = compositor.surfaces.at(0)->client(); + QWaylandClient *cb = compositor.surfaces.at(1)->client(); + QWaylandClient *cc = compositor.surfaces.at(2)->client(); + + QVERIFY(ca != cb); + QVERIFY(ca != cc); + QVERIFY(cb != cc); + QVERIFY(ca != 0); + + QCOMPARE(compositor.surfacesForClient(ca).size(), 1); + QCOMPARE(compositor.surfacesForClient(ca).at(0), compositor.surfaces.at(0)); + + QCOMPARE(compositor.surfacesForClient(cb).size(), 1); + QCOMPARE(compositor.surfacesForClient(cb).at(0), compositor.surfaces.at(1)); + + QCOMPARE(compositor.surfacesForClient(cc).size(), 1); + QCOMPARE(compositor.surfacesForClient(cc).at(0), compositor.surfaces.at(2)); + + wl_surface_destroy(sa); + wl_surface_destroy(sb); + wl_surface_destroy(sc); + + QTRY_COMPARE(compositor.surfaces.size(), 0); +} + +void tst_WaylandCompositor::keyboardGrab() +{ + TestCompositor compositor((QWaylandCompositor::ExtensionFlag)0); + MockClient mc; + + mc.createSurface(); + // This is needed for timing purposes, otherwise the query for the + // compositor surfaces will return null + QTRY_COMPARE(compositor.surfaces.size(), 1); + + // Set the focused surface so that key event will flow through + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + QWaylandInputDevice* inputDevice = compositor.defaultInputDevice(); + inputDevice->handle()->keyboardDevice()->setFocus(waylandSurface->handle()); + + TestKeyboardGrabber grab; + QSignalSpy grabFocusSpy(&grab, SIGNAL(focusedCalled())); + QSignalSpy grabKeySpy(&grab, SIGNAL(keyCalled())); + QSignalSpy grabModifierSpy(&grab, SIGNAL(modifiersCalled())); + + QtWayland::Keyboard *keyboard = inputDevice->handle()->keyboardDevice(); + keyboard->startGrab(&grab); + + QTRY_COMPARE(grabFocusSpy.count(), 1); + QCOMPARE(grab.m_keyboard, inputDevice->handle()->keyboardDevice()); + + QKeyEvent ke(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, 30, 0, 0); + QKeyEvent ke1(QEvent::KeyRelease, Qt::Key_A, Qt::NoModifier, 30, 0, 0); + inputDevice->sendFullKeyEvent(&ke); + inputDevice->sendFullKeyEvent(&ke1); + QTRY_COMPARE(grabKeySpy.count(), 2); + + QKeyEvent ke2(QEvent::KeyPress, Qt::Key_Shift, Qt::NoModifier, 50, 0, 0); + QKeyEvent ke3(QEvent::KeyRelease, Qt::Key_Shift, Qt::NoModifier, 50, 0, 0); + inputDevice->sendFullKeyEvent(&ke2); + inputDevice->sendFullKeyEvent(&ke3); + QTRY_COMPARE(grabModifierSpy.count(), 2); + // Modifiers are also keys + QTRY_COMPARE(grabKeySpy.count(), 4); + + // Stop grabbing + keyboard->endGrab(); + inputDevice->sendFullKeyEvent(&ke); + inputDevice->sendFullKeyEvent(&ke1); + QTRY_COMPARE(grabKeySpy.count(), 4); +} + +void tst_WaylandCompositor::geometry() +{ + TestCompositor compositor; + + QRect geometry(0, 0, 4096, 3072); + compositor.setOutputGeometry(geometry); + + MockClient client; + + QTRY_COMPARE(client.geometry, geometry); +} + +void tst_WaylandCompositor::mapSurface() +{ + TestCompositor compositor; + + MockClient client; + + wl_surface *surface = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + + QSignalSpy mappedSpy(waylandSurface, SIGNAL(mapped())); + + QCOMPARE(waylandSurface->size(), QSize()); + QCOMPARE(waylandSurface->type(), QWaylandSurface::Invalid); + + QSize size(256, 256); + ShmBuffer buffer(size, client.shm); + + // we need to create a shell surface here or the surface won't be mapped + client.createShellSurface(surface); + wl_surface_attach(surface, buffer.handle, 0, 0); + wl_surface_damage(surface, 0, 0, size.width(), size.height()); + wl_surface_commit(surface); + + QTRY_COMPARE(waylandSurface->size(), size); + QTRY_COMPARE(waylandSurface->type(), QWaylandSurface::Shm); + QTRY_COMPARE(mappedSpy.count(), 1); + + wl_surface_destroy(surface); +} + +static void frameCallbackFunc(void *data, wl_callback *callback, uint32_t) +{ + ++*static_cast(data); + wl_callback_destroy(callback); +} + +static void registerFrameCallback(wl_surface *surface, int *counter) +{ + static const wl_callback_listener frameCallbackListener = { + frameCallbackFunc + }; + + wl_callback_add_listener(wl_surface_frame(surface), &frameCallbackListener, counter); +} + +void tst_WaylandCompositor::frameCallback() +{ + class BufferAttacher : public QWaylandBufferAttacher + { + public: + void attach(const QWaylandBufferRef &ref) Q_DECL_OVERRIDE + { + bufferRef = ref; + } + void unmap() Q_DECL_OVERRIDE + { + } + + QImage image() const + { + if (!bufferRef || !bufferRef.isShm()) + return QImage(); + return bufferRef.image(); + } + + QWaylandBufferRef bufferRef; + }; + + TestCompositor compositor; + + MockClient client; + + wl_surface *surface = client.createSurface(); + + int frameCounter = 0; + + QTRY_COMPARE(compositor.surfaces.size(), 1); + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + BufferAttacher attacher; + waylandSurface->setBufferAttacher(&attacher); + QSignalSpy damagedSpy(waylandSurface, SIGNAL(damaged(const QRegion &))); + + for (int i = 0; i < 10; ++i) { + QSize size(i * 8 + 2, i * 8 + 2); + ShmBuffer buffer(size, client.shm); + + // attach a new buffer every frame, else the damage signal won't be fired + wl_surface_attach(surface, buffer.handle, 0, 0); + registerFrameCallback(surface, &frameCounter); + wl_surface_damage(surface, 0, 0, size.width(), size.height()); + wl_surface_commit(surface); + + QTRY_COMPARE(waylandSurface->type(), QWaylandSurface::Shm); + QTRY_COMPARE(damagedSpy.count(), i + 1); + + QCOMPARE(static_cast(waylandSurface->bufferAttacher())->image(), buffer.image); + compositor.frameStarted(); + compositor.sendFrameCallbacks(QList() << waylandSurface); + + QTRY_COMPARE(frameCounter, i + 1); + } + + wl_surface_destroy(surface); +} + +void tst_WaylandCompositor::inputDeviceCapabilities() +{ + TestCompositor compositor; + QtWayland::InputDevice dev(NULL, compositor.handle(), QWaylandInputDevice::Pointer); + + QTRY_VERIFY(dev.pointerDevice()); + QTRY_VERIFY(!dev.keyboardDevice()); + QTRY_VERIFY(!dev.touchDevice()); + + dev.setCapabilities(QWaylandInputDevice::Keyboard | QWaylandInputDevice::Touch); + QTRY_VERIFY(!dev.pointerDevice()); + QTRY_VERIFY(dev.keyboardDevice()); + QTRY_VERIFY(dev.touchDevice()); + + // Test that existing devices do not change when another is removed + QtWayland::Keyboard *k = dev.keyboardDevice(); + dev.setCapabilities(QWaylandInputDevice::Keyboard); + QTRY_COMPARE(k, dev.keyboardDevice()); +} + +void tst_WaylandCompositor::inputDeviceCreation() +{ + TestCompositor compositor; + TestInputDevice dev1(&compositor, QWaylandInputDevice::Pointer | QWaylandInputDevice::Keyboard); + TestInputDevice dev2(&compositor, QWaylandInputDevice::Pointer | QWaylandInputDevice::Keyboard); + + compositor.handle()->registerInputDevice(&dev1); + compositor.handle()->registerInputDevice(&dev2); + + // The compositor will create the default input device + QTRY_COMPARE(compositor.handle()->inputDevices().count(), 3); + // Test the order + QTRY_COMPARE(compositor.handle()->inputDevices().at(0), &dev2); + QTRY_COMPARE(compositor.handle()->inputDevices().at(1), &dev1); + QTRY_COMPARE(compositor.handle()->inputDevices().at(2), compositor.defaultInputDevice()); + + QList allEvents; + allEvents += dev1.createMouseEvents(2); + allEvents += dev2.createMouseEvents(5); + foreach (QMouseEvent *me, allEvents) { + compositor.inputDeviceFor(me); + } + + // The first input device will only get called exatly the number of times it has created + // the events + QTRY_COMPARE(dev1.queryCount(), 2); + // The second will get called the total number of times as it sits as the first item in + // the registered input devices list + QTRY_COMPARE(dev2.queryCount(), 7); +} + +void tst_WaylandCompositor::inputDeviceKeyboardFocus() +{ + TestCompositor compositor; + + + TestInputDevice dev1(&compositor, QWaylandInputDevice::Keyboard); + TestInputDevice dev2(&compositor, QWaylandInputDevice::Keyboard); + + compositor.handle()->registerInputDevice(&dev1); + compositor.handle()->registerInputDevice(&dev2); + + // Create client after all the input devices have been set up as the mock client + // does not dynamically listen to new seats + MockClient client; + wl_surface *surface = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + QList devices = compositor.handle()->inputDevices(); + foreach (QWaylandInputDevice *dev, devices) { + dev->setKeyboardFocus(waylandSurface); + } + QTRY_COMPARE(compositor.defaultInputDevice()->keyboardFocus(), waylandSurface); + QTRY_COMPARE(dev1.keyboardFocus(), waylandSurface); + QTRY_COMPARE(dev2.keyboardFocus(), waylandSurface); + + wl_surface_destroy(surface); + QTRY_VERIFY(compositor.surfaces.size() == 0); + // This will normally be called for example in the quick compositor + // but here call it manually to get rid of the surface and have it reset + // the focus + compositor.handle()->cleanupGraphicsResources(); + + QTRY_VERIFY(!compositor.defaultInputDevice()->keyboardFocus()); + QTRY_VERIFY(!dev1.keyboardFocus()); + QTRY_VERIFY(!dev2.keyboardFocus()); +} + +#include +QTEST_MAIN(tst_WaylandCompositor); diff --git a/tests/auto/compositor/mockclient.cpp b/tests/auto/compositor/mockclient.cpp deleted file mode 100644 index 33847da7d..000000000 --- a/tests/auto/compositor/mockclient.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockclient.h" -#include "mockseat.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include - -const struct wl_registry_listener MockClient::registryListener = { - MockClient::handleGlobal -}; - -MockClient::MockClient() - : display(wl_display_connect(0)) - , compositor(0) - , output(0) - , registry(0) - , wlshell(0) -{ - if (!display) - qFatal("MockClient(): wl_display_connect() failed"); - - registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istryListener, this); - - fd = wl_display_get_fd(display); - - QSocketNotifier *readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(readNotifier, SIGNAL(activated(int)), this, SLOT(readEvents())); - - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; - connect(dispatcher, SIGNAL(awake()), this, SLOT(flushDisplay())); - - QElapsedTimer timeout; - timeout.start(); - do { - QCoreApplication::processEvents(); - } while (!(compositor && output) && timeout.elapsed() < 1000); - - if (!compositor || !output) - qFatal("MockClient(): failed to receive globals from display"); -} - -const wl_output_listener MockClient::outputListener = { - MockClient::outputGeometryEvent, - MockClient::outputModeEvent, - MockClient::outputDone, - MockClient::outputScale -}; - -MockClient::~MockClient() -{ - wl_display_disconnect(display); -} - -void MockClient::outputGeometryEvent(void *data, wl_output *, - int32_t x, int32_t y, - int32_t width, int32_t height, - int, const char *, const char *, - int32_t ) -{ - resolve(data)->geometry.moveTopLeft(QPoint(x, y)); -} - -void MockClient::outputModeEvent(void *data, wl_output *, uint32_t, - int w, int h, int) -{ - resolve(data)->geometry.setSize(QSize(w, h)); -} - -void MockClient::outputDone(void *, wl_output *) -{ - -} - -void MockClient::outputScale(void *, wl_output *, int) -{ - -} - -void MockClient::readEvents() -{ - wl_display_dispatch(display); -} - -void MockClient::flushDisplay() -{ - wl_display_dispatch_pending(display); - wl_display_flush(display); -} - -void MockClient::handleGlobal(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) -{ - resolve(data)->handleGlobal(id, QByteArray(interface)); -} - -void MockClient::handleGlobal(uint32_t id, const QByteArray &interface) -{ - if (interface == "wl_compositor") { - compositor = static_cast(wl_registry_bind(registry, id, &wl_compositor_interface, 1)); - } else if (interface == "wl_output") { - output = static_cast(wl_registry_bind(registry, id, &wl_output_interface, 2)); - wl_output_add_listener(output, &outputListener, this); - } else if (interface == "wl_shm") { - shm = static_cast(wl_registry_bind(registry, id, &wl_shm_interface, 1)); - } else if (interface == "wl_shell") { - wlshell = static_cast(wl_registry_bind(registry, id, &wl_shell_interface, 1)); - } else if (interface == "wl_seat") { - wl_seat *s = static_cast(wl_registry_bind(registry, id, &wl_seat_interface, 1)); - m_seats << new MockSeat(s); - } -} - -wl_surface *MockClient::createSurface() -{ - flushDisplay(); - return wl_compositor_create_surface(compositor); -} - -wl_shell_surface *MockClient::createShellSurface(wl_surface *surface) -{ - flushDisplay(); - return wl_shell_get_shell_surface(wlshell, surface); -} - -ShmBuffer::ShmBuffer(const QSize &size, wl_shm *shm) - : handle(0) -{ - int stride = size.width() * 4; - int alloc = stride * size.height(); - - char filename[] = "/tmp/wayland-shm-XXXXXX"; - - int fd = mkstemp(filename); - if (fd < 0) { - qWarning("open %s failed: %s", filename, strerror(errno)); - return; - } - - if (ftruncate(fd, alloc) < 0) { - qWarning("ftruncate failed: %s", strerror(errno)); - close(fd); - return; - } - - void *data = mmap(0, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - unlink(filename); - - if (data == MAP_FAILED) { - qWarning("mmap failed: %s", strerror(errno)); - close(fd); - return; - } - - image = QImage(static_cast(data), size.width(), size.height(), stride, QImage::Format_ARGB32); - shm_pool = wl_shm_create_pool(shm,fd,alloc); - handle = wl_shm_pool_create_buffer(shm_pool,0, size.width(), size.height(), - stride, WL_SHM_FORMAT_ARGB8888); - close(fd); -} - -ShmBuffer::~ShmBuffer() -{ - munmap(image.bits(), image.byteCount()); - wl_buffer_destroy(handle); - wl_shm_pool_destroy(shm_pool); -} - diff --git a/tests/auto/compositor/mockclient.h b/tests/auto/compositor/mockclient.h deleted file mode 100644 index 8647205f2..000000000 --- a/tests/auto/compositor/mockclient.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include -#include -#include - -class MockSeat; - -class ShmBuffer -{ -public: - ShmBuffer(const QSize &size, wl_shm *shm); - ~ShmBuffer(); - - struct wl_buffer *handle; - struct wl_shm_pool *shm_pool; - QImage image; -}; - -class MockClient : public QObject -{ - Q_OBJECT - -public: - MockClient(); - ~MockClient(); - - wl_surface *createSurface(); - wl_shell_surface *createShellSurface(wl_surface *surface); - - wl_display *display; - wl_compositor *compositor; - wl_output *output; - wl_shm *shm; - wl_registry *registry; - wl_shell *wlshell; - - QList m_seats; - - QRect geometry; - - int fd; - -private slots: - void readEvents(); - void flushDisplay(); - -private: - static MockClient *resolve(void *data) { return static_cast(data); } - static const struct wl_registry_listener registryListener; - static void handleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version); - static int sourceUpdate(uint32_t mask, void *data); - - static void outputGeometryEvent(void *data, - wl_output *output, - int32_t x, int32_t y, - int32_t width, int32_t height, - int subpixel, - const char *make, - const char *model, - int32_t transform); - - static void outputModeEvent(void *data, - wl_output *wl_output, - uint32_t flags, - int width, - int height, - int refresh); - static void outputDone(void *data, wl_output *output); - static void outputScale(void *data, wl_output *output, int factor); - - void handleGlobal(uint32_t id, const QByteArray &interface); - - static const wl_output_listener outputListener; -}; - diff --git a/tests/auto/compositor/mockseat.cpp b/tests/auto/compositor/mockseat.cpp deleted file mode 100644 index ebf387f94..000000000 --- a/tests/auto/compositor/mockseat.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 LG Electronics Ltd., author: -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockseat.h" - -MockSeat::MockSeat(wl_seat *seat) - : m_seat(seat) -{ - // Bind to the keyboard interface so that the compositor has - // the right resource associations - m_keyboard = wl_seat_get_keyboard(seat); -} - -MockSeat::~MockSeat() -{ - wl_keyboard_destroy(m_keyboard); - wl_seat_destroy(m_seat); -} diff --git a/tests/auto/compositor/mockseat.h b/tests/auto/compositor/mockseat.h deleted file mode 100644 index 24399a448..000000000 --- a/tests/auto/compositor/mockseat.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 LG Electronics Ltd., author: -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef MOCKSEAT -#define MOCKSEAT - -#include -#include - -class MockSeat : public QObject -{ - Q_OBJECT - -public: - MockSeat(wl_seat *seat); - ~MockSeat(); - - wl_seat *m_seat; - wl_keyboard *m_keyboard; -}; -#endif diff --git a/tests/auto/compositor/testcompositor.cpp b/tests/auto/compositor/testcompositor.cpp deleted file mode 100644 index 95dd87e3c..000000000 --- a/tests/auto/compositor/testcompositor.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "testcompositor.h" - -TestCompositor::TestCompositor(QWaylandCompositor::ExtensionFlag flags) : QWaylandCompositor(0, flags) -{ - createOutput(0, "", ""); - addDefaultShell(); -} - -void TestCompositor::surfaceCreated(QWaylandSurface *surface) -{ - surfaces << surface; -} - -void TestCompositor::surfaceAboutToBeDestroyed(QWaylandSurface *surface) -{ - surfaces.removeOne(surface); -} - - diff --git a/tests/auto/compositor/testcompositor.h b/tests/auto/compositor/testcompositor.h deleted file mode 100644 index c7d571d23..000000000 --- a/tests/auto/compositor/testcompositor.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandcompositor.h" -#include "qwaylandsurface.h" - -class TestCompositor : public QWaylandCompositor -{ -public: - TestCompositor(QWaylandCompositor::ExtensionFlag flags = QWaylandCompositor::DefaultExtensions); - - void surfaceCreated(QWaylandSurface *surface); - void surfaceAboutToBeDestroyed(QWaylandSurface *surface); - - QList surfaces; -}; - diff --git a/tests/auto/compositor/testinputdevice.cpp b/tests/auto/compositor/testinputdevice.cpp deleted file mode 100644 index db2d1d706..000000000 --- a/tests/auto/compositor/testinputdevice.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 LG Electronics, Inc., author: -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "testinputdevice.h" - -#include - -TestInputDevice::TestInputDevice(QWaylandCompositor *compositor, QWaylandInputDevice::CapabilityFlags caps) - : QWaylandInputDevice(compositor, caps) -{ - m_queryCount = 0; -} - -TestInputDevice::~TestInputDevice() -{ -} - -bool TestInputDevice::isOwner(QInputEvent *event) -{ - m_queryCount++; - QMouseEvent *me = dynamic_cast(event); - return m_events.contains(me); -} - -QList TestInputDevice::createMouseEvents(int count) -{ - for (int i = 0; i < count; i++) { - m_events.append(new QMouseEvent(QEvent::MouseMove, QPointF(10 + i, 10 + i), Qt::NoButton, Qt::NoButton, Qt::NoModifier)); - } - return m_events; -} - diff --git a/tests/auto/compositor/testinputdevice.h b/tests/auto/compositor/testinputdevice.h deleted file mode 100644 index df5c646d1..000000000 --- a/tests/auto/compositor/testinputdevice.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 LG Electronics, Inc., author: -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE -class QInputEvent; -class QMouseEvent; -QT_END_NAMESPACE - -class TestInputDevice : public QWaylandInputDevice -{ - -public: - - TestInputDevice(QWaylandCompositor *compositor, QWaylandInputDevice::CapabilityFlags caps); - ~TestInputDevice(); - - bool isOwner(QInputEvent *event); - - QList createMouseEvents(int count); - - int queryCount() { return m_queryCount; } - -private: - int m_queryCount; - QList m_events; -}; diff --git a/tests/auto/compositor/testkeyboardgrabber.cpp b/tests/auto/compositor/testkeyboardgrabber.cpp deleted file mode 100644 index da2f467d9..000000000 --- a/tests/auto/compositor/testkeyboardgrabber.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 LG Electronics, Inc., author: -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "testkeyboardgrabber.h" - -namespace QtWayland { - KeyboardGrabber::~KeyboardGrabber() {} -} - -void TestKeyboardGrabber::focused(QtWayland::Surface *surface) -{ - Q_UNUSED(surface); - Q_EMIT focusedCalled(); -} - -void TestKeyboardGrabber::key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - Q_UNUSED(serial); - Q_UNUSED(time); - Q_UNUSED(key); - Q_UNUSED(state); - Q_EMIT keyCalled(); -} - -void TestKeyboardGrabber::modifiers(uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group) -{ - Q_UNUSED(serial); - Q_UNUSED(mods_depressed); - Q_UNUSED(mods_latched); - Q_UNUSED(mods_locked); - Q_UNUSED(group); - Q_EMIT modifiersCalled(); -} - diff --git a/tests/auto/compositor/testkeyboardgrabber.h b/tests/auto/compositor/testkeyboardgrabber.h deleted file mode 100644 index 0ce56b1a7..000000000 --- a/tests/auto/compositor/testkeyboardgrabber.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 LG Electronics, Inc., author: -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "QtCompositor/private/qwlkeyboard_p.h" -#include "QtCompositor/private/qwlsurface_p.h" - -class TestKeyboardGrabber : public QObject, public QtWayland::KeyboardGrabber -{ - Q_OBJECT - -public: - - TestKeyboardGrabber() {} - ~TestKeyboardGrabber() {} - - void focused(QtWayland::Surface *surface); - void key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state); - void modifiers(uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group); - -signals: - void focusedCalled(); - void keyCalled(); - void modifiersCalled(); -}; - - diff --git a/tests/auto/compositor/tst_compositor.cpp b/tests/auto/compositor/tst_compositor.cpp deleted file mode 100644 index c30ebc02b..000000000 --- a/tests/auto/compositor/tst_compositor.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mockclient.h" -#include "testcompositor.h" -#include "testkeyboardgrabber.h" - -#include "QtCompositor/private/qwlkeyboard_p.h" -#include "QtCompositor/private/qwlinputdevice_p.h" -#include "QtCompositor/private/qwlcompositor_p.h" -#include "testinputdevice.h" - -#include "qwaylandbufferref.h" - -#include - -#include - -class tst_WaylandCompositor : public QObject -{ - Q_OBJECT - -public: - tst_WaylandCompositor() { - setenv("XDG_RUNTIME_DIR", ".", 1); - } - -private slots: - void inputDeviceCapabilities(); - void keyboardGrab(); - void inputDeviceCreation(); - void inputDeviceKeyboardFocus(); - void singleClient(); - void multipleClients(); - void geometry(); - void mapSurface(); - void frameCallback(); -}; - -void tst_WaylandCompositor::singleClient() -{ - TestCompositor compositor; - - MockClient client; - - wl_surface *sa = client.createSurface(); - QTRY_COMPARE(compositor.surfaces.size(), 1); - - wl_surface *sb = client.createSurface(); - QTRY_COMPARE(compositor.surfaces.size(), 2); - - QWaylandClient *ca = compositor.surfaces.at(0)->client(); - QWaylandClient *cb = compositor.surfaces.at(1)->client(); - - QCOMPARE(ca, cb); - QVERIFY(ca != 0); - - QList surfaces = compositor.surfacesForClient(ca); - QCOMPARE(surfaces.size(), 2); - QVERIFY((surfaces.at(0) == compositor.surfaces.at(0) && surfaces.at(1) == compositor.surfaces.at(1)) - || (surfaces.at(0) == compositor.surfaces.at(1) && surfaces.at(1) == compositor.surfaces.at(0))); - - wl_surface_destroy(sa); - QTRY_COMPARE(compositor.surfaces.size(), 1); - - wl_surface_destroy(sb); - QTRY_COMPARE(compositor.surfaces.size(), 0); -} - -void tst_WaylandCompositor::multipleClients() -{ - TestCompositor compositor; - - MockClient a; - MockClient b; - MockClient c; - - wl_surface *sa = a.createSurface(); - wl_surface *sb = b.createSurface(); - wl_surface *sc = c.createSurface(); - - QTRY_COMPARE(compositor.surfaces.size(), 3); - - QWaylandClient *ca = compositor.surfaces.at(0)->client(); - QWaylandClient *cb = compositor.surfaces.at(1)->client(); - QWaylandClient *cc = compositor.surfaces.at(2)->client(); - - QVERIFY(ca != cb); - QVERIFY(ca != cc); - QVERIFY(cb != cc); - QVERIFY(ca != 0); - - QCOMPARE(compositor.surfacesForClient(ca).size(), 1); - QCOMPARE(compositor.surfacesForClient(ca).at(0), compositor.surfaces.at(0)); - - QCOMPARE(compositor.surfacesForClient(cb).size(), 1); - QCOMPARE(compositor.surfacesForClient(cb).at(0), compositor.surfaces.at(1)); - - QCOMPARE(compositor.surfacesForClient(cc).size(), 1); - QCOMPARE(compositor.surfacesForClient(cc).at(0), compositor.surfaces.at(2)); - - wl_surface_destroy(sa); - wl_surface_destroy(sb); - wl_surface_destroy(sc); - - QTRY_COMPARE(compositor.surfaces.size(), 0); -} - -void tst_WaylandCompositor::keyboardGrab() -{ - TestCompositor compositor((QWaylandCompositor::ExtensionFlag)0); - MockClient mc; - - mc.createSurface(); - // This is needed for timing purposes, otherwise the query for the - // compositor surfaces will return null - QTRY_COMPARE(compositor.surfaces.size(), 1); - - // Set the focused surface so that key event will flow through - QWaylandSurface *waylandSurface = compositor.surfaces.at(0); - QWaylandInputDevice* inputDevice = compositor.defaultInputDevice(); - inputDevice->handle()->keyboardDevice()->setFocus(waylandSurface->handle()); - - TestKeyboardGrabber grab; - QSignalSpy grabFocusSpy(&grab, SIGNAL(focusedCalled())); - QSignalSpy grabKeySpy(&grab, SIGNAL(keyCalled())); - QSignalSpy grabModifierSpy(&grab, SIGNAL(modifiersCalled())); - - QtWayland::Keyboard *keyboard = inputDevice->handle()->keyboardDevice(); - keyboard->startGrab(&grab); - - QTRY_COMPARE(grabFocusSpy.count(), 1); - QCOMPARE(grab.m_keyboard, inputDevice->handle()->keyboardDevice()); - - QKeyEvent ke(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, 30, 0, 0); - QKeyEvent ke1(QEvent::KeyRelease, Qt::Key_A, Qt::NoModifier, 30, 0, 0); - inputDevice->sendFullKeyEvent(&ke); - inputDevice->sendFullKeyEvent(&ke1); - QTRY_COMPARE(grabKeySpy.count(), 2); - - QKeyEvent ke2(QEvent::KeyPress, Qt::Key_Shift, Qt::NoModifier, 50, 0, 0); - QKeyEvent ke3(QEvent::KeyRelease, Qt::Key_Shift, Qt::NoModifier, 50, 0, 0); - inputDevice->sendFullKeyEvent(&ke2); - inputDevice->sendFullKeyEvent(&ke3); - QTRY_COMPARE(grabModifierSpy.count(), 2); - // Modifiers are also keys - QTRY_COMPARE(grabKeySpy.count(), 4); - - // Stop grabbing - keyboard->endGrab(); - inputDevice->sendFullKeyEvent(&ke); - inputDevice->sendFullKeyEvent(&ke1); - QTRY_COMPARE(grabKeySpy.count(), 4); -} - -void tst_WaylandCompositor::geometry() -{ - TestCompositor compositor; - - QRect geometry(0, 0, 4096, 3072); - compositor.setOutputGeometry(geometry); - - MockClient client; - - QTRY_COMPARE(client.geometry, geometry); -} - -void tst_WaylandCompositor::mapSurface() -{ - TestCompositor compositor; - - MockClient client; - - wl_surface *surface = client.createSurface(); - QTRY_COMPARE(compositor.surfaces.size(), 1); - - QWaylandSurface *waylandSurface = compositor.surfaces.at(0); - - QSignalSpy mappedSpy(waylandSurface, SIGNAL(mapped())); - - QCOMPARE(waylandSurface->size(), QSize()); - QCOMPARE(waylandSurface->type(), QWaylandSurface::Invalid); - - QSize size(256, 256); - ShmBuffer buffer(size, client.shm); - - // we need to create a shell surface here or the surface won't be mapped - client.createShellSurface(surface); - wl_surface_attach(surface, buffer.handle, 0, 0); - wl_surface_damage(surface, 0, 0, size.width(), size.height()); - wl_surface_commit(surface); - - QTRY_COMPARE(waylandSurface->size(), size); - QTRY_COMPARE(waylandSurface->type(), QWaylandSurface::Shm); - QTRY_COMPARE(mappedSpy.count(), 1); - - wl_surface_destroy(surface); -} - -static void frameCallbackFunc(void *data, wl_callback *callback, uint32_t) -{ - ++*static_cast(data); - wl_callback_destroy(callback); -} - -static void registerFrameCallback(wl_surface *surface, int *counter) -{ - static const wl_callback_listener frameCallbackListener = { - frameCallbackFunc - }; - - wl_callback_add_listener(wl_surface_frame(surface), &frameCallbackListener, counter); -} - -void tst_WaylandCompositor::frameCallback() -{ - class BufferAttacher : public QWaylandBufferAttacher - { - public: - void attach(const QWaylandBufferRef &ref) Q_DECL_OVERRIDE - { - bufferRef = ref; - } - void unmap() Q_DECL_OVERRIDE - { - } - - QImage image() const - { - if (!bufferRef || !bufferRef.isShm()) - return QImage(); - return bufferRef.image(); - } - - QWaylandBufferRef bufferRef; - }; - - TestCompositor compositor; - - MockClient client; - - wl_surface *surface = client.createSurface(); - - int frameCounter = 0; - - QTRY_COMPARE(compositor.surfaces.size(), 1); - QWaylandSurface *waylandSurface = compositor.surfaces.at(0); - BufferAttacher attacher; - waylandSurface->setBufferAttacher(&attacher); - QSignalSpy damagedSpy(waylandSurface, SIGNAL(damaged(const QRegion &))); - - for (int i = 0; i < 10; ++i) { - QSize size(i * 8 + 2, i * 8 + 2); - ShmBuffer buffer(size, client.shm); - - // attach a new buffer every frame, else the damage signal won't be fired - wl_surface_attach(surface, buffer.handle, 0, 0); - registerFrameCallback(surface, &frameCounter); - wl_surface_damage(surface, 0, 0, size.width(), size.height()); - wl_surface_commit(surface); - - QTRY_COMPARE(waylandSurface->type(), QWaylandSurface::Shm); - QTRY_COMPARE(damagedSpy.count(), i + 1); - - QCOMPARE(static_cast(waylandSurface->bufferAttacher())->image(), buffer.image); - compositor.frameStarted(); - compositor.sendFrameCallbacks(QList() << waylandSurface); - - QTRY_COMPARE(frameCounter, i + 1); - } - - wl_surface_destroy(surface); -} - -void tst_WaylandCompositor::inputDeviceCapabilities() -{ - TestCompositor compositor; - QtWayland::InputDevice dev(NULL, compositor.handle(), QWaylandInputDevice::Pointer); - - QTRY_VERIFY(dev.pointerDevice()); - QTRY_VERIFY(!dev.keyboardDevice()); - QTRY_VERIFY(!dev.touchDevice()); - - dev.setCapabilities(QWaylandInputDevice::Keyboard | QWaylandInputDevice::Touch); - QTRY_VERIFY(!dev.pointerDevice()); - QTRY_VERIFY(dev.keyboardDevice()); - QTRY_VERIFY(dev.touchDevice()); - - // Test that existing devices do not change when another is removed - QtWayland::Keyboard *k = dev.keyboardDevice(); - dev.setCapabilities(QWaylandInputDevice::Keyboard); - QTRY_COMPARE(k, dev.keyboardDevice()); -} - -void tst_WaylandCompositor::inputDeviceCreation() -{ - TestCompositor compositor; - TestInputDevice dev1(&compositor, QWaylandInputDevice::Pointer | QWaylandInputDevice::Keyboard); - TestInputDevice dev2(&compositor, QWaylandInputDevice::Pointer | QWaylandInputDevice::Keyboard); - - compositor.handle()->registerInputDevice(&dev1); - compositor.handle()->registerInputDevice(&dev2); - - // The compositor will create the default input device - QTRY_COMPARE(compositor.handle()->inputDevices().count(), 3); - // Test the order - QTRY_COMPARE(compositor.handle()->inputDevices().at(0), &dev2); - QTRY_COMPARE(compositor.handle()->inputDevices().at(1), &dev1); - QTRY_COMPARE(compositor.handle()->inputDevices().at(2), compositor.defaultInputDevice()); - - QList allEvents; - allEvents += dev1.createMouseEvents(2); - allEvents += dev2.createMouseEvents(5); - foreach (QMouseEvent *me, allEvents) { - compositor.inputDeviceFor(me); - } - - // The first input device will only get called exatly the number of times it has created - // the events - QTRY_COMPARE(dev1.queryCount(), 2); - // The second will get called the total number of times as it sits as the first item in - // the registered input devices list - QTRY_COMPARE(dev2.queryCount(), 7); -} - -void tst_WaylandCompositor::inputDeviceKeyboardFocus() -{ - TestCompositor compositor; - - - TestInputDevice dev1(&compositor, QWaylandInputDevice::Keyboard); - TestInputDevice dev2(&compositor, QWaylandInputDevice::Keyboard); - - compositor.handle()->registerInputDevice(&dev1); - compositor.handle()->registerInputDevice(&dev2); - - // Create client after all the input devices have been set up as the mock client - // does not dynamically listen to new seats - MockClient client; - wl_surface *surface = client.createSurface(); - QTRY_COMPARE(compositor.surfaces.size(), 1); - - QWaylandSurface *waylandSurface = compositor.surfaces.at(0); - QList devices = compositor.handle()->inputDevices(); - foreach (QWaylandInputDevice *dev, devices) { - dev->setKeyboardFocus(waylandSurface); - } - QTRY_COMPARE(compositor.defaultInputDevice()->keyboardFocus(), waylandSurface); - QTRY_COMPARE(dev1.keyboardFocus(), waylandSurface); - QTRY_COMPARE(dev2.keyboardFocus(), waylandSurface); - - wl_surface_destroy(surface); - QTRY_VERIFY(compositor.surfaces.size() == 0); - // This will normally be called for example in the quick compositor - // but here call it manually to get rid of the surface and have it reset - // the focus - compositor.handle()->cleanupGraphicsResources(); - - QTRY_VERIFY(!compositor.defaultInputDevice()->keyboardFocus()); - QTRY_VERIFY(!dev1.keyboardFocus()); - QTRY_VERIFY(!dev2.keyboardFocus()); -} - -#include -QTEST_MAIN(tst_WaylandCompositor); diff --git a/tests/global/.gitignore b/tests/global/.gitignore new file mode 100644 index 000000000..7407af1a5 --- /dev/null +++ b/tests/global/.gitignore @@ -0,0 +1 @@ +global.pro -- cgit v1.2.3