tests: port tst_client to use shared folder

instead of shared_old

Task-number: QTBUG-96440
Change-Id: I1f9e04841b432937e47ed337b05fe96b2e0662fc
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
Liang Qi 2021-09-29 16:42:30 +02:00
parent 5c9a38e768
commit 4767e91f7b
27 changed files with 503 additions and 2462 deletions

View File

@ -6,34 +6,9 @@
qt_internal_add_test(tst_client
SOURCES
../shared_old/mockcompositor.cpp ../shared_old/mockcompositor.h
../shared_old/mockfullscreenshellv1.cpp ../shared_old/mockfullscreenshellv1.h
../shared_old/mockinput.cpp ../shared_old/mockinput.h
../shared_old/mockiviapplication.cpp ../shared_old/mockiviapplication.h
../shared_old/mockoutput.cpp ../shared_old/mockoutput.h
../shared_old/mockregion.cpp ../shared_old/mockregion.h
../shared_old/mocksurface.cpp ../shared_old/mocksurface.h
../shared_old/mockwlshell.cpp ../shared_old/mockwlshell.h
tst_client.cpp
INCLUDE_DIRECTORIES
../shared_old
PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
Qt::OpenGL
Qt::WaylandClientPrivate
Wayland::Client
Wayland::Server
Threads::Threads # special case
)
qt6_generate_wayland_protocol_server_sources(tst_client
FILES
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/3rdparty/protocol/fullscreen-shell-unstable-v1.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/3rdparty/protocol/ivi-application.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/3rdparty/protocol/wayland.xml
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/3rdparty/protocol/xdg-shell.xml
SharedClientTest
)
#### Keys ignored in scope 1:.:.:client.pro:<TRUE>:

View File

