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:
parent
5c9a38e768
commit
4767e91f7b
@ -6,34 +6,9 @@
|
|||||||
|
|
||||||
qt_internal_add_test(tst_client
|
qt_internal_add_test(tst_client
|
||||||
SOURCES
|
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
|
tst_client.cpp
|
||||||
INCLUDE_DIRECTORIES
|
|
||||||
../shared_old
|
|
||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::CorePrivate
|
SharedClientTest
|
||||||
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
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#### Keys ignored in scope 1:.:.:client.pro:<TRUE>:
|
#### Keys ignored in scope 1:.:.:client.pro:<TRUE>:
|
||||||
|
@ -44,8 +44,24 @@
|
|||||||
#include <QtWaylandClient/private/qwaylandintegration_p.h>
|
#include <QtWaylandClient/private/qwaylandintegration_p.h>
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
|
|
||||||
|
using namespace MockCompositor;
|
||||||
|
|
||||||
static const QSize screenSize(1600, 1200);
|
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
|
class TestWindow : public QWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -141,35 +157,14 @@ void TestGlWindow::paintGL()
|
|||||||
}
|
}
|
||||||
#endif // QT_CONFIG(opengl)
|
#endif // QT_CONFIG(opengl)
|
||||||
|
|
||||||
class tst_WaylandClient : public QObject
|
class tst_WaylandClient : public QObject, private TestCompositor
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
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:
|
private slots:
|
||||||
|
void cleanup() {
|
||||||
|
QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage()));
|
||||||
|
}
|
||||||
void createDestroyWindow();
|
void createDestroyWindow();
|
||||||
void activeWindowFollowsKeyboardFocus();
|
void activeWindowFollowsKeyboardFocus();
|
||||||
void events();
|
void events();
|
||||||
@ -184,9 +179,6 @@ private slots:
|
|||||||
#endif // QT_CONFIG(opengl)
|
#endif // QT_CONFIG(opengl)
|
||||||
void longWindowTitle();
|
void longWindowTitle();
|
||||||
void longWindowTitleWithUtf16Characters();
|
void longWindowTitleWithUtf16Characters();
|
||||||
|
|
||||||
private:
|
|
||||||
MockCompositor *compositor = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_WaylandClient::createDestroyWindow()
|
void tst_WaylandClient::createDestroyWindow()
|
||||||
@ -194,10 +186,10 @@ void tst_WaylandClient::createDestroyWindow()
|
|||||||
TestWindow window;
|
TestWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
QTRY_VERIFY(compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
|
|
||||||
window.destroy();
|
window.destroy();
|
||||||
QTRY_VERIFY(!compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_WaylandClient::activeWindowFollowsKeyboardFocus()
|
void tst_WaylandClient::activeWindowFollowsKeyboardFocus()
|
||||||
@ -205,21 +197,26 @@ void tst_WaylandClient::activeWindowFollowsKeyboardFocus()
|
|||||||
TestWindow window;
|
TestWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
WlShellSurface *ss = s->wlShellSurface();
|
||||||
|
ss->sendConfigure(0, 0, 0);
|
||||||
|
|
||||||
QTRY_VERIFY(window.isExposed());
|
QCOMPOSITOR_TRY_VERIFY(window.isExposed());
|
||||||
|
|
||||||
QCOMPARE(window.focusInEventCount, 0);
|
QCOMPARE(window.focusInEventCount, 0);
|
||||||
compositor->setKeyboardFocus(surface);
|
exec([=] {
|
||||||
|
keyboard()->sendEnter(s);
|
||||||
|
});
|
||||||
QTRY_COMPARE(window.focusInEventCount, 1);
|
QTRY_COMPARE(window.focusInEventCount, 1);
|
||||||
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
|
QCOMPARE(QGuiApplication::focusWindow(), &window);
|
||||||
|
|
||||||
QCOMPARE(window.focusOutEventCount, 0);
|
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(window.focusOutEventCount, 1);
|
||||||
QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(nullptr));
|
QCOMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_WaylandClient::events()
|
void tst_WaylandClient::events()
|
||||||
@ -227,46 +224,77 @@ void tst_WaylandClient::events()
|
|||||||
TestWindow window;
|
TestWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
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(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
|
uint keyCode = 80; // arbitrarily chosen
|
||||||
QCOMPARE(window.keyPressEventCount, 0);
|
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.keyPressEventCount, 1);
|
||||||
QTRY_COMPARE(window.keyCode, keyCode);
|
QCOMPARE(window.keyCode, keyCode);
|
||||||
|
|
||||||
QCOMPARE(window.keyReleaseEventCount, 0);
|
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);
|
QTRY_COMPARE(window.keyReleaseEventCount, 1);
|
||||||
QCOMPARE(window.keyCode, keyCode);
|
QCOMPARE(window.keyCode, keyCode);
|
||||||
|
|
||||||
const int touchId = 0;
|
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.
|
// Note: wl_touch.frame should not be the last event in a test until QTBUG-66563 is fixed.
|
||||||
// See also: QTBUG-66537
|
// See also: QTBUG-66537
|
||||||
compositor->sendTouchFrame(surface);
|
exec([=] {
|
||||||
|
touch()->sendFrame(client());
|
||||||
|
});
|
||||||
QTRY_COMPARE(window.touchEventCount, 1);
|
QTRY_COMPARE(window.touchEventCount, 1);
|
||||||
|
|
||||||
compositor->sendTouchUp(surface, touchId);
|
exec([=] {
|
||||||
compositor->sendTouchFrame(surface);
|
touch()->sendUp(client(), touchId);
|
||||||
|
touch()->sendFrame(client());
|
||||||
|
});
|
||||||
QTRY_COMPARE(window.touchEventCount, 2);
|
QTRY_COMPARE(window.touchEventCount, 2);
|
||||||
|
|
||||||
QPoint mousePressPos(16, 16);
|
QPoint mousePressPos(16, 16);
|
||||||
QCOMPARE(window.mousePressEventCount, 0);
|
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.mousePressEventCount, 1);
|
||||||
QTRY_COMPARE(window.mousePressPos, mousePressPos);
|
QTRY_COMPARE(window.mousePressPos, mousePressPos);
|
||||||
|
|
||||||
QCOMPARE(window.mouseReleaseEventCount, 0);
|
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);
|
QTRY_COMPARE(window.mouseReleaseEventCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,9 +303,10 @@ void tst_WaylandClient::backingStore()
|
|||||||
TestWindow window;
|
TestWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
WlShellSurface *ss = s->wlShellSurface();
|
||||||
|
ss->sendConfigure(0, 0, 0);
|
||||||
|
|
||||||
QRect rect(QPoint(), window.size());
|
QRect rect(QPoint(), window.size());
|
||||||
|
|
||||||
@ -294,17 +323,17 @@ void tst_WaylandClient::backingStore()
|
|||||||
|
|
||||||
backingStore.endPaint();
|
backingStore.endPaint();
|
||||||
|
|
||||||
QVERIFY(surface->image.isNull());
|
QVERIFY(s->m_image.isNull());
|
||||||
|
|
||||||
backingStore.flush(rect);
|
backingStore.flush(rect);
|
||||||
|
|
||||||
QTRY_COMPARE(surface->image.size(), window.frameGeometry().size());
|
QTRY_COMPARE(s->m_image.size(), window.frameGeometry().size());
|
||||||
QTRY_COMPARE(surface->image.pixel(window.frameMargins().left(), window.frameMargins().top()), color.rgba());
|
QTRY_COMPARE(s->m_image.pixel(window.frameMargins().left(), window.frameMargins().top()), color.rgba());
|
||||||
|
|
||||||
window.hide();
|
window.hide();
|
||||||
|
|
||||||
// hiding the window should destroy the surface
|
// hiding the window should destroy the surface
|
||||||
QTRY_VERIFY(!compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
class DndWindow : public QWindow
|
class DndWindow : public QWindow
|
||||||
@ -343,29 +372,75 @@ private:
|
|||||||
QPixmap m_dragIcon;
|
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()
|
void tst_WaylandClient::touchDrag()
|
||||||
{
|
{
|
||||||
DndWindow window;
|
DndWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
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);
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
|
||||||
|
|
||||||
const int id = 0;
|
const int touchId = 0;
|
||||||
compositor->sendTouchDown(surface, window.frameOffset() + QPoint(10, 10), id);
|
exec([&] {
|
||||||
compositor->sendTouchFrame(surface);
|
touch()->sendDown(s, window.frameOffset() + QPoint(10, 10), touchId);
|
||||||
compositor->sendTouchMotion(surface, window.frameOffset() + QPoint(20, 20), id);
|
touch()->sendFrame(client());
|
||||||
compositor->sendTouchFrame(surface);
|
touch()->sendMotion(client(), window.frameOffset() + QPoint(20, 20), touchId);
|
||||||
compositor->waitForStartDrag();
|
touch()->sendFrame(client());
|
||||||
compositor->sendDataDeviceDataOffer(surface);
|
});
|
||||||
compositor->sendDataDeviceEnter(surface, window.frameOffset() + QPoint(20, 20));
|
|
||||||
compositor->sendDataDeviceMotion(window.frameOffset() + QPoint(21, 21));
|
|
||||||
compositor->sendDataDeviceDrop(surface);
|
|
||||||
compositor->sendDataDeviceLeave(surface);
|
|
||||||
QTRY_VERIFY(window.dragStarted);
|
QTRY_VERIFY(window.dragStarted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,20 +449,39 @@ void tst_WaylandClient::mouseDrag()
|
|||||||
DndWindow window;
|
DndWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
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);
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
|
||||||
|
|
||||||
compositor->sendMousePress(surface, window.frameOffset() + QPoint(10, 10));
|
QPoint mousePressPos(16, 16);
|
||||||
compositor->sendDataDeviceDataOffer(surface);
|
exec([&] {
|
||||||
compositor->sendDataDeviceEnter(surface, window.frameOffset() + QPoint(20, 20));
|
pointer()->sendEnter(s, window.frameOffset() + mousePressPos);
|
||||||
compositor->sendDataDeviceMotion(window.frameOffset() + QPoint(21, 21));
|
pointer()->sendFrame(client());
|
||||||
compositor->waitForStartDrag();
|
pointer()->sendMotion(client(), window.frameOffset() + mousePressPos);
|
||||||
compositor->sendDataDeviceDrop(surface);
|
pointer()->sendFrame(client());
|
||||||
compositor->sendDataDeviceLeave(surface);
|
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);
|
QTRY_VERIFY(window.dragStarted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,10 +506,11 @@ void tst_WaylandClient::dontCrashOnMultipleCommits()
|
|||||||
backingStore.flush(rect);
|
backingStore.flush(rect);
|
||||||
backingStore.flush(rect);
|
backingStore.flush(rect);
|
||||||
|
|
||||||
compositor->processWaylandEvents();
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
delete window;
|
delete window;
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_WaylandClient::hiddenTransientParent()
|
void tst_WaylandClient::hiddenTransientParent()
|
||||||
@ -426,15 +521,14 @@ void tst_WaylandClient::hiddenTransientParent()
|
|||||||
transient.setTransientParent(&parent);
|
transient.setTransientParent(&parent);
|
||||||
|
|
||||||
parent.show();
|
parent.show();
|
||||||
QTRY_VERIFY(compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
|
|
||||||
parent.hide();
|
parent.hide();
|
||||||
QTRY_VERIFY(!compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
|
||||||
|
|
||||||
transient.show();
|
transient.show();
|
||||||
QTRY_VERIFY(compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_WaylandClient::hiddenPopupParent()
|
void tst_WaylandClient::hiddenPopupParent()
|
||||||
{
|
{
|
||||||
TestWindow toplevel;
|
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
|
// wl_shell relies on a mouse event in order to send a serial and seat
|
||||||
// with the set_popup request.
|
// with the set_popup request.
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
WlShellSurface *ss = s->wlShellSurface();
|
||||||
|
ss->sendConfigure(0, 0, 0);
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(toplevel.isExposed());
|
||||||
|
|
||||||
QPoint mousePressPos(16, 16);
|
QPoint mousePressPos(16, 16);
|
||||||
QCOMPARE(toplevel.mousePressEventCount, 0);
|
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);
|
QTRY_COMPARE(toplevel.mousePressEventCount, 1);
|
||||||
|
|
||||||
QWindow popup;
|
QWindow popup;
|
||||||
@ -455,10 +559,10 @@ void tst_WaylandClient::hiddenPopupParent()
|
|||||||
popup.setFlag(Qt::Popup, true);
|
popup.setFlag(Qt::Popup, true);
|
||||||
|
|
||||||
toplevel.hide();
|
toplevel.hide();
|
||||||
QTRY_VERIFY(!compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
|
||||||
|
|
||||||
popup.show();
|
popup.show();
|
||||||
QTRY_VERIFY(compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(opengl)
|
#if QT_CONFIG(opengl)
|
||||||
@ -468,9 +572,10 @@ void tst_WaylandClient::glWindow()
|
|||||||
|
|
||||||
QScopedPointer<TestGlWindow> testWindow(new TestGlWindow);
|
QScopedPointer<TestGlWindow> testWindow(new TestGlWindow);
|
||||||
testWindow->show();
|
testWindow->show();
|
||||||
QSharedPointer<MockSurface> surface;
|
Surface *s = nullptr;
|
||||||
QTRY_VERIFY(surface = compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(s = wlSurface(0));
|
||||||
compositor->sendShellSurfaceConfigure(surface);
|
WlShellSurface *ss = s->wlShellSurface();
|
||||||
|
ss->sendConfigure(0, 0, 0);
|
||||||
|
|
||||||
QTRY_COMPARE(testWindow->paintGLCalled, 1);
|
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
|
//confirm we don't crash when we delete an already hidden GL window
|
||||||
//QTBUG-65553
|
//QTBUG-65553
|
||||||
testWindow->setVisible(false);
|
testWindow->setVisible(false);
|
||||||
QTRY_VERIFY(!compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(!wlSurface(0));
|
||||||
}
|
}
|
||||||
#endif // QT_CONFIG(opengl)
|
#endif // QT_CONFIG(opengl)
|
||||||
|
|
||||||
@ -496,7 +601,7 @@ void tst_WaylandClient::longWindowTitle()
|
|||||||
QString absurdlyLongTitle(10000, QLatin1Char('z'));
|
QString absurdlyLongTitle(10000, QLatin1Char('z'));
|
||||||
window.setTitle(absurdlyLongTitle);
|
window.setTitle(absurdlyLongTitle);
|
||||||
window.show();
|
window.show();
|
||||||
QTRY_VERIFY(compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_WaylandClient::longWindowTitleWithUtf16Characters()
|
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
|
Q_ASSERT(absurdlyLongTitle.length() == 10000); // just making sure the test isn't broken
|
||||||
window.setTitle(absurdlyLongTitle);
|
window.setTitle(absurdlyLongTitle);
|
||||||
window.show();
|
window.show();
|
||||||
QTRY_VERIFY(compositor->surface());
|
QCOMPOSITOR_TRY_VERIFY(wlSurface(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -514,22 +619,13 @@ int main(int argc, char **argv)
|
|||||||
QTemporaryDir tmpRuntimeDir;
|
QTemporaryDir tmpRuntimeDir;
|
||||||
setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1);
|
setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1);
|
||||||
setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
|
setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
|
||||||
|
setenv("QT_WAYLAND_SHELL_INTEGRATION", "wl-shell", 1);
|
||||||
|
|
||||||
MockCompositor compositor;
|
tst_WaylandClient tc;
|
||||||
compositor.setOutputMode(screenSize);
|
|
||||||
|
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
|
QTEST_SET_MAIN_SOURCE_PATH
|
||||||
// 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);
|
|
||||||
return QTest::qExec(&tc, argc, argv);
|
return QTest::qExec(&tc, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <tst_client.moc>
|
#include <tst_client.moc>
|
||||||
|
|
||||||
|
@ -31,8 +31,9 @@
|
|||||||
|
|
||||||
namespace MockCompositor {
|
namespace MockCompositor {
|
||||||
|
|
||||||
CoreCompositor::CoreCompositor()
|
CoreCompositor::CoreCompositor(CompositorType t)
|
||||||
: m_display(wl_display_create())
|
: m_type(t)
|
||||||
|
, m_display(wl_display_create())
|
||||||
, m_socketName(wl_display_add_socket_auto(m_display))
|
, m_socketName(wl_display_add_socket_auto(m_display))
|
||||||
, m_eventLoop(wl_display_get_event_loop(m_display))
|
, m_eventLoop(wl_display_get_event_loop(m_display))
|
||||||
|
|
||||||
@ -77,11 +78,10 @@ QString CoreCompositor::dirtyMessage()
|
|||||||
return messages.join(", ");
|
return messages.join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreCompositor::dispatch()
|
void CoreCompositor::dispatch(int timeout)
|
||||||
{
|
{
|
||||||
Lock lock(this);
|
Lock lock(this);
|
||||||
wl_display_flush_clients(m_display);
|
wl_display_flush_clients(m_display);
|
||||||
constexpr int timeout = 0; // immediate return
|
|
||||||
wl_event_loop_dispatch(m_eventLoop, timeout);
|
wl_event_loop_dispatch(m_eventLoop, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,11 +48,17 @@ public:
|
|||||||
class CoreCompositor
|
class CoreCompositor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CoreCompositor();
|
enum CompositorType {
|
||||||
|
Default,
|
||||||
|
Legacy // wl-shell
|
||||||
|
};
|
||||||
|
|
||||||
|
CompositorType m_type = Default;
|
||||||
|
explicit CoreCompositor(CompositorType t = Default);
|
||||||
~CoreCompositor();
|
~CoreCompositor();
|
||||||
bool isClean();
|
bool isClean();
|
||||||
QString dirtyMessage();
|
QString dirtyMessage();
|
||||||
void dispatch();
|
void dispatch(int timeout = 0);
|
||||||
|
|
||||||
template<typename function_type, typename... arg_types>
|
template<typename function_type, typename... arg_types>
|
||||||
auto exec(function_type func, arg_types&&... args) -> decltype(func())
|
auto exec(function_type func, arg_types&&... args) -> decltype(func())
|
||||||
@ -164,6 +170,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
// Only use this carefully from the test thread (i.e. lock first)
|
// Only use this carefully from the test thread (i.e. lock first)
|
||||||
wl_display *m_display = nullptr;
|
wl_display *m_display = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Lock {
|
class Lock {
|
||||||
public:
|
public:
|
||||||
|
@ -31,6 +31,21 @@
|
|||||||
|
|
||||||
namespace MockCompositor {
|
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()
|
void Surface::sendFrameCallbacks()
|
||||||
{
|
{
|
||||||
uint time = m_wlCompositor->m_compositor->currentTimeMilliseconds();
|
uint time = m_wlCompositor->m_compositor->currentTimeMilliseconds();
|
||||||
@ -55,6 +70,11 @@ void Surface::sendLeave(Output *output)
|
|||||||
wl_surface::send_leave(resource()->handle, outputResource->handle);
|
wl_surface::send_leave(resource()->handle, outputResource->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Surface::map()
|
||||||
|
{
|
||||||
|
m_mapped = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Surface::surface_destroy_resource(Resource *resource)
|
void Surface::surface_destroy_resource(Resource *resource)
|
||||||
{
|
{
|
||||||
Q_UNUSED(resource);
|
Q_UNUSED(resource);
|
||||||
@ -65,14 +85,29 @@ void Surface::surface_destroy_resource(Resource *resource)
|
|||||||
delete 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, wl_resource *buffer, int32_t x, int32_t y)
|
void Surface::surface_attach(Resource *resource, wl_resource *buffer, int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
Q_UNUSED(resource);
|
Q_UNUSED(resource);
|
||||||
QPoint offset(x, y);
|
if (m_wlshell) {
|
||||||
m_pending.buffer = fromResource<Buffer>(buffer);
|
m_buffer = buffer;
|
||||||
m_pending.commitSpecific.attachOffset = offset;
|
if (!buffer)
|
||||||
m_pending.commitSpecific.attached = true;
|
m_image = QImage();
|
||||||
emit attach(buffer, offset);
|
} 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)
|
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)
|
void Surface::surface_commit(Resource *resource)
|
||||||
{
|
{
|
||||||
Q_UNUSED(resource);
|
Q_UNUSED(resource);
|
||||||
m_committed = m_pending;
|
|
||||||
m_commits.append(new DoubleBufferedState(m_committed));
|
|
||||||
|
|
||||||
if (auto *frame = m_pending.commitSpecific.frame)
|
if (m_wlshell) {
|
||||||
m_waitingFrameCallbacks.append(frame);
|
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();
|
for (wl_resource *frameCallback : qExchange(m_frameCallbackList, {})) {
|
||||||
emit commit();
|
auto time = m_wlCompositor->m_compositor->currentTimeMilliseconds();
|
||||||
if (m_committed.commitSpecific.attached)
|
wl_callback_send_done(frameCallback, time);
|
||||||
emit bufferCommitted();
|
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)
|
void Surface::surface_frame(Resource *resource, uint32_t callback)
|
||||||
{
|
{
|
||||||
// Although valid, there is really no point having multiple frame requests in the same commit.
|
if (m_wlshell) {
|
||||||
// Make sure we don't do it
|
wl_resource *frameCallback = wl_resource_create(resource->client(), &wl_callback_interface, 1, callback);
|
||||||
QCOMPARE(m_pending.commitSpecific.frame, nullptr);
|
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);
|
auto *frame = new Callback(resource->client(), callback, 1);
|
||||||
m_pending.commitSpecific.frame = frame;
|
m_pending.commitSpecific.frame = frame;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WlCompositor::isClean() {
|
bool WlCompositor::isClean() {
|
||||||
for (auto *surface : qAsConst(m_surfaces)) {
|
for (auto *surface : qAsConst(m_surfaces)) {
|
||||||
if (!CursorRole::fromSurface(surface))
|
if (!CursorRole::fromSurface(surface)) {
|
||||||
return false;
|
if (m_compositor->m_type != CoreCompositor::CompositorType::Legacy)
|
||||||
|
return false;
|
||||||
|
if (surface->isMapped())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -299,8 +365,9 @@ uint Pointer::sendEnter(Surface *surface, const QPointF &position)
|
|||||||
|
|
||||||
wl_client *client = surface->resource()->client();
|
wl_client *client = surface->resource()->client();
|
||||||
const auto pointerResources = resourceMap().values(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);
|
wl_pointer::send_enter(r->handle, serial, surface->resource()->handle, x ,y);
|
||||||
|
}
|
||||||
return serial;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,8 +546,9 @@ uint Keyboard::sendKey(wl_client *client, uint key, uint state)
|
|||||||
auto time = m_seat->m_compositor->currentTimeMilliseconds();
|
auto time = m_seat->m_compositor->currentTimeMilliseconds();
|
||||||
uint serial = m_seat->m_compositor->nextSerial();
|
uint serial = m_seat->m_compositor->nextSerial();
|
||||||
const auto pointerResources = resourceMap().values(client);
|
const auto pointerResources = resourceMap().values(client);
|
||||||
for (auto *r : pointerResources)
|
for (auto *r : pointerResources) {
|
||||||
send_key(r->handle, serial, time, key, state);
|
send_key(r->handle, serial, time, key, state);
|
||||||
|
}
|
||||||
return serial;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,4 +602,38 @@ void ShmPool::shm_pool_destroy_resource(Resource *resource)
|
|||||||
delete this;
|
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
|
} // namespace MockCompositor
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
namespace MockCompositor {
|
namespace MockCompositor {
|
||||||
|
|
||||||
class WlCompositor;
|
class WlCompositor;
|
||||||
|
class WlShell;
|
||||||
|
class WlShellSurface;
|
||||||
class Output;
|
class Output;
|
||||||
class Pointer;
|
class Pointer;
|
||||||
class Touch;
|
class Touch;
|
||||||
@ -96,18 +98,18 @@ class Surface : public QObject, public QtWaylandServer::wl_surface
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Surface(WlCompositor *wlCompositor, wl_client *client, int id, int version)
|
explicit Surface(WlCompositor *wlCompositor, wl_client *client, int id, int version);
|
||||||
: QtWaylandServer::wl_surface(client, id, version)
|
~Surface() override;
|
||||||
, m_wlCompositor(wlCompositor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~Surface() override { qDeleteAll(m_commits); } // TODO: maybe make sure buffers are released?
|
|
||||||
void sendFrameCallbacks();
|
void sendFrameCallbacks();
|
||||||
void sendEnter(Output *output);
|
void sendEnter(Output *output);
|
||||||
void send_enter(::wl_resource *output) = delete;
|
void send_enter(::wl_resource *output) = delete;
|
||||||
void sendLeave(Output *output);
|
void sendLeave(Output *output);
|
||||||
void send_leave(::wl_resource *output) = delete;
|
void send_leave(::wl_resource *output) = delete;
|
||||||
|
|
||||||
|
void map();
|
||||||
|
bool isMapped() const { return m_mapped; }
|
||||||
|
WlShellSurface *wlShellSurface() const { return m_wlShellSurface; }
|
||||||
|
|
||||||
WlCompositor *m_wlCompositor;
|
WlCompositor *m_wlCompositor;
|
||||||
struct PerCommitData {
|
struct PerCommitData {
|
||||||
Callback *frame = nullptr;
|
Callback *frame = nullptr;
|
||||||
@ -125,6 +127,14 @@ public:
|
|||||||
QList<Output *> m_outputs;
|
QList<Output *> m_outputs;
|
||||||
SurfaceRole *m_role = nullptr;
|
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:
|
signals:
|
||||||
void attach(void *buffer, QPoint offset);
|
void attach(void *buffer, QPoint offset);
|
||||||
void commit();
|
void commit();
|
||||||
@ -132,7 +142,7 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void surface_destroy_resource(Resource *resource) override;
|
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_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_set_buffer_scale(Resource *resource, int32_t scale) override;
|
||||||
void surface_commit(Resource *resource) 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
|
class Subsurface : public QObject, public QtWaylandServer::wl_subsurface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -60,6 +60,11 @@ void DataDeviceManager::data_device_manager_get_data_device(Resource *resource,
|
|||||||
device->add(resource->client(), id, resource->version());
|
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()
|
DataDevice::~DataDevice()
|
||||||
{
|
{
|
||||||
// If the client(s) hasn't deleted the wayland object, just ignore subsequent events
|
// 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);
|
Q_ASSERT(client);
|
||||||
auto *offer = new DataOffer(this, client, m_manager->m_version);
|
auto *offer = new DataOffer(this, client, m_manager->m_version);
|
||||||
|
m_offers << offer;
|
||||||
for (auto *resource : resourceMap().values(client))
|
for (auto *resource : resourceMap().values(client))
|
||||||
wl_data_device::send_data_offer(resource->handle, offer->resource()->handle);
|
wl_data_device::send_data_offer(resource->handle, offer->resource()->handle);
|
||||||
for (const auto &mimeType : mimeTypes)
|
for (const auto &mimeType : mimeTypes)
|
||||||
@ -86,6 +92,33 @@ void DataDevice::sendSelection(DataOffer *offer)
|
|||||||
m_sentSelectionOffers << 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)
|
void DataOffer::data_offer_destroy_resource(Resource *resource)
|
||||||
{
|
{
|
||||||
Q_UNUSED(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)
|
void DataOffer::data_offer_destroy(QtWaylandServer::wl_data_offer::Resource *resource)
|
||||||
{
|
{
|
||||||
bool removed = m_dataDevice->m_sentSelectionOffers.removeOne(this);
|
bool removed = m_dataDevice->m_sentSelectionOffers.removeOne(this);
|
||||||
|
if (!removed)
|
||||||
|
removed = m_dataDevice->m_offers.removeOne(this);
|
||||||
QVERIFY(removed);
|
QVERIFY(removed);
|
||||||
wl_resource_destroy(resource->handle);
|
wl_resource_destroy(resource->handle);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ public:
|
|||||||
explicit DataDeviceManager(CoreCompositor *compositor, int version = 1)
|
explicit DataDeviceManager(CoreCompositor *compositor, int version = 1)
|
||||||
: QtWaylandServer::wl_data_device_manager(compositor->m_display, version)
|
: QtWaylandServer::wl_data_device_manager(compositor->m_display, version)
|
||||||
, m_version(version)
|
, m_version(version)
|
||||||
|
, m_compositor(compositor)
|
||||||
{}
|
{}
|
||||||
~DataDeviceManager() override { qDeleteAll(m_dataDevices); }
|
~DataDeviceManager() override { qDeleteAll(m_dataDevices); }
|
||||||
bool isClean() override;
|
bool isClean() override;
|
||||||
@ -50,13 +51,16 @@ public:
|
|||||||
|
|
||||||
int m_version = 1; // TODO: remove on libwayland upgrade
|
int m_version = 1; // TODO: remove on libwayland upgrade
|
||||||
QMap<Seat *, DataDevice *> m_dataDevices;
|
QMap<Seat *, DataDevice *> m_dataDevices;
|
||||||
|
CoreCompositor *m_compositor;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void data_device_manager_get_data_device(Resource *resource, uint32_t id, ::wl_resource *seatResource) override;
|
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:
|
public:
|
||||||
explicit DataDevice(DataDeviceManager *manager, Seat *seat)
|
explicit DataDevice(DataDeviceManager *manager, Seat *seat)
|
||||||
: m_manager(manager)
|
: m_manager(manager)
|
||||||
@ -69,11 +73,37 @@ public:
|
|||||||
void send_selection(::wl_resource *resource) = delete;
|
void send_selection(::wl_resource *resource) = delete;
|
||||||
void sendSelection(DataOffer *offer);
|
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;
|
DataDeviceManager *m_manager = nullptr;
|
||||||
Seat *m_seat = nullptr;
|
Seat *m_seat = nullptr;
|
||||||
QList<DataOffer *> m_sentSelectionOffers;
|
QList<DataOffer *> m_sentSelectionOffers;
|
||||||
|
QList<DataOffer *> m_offers;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dragStarted();
|
||||||
|
|
||||||
protected:
|
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
|
void data_device_release(Resource *resource) override
|
||||||
{
|
{
|
||||||
int removed = m_manager->m_dataDevices.remove(m_seat);
|
int removed = m_manager->m_dataDevices.remove(m_seat);
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
|
|
||||||
namespace MockCompositor {
|
namespace MockCompositor {
|
||||||
|
|
||||||
DefaultCompositor::DefaultCompositor()
|
DefaultCompositor::DefaultCompositor(CompositorType t)
|
||||||
|
: CoreCompositor(t)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Lock l(this);
|
Lock l(this);
|
||||||
@ -43,8 +44,16 @@ DefaultCompositor::DefaultCompositor()
|
|||||||
auto *output = add<Output>();
|
auto *output = add<Output>();
|
||||||
output->m_data.physicalSize = output->m_data.mode.physicalSizeForDpi(96);
|
output->m_data.physicalSize = output->m_data.mode.physicalSizeForDpi(96);
|
||||||
add<Seat>(Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch);
|
add<Seat>(Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch);
|
||||||
|
add<WlShell>();
|
||||||
add<XdgWmBase>();
|
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<FullScreenShellV1>();
|
||||||
add<IviApplication>();
|
add<IviApplication>();
|
||||||
|
|
||||||
@ -89,4 +98,24 @@ void DefaultCompositor::xdgPingAndWaitForPong()
|
|||||||
QTRY_COMPARE(pongSpy.first().at(0).toUInt(), serial);
|
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
|
} // namespace MockCompositor
|
||||||
|
@ -55,11 +55,13 @@ namespace MockCompositor {
|
|||||||
class DefaultCompositor : public CoreCompositor
|
class DefaultCompositor : public CoreCompositor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DefaultCompositor();
|
explicit DefaultCompositor(CompositorType t = CompositorType::Default);
|
||||||
// Convenience functions
|
// Convenience functions
|
||||||
Output *output(int i = 0) { return getAll<Output>().value(i, nullptr); }
|
Output *output(int i = 0) { return getAll<Output>().value(i, nullptr); }
|
||||||
Surface *surface(int i = 0) { return get<WlCompositor>()->m_surfaces.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); }
|
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); }
|
XdgSurface *xdgSurface(int i = 0) { return get<XdgWmBase>()->m_xdgSurfaces.value(i, nullptr); }
|
||||||
XdgToplevel *xdgToplevel(int i = 0) { return get<XdgWmBase>()->toplevel(i); }
|
XdgToplevel *xdgToplevel(int i = 0) { return get<XdgWmBase>()->toplevel(i); }
|
||||||
XdgPopup *xdgPopup(int i = 0) { return get<XdgWmBase>()->popup(i); }
|
XdgPopup *xdgPopup(int i = 0) { return get<XdgWmBase>()->popup(i); }
|
||||||
@ -80,6 +82,12 @@ public:
|
|||||||
void resetConfig() { exec([&] { m_config = Config{}; }); }
|
void resetConfig() { exec([&] { m_config = Config{}; }); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WlShellCompositor : public DefaultCompositor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit WlShellCompositor(CompositorType t = CompositorType::Legacy);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace MockCompositor
|
} // namespace MockCompositor
|
||||||
|
|
||||||
#define QCOMPOSITOR_VERIFY(expr) QVERIFY(exec([&]{ return expr; }))
|
#define QCOMPOSITOR_VERIFY(expr) QVERIFY(exec([&]{ return expr; }))
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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> ¶meters);
|
|
||||||
static void sendMousePress(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendMouseRelease(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendKeyPress(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendKeyRelease(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendTouchDown(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendTouchUp(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendTouchMotion(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendTouchFrame(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendDataDeviceDataOffer(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendDataDeviceEnter(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendDataDeviceMotion(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendDataDeviceDrop(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendDataDeviceLeave(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void waitForStartDrag(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void setOutputMode(void *compositor, const QList<QVariant> ¶meters);
|
|
||||||
static void sendShellSurfaceConfigure(void *data, const QList<QVariant> ¶meters);
|
|
||||||
static void sendIviSurfaceConfigure(void *data, const QList<QVariant> ¶meters);
|
|
||||||
|
|
||||||
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> ¶meters);
|
|
||||||
|
|
||||||
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
|
|
@ -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
|
|
@ -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
|
|
@ -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> ¶meters)
|
|
||||||
{
|
|
||||||
Compositor *compositor = static_cast<Compositor *>(data);
|
|
||||||
compositor->m_keyboard->setFocus(resolveSurface(parameters.first()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Compositor::sendMousePress(void *data, const QList<QVariant> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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> ¶meters)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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
|
|
@ -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> ¶meters)
|
|
||||||
{
|
|
||||||
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
|
|
@ -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
|
|
@ -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> ¶meters)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
}
|
|
@ -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
|
|
@ -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) { }
|
|
@ -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
|
|
@ -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> ¶meters)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
Loading…
x
Reference in New Issue
Block a user