KWin
Loading...
Searching...
No Matches
waylandservertest.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
7#include "wayland/display.h"
8#include "wayland/output.h"
9#include "wayland/seat.h"
10#include "wayland/xdgshell.h"
11
12#include "fakeoutput.h"
13
14#include <QFile>
15#include <QGuiApplication>
16#include <private/qeventdispatcher_glib_p.h>
17
18#include <iostream>
19#include <sys/select.h>
20#include <unistd.h>
21
22static int startXServer()
23{
24 const QByteArray process = QByteArrayLiteral("Xwayland");
25 int pipeFds[2];
26 if (pipe(pipeFds) != 0) {
27 std::cerr << "FATAL ERROR failed to create pipe to start X Server " << process.constData() << std::endl;
28 exit(1);
29 }
30
31 pid_t pid = fork();
32 if (pid == 0) {
33 // child process - should be turned into Xwayland
34 // writes to pipe, closes read side
35 close(pipeFds[0]);
36 char fdbuf[16];
37 sprintf(fdbuf, "%d", pipeFds[1]);
38 execlp(process.constData(), process.constData(), "-displayfd", fdbuf, (char *)nullptr);
39 close(pipeFds[1]);
40 exit(20);
41 }
42 // parent process - this is the wayland server
43 // reads from pipe, closes write side
44 close(pipeFds[1]);
45 return pipeFds[0];
46}
47
48static void readDisplayFromPipe(int pipe)
49{
50 QFile readPipe;
51 if (!readPipe.open(pipe, QIODevice::ReadOnly)) {
52 std::cerr << "FATAL ERROR failed to open pipe to start X Server XWayland" << std::endl;
53 exit(1);
54 }
55 QByteArray displayNumber = readPipe.readLine();
56
57 displayNumber.prepend(QByteArray(":"));
58 displayNumber.remove(displayNumber.size() - 1, 1);
59 std::cout << "X-Server started on display " << displayNumber.constData() << std::endl;
60
61 setenv("DISPLAY", displayNumber.constData(), true);
62
63 // close our pipe
64 close(pipe);
65}
66
67int main(int argc, char **argv)
68{
69 using namespace KWin;
70
71 // set our own event dispatcher to be able to dispatch events before the event loop is started
72 QAbstractEventDispatcher *eventDispatcher = new QEventDispatcherGlib();
73 QCoreApplication::setEventDispatcher(eventDispatcher);
74
75 // first create the Server and setup with minimum to get an XWayland connected
76 KWin::Display display;
77 display.start();
78 display.createShm();
79 new CompositorInterface(&display, &display);
80 new XdgShellInterface(&display, &display);
81
82 auto outputHandle = std::make_unique<FakeOutput>();
83 outputHandle->setMode(QSize(1024, 768), 60000);
84 outputHandle->setPhysicalSize(QSize(10, 10));
85
86 auto outputInterface = std::make_unique<OutputInterface>(&display, outputHandle.get());
87
88 // starts XWayland by forking and opening a pipe
89 const int pipe = startXServer();
90 if (pipe == -1) {
91 exit(1);
92 }
93
94 fd_set rfds;
95 struct timeval tv;
96 tv.tv_sec = 0;
97 tv.tv_usec = 0;
98 do {
99 eventDispatcher->processEvents(QEventLoop::WaitForMoreEvents);
100 FD_ZERO(&rfds);
101 FD_SET(pipe, &rfds);
102 } while (select(pipe + 1, &rfds, nullptr, nullptr, &tv) == 0);
103
104 // now Xwayland is ready and we can read the pipe to get the display
105 readDisplayFromPipe(pipe);
106
107 QGuiApplication app(argc, argv);
108
109 SeatInterface *seat = new SeatInterface(&display);
110 seat->setName(QStringLiteral("testSeat0"));
111
112 return app.exec();
113}
Class holding the Wayland server display loop.
Definition display.h:34
void createShm()
Definition display.cpp:128
bool start()
Definition display.cpp:92
Represents a Seat on the Wayland Display.
Definition seat.h:134