@ -44,8 +44,24 @@
#include <QtWaylandClient/private/qwaylandintegration_p.h>
#include <QtGui/private/qguiapplication_p.h>
using namespace MockCompositor;
static const QSize screenSize(1600, 1200);
constexpr int dataDeviceVersion = 1;
class TestCompositor : public WlShellCompositor {
public:
explicit TestCompositor()
{
exec([this] {
m_config.autoConfigure = true;
add<DataDeviceManager>(dataDeviceVersion);
});
}
DataDevice *dataDevice() { return get<DataDeviceManager>()->deviceFor(get<Seat>()); }
};
class TestWindow : public QWindow
{
public:
@ -141,35 +157,14 @@ void TestGlWindow::paintGL()
}
#endif // QT_CONFIG(opengl)
class tst_WaylandClient : public QObject
class tst_WaylandClient : public QObject, private TestCompositor
{
Q_OBJECT
public:
tst_WaylandClient(MockCompositor *c)
: compositor(c)
{
QSocketNotifier *notifier = new QSocketNotifier(compositor->waylandFileDescriptor(), QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(QSocketDescriptor)), 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());
QTRY_VERIFY(!compositor->iviSurface());
}
private slots:
void cleanup() {
QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage()));
}
void createDestroyWindow();
void activeWindowFollowsKeyboardFocus();
void events();
@ -184,9 +179,6 @@ private slots:
#endif // QT_CONFIG(opengl)
void longWindowTitle();
void longWindowTitleWithUtf16Characters();
private:
MockCompositor *compositor = nullptr;
};
void tst_WaylandClient::createDestroyWindow()
@ -194,10 +186,10 @@ void tst_WaylandClient::createDestroyWindow()
TestWindow window;
window.show();
QTRY_VERIFY(compositor->surface());
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
window.destroy();
QTRY_VERIFY(!compositor->surface());
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
}
void tst_WaylandClient::activeWindowFollowsKeyboardFocus()
@ -205,21 +197,26 @@ void tst_WaylandClient::activeWindowFollowsKeyboardFocus()
TestWindow window;
window.show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
QTRY_VERIFY(window.isExposed());
QCOMPOSITOR_TRY_VERIFY(window.isExposed());
QCOMPARE(window.focusInEventCount, 0);
compositor->setKeyboardFocus(surface);
exec([=] {
keyboard()->sendEnter(s);
});
QTRY_COMPARE(window.focusInEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
QCOMPARE(QGuiApplication::focusWindow(), &window);
QCOMPARE(window.focusOutEventCount, 0);
compositor->setKeyboardFocus(QSharedPointer<MockSurface>(nullptr));
exec([=] {
keyboard()->sendLeave(s); // or implement setFocus in Keyboard
});
QTRY_COMPARE(window.focusOutEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(nullptr));
QCOMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(nullptr));
}
void tst_WaylandClient::events()
@ -227,46 +224,77 @@ void tst_WaylandClient::events()
TestWindow window;
window.show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
QTRY_VERIFY(window.isExposed());
QCOMPOSITOR_TRY_VERIFY(window.isExposed());
compositor->setKeyboardFocus(surface);
QCOMPARE(window.focusInEventCount, 0);
exec([=] {
keyboard()->sendEnter(s);
});
QTRY_COMPARE(window.focusInEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
QCOMPARE(QGuiApplication::focusWindow(), &window);
// See also https://wayland.app/protocols/wayland#wl_keyboard:enum:keymap_format
// wl_keyboard::keymap_format
// keymap_format { no_keymap, xkb_v1 }
// Argument Value Description
// no_keymap 0 no keymap; client must understand how to interpret the raw keycode
// xkb_v1 1 libxkbcommon compatible; to determine the xkb keycode, clients must add 8 to the key event keycode
uint keyCode = 80; // arbitrarily chosen
QCOMPARE(window.keyPressEventCount, 0);
compositor->sendKeyPress(surface, keyCode);
exec([=] {
keyboard()->sendKey(client(), keyCode - 8, Keyboard::key_state_pressed); // related with native scan code
});
QTRY_COMPARE(window.keyPressEventCount, 1);
QTRY_COMPARE(window.keyCode, keyCode);
QCOMPARE(window.keyCode, keyCode);
QCOMPARE(window.keyReleaseEventCount, 0);
compositor->sendKeyRelease(surface, keyCode);
exec([=] {
keyboard()->sendKey(client(), keyCode - 8, Keyboard::key_state_released); // related with native scan code
});
QTRY_COMPARE(window.keyReleaseEventCount, 1);
QCOMPARE(window.keyCode, keyCode);
const int touchId = 0;
compositor->sendTouchDown(surface, window.frameOffset() + QPoint(10, 10), touchId);
exec([&] {
touch()->sendDown(s, window.frameOffset() + QPoint(10, 10), touchId);
});
// Note: wl_touch.frame should not be the last event in a test until QTBUG-66563 is fixed.
// See also: QTBUG-66537
compositor->sendTouchFrame(surface);
exec([=] {
touch()->sendFrame(client());
});
QTRY_COMPARE(window.touchEventCount, 1);
compositor->sendTouchUp(surface, touchId);
compositor->sendTouchFrame(surface);
exec([=] {
touch()->sendUp(client(), touchId);
touch()->sendFrame(client());
});
QTRY_COMPARE(window.touchEventCount, 2);
QPoint mousePressPos(16, 16);
QCOMPARE(window.mousePressEventCount, 0);
compositor->sendMousePress(surface, window.frameOffset() + mousePressPos);
exec([&] {
pointer()->sendEnter(s, window.frameOffset() + mousePressPos);
pointer()->sendFrame(client());
pointer()->sendMotion(client(), window.frameOffset() + mousePressPos);
pointer()->sendFrame(client());
pointer()->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
pointer()->sendFrame(client());
});
QTRY_COMPARE(window.mousePressEventCount, 1);
QTRY_COMPARE(window.mousePressPos, mousePressPos);
QCOMPARE(window.mouseReleaseEventCount, 0);
compositor->sendMouseRelease(surface);
exec([=] {
pointer()->sendButton(client(), BTN_LEFT, Pointer::button_state_released);
pointer()->sendFrame(client());
});
QTRY_COMPARE(window.mouseReleaseEventCount, 1);
}
@ -275,9 +303,10 @@ void tst_WaylandClient::backingStore()
TestWindow window;
window.show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
QRect rect(QPoint(), window.size());
@ -294,17 +323,17 @@ void tst_WaylandClient::backingStore()
backingStore.endPaint();
QVERIFY(surface->image.isNull());
QVERIFY(s->m_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());
QTRY_COMPARE(s->m_image.size(), window.frameGeometry().size());
QTRY_COMPARE(s->m_image.pixel(window.frameMargins().left(), window.frameMargins().top()), color.rgba());
window.hide();
// hiding the window should destroy the surface
QTRY_VERIFY(!compositor->surface());
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
}
class DndWindow : public QWindow
@ -343,29 +372,75 @@ private:
QPixmap m_dragIcon;
};
class DNDTest : public QObject
{
Q_OBJECT
public:
DNDTest(QObject *parent = nullptr)
: QObject(parent) {}
Surface *m_surface = nullptr;
TestCompositor *m_compositor = nullptr;
QPoint m_frameOffset;
public slots:
void finishMouseDrag();
void touchDrag();
};
void DNDTest::finishMouseDrag()
{
m_compositor->exec([&] {
m_compositor->dataDevice()->sendDrop(m_surface);
m_compositor->dataDevice()->sendLeave(m_surface);
});
}
void DNDTest::touchDrag()
{
m_compositor->exec([&] {
m_compositor->dataDevice()->sendDataOffer(m_surface->resource()->client());
m_compositor->dataDevice()->sendEnter(m_surface, m_frameOffset + QPoint(20, 20));
m_compositor->dataDevice()->sendMotion(m_surface, m_frameOffset + QPoint(21, 21));
m_compositor->dataDevice()->sendDrop(m_surface);
m_compositor->dataDevice()->sendLeave(m_surface);
});
}
void tst_WaylandClient::touchDrag()
{
DndWindow window;
window.show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
compositor->setKeyboardFocus(surface);
DNDTest test;
test.m_surface = s;
test.m_compositor = this;
test.m_frameOffset = window.frameOffset();
exec([&] {
QObject::connect(dataDevice(), &DataDevice::dragStarted,
&test, &DNDTest::touchDrag);
});
exec([=] {
keyboard()->sendEnter(s);
});
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
const int id = 0;
compositor->sendTouchDown(surface, window.frameOffset() + QPoint(10, 10), id);
compositor->sendTouchFrame(surface);
compositor->sendTouchMotion(surface, window.frameOffset() + QPoint(20, 20), id);
compositor->sendTouchFrame(surface);
compositor->waitForStartDrag();
compositor->sendDataDeviceDataOffer(surface);
compositor->sendDataDeviceEnter(surface, window.frameOffset() + QPoint(20, 20));
compositor->sendDataDeviceMotion(window.frameOffset() + QPoint(21, 21));
compositor->sendDataDeviceDrop(surface);
compositor->sendDataDeviceLeave(surface);
const int touchId = 0;
exec([&] {
touch()->sendDown(s, window.frameOffset() + QPoint(10, 10), touchId);
touch()->sendFrame(client());
touch()->sendMotion(client(), window.frameOffset() + QPoint(20, 20), touchId);
touch()->sendFrame(client());
});
QTRY_VERIFY(window.dragStarted);
}
@ -374,20 +449,39 @@ void tst_WaylandClient::mouseDrag()
DndWindow window;
window.show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
compositor->setKeyboardFocus(surface);
DNDTest test;
test.m_surface = s;
test.m_compositor = this;
exec([&] {
QObject::connect(dataDevice(), &DataDevice::dragStarted,
&test, &DNDTest::finishMouseDrag);
});
exec([=] {
keyboard()->sendEnter(s);
});
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
compositor->sendMousePress(surface, window.frameOffset() + QPoint(10, 10));
compositor->sendDataDeviceDataOffer(surface);
compositor->sendDataDeviceEnter(surface, window.frameOffset() + QPoint(20, 20));
compositor->sendDataDeviceMotion(window.frameOffset() + QPoint(21, 21));
compositor->waitForStartDrag();
compositor->sendDataDeviceDrop(surface);
compositor->sendDataDeviceLeave(surface);
QPoint mousePressPos(16, 16);
exec([&] {
pointer()->sendEnter(s, window.frameOffset() + mousePressPos);
pointer()->sendFrame(client());
pointer()->sendMotion(client(), window.frameOffset() + mousePressPos);
pointer()->sendFrame(client());
pointer()->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
pointer()->sendFrame(client());
dataDevice()->sendDataOffer(s->resource()->client());
dataDevice()->sendEnter(s, window.frameOffset() + QPoint(20, 20));
dataDevice()->sendMotion(s, window.frameOffset() + QPoint(21, 21));
});
QTRY_VERIFY(window.dragStarted);
}
@ -412,10 +506,11 @@ void tst_WaylandClient::dontCrashOnMultipleCommits()
backingStore.flush(rect);
backingStore.flush(rect);
compositor->processWaylandEvents();
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
}
delete window;
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
}
void tst_WaylandClient::hiddenTransientParent()
@ -426,15 +521,14 @@ void tst_WaylandClient::hiddenTransientParent()
transient.setTransientParent(&parent);
parent.show();
QTRY_VERIFY(compositor->surface());
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
parent.hide();
QTRY_VERIFY(!compositor->surface());
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
transient.show();
QTRY_VERIFY(compositor->surface());
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
}
void tst_WaylandClient::hiddenPopupParent()
{
TestWindow toplevel;
@ -442,12 +536,22 @@ void tst_WaylandClient::hiddenPopupParent()
// wl_shell relies on a mouse event in order to send a serial and seat
// with the set_popup request.
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
QCOMPOSITOR_TRY_VERIFY(toplevel.isExposed());
QPoint mousePressPos(16, 16);
QCOMPARE(toplevel.mousePressEventCount, 0);
compositor->sendMousePress(surface, toplevel.frameOffset() + mousePressPos);
exec([&] {
pointer()->sendEnter(s, toplevel.frameOffset() + mousePressPos);
pointer()->sendFrame(client());
pointer()->sendMotion(client(), toplevel.frameOffset() + mousePressPos);
pointer()->sendFrame(client());
pointer()->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
pointer()->sendFrame(client());
});
QTRY_COMPARE(toplevel.mousePressEventCount, 1);
QWindow popup;
@ -455,10 +559,10 @@ void tst_WaylandClient::hiddenPopupParent()
popup.setFlag(Qt::Popup, true);
toplevel.hide();
QTRY_VERIFY(!compositor->surface());
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
popup.show();
QTRY_VERIFY(compositor->surface());
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
}
#if QT_CONFIG(opengl)
@ -468,9 +572,10 @@ void tst_WaylandClient::glWindow()
QScopedPointer<TestGlWindow> testWindow(new TestGlWindow);
testWindow->show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
Surface *s = nullptr;
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
WlShellSurface *ss = s->wlShellSurface();
ss->sendConfigure(0, 0, 0);
QTRY_COMPARE(testWindow->paintGLCalled, 1);
@ -485,7 +590,7 @@ void tst_WaylandClient::glWindow()
//confirm we don't crash when we delete an already hidden GL window
//QTBUG-65553
testWindow->setVisible(false);
QTRY_VERIFY(!compositor->surface());
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
}
#endif // QT_CONFIG(opengl)
@ -496,7 +601,7 @@ void tst_WaylandClient::longWindowTitle()
QString absurdlyLongTitle(10000, QLatin1Char('z'));
window.setTitle(absurdlyLongTitle);
window.show();
QTRY_VERIFY(compositor->surface());
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
}
void tst_WaylandClient::longWindowTitleWithUtf16Characters()
@ -506,7 +611,7 @@ void tst_WaylandClient::longWindowTitleWithUtf16Characters()
Q_ASSERT(absurdlyLongTitle.length() == 10000); // just making sure the test isn't broken
window.setTitle(absurdlyLongTitle);
window.show();
QTRY_VERIFY(compositor->surface());
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
}
int main(int argc, char **argv)
@ -514,22 +619,13 @@ int main(int argc, char **argv)
QTemporaryDir tmpRuntimeDir;
setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1);
setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
setenv("QT_WAYLAND_SHELL_INTEGRATION", "wl-shell", 1);
MockCompositor compositor;
compositor.setOutputMode(screenSize);
tst_WaylandClient tc;
QGuiApplication app(argc, argv);
// Initializing some client buffer integrations (i.e. eglInitialize) may block while waiting
// for a wayland sync. So we call clientBufferIntegration prior to applicationInitialized
// (while the compositor processes events without waiting) in order to avoid hanging later.
auto *waylandIntegration = static_cast<QtWaylandClient::QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration());
waylandIntegration->clientBufferIntegration();
compositor.applicationInitialized();
tst_WaylandClient tc(&compositor);
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
}
#include <tst_client.moc>

View File

