KWaylandServer

display.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3  SPDX-FileCopyrightText: 2018 David Edmundson <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #include "display.h"
8 #include "display_p.h"
9 #include "logging.h"
10 
11 #include <QCoreApplication>
12 #include <QDebug>
13 #include <QAbstractEventDispatcher>
14 
15 namespace KWaylandServer
16 {
17 
18 DisplayPrivate *DisplayPrivate::get(Display *display)
19 {
20  return display->d.data();
21 }
22 
23 DisplayPrivate::DisplayPrivate(Display *q)
24  : q(q)
25 {
26 }
27 
28 void DisplayPrivate::registerSocketName(const QString &socketName)
29 {
30  socketNames.append(socketName);
31  emit q->socketNamesChanged();
32 }
33 
34 Display::Display(QObject *parent)
35  : QObject(parent)
36  , d(new DisplayPrivate(this))
37 {
38  d->display = wl_display_create();
39  d->loop = wl_display_get_event_loop(d->display);
40 }
41 
42 Display::~Display()
43 {
44  wl_display_destroy_clients(d->display);
45  wl_display_destroy(d->display);
46 }
47 
48 bool Display::addSocketFileDescriptor(int fileDescriptor)
49 {
50  if (wl_display_add_socket_fd(d->display, fileDescriptor)) {
51  qCWarning(KWAYLAND_SERVER, "Failed to add %d fd to display", fileDescriptor);
52  return false;
53  }
54  return true;
55 }
56 
58 {
59  if (name.isEmpty()) {
60  const char *socket = wl_display_add_socket_auto(d->display);
61  if (!socket) {
62  qCWarning(KWAYLAND_SERVER, "Failed to find a free display socket");
63  return false;
64  }
65  d->registerSocketName(QString::fromUtf8(socket));
66  } else {
67  if (wl_display_add_socket(d->display, qPrintable(name))) {
68  qCWarning(KWAYLAND_SERVER, "Failed to add %s socket to display", qPrintable(name));
69  return false;
70  }
71  d->registerSocketName(name);
72  }
73  return true;
74 }
75 
77 {
78  return d->socketNames;
79 }
80 
82 {
83  if (d->running) {
84  return true;
85  }
86 
87  const int fileDescriptor = wl_event_loop_get_fd(d->loop);
88  if (fileDescriptor == -1) {
89  qCWarning(KWAYLAND_SERVER) << "Did not get the file descriptor for the event loop";
90  return false;
91  }
92 
93  d->socketNotifier = new QSocketNotifier(fileDescriptor, QSocketNotifier::Read, this);
94  connect(d->socketNotifier, &QSocketNotifier::activated, this, &Display::dispatchEvents);
95 
97  connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, this, &Display::flush);
98 
99  d->running = true;
100  emit runningChanged(true);
101 
102  return true;
103 }
104 
105 void Display::dispatchEvents()
106 {
107  if (wl_event_loop_dispatch(d->loop, 0) != 0) {
108  qCWarning(KWAYLAND_SERVER) << "Error on dispatching Wayland event loop";
109  }
110 }
111 
112 void Display::flush()
113 {
114  wl_display_flush_clients(d->display);
115 }
116 
117 void Display::createShm()
118 {
119  Q_ASSERT(d->display);
120  wl_display_init_shm(d->display);
121 }
122 
123 quint32 Display::nextSerial()
124 {
125  return wl_display_next_serial(d->display);
126 }
127 
128 quint32 Display::serial()
129 {
130  return wl_display_get_serial(d->display);
131 }
132 
133 bool Display::isRunning() const
134 {
135  return d->running;
136 }
137 
138 Display::operator wl_display*()
139 {
140  return d->display;
141 }
142 
143 Display::operator wl_display*() const
144 {
145  return d->display;
146 }
147 
148 QList< OutputInterface* > Display::outputs() const
149 {
150  return d->outputs;
151 }
152 
153 QList< OutputDeviceInterface* > Display::outputDevices() const
154 {
155  return d->outputdevices;
156 }
157 
159 {
160  return d->seats;
161 }
162 
164 {
165  Q_ASSERT(client);
166  auto it = std::find_if(d->clients.constBegin(), d->clients.constEnd(),
167  [client](ClientConnection *c) {
168  return c->client() == client;
169  }
170  );
171  if (it != d->clients.constEnd()) {
172  return *it;
173  }
174  // no ConnectionData yet, create it
175  auto c = new ClientConnection(client, this);
176  d->clients << c;
178  [this] (ClientConnection *c) {
179  const int index = d->clients.indexOf(c);
180  Q_ASSERT(index != -1);
181  d->clients.remove(index);
182  Q_ASSERT(d->clients.indexOf(c) == -1);
183  emit clientDisconnected(c);
184  }
185  );
186  emit clientConnected(c);
187  return c;
188 }
189 
190 QVector< ClientConnection* > Display::connections() const
191 {
192  return d->clients;
193 }
194 
196 {
197  Q_ASSERT(fd != -1);
198  Q_ASSERT(d->display);
199  wl_client *c = wl_client_create(d->display, fd);
200  if (!c) {
201  return nullptr;
202  }
203  return getConnection(c);
204 }
205 
206 void Display::setEglDisplay(void *display)
207 {
208  if (d->eglDisplay != EGL_NO_DISPLAY) {
209  qCWarning(KWAYLAND_SERVER) << "EGLDisplay cannot be changed";
210  return;
211  }
212  d->eglDisplay = (EGLDisplay)display;
213 }
214 
215 void *Display::eglDisplay() const
216 {
217  return d->eglDisplay;
218 }
219 
220 }
void activated(QSocketDescriptor socket, QSocketNotifier::Type type)
void * eglDisplay() const
Definition: display.cpp:215
QVector< SeatInterface * > seats() const
Definition: display.cpp:158
void setEglDisplay(void *display)
Set the EGL display for this Wayland display.
Definition: display.cpp:206
bool addSocketName(const QString &name=QString())
Adds a UNIX socket with the specified name to the Wayland display.
Definition: display.cpp:57
ClientConnection * createClient(int fd)
Create a client for the given file descriptor.
Definition: display.cpp:195
QString fromUtf8(const char *str, int size)
bool isEmpty() const const
QStringList socketNames() const
Returns the list of socket names that the display listens for client connections. ...
Definition: display.cpp:76
void disconnected(KWaylandServer::ClientConnection *)
Signal emitted when the ClientConnection got disconnected from the server.
ClientConnection * getConnection(wl_client *client)
Gets the ClientConnection for the given client.
Definition: display.cpp:163
Convenient Class which represents a wl_client.
QAbstractEventDispatcher * eventDispatcher()
bool start()
Start accepting client connections.
Definition: display.cpp:81
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
bool addSocketFileDescriptor(int fileDescriptor)
Adds a socket with the given fileDescriptor to the Wayland display.
Definition: display.cpp:48
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jan 27 2021 23:07:26 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.