Commit d65c19cf authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧
Browse files

Build standalone

parent 129e2526
add_subdirectory(testserver)
include(ECMMarkAsTest)
set(scannerSRCS generator.cpp)
add_definitions(-DMAPPING_FILE="${CMAKE_CURRENT_SOURCE_DIR}/mapping.txt")
add_executable(kwaylandScanner ${scannerSRCS})
target_link_libraries(kwaylandScanner Qt5::Core Qt5::Concurrent)
ecm_mark_as_test(kwaylandScanner)
This diff is collapsed.
/*
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef KWAYLAND_TOOLS_GENERATOR_H
#define KWAYLAND_TOOLS_GENERATOR_H
#include <QObject>
#include <QMap>
#include <QMutex>
#include <QThreadStorage>
#include <QWaitCondition>
#include <QXmlStreamReader>
class QTextStream;
namespace KWayland
{
namespace Tools
{
class Argument
{
public:
explicit Argument();
explicit Argument(const QXmlStreamAttributes &attributes);
~Argument();
enum class Type {
Unknown,
NewId,
Destructor,
Object,
FileDescriptor,
Fixed,
Uint,
Int,
String
};
QString name() const {
return m_name;
}
Type type() const {
return m_type;
}
bool isNullAllowed() const {
return m_allowNull;
}
QString interface() const {
return m_inteface;
}
QString typeAsQt() const;
QString typeAsServerWl() const;
private:
Type parseType(const QStringRef &type);
QString m_name;
Type m_type = Type::Unknown;
bool m_allowNull = false;
QString m_inteface;
};
class Request
{
public:
explicit Request();
explicit Request(const QString &name);
~Request();
void addArgument(const Argument &arg) {
m_arguments << arg;
}
QString name() const {
return m_name;
}
QVector<Argument> arguments() const {
return m_arguments;
}
bool isDestructor() const {
return m_destructor;
}
bool isFactory() const;
void markAsDestructor() {
m_destructor = true;
}
private:
QString m_name;
QVector<Argument> m_arguments;
bool m_destructor = false;
};
class Event
{
public:
explicit Event();
explicit Event(const QString &name);
~Event();
void addArgument(const Argument &arg) {
m_arguments << arg;
}
QString name() const {
return m_name;
}
QVector<Argument> arguments() const {
return m_arguments;
}
private:
QString m_name;
QVector<Argument> m_arguments;
};
class Interface
{
public:
explicit Interface();
explicit Interface(const QXmlStreamAttributes &attributes);
virtual ~Interface();
void addRequest(const Request &request) {
m_requests << request;
}
void addEvent(const Event &event) {
m_events << event;
}
QString name() const {
return m_name;
}
quint32 version() const {
return m_version;
}
QString kwaylandClientName() const {
return m_clientName;
}
QString kwaylandServerName() const {
return m_clientName + QStringLiteral("Interface");
}
QVector<Request> requests() const {
return m_requests;
}
QVector<Event> events() const {
return m_events;
}
void markAsGlobal() {
m_global = true;
}
bool isGlobal() const {
return m_global;
}
void setFactory(Interface *factory) {
m_factory = factory;
}
Interface *factory() const {
return m_factory;
}
bool isUnstableInterface() const {
return m_name.startsWith(QLatin1String("zwp"));
}
private:
QString m_name;
QString m_clientName;
quint32 m_version;
QVector<Request> m_requests;
QVector<Event> m_events;
bool m_global = false;
Interface *m_factory;
};
class Generator : public QObject
{
Q_OBJECT
public:
explicit Generator(QObject *parent = nullptr);
virtual ~Generator();
void setXmlFileName(const QString &name) {
m_xmlFileName = name;
}
void setBaseFileName(const QString &name) {
m_baseFileName = name;
}
void start();
private:
void generateCopyrightHeader();
void generateStartIncludeGuard();
void generateEndIncludeGuard();
void generateStartNamespace();
void generateEndNamespace();
void generateHeaderIncludes();
void generateCppIncludes();
void generatePrivateClass(const Interface &interface);
void generateClientPrivateClass(const Interface &interface);
void generateClientPrivateResourceClass(const Interface &interface);
void generateClientPrivateGlobalClass(const Interface &interface);
void generateServerPrivateGlobalClass(const Interface &interface);
void generateServerPrivateResourceClass(const Interface &interface);
void generateServerPrivateInterfaceClass(const Interface &interface);
void generateServerPrivateGlobalCtorBindClass(const Interface &interface);
void generateServerPrivateResourceCtorDtorClass(const Interface &interface);
void generateServerPrivateCallbackDefinitions(const Interface &interface);
void generateServerPrivateCallbackImpl(const Interface &interface);
void generateClientCpp(const Interface &interface);
void generateClass(const Interface &interface);
void generateClientGlobalClass(const Interface &interface);
void generateClientResourceClass(const Interface &interface);
void generateServerGlobalClass(const Interface &interface);
void generateServerGlobalClassUnstable(const Interface &interface);
void generateServerResourceClass(const Interface &interface);
void generateServerResourceClassUnstable(const Interface &interface);
void generateClientClassQObjectDerived(const Interface &interface);
void generateClientGlobalClassDoxy(const Interface &interface);
void generateClientGlobalClassCtor(const Interface &interface);
void generateClientGlobalClassSetup(const Interface &interface);
void generateClientResourceClassSetup(const Interface &interface);
void generateClientClassDtor(const Interface &interface);
void generateClientClassReleaseDestroy(const Interface &interface);
void generateClientClassStart(const Interface &interface);
void generateClientClassCasts(const Interface &interface);
void generateClientClassSignals(const Interface &interface);
void generateClientClassDptr(const Interface &interface);
void generateClientGlobalClassEnd(const Interface &interface);
void generateClientResourceClassEnd(const Interface &interface);
void generateClientClassRequests(const Interface &interface);
void generateClientCppRequests(const Interface &interface);
void generateWaylandForwardDeclarations();
void generateNamespaceForwardDeclarations();
void startParseXml();
void startAuthorNameProcess();
void startAuthorEmailProcess();
void startGenerateHeaderFile();
void startGenerateCppFile();
void startGenerateServerHeaderFile();
void startGenerateServerCppFile();
void checkEnd();
void parseProtocol();
Interface parseInterface();
Request parseRequest();
Event parseEvent();
QString projectToName() const;
QThreadStorage<QTextStream*> m_stream;
QString m_xmlFileName;
enum class Project {
Client,
Server
};
QThreadStorage<Project> m_project;
QString m_authorName;
QString m_authorEmail;
QString m_baseFileName;
QMutex m_mutex;
QWaitCondition m_waitCondition;
QXmlStreamReader m_xmlReader;
QVector<Interface> m_interfaces;
int m_finishedCounter = 0;
};
}
}
#endif
#wl_name;KWayland::ClientName
wl_buffer;Buffer
wl_compositor;Compositor
wl_data_device;DataDevice
wl_data_device_manager;DataDeviceManager
wl_data_offer;DataOffer
wl_data_source;DataSource
wl_event_queue;EventQueue
wl_keyboard;Keyboard
wl_output;Output
wl_pointer;Pointer
wl_region;Region
wl_registry;Registry
wl_seat;Seat
wl_shell;Shell
wl_shell_surface;ShellSurface
wl_shm;ShmPool
wl_subcompositor;SubCompositor
wl_subsurface;SubSurface
wl_surface;Surface
wl_touch;Touch
_wl_fullscreen_shell;FullscreenShell
org_kde_kwin_blur;Blur
org_kde_kwin_blur_manager;BlurManager
org_kde_kwin_contrast;Contrast
org_kde_kwin_contrast_manager;ContrastManager
org_kde_kwin_slide;Slide
org_kde_kwin_slide_manager;SlideManager
org_kde_kwin_fake_input;FakeInput
org_kde_kwin_idle;Idle
org_kde_kwin_idle_timeout;IdleTimeout
org_kde_kwin_outputmanagement;OutputManagement
org_kde_kwin_outputconfiguration;OutputConfiguration
org_kde_kwin_outputdevice;OutputDevice
org_kde_kwin_shadow;Shadow
org_kde_kwin_shadow_manager;ShadowManager
org_kde_plasma_shell;PlasmaShell
org_kde_plasma_surface;PlasmaShellSurface
org_kde_plasma_virtual_desktop_management;PlasmaVirtualDesktopManagement
org_kde_plasma_virtual_desktop;PlasmaVirtualDesktop
org_kde_plasma_window_management;PlasmaWindowManagement
org_kde_plasma_window;PlasmaWindow
org_kde_kwin_server_decoration_manager;ServerSideDecorationManager
org_kde_kwin_server_decoration;ServerSideDecoration
wl_text_input;TextInputUnstableV0
wl_text_input_manager;TextInputManagerUnstableV0
zwp_text_input_v2;TextInputUnstableV2
zwp_text_input_manager_v2;TextInputManagerUnstableV2
xdg_shell;XdgShellV5
xdg_surface;XdgSurfaceV5
xdg_popup;XdgPopupV5
xdg_toplevel;XdgShell
zxdg_shell_v6;XdgShellV6
zxdg_surface_v6;XdgSurfaceV6
zxdg_popup_v6;XdgPopupV6
zwp_relative_pointer_manager_v1;RelativePointerManagerUnstableV1
zwp_relative_pointer_v1;RelativePointerUnstableV1
zwp_pointer_gestures_v1;PointerGesturesUnstableV1
zwp_pointer_gesture_swipe_v1;PointerSwipeGestureUnstableV1
zwp_pointer_gesture_pinch_v1;PointerPinchGestureUnstableV1
zwp_pointer_constraints_v1;PointerConstraints
zwp_locked_pointer_v1;LockedPointer
zwp_confined_pointer_v1;ConfinedPointer
zwp_idle_inhibit_manager_v1;IdleInhibitManager
zwp_idle_inhibitor_v1;IdleInhibitor
org_kde_kwin_remote_access_manager;RemoteAccessManager
org_kde_kwin_remote_buffer;RemoteBuffer
zxdg_output_v1;XdgOutput
zxdg_output_manager_v1;XdgOutputManager
zxdg_decoration_manager_v1;XdgDecorationManager
zxdg_toplevel_decoration_v1;XdgDecoration
add_executable(org-kde-kf5-kwayland-testserver main.cpp testserver.cpp)
target_link_libraries(org-kde-kf5-kwayland-testserver Qt5::Core KF5::WaylandServer)
install(TARGETS org-kde-kf5-kwayland-testserver DESTINATION ${LIBEXEC_INSTALL_DIR} )
/*
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "testserver.h"
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto arguments = QCoreApplication::arguments();
// get rid of our own application path
arguments.removeFirst();
if (arguments.size() < 1) {
return 1;
}
TestServer *server = new TestServer(&a);
server->init();
server->startTestApp(arguments.takeFirst(), arguments);
return a.exec();
}
/*
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "testserver.h"
#include "../../server/display.h"
#include "../../server/compositor_interface.h"
#include "../../server/datadevicemanager_interface.h"
#include "../../server/idle_interface.h"
#include "../../server/fakeinput_interface.h"
#include "../../server/seat_interface.h"
#include "../../server/shell_interface.h"
#include "../../server/surface_interface.h"
#include "../../server/subcompositor_interface.h"
#include <QCoreApplication>
#include <QElapsedTimer>
#include <QProcess>
#include <QTimer>
// system
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
using namespace KWayland::Server;
TestServer::TestServer(QObject *parent)
: QObject(parent)
, m_repaintTimer(new QTimer(this))
, m_timeSinceStart(new QElapsedTimer)
, m_cursorPos(QPointF(0, 0))
{
}
TestServer::~TestServer() = default;
void TestServer::init()
{
Q_ASSERT(!m_display);
m_display = new Display(this);
m_display->start(Display::StartMode::ConnectClientsOnly);
m_display->createShm();
m_display->createCompositor()->create();
m_shell = m_display->createShell(m_display);
connect(m_shell, &ShellInterface::surfaceCreated, this,
[this] (ShellSurfaceInterface *surface) {
m_shellSurfaces << surface;
// TODO: pass keyboard/pointer/touch focus on mapped
connect(surface, &QObject::destroyed, this,
[this, surface] {
m_shellSurfaces.removeOne(surface);
}
);
}
);
m_shell->create();
m_seat = m_display->createSeat(m_display);
m_seat->setHasKeyboard(true);
m_seat->setHasPointer(true);
m_seat->setHasTouch(true);
m_seat->create();
m_display->createDataDeviceManager(m_display)->create();
m_display->createIdle(m_display)->create();
m_display->createSubCompositor(m_display)->create();
// output
auto output = m_display->createOutput(m_display);
const QSize size(1280, 1024);
output->setGlobalPosition(QPoint(0, 0));
output->setPhysicalSize(size / 3.8);
output->addMode(size);
output->create();
auto fakeInput = m_display->createFakeInput(m_display);
fakeInput->create();
connect(fakeInput, &FakeInputInterface::deviceCreated, this,
[this] (FakeInputDevice *device) {
device->setAuthentication(true);
connect(device, &FakeInputDevice::pointerMotionRequested, this,
[this] (const QSizeF &delta) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_cursorPos = m_cursorPos + QPointF(delta.width(), delta.height());
m_seat->setPointerPos(m_cursorPos);
}
);
connect(device, &FakeInputDevice::pointerButtonPressRequested, this,
[this] (quint32 button) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_seat->pointerButtonPressed(button);
}
);
connect(device, &FakeInputDevice::pointerButtonReleaseRequested, this,
[this] (quint32 button) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_seat->pointerButtonReleased(button);
}
);
connect(device, &FakeInputDevice::pointerAxisRequested, this,
[this] (Qt::Orientation orientation, qreal delta) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_seat->pointerAxis(orientation, delta);
}
);
connect(device, &FakeInputDevice::touchDownRequested, this,
[this] (quint32 id, const QPointF &pos) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_touchIdMapper.insert(id, m_seat->touchDown(pos));
}
);
connect(device, &FakeInputDevice::touchMotionRequested, this,
[this] (quint32 id, const QPointF &pos) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
const auto it = m_touchIdMapper.constFind(id);
if (it != m_touchIdMapper.constEnd()) {
m_seat->touchMove(it.value(), pos);
}
}
);
connect(device, &FakeInputDevice::touchUpRequested, this,
[this] (quint32 id) {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
const auto it = m_touchIdMapper.find(id);
if (it != m_touchIdMapper.end()) {
m_seat->touchUp(it.value());
m_touchIdMapper.erase(it);
}
}
);
connect(device, &FakeInputDevice::touchCancelRequested, this,
[this] {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_seat->cancelTouchSequence();
}
);
connect(device, &FakeInputDevice::touchFrameRequested, this,
[this] {
m_seat->setTimestamp(m_timeSinceStart->elapsed());
m_seat->touchFrame();
}
);
}
);
m_repaintTimer->setInterval(1000 / 60);
connect(m_repaintTimer, &QTimer::timeout, this, &TestServer::repaint);
m_repaintTimer->start();
m_timeSinceStart->start();
}
void TestServer::startTestApp(const QString &app, const QStringList &arguments)
{
int sx[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) < 0) {
QCoreApplication::instance()->exit(1);
return;
}
m_display->createClient(sx[0]);
int socket = dup(sx[1]);
if (socket == -1) {
QCoreApplication::instance()->exit(1);
return;
}
QProcess *p = new QProcess(this);
p->setProcessChannelMode(QProcess::ForwardedChannels);
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
environment.insert(QStringLiteral("WAYLAND_SOCKET"), QString::fromUtf8(QByteArray::number(socket)));
p->setProcessEnvironment(environment);
auto finishedSignal = static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished);
connect(p, finishedSignal, QCoreApplication::instance(), &QCoreApplication::exit);
connect(p, &QProcess::errorOccurred, this,
[] {
QCoreApplication::instance()->exit(1);
}
);
p->start(app, arguments);
}
void TestServer::repaint()
{
for (auto it = m_shellSurfaces.constBegin(), end = m_shellSurfaces.constEnd(); it != end; ++it) {
(*it)->surface()->frameRendered(m_timeSinceStart->elapsed());
}
}
/*
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef TESTSERVER_H
#define TESTSERVER_H
#include <QHash>
#include <QObject>
#include <QPointF>
#include <QVector>
class QElapsedTimer;
class QTimer;
namespace KWayland
{
namespace Server
{
class Display;
class SeatInterface;
class