@ -31,8 +31,9 @@
namespace MockCompositor {
CoreCompositor::CoreCompositor()
: m_display(wl_display_create())
CoreCompositor::CoreCompositor(CompositorType t)
: m_type(t)
, m_display(wl_display_create())
, m_socketName(wl_display_add_socket_auto(m_display))
, m_eventLoop(wl_display_get_event_loop(m_display))
@ -77,11 +78,10 @@ QString CoreCompositor::dirtyMessage()
return messages.join(", ");
}
void CoreCompositor::dispatch()
void CoreCompositor::dispatch(int timeout)
{
Lock lock(this);
wl_display_flush_clients(m_display);
constexpr int timeout = 0; // immediate return
wl_event_loop_dispatch(m_eventLoop, timeout);
}

View File

@ -48,11 +48,17 @@ public:
class CoreCompositor
{
public:
explicit CoreCompositor();
enum CompositorType {
Default,
Legacy // wl-shell
};
CompositorType m_type = Default;
explicit CoreCompositor(CompositorType t = Default);
~CoreCompositor();
bool isClean();
QString dirtyMessage();
void dispatch();
void dispatch(int timeout = 0);
template<typename function_type, typename... arg_types>
auto exec(function_type func, arg_types&&... args) -> decltype(func())
@ -164,6 +170,7 @@ public:
public:
// Only use this carefully from the test thread (i.e. lock first)
wl_display *m_display = nullptr;
protected:
class Lock {
public:

View File

@ -31,6 +31,21 @@
namespace MockCompositor {
Surface::Surface(WlCompositor *wlCompositor, wl_client *client, int id, int version)
: QtWaylandServer::wl_surface(client, id, version)
, m_wlCompositor(wlCompositor)
, m_wlshell(wlCompositor->m_compositor->m_type == CoreCompositor::CompositorType::Legacy)
{
}
Surface::~Surface()
{
// TODO: maybe make sure buffers are released?
qDeleteAll(m_commits);
if (m_wlShellSurface)
m_wlShellSurface->m_surface = nullptr;
}
void Surface::sendFrameCallbacks()
{
uint time = m_wlCompositor->m_compositor->currentTimeMilliseconds();
@ -55,6 +70,11 @@ void Surface::sendLeave(Output *output)
wl_surface::send_leave(resource()->handle, outputResource->handle);
}
void Surface::map()
{
m_mapped = true;
}
void Surface::surface_destroy_resource(Resource *resource)
{
Q_UNUSED(resource);
@ -65,14 +85,29 @@ void Surface::surface_destroy_resource(Resource *resource)
delete this;
}
void Surface::surface_destroy(Resource *resource)
{
if (m_wlShellSurface) // on wl-shell the shell surface is automatically destroyed with the surface
wl_resource_destroy(m_wlShellSurface->resource()->handle);
Q_ASSERT(!m_wlShellSurface);
wl_resource_destroy(resource->handle);
}
void Surface::surface_attach(Resource *resource, wl_resource *buffer, int32_t x, int32_t y)
{
Q_UNUSED(resource);
QPoint offset(x, y);
m_pending.buffer = fromResource<Buffer>(buffer);
m_pending.commitSpecific.attachOffset = offset;
m_pending.commitSpecific.attached = true;
emit attach(buffer, offset);
if (m_wlshell) {
m_buffer = buffer;
if (!buffer)
m_image = QImage();
} else {
QPoint offset(x, y);
m_pending.buffer = fromResource<Buffer>(buffer);
m_pending.commitSpecific.attachOffset = offset;
m_pending.commitSpecific.attached = true;
emit attach(buffer, offset);
}
}
void Surface::surface_set_buffer_scale(QtWaylandServer::wl_surface::Resource *resource, int32_t scale)
@ -84,32 +119,63 @@ void Surface::surface_set_buffer_scale(QtWaylandServer::wl_surface::Resource *re
void Surface::surface_commit(Resource *resource)
{
Q_UNUSED(resource);
m_committed = m_pending;
m_commits.append(new DoubleBufferedState(m_committed));
if (auto *frame = m_pending.commitSpecific.frame)
m_waitingFrameCallbacks.append(frame);
if (m_wlshell) {
if (m_buffer) {
struct ::wl_shm_buffer *shm_buffer = wl_shm_buffer_get(m_buffer);
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<const uchar *>(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_image = img;
}
}
m_pending.commitSpecific = PerCommitData();
emit commit();
if (m_committed.commitSpecific.attached)
emit bufferCommitted();
for (wl_resource *frameCallback : qExchange(m_frameCallbackList, {})) {
auto time = m_wlCompositor->m_compositor->currentTimeMilliseconds();
wl_callback_send_done(frameCallback, time);
wl_resource_destroy(frameCallback);
}
} else {
m_committed = m_pending;
m_commits.append(new DoubleBufferedState(m_committed));
if (auto *frame = m_pending.commitSpecific.frame)
m_waitingFrameCallbacks.append(frame);
m_pending.commitSpecific = PerCommitData();
emit commit();
if (m_committed.commitSpecific.attached)
emit bufferCommitted();
}
}
void Surface::surface_frame(Resource *resource, uint32_t callback)
{
// Although valid, there is really no point having multiple frame requests in the same commit.
// Make sure we don't do it
QCOMPARE(m_pending.commitSpecific.frame, nullptr);
if (m_wlshell) {
wl_resource *frameCallback = wl_resource_create(resource->client(), &wl_callback_interface, 1, callback);
m_frameCallbackList << frameCallback;
} else {
// Although valid, there is really no point having multiple frame requests in the same commit.
// Make sure we don't do it
QCOMPARE(m_pending.commitSpecific.frame, nullptr);
auto *frame = new Callback(resource->client(), callback, 1);
m_pending.commitSpecific.frame = frame;
auto *frame = new Callback(resource->client(), callback, 1);
m_pending.commitSpecific.frame = frame;
}
}
bool WlCompositor::isClean() {
for (auto *surface : qAsConst(m_surfaces)) {
if (!CursorRole::fromSurface(surface))
return false;
if (!CursorRole::fromSurface(surface)) {
if (m_compositor->m_type != CoreCompositor::CompositorType::Legacy)
return false;
if (surface->isMapped())
return false;
}
}
return true;
}
@ -299,8 +365,9 @@ uint Pointer::sendEnter(Surface *surface, const QPointF &position)
wl_client *client = surface->resource()->client();
const auto pointerResources = resourceMap().values(client);
for (auto *r : pointerResources)
for (auto *r : pointerResources) {
wl_pointer::send_enter(r->handle, serial, surface->resource()->handle, x ,y);
}
return serial;
}
@ -479,8 +546,9 @@ uint Keyboard::sendKey(wl_client *client, uint key, uint state)
auto time = m_seat->m_compositor->currentTimeMilliseconds();
uint serial = m_seat->m_compositor->nextSerial();
const auto pointerResources = resourceMap().values(client);
for (auto *r : pointerResources)
for (auto *r : pointerResources) {
send_key(r->handle, serial, time, key, state);
}
return serial;
}
@ -534,4 +602,38 @@ void ShmPool::shm_pool_destroy_resource(Resource *resource)
delete this;
}
WlShell::WlShell(CoreCompositor *compositor, int version)
: QtWaylandServer::wl_shell(compositor->m_display, version)
, m_compositor(compositor)
{
}
void WlShell::shell_get_shell_surface(Resource *resource, uint32_t id, wl_resource *surface)
{
auto *s = fromResource<Surface>(surface);
auto *wlShellSurface = new WlShellSurface(this, resource->client(), id, s);
m_wlShellSurfaces << wlShellSurface;
emit wlShellSurfaceCreated(wlShellSurface);
}
WlShellSurface::WlShellSurface(WlShell *wlShell, wl_client *client, int id, Surface *surface)
: QtWaylandServer::wl_shell_surface(client, id, 1)
, m_wlShell(wlShell)
, m_surface(surface)
{
surface->m_wlShellSurface = this;
surface->map();
}
WlShellSurface::~WlShellSurface()
{
if (m_surface)
m_surface->m_wlShellSurface = nullptr;
}
void WlShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height)
{
wl_shell_surface::send_configure(edges, width, height);
}
} // namespace MockCompositor

View File

