1 /*
2     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3     SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #pragma once
8 
9 #include <QList>
10 #include <QObject>
11 
12 #include <KWaylandServer/kwaylandserver_export.h>
13 
14 #include "clientconnection.h"
15 
16 struct wl_client;
17 struct wl_display;
18 
19 namespace KWaylandServer
20 {
21 /**
22  * @short KWayland Server.
23  *
24  * This namespace groups all classes related to the Server module.
25  *
26  * The main entry point into the KWaylandServer API is the Display class.
27  * It allows to create a Wayland server and create various global objects on it.
28  *
29  * KWaylandServer is an API to easily create a head-less Wayland server with a
30  * Qt style API.
31  *
32  * @see Display
33  */
34 
35 class ClientBuffer;
36 class ClientConnection;
37 class DisplayPrivate;
38 class OutputInterface;
39 class OutputDeviceV2Interface;
40 class SeatInterface;
41 
42 /**
43  * @brief Class holding the Wayland server display loop.
44  *
45  * @todo Improve documentation
46  */
47 class KWAYLANDSERVER_EXPORT Display : public QObject
48 {
49     Q_OBJECT
50     Q_PROPERTY(bool running READ isRunning NOTIFY runningChanged)
51 public:
52     explicit Display(QObject *parent = nullptr);
53     virtual ~Display();
54 
55     /**
56      * Adds a socket with the given @p fileDescriptor to the Wayland display. This function
57      * returns @c true if the socket has been added successfully; otherwise returns @c false.
58      *
59      * The compositor can call this function even after the display has been started.
60      * @arg socketName can optionally be parsed to store the socket name represented by the given file-descriptor
61      *
62      * @see start()
63      */
64     bool addSocketFileDescriptor(int fileDescriptor, const QString &socketName = QString());
65     /**
66      * Adds a UNIX socket with the specified @p name to the Wayland display. This function
67      * returns @c true if the socket has been added successfully; otherwise returns @c false.
68      *
69      * If the specified socket name @p name is empty, the display will pick a free socket with
70      * a filename "wayland-%d".
71      *
72      * The compositor can call this function even after the display has been started.
73      *
74      * @see start()
75      */
76     bool addSocketName(const QString &name = QString());
77 
78     /**
79      * Returns the list of socket names that the display listens for client connections.
80      */
81     QStringList socketNames() const;
82 
83     quint32 serial();
84     quint32 nextSerial();
85 
86     /**
87      * Start accepting client connections. If the display has started successfully, this
88      * function returns @c true; otherwise @c false is returned.
89      */
90     bool start();
91     void dispatchEvents();
92 
93     /**
94      * Create a client for the given file descriptor.
95      *
96      * The client is created as if it connected through the normal server
97      * socket. This method can be used to create a connection bypassing the
98      * normal socket connection. It's recommended to use together with
99      * socketpair and pass the other side of the socket to the client.
100      *
101      * @param fd The file descriptor for the socket to the client
102      * @returns The new ClientConnection or @c null on failure.
103      */
104     ClientConnection *createClient(int fd);
105 
106     operator wl_display *();
107     operator wl_display *() const;
108     bool isRunning() const;
109 
110     void createShm();
111     /**
112      * @returns All SeatInterface currently managed on the Display.
113      */
114     QVector<SeatInterface*> seats() const;
115     QList<OutputDeviceV2Interface *> outputDevices() const;
116     QList<OutputInterface *> outputs() const;
117     QVector<OutputInterface *> outputsIntersecting(const QRect &rect) const;
118 
119     /**
120      * Gets the ClientConnection for the given @p client.
121      * If there is no ClientConnection yet for the given @p client, it will be created.
122      * @param client The native client for which the ClientConnection is retrieved
123      * @return The ClientConnection for the given native client
124      */
125     ClientConnection *getConnection(wl_client *client);
126     QVector<ClientConnection *> connections() const;
127 
128     /**
129      * Set the EGL @p display for this Wayland display.
130      * The EGLDisplay can only be set once and must be alive as long as the Wayland display
131      * is alive. The user should have set up the binding between the EGLDisplay and the
132      * Wayland display prior to calling this method.
133      *
134      * @see eglDisplay
135      */
136     void setEglDisplay(void *display);
137     /**
138      * @returns the EGLDisplay used for this Wayland display or EGL_NO_DISPLAY if not set.
139      * @see setEglDisplay
140      */
141     void *eglDisplay() const;
142 
143     /**
144      * Returns the client buffer with the specified @a resource. Returns @c null if there's
145      * no such a buffer.
146      */
147     ClientBuffer *clientBufferForResource(wl_resource *resource) const;
148 
149 private Q_SLOTS:
150     void flush();
151 
152 Q_SIGNALS:
153     void socketNamesChanged();
154     void runningChanged(bool);
155     void clientConnected(KWaylandServer::ClientConnection *);
156     void clientDisconnected(KWaylandServer::ClientConnection *);
157 
158 private:
159     friend class DisplayPrivate;
160     QScopedPointer<DisplayPrivate> d;
161 };
162 
163 }
164