1 /* 2 KWin - the KDE window manager 3 This file is part of the KDE project. 4 5 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 6 7 SPDX-License-Identifier: GPL-2.0-or-later 8 */ 9 #ifndef KWIN_WAYLAND_SERVER_H 10 #define KWIN_WAYLAND_SERVER_H 11 12 #include <kwinglobals.h> 13 #include "keyboard_input.h" 14 15 #include <QObject> 16 17 class QThread; 18 class QProcess; 19 class QWindow; 20 21 namespace KWayland 22 { 23 namespace Client 24 { 25 class ConnectionThread; 26 class EventQueue; 27 class Registry; 28 class Compositor; 29 class Seat; 30 class DataDeviceManager; 31 class Surface; 32 } 33 } 34 namespace KWaylandServer 35 { 36 class AppMenuManagerInterface; 37 class ClientConnection; 38 class CompositorInterface; 39 class Display; 40 class DataDeviceInterface; 41 class IdleInterface; 42 class InputMethodV1Interface; 43 class SeatInterface; 44 class DataDeviceManagerInterface; 45 class ServerSideDecorationManagerInterface; 46 class ServerSideDecorationPaletteManagerInterface; 47 class SurfaceInterface; 48 class OutputInterface; 49 class PlasmaShellInterface; 50 class PlasmaWindowActivationFeedbackInterface; 51 class PlasmaVirtualDesktopManagementInterface; 52 class PlasmaWindowManagementInterface; 53 class OutputManagementV2Interface; 54 class XdgForeignV2Interface; 55 class XdgOutputManagerV1Interface; 56 class KeyStateInterface; 57 class LinuxDmaBufV1ClientBufferIntegration; 58 class LinuxDmaBufV1ClientBuffer; 59 class TabletManagerV2Interface; 60 class KeyboardShortcutsInhibitManagerV1Interface; 61 class XdgDecorationManagerV1Interface; 62 } 63 64 65 namespace KWin 66 { 67 68 class AbstractClient; 69 class AbstractOutput; 70 class Toplevel; 71 class XdgPopupClient; 72 class XdgSurfaceClient; 73 class XdgToplevelClient; 74 class AbstractWaylandOutput; 75 class WaylandOutput; 76 class WaylandOutputDevice; 77 78 class KWIN_EXPORT WaylandServer : public QObject 79 { 80 Q_OBJECT 81 82 public: 83 enum class InitializationFlag { 84 NoOptions = 0x0, 85 LockScreen = 0x1, 86 NoLockScreenIntegration = 0x2, 87 NoGlobalShortcuts = 0x4 88 }; 89 90 Q_DECLARE_FLAGS(InitializationFlags, InitializationFlag) 91 92 ~WaylandServer() override; 93 bool init(const QString &socketName, InitializationFlags flags = InitializationFlag::NoOptions); 94 bool init(InitializationFlags flags = InitializationFlag::NoOptions); 95 96 bool start(); 97 void terminateClientConnections(); 98 display()99 KWaylandServer::Display *display() const 100 { 101 return m_display; 102 } compositor()103 KWaylandServer::CompositorInterface *compositor() const 104 { 105 return m_compositor; 106 } seat()107 KWaylandServer::SeatInterface *seat() const 108 { 109 return m_seat; 110 } tabletManagerV2()111 KWaylandServer::TabletManagerV2Interface *tabletManagerV2() const 112 { 113 return m_tabletManagerV2; 114 } dataDeviceManager()115 KWaylandServer::DataDeviceManagerInterface *dataDeviceManager() const 116 { 117 return m_dataDeviceManager; 118 } plasmaActivationFeedback()119 KWaylandServer::PlasmaWindowActivationFeedbackInterface *plasmaActivationFeedback() const 120 { 121 return m_plasmaActivationFeedback; 122 } virtualDesktopManagement()123 KWaylandServer::PlasmaVirtualDesktopManagementInterface *virtualDesktopManagement() const 124 { 125 return m_virtualDesktopManagement; 126 } windowManagement()127 KWaylandServer::PlasmaWindowManagementInterface *windowManagement() const 128 { 129 return m_windowManagement; 130 } decorationManager()131 KWaylandServer::ServerSideDecorationManagerInterface *decorationManager() const { 132 return m_decorationManager; 133 } xdgOutputManagerV1()134 KWaylandServer::XdgOutputManagerV1Interface *xdgOutputManagerV1() const { 135 return m_xdgOutputManagerV1; 136 } keyboardShortcutsInhibitManager()137 KWaylandServer::KeyboardShortcutsInhibitManagerV1Interface *keyboardShortcutsInhibitManager() const 138 { 139 return m_keyboardShortcutsInhibitManager; 140 } 141 142 bool isKeyboardShortcutsInhibited() const; 143 144 KWaylandServer::LinuxDmaBufV1ClientBufferIntegration *linuxDmabuf(); 145 inputMethod()146 KWaylandServer::InputMethodV1Interface *inputMethod() const { 147 return m_inputMethod; 148 } 149 clients()150 QList<AbstractClient *> clients() const { 151 return m_clients; 152 } 153 void removeClient(AbstractClient *c); 154 AbstractClient *findClient(const KWaylandServer::SurfaceInterface *surface) const; 155 XdgToplevelClient *findXdgToplevelClient(KWaylandServer::SurfaceInterface *surface) const; 156 XdgSurfaceClient *findXdgSurfaceClient(KWaylandServer::SurfaceInterface *surface) const; 157 158 /** 159 * @returns a transient parent of a surface imported with the foreign protocol, if any 160 */ 161 KWaylandServer::SurfaceInterface *findForeignTransientForSurface(KWaylandServer::SurfaceInterface *surface); 162 163 /** 164 * @returns file descriptor for Xwayland to connect to. 165 */ 166 int createXWaylandConnection(); 167 void destroyXWaylandConnection(); 168 169 /** 170 * @returns file descriptor to the input method server's socket. 171 */ 172 int createInputMethodConnection(); 173 void destroyInputMethodConnection(); 174 175 /** 176 * @returns true if screen is locked. 177 */ 178 bool isScreenLocked() const; 179 /** 180 * @returns whether integration with KScreenLocker is available. 181 */ 182 bool hasScreenLockerIntegration() const; 183 184 /** 185 * @returns whether any kind of global shortcuts are supported. 186 */ 187 bool hasGlobalShortcutSupport() const; 188 189 void createInternalConnection(); 190 void initPlatform(); 191 void initWorkspace(); 192 193 KWaylandServer::ClientConnection *xWaylandConnection() const; inputMethodConnection()194 KWaylandServer::ClientConnection *inputMethodConnection() const { 195 return m_inputMethodServerConnection; 196 } internalConnection()197 KWaylandServer::ClientConnection *internalConnection() const { 198 return m_internalConnection.server; 199 } screenLockerClientConnection()200 KWaylandServer::ClientConnection *screenLockerClientConnection() const { 201 return m_screenLockerClientConnection; 202 } internalCompositor()203 KWayland::Client::Compositor *internalCompositor() { 204 return m_internalConnection.compositor; 205 } internalSeat()206 KWayland::Client::Seat *internalSeat() { 207 return m_internalConnection.seat; 208 } internalDataDeviceManager()209 KWayland::Client::DataDeviceManager *internalDataDeviceManager() { 210 return m_internalConnection.ddm; 211 } internalClientConection()212 KWayland::Client::ConnectionThread *internalClientConection() { 213 return m_internalConnection.client; 214 } internalClientRegistry()215 KWayland::Client::Registry *internalClientRegistry() { 216 return m_internalConnection.registry; 217 } 218 void dispatch(); 219 220 /** 221 * Struct containing information for a created Wayland connection through a 222 * socketpair. 223 */ 224 struct SocketPairConnection { 225 /** 226 * ServerSide Connection 227 */ 228 KWaylandServer::ClientConnection *connection = nullptr; 229 /** 230 * client-side file descriptor for the socket 231 */ 232 int fd = -1; 233 }; 234 /** 235 * Creates a Wayland connection using a socket pair. 236 */ 237 SocketPairConnection createConnection(); 238 239 void simulateUserActivity(); 240 void updateKeyState(KWin::Xkb::LEDs leds); 241 linuxDmabufBuffers()242 QSet<KWaylandServer::LinuxDmaBufV1ClientBuffer*> linuxDmabufBuffers() const { 243 return m_linuxDmabufBuffers; 244 } addLinuxDmabufBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer * buffer)245 void addLinuxDmabufBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) { 246 m_linuxDmabufBuffers << buffer; 247 } removeLinuxDmabufBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer * buffer)248 void removeLinuxDmabufBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) { 249 m_linuxDmabufBuffers.remove(buffer); 250 } 251 252 AbstractWaylandOutput *findOutput(KWaylandServer::OutputInterface *output) const; 253 254 /** 255 * Returns the first socket name that can be used to connect to this server. 256 * For a full list, use display()->socketNames() 257 */ 258 QString socketName() const; 259 260 Q_SIGNALS: 261 void shellClientAdded(KWin::AbstractClient *); 262 void shellClientRemoved(KWin::AbstractClient *); 263 void terminatingInternalClientConnection(); 264 void initialized(); 265 void foreignTransientChanged(KWaylandServer::SurfaceInterface *child); 266 267 private: 268 int createScreenLockerConnection(); 269 void shellClientShown(Toplevel *t); 270 void destroyInternalConnection(); 271 void initScreenLocker(); 272 void registerXdgGenericClient(AbstractClient *client); 273 void registerXdgToplevelClient(XdgToplevelClient *client); 274 void registerXdgPopupClient(XdgPopupClient *client); 275 void registerShellClient(AbstractClient *client); 276 void handleOutputAdded(AbstractOutput *output); 277 void handleOutputRemoved(AbstractOutput *output); 278 void handleOutputEnabled(AbstractOutput *output); 279 void handleOutputDisabled(AbstractOutput *output); 280 KWaylandServer::Display *m_display = nullptr; 281 KWaylandServer::CompositorInterface *m_compositor = nullptr; 282 KWaylandServer::SeatInterface *m_seat = nullptr; 283 KWaylandServer::TabletManagerV2Interface *m_tabletManagerV2 = nullptr; 284 KWaylandServer::DataDeviceManagerInterface *m_dataDeviceManager = nullptr; 285 KWaylandServer::PlasmaShellInterface *m_plasmaShell = nullptr; 286 KWaylandServer::PlasmaWindowActivationFeedbackInterface *m_plasmaActivationFeedback = nullptr; 287 KWaylandServer::PlasmaWindowManagementInterface *m_windowManagement = nullptr; 288 KWaylandServer::PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr; 289 KWaylandServer::ServerSideDecorationManagerInterface *m_decorationManager = nullptr; 290 KWaylandServer::OutputManagementV2Interface *m_outputManagement = nullptr; 291 KWaylandServer::AppMenuManagerInterface *m_appMenuManager = nullptr; 292 KWaylandServer::ServerSideDecorationPaletteManagerInterface *m_paletteManager = nullptr; 293 KWaylandServer::IdleInterface *m_idle = nullptr; 294 KWaylandServer::XdgOutputManagerV1Interface *m_xdgOutputManagerV1 = nullptr; 295 KWaylandServer::XdgDecorationManagerV1Interface *m_xdgDecorationManagerV1 = nullptr; 296 KWaylandServer::LinuxDmaBufV1ClientBufferIntegration *m_linuxDmabuf = nullptr; 297 KWaylandServer::KeyboardShortcutsInhibitManagerV1Interface *m_keyboardShortcutsInhibitManager = nullptr; 298 QSet<KWaylandServer::LinuxDmaBufV1ClientBuffer*> m_linuxDmabufBuffers; 299 QPointer<KWaylandServer::ClientConnection> m_xwaylandConnection; 300 KWaylandServer::InputMethodV1Interface *m_inputMethod = nullptr; 301 KWaylandServer::ClientConnection *m_inputMethodServerConnection = nullptr; 302 KWaylandServer::ClientConnection *m_screenLockerClientConnection = nullptr; 303 struct { 304 KWaylandServer::ClientConnection *server = nullptr; 305 KWayland::Client::ConnectionThread *client = nullptr; 306 KWayland::Client::EventQueue *eventQueue = nullptr; 307 QThread *clientThread = nullptr; 308 KWayland::Client::Registry *registry = nullptr; 309 KWayland::Client::Compositor *compositor = nullptr; 310 KWayland::Client::Seat *seat = nullptr; 311 KWayland::Client::DataDeviceManager *ddm = nullptr; 312 bool interfacesAnnounced = false; 313 314 } m_internalConnection; 315 KWaylandServer::XdgForeignV2Interface *m_XdgForeign = nullptr; 316 KWaylandServer::KeyStateInterface *m_keyState = nullptr; 317 QList<AbstractClient *> m_clients; 318 InitializationFlags m_initFlags; 319 QHash<AbstractWaylandOutput *, WaylandOutput *> m_waylandOutputs; 320 QHash<AbstractWaylandOutput *, WaylandOutputDevice *> m_waylandOutputDevices; 321 KWIN_SINGLETON(WaylandServer) 322 }; 323 324 inline waylandServer()325WaylandServer *waylandServer() { 326 return WaylandServer::self(); 327 } 328 329 } // namespace KWin 330 331 #endif 332 333