@ -36,6 +36,8 @@
namespace MockCompositor {
class WlCompositor;
class WlShell;
class WlShellSurface;
class Output;
class Pointer;
class Touch;
@ -96,18 +98,18 @@ class Surface : public QObject, public QtWaylandServer::wl_surface
{
Q_OBJECT
public:
explicit Surface(WlCompositor *wlCompositor, wl_client *client, int id, int version)
: QtWaylandServer::wl_surface(client, id, version)
, m_wlCompositor(wlCompositor)
{
}
~Surface() override { qDeleteAll(m_commits); } // TODO: maybe make sure buffers are released?
explicit Surface(WlCompositor *wlCompositor, wl_client *client, int id, int version);
~Surface() override;
void sendFrameCallbacks();
void sendEnter(Output *output);
void send_enter(::wl_resource *output) = delete;
void sendLeave(Output *output);
void send_leave(::wl_resource *output) = delete;
void map();
bool isMapped() const { return m_mapped; }
WlShellSurface *wlShellSurface() const { return m_wlShellSurface; }
WlCompositor *m_wlCompositor;
struct PerCommitData {
Callback *frame = nullptr;
@ -125,6 +127,14 @@ public:
QList<Output *> m_outputs;
SurfaceRole *m_role = nullptr;
WlShellSurface *m_wlShellSurface = nullptr;
bool m_mapped = false;
QList<wl_resource *> m_frameCallbackList;
wl_resource *m_buffer = nullptr;
QImage m_image; // checking backingStore
bool m_wlshell = false;
signals:
void attach(void *buffer, QPoint offset);
void commit();
@ -132,7 +142,7 @@ signals:
protected:
void surface_destroy_resource(Resource *resource) override;
void surface_destroy(Resource *resource) override { wl_resource_destroy(resource->handle); }
void surface_destroy(Resource *resource) override;
void surface_attach(Resource *resource, wl_resource *buffer, int32_t x, int32_t y) override;
void surface_set_buffer_scale(Resource *resource, int32_t scale) override;
void surface_commit(Resource *resource) override;
@ -184,6 +194,36 @@ protected:
}
};
class WlShell : public Global, public QtWaylandServer::wl_shell
{
Q_OBJECT
public:
explicit WlShell(CoreCompositor *compositor, int version = 1);
QList<WlShellSurface *> m_wlShellSurfaces;
CoreCompositor *m_compositor = nullptr;
signals:
void wlShellSurfaceCreated(WlShellSurface *wlShellSurface);
protected:
void shell_get_shell_surface(Resource *resource, uint32_t id, ::wl_resource *surface) override;
};
class WlShellSurface : public QObject, public QtWaylandServer::wl_shell_surface
{
Q_OBJECT
public:
explicit WlShellSurface(WlShell *wlShell, wl_client *client, int id, Surface *surface);
~WlShellSurface() override;
void sendConfigure(uint32_t edges, int32_t width, int32_t height);
void send_configure(uint32_t edges, int32_t width, int32_t height) = delete;
void shell_surface_destroy_resource(Resource *) override { delete this; }
WlShell *m_wlShell = nullptr;
Surface *m_surface = nullptr;
};
class Subsurface : public QObject, public QtWaylandServer::wl_subsurface
{
Q_OBJECT

View File

@ -60,6 +60,11 @@ void DataDeviceManager::data_device_manager_get_data_device(Resource *resource,
device->add(resource->client(), id, resource->version());
}
void DataDeviceManager::data_device_manager_create_data_source(Resource *resource, uint32_t id)
{
new QtWaylandServer::wl_data_source(resource->client(), id, 1);
}
DataDevice::~DataDevice()
{
// If the client(s) hasn't deleted the wayland object, just ignore subsequent events
@ -71,6 +76,7 @@ DataOffer *DataDevice::sendDataOffer(wl_client *client, const QStringList &mimeT
{
Q_ASSERT(client);
auto *offer = new DataOffer(this, client, m_manager->m_version);
m_offers << offer;
for (auto *resource : resourceMap().values(client))
wl_data_device::send_data_offer(resource->handle, offer->resource()->handle);
for (const auto &mimeType : mimeTypes)
@ -86,6 +92,33 @@ void DataDevice::sendSelection(DataOffer *offer)
m_sentSelectionOffers << offer;
}
void DataDevice::sendEnter(Surface *surface, const QPoint &position)
{
uint serial = m_manager->m_compositor->nextSerial();
Resource *resource = resourceMap().value(surface->resource()->client());
for (DataOffer *offer: m_offers)
wl_data_device::send_enter(resource->handle, serial, surface->resource()->handle, position.x(), position.y(), offer->resource()->handle);
}
void DataDevice::sendMotion(Surface *surface, const QPoint &position)
{
uint32_t time = m_manager->m_compositor->nextSerial();
Resource *resource = resourceMap().value(surface->resource()->client());
wl_data_device::send_motion(resource->handle, time, position.x(), position.y());
}
void DataDevice::sendDrop(Surface *surface)
{
Resource *resource = resourceMap().value(surface->resource()->client());
wl_data_device::send_drop(resource->handle);
}
void DataDevice::sendLeave(Surface *surface)
{
Resource *resource = resourceMap().value(surface->resource()->client());
wl_data_device::send_leave(resource->handle);
}
void DataOffer::data_offer_destroy_resource(Resource *resource)
{
Q_UNUSED(resource);
@ -101,6 +134,8 @@ void DataOffer::data_offer_receive(Resource *resource, const QString &mime_type,
void DataOffer::data_offer_destroy(QtWaylandServer::wl_data_offer::Resource *resource)
{
bool removed = m_dataDevice->m_sentSelectionOffers.removeOne(this);
if (!removed)
removed = m_dataDevice->m_offers.removeOne(this);
QVERIFY(removed);
wl_resource_destroy(resource->handle);
}

View File

@ -43,6 +43,7 @@ public:
explicit DataDeviceManager(CoreCompositor *compositor, int version = 1)
: QtWaylandServer::wl_data_device_manager(compositor->m_display, version)
, m_version(version)
, m_compositor(compositor)
{}
~DataDeviceManager() override { qDeleteAll(m_dataDevices); }
bool isClean() override;
@ -50,13 +51,16 @@ public:
int m_version = 1; // TODO: remove on libwayland upgrade
QMap<Seat *, DataDevice *> m_dataDevices;
CoreCompositor *m_compositor;
protected:
void data_device_manager_get_data_device(Resource *resource, uint32_t id, ::wl_resource *seatResource) override;
void data_device_manager_create_data_source(Resource *resource, uint32_t id) override;
};
class DataDevice : public QtWaylandServer::wl_data_device
class DataDevice : public QObject, public QtWaylandServer::wl_data_device
{
Q_OBJECT
public:
explicit DataDevice(DataDeviceManager *manager, Seat *seat)
: m_manager(manager)
@ -69,11 +73,37 @@ public:
void send_selection(::wl_resource *resource) = delete;
void sendSelection(DataOffer *offer);
void send_enter(uint32_t serial, ::wl_resource *surface, wl_fixed_t x, wl_fixed_t y, ::wl_resource *id) = delete;
void sendEnter(Surface *surface, const QPoint& position);
void send_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y) = delete;
void sendMotion(Surface *surface, const QPoint &position);
void send_drop(::wl_resource *resource) = delete;
void sendDrop(Surface *surface);
void send_leave(::wl_resource *resource) = delete;
void sendLeave(Surface *surface);
DataDeviceManager *m_manager = nullptr;
Seat *m_seat = nullptr;
QList<DataOffer *> m_sentSelectionOffers;
QList<DataOffer *> m_offers;
signals:
void dragStarted();
protected:
void data_device_start_drag(Resource *resource, ::wl_resource *source, ::wl_resource *origin, ::wl_resource *icon, uint32_t serial) override
{
Q_UNUSED(resource);
Q_UNUSED(source);
Q_UNUSED(origin);
Q_UNUSED(icon);
Q_UNUSED(serial);
emit dragStarted();
}
void data_device_release(Resource *resource) override
{
int removed = m_manager->m_dataDevices.remove(m_seat);

View File

@ -31,7 +31,8 @@
namespace MockCompositor {
DefaultCompositor::DefaultCompositor()
DefaultCompositor::DefaultCompositor(CompositorType t)
: CoreCompositor(t)
{
{
Lock l(this);
@ -43,8 +44,16 @@ DefaultCompositor::DefaultCompositor()
auto *output = add<Output>();
output->m_data.physicalSize = output->m_data.mode.physicalSizeForDpi(96);
add<Seat>(Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch);
add<WlShell>();
add<XdgWmBase>();
add<Shm>();
switch (m_type) {
case CompositorType::Default:
add<Shm>();
break;
case CompositorType::Legacy:
wl_display_init_shm(m_display);
break;
}
add<FullScreenShellV1>();
add<IviApplication>();
@ -89,4 +98,24 @@ void DefaultCompositor::xdgPingAndWaitForPong()
QTRY_COMPARE(pongSpy.first().at(0).toUInt(), serial);
}
WlShellCompositor::WlShellCompositor(CompositorType t)
: DefaultCompositor(t)
{
}
Surface *DefaultCompositor::wlSurface(int i)
{
QList<Surface *> surfaces, msurfaces;
msurfaces = get<WlCompositor>()->m_surfaces;
for (Surface *surface : msurfaces) {
if (surface->isMapped())
surfaces << surface;
}
if (i >=0 && i < surfaces.size())
return surfaces[i];
return nullptr;
}
} // namespace MockCompositor

View File

@ -55,11 +55,13 @@ namespace MockCompositor {
class DefaultCompositor : public CoreCompositor
{
public:
explicit DefaultCompositor();
explicit DefaultCompositor(CompositorType t = CompositorType::Default);
// Convenience functions
Output *output(int i = 0) { return getAll<Output>().value(i, nullptr); }
Surface *surface(int i = 0) { return get<WlCompositor>()->m_surfaces.value(i, nullptr); }
Subsurface *subSurface(int i = 0) { return get<SubCompositor>()->m_subsurfaces.value(i, nullptr); }
WlShellSurface *wlShellSurface(int i = 0) { return get<WlShell>()->m_wlShellSurfaces.value(i, nullptr); }
Surface *wlSurface(int i = 0);
XdgSurface *xdgSurface(int i = 0) { return get<XdgWmBase>()->m_xdgSurfaces.value(i, nullptr); }
XdgToplevel *xdgToplevel(int i = 0) { return get<XdgWmBase>()->toplevel(i); }
XdgPopup *xdgPopup(int i = 0) { return get<XdgWmBase>()->popup(i); }
@ -80,6 +82,12 @@ public:
void resetConfig() { exec([&] { m_config = Config{}; }); }
};
class WlShellCompositor : public DefaultCompositor
{
public:
explicit WlShellCompositor(CompositorType t = CompositorType::Legacy);
};
} // namespace MockCompositor
#define QCOMPOSITOR_VERIFY(expr) QVERIFY(exec([&]{ return expr; }))

View File

@ -1,453 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include "mockinput.h"
#include "mockoutput.h"
#include "mocksurface.h"
#include "mockwlshell.h"
#include "mockiviapplication.h"
#include <stdio.h>
MockCompositor::MockCompositor()
{
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::setOutputMode(const QSize &size)
{
Command command = makeCommand(Impl::Compositor::setOutputMode, m_compositor);
command.parameters << size;
processCommand(command);
}
void MockCompositor::setKeyboardFocus(const QSharedPointer<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::setKeyboardFocus, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendMousePress(const QSharedPointer<MockSurface> &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<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::sendMouseRelease, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendKeyPress(const QSharedPointer<MockSurface> &surface, uint code)
{
Command command = makeCommand(Impl::Compositor::sendKeyPress, m_compositor);
command.parameters << QVariant::fromValue(surface) << code;
processCommand(command);
}
void MockCompositor::sendKeyRelease(const QSharedPointer<MockSurface> &surface, uint code)
{
Command command = makeCommand(Impl::Compositor::sendKeyRelease, m_compositor);
command.parameters << QVariant::fromValue(surface) << code;
processCommand(command);
}
void MockCompositor::sendTouchDown(const QSharedPointer<MockSurface> &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<MockSurface> &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<MockSurface> &surface, int id)
{
Command command = makeCommand(Impl::Compositor::sendTouchUp, m_compositor);
command.parameters << QVariant::fromValue(surface) << id;
processCommand(command);
}
void MockCompositor::sendTouchFrame(const QSharedPointer<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::sendTouchFrame, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendDataDeviceDataOffer(const QSharedPointer<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::sendDataDeviceDataOffer, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendDataDeviceEnter(const QSharedPointer<MockSurface> &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<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::sendDataDeviceDrop, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendDataDeviceLeave(const QSharedPointer<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::sendDataDeviceLeave, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size)
{
Command command = makeCommand(Impl::Compositor::sendShellSurfaceConfigure, m_compositor);
command.parameters << QVariant::fromValue(surface);
command.parameters << QVariant::fromValue(size);
processCommand(command);
}
void MockCompositor::sendIviSurfaceConfigure(const QSharedPointer<MockIviSurface> iviSurface, const QSize &size)
{
Command command = makeCommand(Impl::Compositor::sendIviSurfaceConfigure, m_compositor);
command.parameters << QVariant::fromValue(iviSurface);
command.parameters << QVariant::fromValue(size);
processCommand(command);
}
void MockCompositor::waitForStartDrag()
{
Command command = makeCommand(Impl::Compositor::waitForStartDrag, m_compositor);
processCommand(command);
}
QSharedPointer<MockSurface> MockCompositor::surface()
{
QSharedPointer<MockSurface> result;
lock();
{
const QList<Impl::Surface *> surfaces = m_compositor->surfaces();
for (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;
}
QSharedPointer<MockOutput> MockCompositor::output(int index)
{
QSharedPointer<MockOutput> result;
lock();
if (Impl::Output *output = m_compositor->outputs().value(index, nullptr))
result = output->mockOutput();
unlock();
return result;
}
QSharedPointer<MockIviSurface> MockCompositor::iviSurface(int index)
{
QSharedPointer<MockIviSurface> result;
lock();
if (Impl::IviSurface *toplevel = m_compositor->iviApplication()->iviSurfaces().value(index, nullptr))
result = toplevel->mockIviSurface();
unlock();
return result;
}
QSharedPointer<MockSurface> MockCompositor::fullScreenShellV1Surface(int index)
{
QSharedPointer<MockSurface> result;
lock();
if (Impl::Surface *surface = m_compositor->fullScreenShellV1()->surfaces().value(index, nullptr))
result = surface->mockSurface();
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<MockCompositor *>(data);
Impl::Compositor compositor(controller);
controller->m_compositor = &compositor;
while (!controller->m_ready) {
controller->m_waitCondition.wakeOne();
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(MockCompositor *mockCompositor)
: m_mockCompositor(mockCompositor), m_display(wl_display_create())
{
if (wl_display_add_socket(m_display, 0)) {
fprintf(stderr, "Fatal: Failed to open server socket\n");
exit(EXIT_FAILURE);
}
wl_global_create(m_display, &wl_compositor_interface, 4, 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();
m_outputs.append(new Output(m_display, QSize(1920, 1080), QPoint(0, 0)));
m_iviApplication.reset(new IviApplication(m_display));
m_wlShell.reset(new WlShell(m_display));
m_fullScreenShellV1.reset(new FullScreenShellV1(m_display));
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<Compositor *>(wl_resource_get_user_data(compositorResource));
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)
{
Compositor *compositor =
static_cast<Compositor *>(wl_resource_get_user_data(compositorResource));
new Region(client, id, wl_resource_get_version(compositorResource), compositor);
}
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
};
wl_resource *resource = wl_resource_create(client, &wl_compositor_interface, static_cast<int>(version), id);
wl_resource_set_implementation(resource, &compositorInterface, compositorData, nullptr);
}
static void unregisterResourceCallback(wl_listener *listener, void *data)
{
struct wl_resource *resource = reinterpret_cast<struct wl_resource *>(data);
wl_list_remove(wl_resource_get_link(resource));
delete listener;
}
void registerResource(wl_list *list, wl_resource *resource)
{
wl_list_insert(list, wl_resource_get_link(resource));
wl_listener *listener = new wl_listener;
listener->notify = unregisterResourceCallback;
wl_resource_add_destroy_listener(resource, listener);
}
QList<Surface *> Compositor::surfaces() const
{
return m_surfaces;
}
QList<Output *> Compositor::outputs() const
{
return m_outputs;
}
IviApplication *Compositor::iviApplication() const
{
return m_iviApplication.data();
}
FullScreenShellV1 *Compositor::fullScreenShellV1() const
{
return m_fullScreenShellV1.data();
}
uint32_t Compositor::nextSerial()
{
return wl_display_next_serial(m_display);
}
void Compositor::addSurface(Surface *surface)
{
m_mockCompositor->lock();
m_surfaces << surface;
m_mockCompositor->unlock();
}
void Compositor::removeSurface(Surface *surface)
{
m_mockCompositor->lock();
m_surfaces.removeOne(surface);
m_keyboard->handleSurfaceDestroyed(surface);
m_pointer->handleSurfaceDestroyed(surface);
m_fullScreenShellV1->removeSurface(surface);
m_mockCompositor->unlock();
}
Surface *Compositor::resolveSurface(const QVariant &v)
{
QSharedPointer<MockSurface> mockSurface = v.value<QSharedPointer<MockSurface> >();
return mockSurface ? mockSurface->handle() : nullptr;
}
Output *Compositor::resolveOutput(const QVariant &v)
{
QSharedPointer<MockOutput> mockOutput = v.value<QSharedPointer<MockOutput> >();
return mockOutput ? mockOutput->handle() : nullptr;
}
IviSurface *Compositor::resolveIviSurface(const QVariant &v)
{
QSharedPointer<MockIviSurface> mockIviSurface = v.value<QSharedPointer<MockIviSurface>>();
return mockIviSurface ? mockIviSurface->handle() : nullptr;
}
}

View File

@ -1,268 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKCOMPOSITOR_H
#define MOCKCOMPOSITOR_H
#include "mockiviapplication.h"
#include "mockfullscreenshellv1.h"
#include "mockregion.h"
#include <pthread.h>
#include <qglobal.h>
#include <wayland-server-core.h>
#include <QImage>
#include <QRegion>
#include <QList>
#include <QMutex>
#include <QRect>
#include <QSharedPointer>
#include <QVariant>
#include <QWaitCondition>
class MockCompositor;
namespace Impl {
typedef void (**Implementation)(void);
class Keyboard;
class Pointer;
class Touch;
class Seat;
class DataDeviceManager;
class Surface;
class Output;
class IviApplication;
class WlShell;
class Region;
class Compositor
{
public:
Compositor(MockCompositor *mockCompositor);
~Compositor();
int fileDescriptor() const { return m_fd; }
void dispatchEvents(int timeout = 0);
uint32_t nextSerial();
uint32_t time() { return ++m_time; }
QList<Surface *> surfaces() const;
QList<Output *> outputs() const;
IviApplication *iviApplication() const;
FullScreenShellV1 *fullScreenShellV1() const;
void addSurface(Surface *surface);
void removeSurface(Surface *surface);
static void setKeyboardFocus(void *data, const QList<QVariant> &parameters);
static void sendMousePress(void *data, const QList<QVariant> &parameters);
static void sendMouseRelease(void *data, const QList<QVariant> &parameters);
static void sendKeyPress(void *data, const QList<QVariant> &parameters);
static void sendKeyRelease(void *data, const QList<QVariant> &parameters);
static void sendTouchDown(void *data, const QList<QVariant> &parameters);
static void sendTouchUp(void *data, const QList<QVariant> &parameters);
static void sendTouchMotion(void *data, const QList<QVariant> &parameters);
static void sendTouchFrame(void *data, const QList<QVariant> &parameters);
static void sendDataDeviceDataOffer(void *data, const QList<QVariant> &parameters);
static void sendDataDeviceEnter(void *data, const QList<QVariant> &parameters);
static void sendDataDeviceMotion(void *data, const QList<QVariant> &parameters);
static void sendDataDeviceDrop(void *data, const QList<QVariant> &parameters);
static void sendDataDeviceLeave(void *data, const QList<QVariant> &parameters);
static void waitForStartDrag(void *data, const QList<QVariant> &parameters);
static void setOutputMode(void *compositor, const QList<QVariant> &parameters);
static void sendShellSurfaceConfigure(void *data, const QList<QVariant> &parameters);
static void sendIviSurfaceConfigure(void *data, const QList<QVariant> &parameters);
public:
bool m_startDragSeen = false;
private:
static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id);
static Surface *resolveSurface(const QVariant &v);
static Output *resolveOutput(const QVariant &v);
static IviSurface *resolveIviSurface(const QVariant &v);
void initShm();
MockCompositor *m_mockCompositor = nullptr;
QRect m_outputGeometry;
wl_display *m_display = nullptr;
wl_event_loop *m_loop = nullptr;
int m_fd = -1;
uint32_t m_time = 0;
QScopedPointer<Seat> m_seat;
Pointer *m_pointer = nullptr;
Keyboard *m_keyboard = nullptr;
Touch *m_touch = nullptr;
QScopedPointer<DataDeviceManager> m_data_device_manager;
QList<Surface *> m_surfaces;
QList<Output *> m_outputs;
QScopedPointer<IviApplication> m_iviApplication;
QScopedPointer<WlShell> m_wlShell;
QScopedPointer<FullScreenShellV1> m_fullScreenShellV1;
};
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 = nullptr;
};
Q_DECLARE_METATYPE(QSharedPointer<MockSurface>)
class MockRegion
{
public:
Impl::Region *handle() const { return m_region; }
private:
MockRegion(Impl::Region *region);
friend class Impl::Compositor;
friend class Impl::Region;
Impl::Region *m_region = nullptr;
};
Q_DECLARE_METATYPE(QSharedPointer<MockRegion>)
class MockIviSurface
{
public:
Impl::IviSurface *handle() const { return m_iviSurface; }
const uint iviId;
private:
MockIviSurface(Impl::IviSurface *iviSurface) : iviId(iviSurface->iviId()), m_iviSurface(iviSurface) {}
friend class Impl::Compositor;
friend class Impl::IviSurface;
Impl::IviSurface *m_iviSurface;
};
Q_DECLARE_METATYPE(QSharedPointer<MockIviSurface>)
class MockOutput {
public:
Impl::Output *handle() const { return m_output; }
MockOutput(Impl::Output *output);
private:
Impl::Output *m_output = nullptr;
};
Q_DECLARE_METATYPE(QSharedPointer<MockOutput>)
class MockCompositor
{
public:
MockCompositor();
~MockCompositor();
void applicationInitialized();
int waylandFileDescriptor() const;
void processWaylandEvents();
void setOutputMode(const QSize &size);
void setKeyboardFocus(const QSharedPointer<MockSurface> &surface);
void sendMousePress(const QSharedPointer<MockSurface> &surface, const QPoint &pos);
void sendMouseRelease(const QSharedPointer<MockSurface> &surface);
void sendKeyPress(const QSharedPointer<MockSurface> &surface, uint code);
void sendKeyRelease(const QSharedPointer<MockSurface> &surface, uint code);
void sendTouchDown(const QSharedPointer<MockSurface> &surface, const QPoint &position, int id);
void sendTouchMotion(const QSharedPointer<MockSurface> &surface, const QPoint &position, int id);
void sendTouchUp(const QSharedPointer<MockSurface> &surface, int id);
void sendTouchFrame(const QSharedPointer<MockSurface> &surface);
void sendDataDeviceDataOffer(const QSharedPointer<MockSurface> &surface);
void sendDataDeviceEnter(const QSharedPointer<MockSurface> &surface, const QPoint &position);
void sendDataDeviceMotion(const QPoint &position);
void sendDataDeviceDrop(const QSharedPointer<MockSurface> &surface);
void sendDataDeviceLeave(const QSharedPointer<MockSurface> &surface);
void sendSurfaceEnter(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
void sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
void sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size = QSize(0, 0));
void sendIviSurfaceConfigure(const QSharedPointer<MockIviSurface> iviSurface, const QSize &size);
void waitForStartDrag();
QSharedPointer<MockSurface> surface();
QSharedPointer<MockOutput> output(int index = 0);
QSharedPointer<MockIviSurface> iviSurface(int index = 0);
QSharedPointer<MockSurface> fullScreenShellV1Surface(int index = 0);
void lock();
void unlock();
private:
struct Command
{
typedef void (*Callback)(void *target, const QList<QVariant> &parameters);
Callback callback;
void *target = nullptr;
QList<QVariant> parameters;
};
static Command makeCommand(Command::Callback callback, void *target);
void processCommand(const Command &command);
void dispatchCommands();
static void *run(void *data);
bool m_alive = true;
bool m_ready = false;
pthread_t m_thread;
QMutex m_mutex;
QWaitCondition m_waitCondition;
Impl::Compositor *m_compositor = nullptr;
QList<Command> m_commandQueue;
};
#endif

View File

@ -1,43 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockfullscreenshellv1.h"
#include "mocksurface.h"
namespace Impl {
void FullScreenShellV1::zwp_fullscreen_shell_v1_present_surface(Resource *resource, struct ::wl_resource *surface, uint32_t method, struct ::wl_resource *output)
{
Q_UNUSED(resource);
Q_UNUSED(method);
Q_UNUSED(output);
m_surfaces.append(Surface::fromResource(surface));
}
} // namespace Impl

View File

@ -1,58 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKFULLSCREENSHELLV1_H
#define MOCKFULLSCREENSHELLV1_H
#include <qwayland-server-fullscreen-shell-unstable-v1.h>
#include <QList>
namespace Impl {
class Surface;
class FullScreenShellV1;
class FullScreenShellV1 : public QtWaylandServer::zwp_fullscreen_shell_v1
{
public:
explicit FullScreenShellV1(::wl_display *display) : zwp_fullscreen_shell_v1(display, 1) {}
QList<Surface *> surfaces() const { return m_surfaces; }
void removeSurface(Surface *surface) { m_surfaces.removeOne(surface); }
protected:
void zwp_fullscreen_shell_v1_present_surface(Resource *resource, struct ::wl_resource *surface, uint32_t method, struct ::wl_resource *output) override;
private:
QList<Surface *> m_surfaces;
};
} // namespace Impl
#endif // MOCKFULLSCREENSHELLV1_H

View File

@ -1,474 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include "mockinput.h"
#include "mocksurface.h"
namespace Impl {
void Compositor::setKeyboardFocus(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
compositor->m_keyboard->setFocus(resolveSurface(parameters.first()));
}
void Compositor::sendMousePress(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
Surface *surface = resolveSurface(parameters.first());
if (!surface)
return;
compositor->m_pointer->sendButton(0x110, 0);
}
void Compositor::sendKeyPress(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
Surface *surface = resolveSurface(parameters.first());
Q_ASSERT(compositor);
Q_ASSERT(surface);
compositor->m_touch->sendFrame(surface);
}
void Compositor::sendDataDeviceDataOffer(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
Q_ASSERT(compositor);
QPoint position = parameters.first().toPoint();
compositor->m_data_device_manager->dataDevice()->sendMotion(position);
}
void Compositor::sendDataDeviceDrop(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(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<QVariant> &parameters)
{
Q_UNUSED(parameters);
Compositor *compositor = static_cast<Compositor *>(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)
: m_compositor(compositor)
{
}
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::handleSurfaceDestroyed(Surface *surface)
{
if (surface == m_focus) {
m_focusResource = nullptr;
m_focus = nullptr;
}
}
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)
: m_compositor(compositor)
{
}
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::handleSurfaceDestroyed(Surface *surface)
{
if (m_focus == surface) {
m_focus = nullptr;
m_focusResource = nullptr;
}
}
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);
auto x = wl_fixed_from_int(position.x());
auto y = wl_fixed_from_int(position.y());
wl_touch_send_down(resource->handle, serial, time, surface->resource()->handle, id, x, 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();
auto x = wl_fixed_from_int(position.x());
auto y = wl_fixed_from_int(position.y());
wl_touch_send_motion(resource->handle, time, id, x, 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)
: m_compositor(compositor)
{
}
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)
{
Q_UNUSED(resource);
Q_UNUSED(source);
Q_UNUSED(origin);
Q_UNUSED(icon);
Q_UNUSED(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)
{
Q_UNUSED(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);
}
}

View File

@ -1,172 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKINPUT_H
#define MOCKINPUT_H
#include <qglobal.h>
#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) override;
void seat_get_keyboard(Resource *resource, uint32_t id) override;
void seat_get_pointer(Resource *resource, uint32_t id) override;
void seat_get_touch(Resource *resource, uint32_t id) override;
private:
Compositor *m_compositor = nullptr;
QScopedPointer<Keyboard> m_keyboard;
QScopedPointer<Pointer> m_pointer;
QScopedPointer<Touch> m_touch;
};
class Keyboard : public QtWaylandServer::wl_keyboard
{
public:
Keyboard(Compositor *compositor);
~Keyboard();
Surface *focus() const { return m_focus; }
void setFocus(Surface *surface);
void handleSurfaceDestroyed(Surface *surface);
void sendKey(uint32_t key, uint32_t state);
protected:
void keyboard_destroy_resource(wl_keyboard::Resource *resource) override;
private:
Compositor *m_compositor = nullptr;
Resource *m_focusResource = nullptr;
Surface *m_focus = nullptr;
};
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 handleSurfaceDestroyed(Surface *surface);
void sendMotion(const QPoint &pos);
void sendButton(uint32_t button, uint32_t state);
protected:
void pointer_destroy_resource(wl_pointer::Resource *resource) override;
private:
Compositor *m_compositor = nullptr;
Resource *m_focusResource = nullptr;
Surface *m_focus = nullptr;
};
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 = nullptr;
};
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 = nullptr;
QtWaylandServer::wl_data_offer *m_dataOffer = nullptr;
Surface* m_focus = nullptr;
};
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) override;
void data_device_manager_create_data_source(Resource *resource, uint32_t id) override;
private:
Compositor *m_compositor = nullptr;
QScopedPointer<DataDevice> m_data_device;
};
}
#endif // MOCKINPUT_H

View File

@ -1,72 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockiviapplication.h"
#include "mocksurface.h"
#include "mockcompositor.h"
namespace Impl {
void Compositor::sendIviSurfaceConfigure(void *data, const QList<QVariant> &parameters)
{
Q_UNUSED(data);
IviSurface *iviSurface = resolveIviSurface(parameters.at(0));
Q_ASSERT(iviSurface && iviSurface->resource());
QSize size = parameters.at(1).toSize();
Q_ASSERT(!size.isEmpty());
iviSurface->send_configure(size.width(), size.height());
}
IviSurface::IviSurface(IviApplication *iviApplication, Surface *surface, uint iviId, wl_client *client, uint32_t id)
: QtWaylandServer::ivi_surface(client, id, 1)
, m_surface(surface)
, m_iviApplication(iviApplication)
, m_iviId(iviId)
, m_mockIviSurface(new MockIviSurface(this))
{
iviApplication->addIviSurface(this);
surface->map();
}
IviSurface::~IviSurface()
{
m_iviApplication->removeIviSurface(this);
m_mockIviSurface->m_iviSurface = nullptr;
}
void IviSurface::ivi_surface_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void IviApplication::ivi_application_surface_create(Resource *resource, uint32_t ivi_id, ::wl_resource *surface, uint32_t id)
{
new IviSurface(this, Surface::fromResource(surface), ivi_id, resource->client(), id);
}
} // namespace Impl

View File

@ -1,85 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKIVIAPPLICATION_H
#define MOCKIVIAPPLICATION_H
#include <qwayland-server-ivi-application.h>
#include <QList>
#include <QSharedPointer>
class MockIviSurface;
namespace Impl {
class Surface;
class IviApplication;
class IviSurface : public QtWaylandServer::ivi_surface
{
public:
IviSurface(IviApplication *iviApplication, Surface *surface, uint iviId, wl_client *client, uint32_t id);
~IviSurface() override;
IviApplication *iviApplication() const { return m_iviApplication; }
Surface *surface() const { return m_surface; }
uint iviId() const { return m_iviId; }
QSharedPointer<MockIviSurface> mockIviSurface() const { return m_mockIviSurface; }
protected:
void ivi_surface_destroy_resource(Resource *) override { delete this; }
void ivi_surface_destroy(Resource *resource) override;
private:
Surface *m_surface = nullptr;
IviApplication *m_iviApplication = nullptr;
const uint m_iviId = 0;
QSharedPointer<MockIviSurface> m_mockIviSurface;
};
class IviApplication : public QtWaylandServer::ivi_application
{
public:
explicit IviApplication(::wl_display *display) : ivi_application(display, 1) {}
QList<IviSurface *> iviSurfaces() const { return m_iviSurfaces; }
protected:
void ivi_application_surface_create(Resource *resource, uint32_t ivi_id, ::wl_resource *surface, uint32_t id) override;
private:
void addIviSurface(IviSurface *iviSurface) { m_iviSurfaces.append(iviSurface); }
void removeIviSurface(IviSurface *iviSurface) { m_iviSurfaces.removeOne(iviSurface); }
QList<IviSurface *> m_iviSurfaces;
friend class IviSurface;
};
} // namespace Impl
#endif // MOCKIVIAPPLICATION_H

View File

@ -1,93 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include "mockoutput.h"
#include <QDebug>
namespace Impl {
void Compositor::setOutputMode(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
QSize size = parameters.first().toSize();
Output *output = compositor->m_outputs.first();
Q_ASSERT(output);
output->setCurrentMode(size);
}
Output::Output(wl_display *display, const QSize &resolution, const QPoint &position)
: wl_output(display, 2)
, m_size(resolution)
, m_position(position)
, m_physicalSize(520, 320)
, m_mockOutput(new MockOutput(this))
{
}
void Output::setCurrentMode(const QSize &size)
{
m_size = size;
for (Resource *resource : resourceMap()) {
sendCurrentMode(resource);
send_done(resource->handle);
}
}
void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource)
{
sendGeometry(resource);
sendCurrentMode(resource);
send_done(resource->handle);
}
void Output::sendGeometry(Resource *resource)
{
const int subPixel = 0;
const int transform = 0;
send_geometry(resource->handle,
m_position.x(), m_position.y(),
m_physicalSize.width(), m_physicalSize.height(),
subPixel, "", "", transform );
}
void Output::sendCurrentMode(Resource *resource)
{
send_mode(resource->handle,
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
m_size.width(), m_size.height(), 60000);
}
} // Impl
MockOutput::MockOutput(Impl::Output *output)
: m_output(output)
{
}

View File

@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKOUTPUT_H
#define MOCKOUTPUT_H
#include <qglobal.h>
#include "qwayland-server-wayland.h"
#include "mockcompositor.h"
namespace Impl {
class Output : public QtWaylandServer::wl_output
{
public:
Output(::wl_display *display, const QSize &resolution, const QPoint &position);
QSharedPointer<MockOutput> mockOutput() const { return m_mockOutput; }
void setCurrentMode(const QSize &size);
protected:
void output_bind_resource(Resource *resource) override;
private:
void sendGeometry(Resource *resource);
void sendCurrentMode(Resource *resource);
QSize m_size;
QPoint m_position;
const QSize m_physicalSize;
QSharedPointer<MockOutput> m_mockOutput;
};
}
#endif // MOCKOUTPUT_H

View File

@ -1,51 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockregion.h"
#include "mockcompositor.h"
namespace Impl {
Region::Region(wl_client *client, uint32_t id, int v, Compositor *compositor)
: QtWaylandServer::wl_region(client, id, v),
m_compositor(compositor),
m_mockRegion(new MockRegion(this))
{
}
Region::~Region() = default;
void Region::region_destroy_resource(Resource *resource)
{
Q_UNUSED(resource)
delete this;
}
}
MockRegion::MockRegion(Impl::Region *region) : m_region(region) { }

View File

@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKREGION_H
#define MOCKREGION_H
#include <qglobal.h>
#include <QSharedPointer>
#include "qwayland-server-wayland.h"
class MockRegion;
namespace Impl {
class Compositor;
class Region : public QtWaylandServer::wl_region
{
public:
Region(wl_client *client, uint32_t id, int v, Compositor *compositor);
~Region();
Compositor *compositor() const { return m_compositor; }
static Region *fromResource(struct ::wl_resource *resource);
protected:
void region_destroy_resource(Resource *resource) override;
private:
Compositor *m_compositor = nullptr;
QSharedPointer<MockRegion> m_mockRegion;
};
}
#endif // MOCKREGION_H

View File

@ -1,160 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mocksurface.h"
#include "mockoutput.h"
#include "mockcompositor.h"
#include "mockwlshell.h"
#include <QDebug>
namespace Impl {
void Compositor::sendShellSurfaceConfigure(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
Surface *surface = resolveSurface(parameters.at(0));
QSize size = parameters.at(1).toSize();
Q_ASSERT(size.isValid());
if (auto wlShellSurface = surface->wlShellSurface()) {
const uint edges = 0;
wlShellSurface->send_configure(edges, size.width(), size.height());
} else {
qWarning() << "The mocking framework doesn't know how to send a configure event for this surface";
}
}
Surface::Surface(wl_client *client, uint32_t id, int v, Compositor *compositor)
: QtWaylandServer::wl_surface(client, id, v)
, m_compositor(compositor)
, m_mockSurface(new MockSurface(this))
{
}
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)
{
if (auto *r = Resource::fromResource(resource))
return static_cast<Surface *>(r->surface_object);
return nullptr;
}
void Surface::surface_destroy_resource(Resource *)
{
compositor()->removeSurface(this);
delete this;
}
void Surface::surface_destroy(Resource *resource)
{
if (m_wlShellSurface) // on wl-shell the shell surface is automatically destroyed with the surface
wl_resource_destroy(m_wlShellSurface->resource()->handle);
Q_ASSERT(!m_wlShellSurface);
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_damage_buffer(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_resource_create(resource->client(), &wl_callback_interface, 1, callback);
m_frameCallbackList << frameCallback;
}
void Surface::surface_commit(Resource *resource)
{
Q_UNUSED(resource);
if (m_buffer) {
struct ::wl_shm_buffer *shm_buffer = wl_shm_buffer_get(m_buffer);
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<const uchar *>(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;
}
}
for (wl_resource *frameCallback : qExchange(m_frameCallbackList, {})) {
wl_callback_send_done(frameCallback, m_compositor->time());
wl_resource_destroy(frameCallback);
}
}
}
MockSurface::MockSurface(Impl::Surface *surface)
: m_surface(surface)
{
}

View File

@ -1,84 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKSURFACE_H
#define MOCKSURFACE_H
#include <qglobal.h>
#include "qwayland-server-wayland.h"
#include "mockcompositor.h"
namespace Impl {
class WlShellSurface;
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;
WlShellSurface *wlShellSurface() const { return m_wlShellSurface; }
QSharedPointer<MockSurface> mockSurface() const { return m_mockSurface; }
protected:
void surface_destroy_resource(Resource *resource) override;
void surface_destroy(Resource *resource) override;
void surface_attach(Resource *resource,
struct wl_resource *buffer, int x, int y) override;
void surface_damage(Resource *resource,
int32_t x, int32_t y, int32_t width, int32_t height) override;
void surface_damage_buffer(Resource *resource,
int32_t x, int32_t y, int32_t width, int32_t height) override;
void surface_frame(Resource *resource,
uint32_t callback) override;
void surface_commit(Resource *resource) override;
private:
wl_resource *m_buffer = nullptr;
WlShellSurface *m_wlShellSurface = nullptr;
Compositor *m_compositor = nullptr;
QSharedPointer<MockSurface> m_mockSurface;
QList<wl_resource *> m_frameCallbackList;
bool m_mapped = false;
friend class WlShellSurface;
};
}
#endif // MOCKSURFACE_H

View File

@ -1,52 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockwlshell.h"
#include "mocksurface.h"
namespace Impl {
WlShellSurface::WlShellSurface(wl_client *client, int id, Surface *surface)
: QtWaylandServer::wl_shell_surface(client, id, 1)
, m_surface(surface)
{
surface->m_wlShellSurface = this;
surface->map();
}
WlShellSurface::~WlShellSurface()
{
m_surface->m_wlShellSurface = nullptr;
}
void WlShell::shell_get_shell_surface(QtWaylandServer::wl_shell::Resource *resource, uint32_t id, wl_resource *surface)
{
new WlShellSurface(resource->client(), id, Surface::fromResource(surface));
}
} // namespace Impl

View File

@ -1,58 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qwayland-server-wayland.h>
#ifndef MOCKWLSHELL_H
#define MOCKWLSHELL_H
namespace Impl {
class Surface;
class WlShellSurface : public QtWaylandServer::wl_shell_surface
{
public:
explicit WlShellSurface(::wl_client *client, int id, Surface *surface);
~WlShellSurface() override;
void shell_surface_destroy_resource(Resource *) override { delete this; }
private:
Surface *m_surface = nullptr;
};
class WlShell : public QtWaylandServer::wl_shell
{
public:
explicit WlShell(::wl_display *display) : wl_shell(display, 1) {}
void shell_get_shell_surface(Resource *resource, uint32_t id, ::wl_resource *surface) override;
};
} // namespace Impl
#endif // MOCKWLSHELL_H

View File

@ -1,34 +0,0 @@
CONFIG += testcase link_pkgconfig
QT += testlib
QT += core-private gui-private waylandclient-private opengl
QMAKE_USE += wayland-client wayland-server
CONFIG += wayland-scanner
WAYLANDSERVERSOURCES += \
../../../../src/3rdparty/protocol/ivi-application.xml \
../../../../src/3rdparty/protocol/wayland.xml \
../../../../src/3rdparty/protocol/xdg-shell.xml \
../../../../src/3rdparty/protocol/fullscreen-shell-unstable-v1.xml
INCLUDEPATH += ../shared_old
SOURCES += \
../shared_old/mockcompositor.cpp \
../shared_old/mockfullscreenshellv1.cpp \
../shared_old/mockinput.cpp \
../shared_old/mockiviapplication.cpp \
../shared_old/mockwlshell.cpp \
../shared_old/mocksurface.cpp \
../shared_old/mockregion.cpp \
../shared_old/mockoutput.cpp
HEADERS += \
../shared_old/mockcompositor.h \
../shared_old/mockfullscreenshellv1.h \
../shared_old/mockinput.h \
../shared_old/mockiviapplication.h \
../shared_old/mockwlshell.h \
../shared_old/mocksurface.h \
../shared_old/mockregion.h \
../shared_old/mockoutput.h