File indexing completed on 2024-12-22 05:09:23
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 #include "registry.h" 0008 #include "appmenu.h" 0009 #include "blur.h" 0010 #include "compositor.h" 0011 #include "connection_thread.h" 0012 #include "contrast.h" 0013 #include "datadevicemanager.h" 0014 #include "dpms.h" 0015 #include "event_queue.h" 0016 #include "fakeinput.h" 0017 #include "idleinhibit.h" 0018 #include "logging.h" 0019 #include "output.h" 0020 #include "plasmashell.h" 0021 #include "plasmavirtualdesktop.h" 0022 #include "plasmawindowmanagement.h" 0023 #include "pointerconstraints.h" 0024 #include "pointergestures.h" 0025 #include "relativepointer.h" 0026 #include "seat.h" 0027 #include "shadow.h" 0028 #include "shell.h" 0029 #include "shm_pool.h" 0030 #include "slide.h" 0031 #include "subcompositor.h" 0032 #include "textinput_p.h" 0033 #include "wayland_pointer_p.h" 0034 #include "xdgdecoration.h" 0035 #include "xdgforeign_v2.h" 0036 #include "xdgoutput.h" 0037 #include "xdgshell.h" 0038 #include "xdgshell_p.h" 0039 // Qt 0040 #include <QDebug> 0041 // wayland 0042 #include "../compat/wayland-xdg-shell-v5-client-protocol.h" 0043 #include <wayland-appmenu-client-protocol.h> 0044 #include <wayland-blur-client-protocol.h> 0045 #include <wayland-client-protocol.h> 0046 #include <wayland-contrast-client-protocol.h> 0047 #include <wayland-dpms-client-protocol.h> 0048 #include <wayland-fake-input-client-protocol.h> 0049 #include <wayland-idle-inhibit-unstable-v1-client-protocol.h> 0050 #include <wayland-plasma-shell-client-protocol.h> 0051 #include <wayland-plasma-virtual-desktop-client-protocol.h> 0052 #include <wayland-plasma-window-management-client-protocol.h> 0053 #include <wayland-pointer-constraints-unstable-v1-client-protocol.h> 0054 #include <wayland-pointer-gestures-unstable-v1-client-protocol.h> 0055 #include <wayland-relativepointer-unstable-v1-client-protocol.h> 0056 #include <wayland-shadow-client-protocol.h> 0057 #include <wayland-slide-client-protocol.h> 0058 #include <wayland-text-input-v0-client-protocol.h> 0059 #include <wayland-text-input-v2-client-protocol.h> 0060 #include <wayland-xdg-decoration-unstable-v1-client-protocol.h> 0061 #include <wayland-xdg-foreign-unstable-v2-client-protocol.h> 0062 #include <wayland-xdg-output-unstable-v1-client-protocol.h> 0063 #include <wayland-xdg-shell-client-protocol.h> 0064 #include <wayland-xdg-shell-v6-client-protocol.h> 0065 0066 /***** 0067 * How to add another interface: 0068 * * define a new enum value in Registry::Interface 0069 * * define the bind<InterfaceName> method 0070 * * define the create<InterfaceName> method 0071 * * define the <interfaceName>Announced signal 0072 * * define the <interfaceName>Removed signal 0073 * * add a block to s_interfaces 0074 * * add the BIND macro for the new bind<InterfaceName> 0075 * * add the CREATE macro for the new create<InterfaceName> 0076 * * extend registry unit test to verify that it works 0077 ****/ 0078 0079 namespace KWayland 0080 { 0081 namespace Client 0082 { 0083 namespace 0084 { 0085 struct SuppertedInterfaceData { 0086 quint32 maxVersion; 0087 QByteArray name; 0088 const wl_interface *interface; 0089 void (Registry::*announcedSignal)(quint32, quint32); 0090 void (Registry::*removedSignal)(quint32); 0091 }; 0092 // clang-format off 0093 static const QMap<Registry::Interface, SuppertedInterfaceData> s_interfaces = { 0094 {Registry::Interface::Compositor, { 0095 4, 0096 QByteArrayLiteral("wl_compositor"), 0097 &wl_compositor_interface, 0098 &Registry::compositorAnnounced, 0099 &Registry::compositorRemoved 0100 }}, 0101 {Registry::Interface::DataDeviceManager, { 0102 3, 0103 QByteArrayLiteral("wl_data_device_manager"), 0104 &wl_data_device_manager_interface, 0105 &Registry::dataDeviceManagerAnnounced, 0106 &Registry::dataDeviceManagerRemoved 0107 }}, 0108 {Registry::Interface::Output, { 0109 4, 0110 QByteArrayLiteral("wl_output"), 0111 &wl_output_interface, 0112 &Registry::outputAnnounced, 0113 &Registry::outputRemoved 0114 }}, 0115 {Registry::Interface::Shm, { 0116 1, 0117 QByteArrayLiteral("wl_shm"), 0118 &wl_shm_interface, 0119 &Registry::shmAnnounced, 0120 &Registry::shmRemoved 0121 }}, 0122 {Registry::Interface::Seat, { 0123 5, 0124 QByteArrayLiteral("wl_seat"), 0125 &wl_seat_interface, 0126 &Registry::seatAnnounced, 0127 &Registry::seatRemoved 0128 }}, 0129 {Registry::Interface::Shell, { 0130 1, 0131 QByteArrayLiteral("wl_shell"), 0132 &wl_shell_interface, 0133 &Registry::shellAnnounced, 0134 &Registry::shellRemoved 0135 }}, 0136 {Registry::Interface::SubCompositor, { 0137 1, 0138 QByteArrayLiteral("wl_subcompositor"), 0139 &wl_subcompositor_interface, 0140 &Registry::subCompositorAnnounced, 0141 &Registry::subCompositorRemoved 0142 }}, 0143 {Registry::Interface::PlasmaShell, { 0144 8, 0145 QByteArrayLiteral("org_kde_plasma_shell"), 0146 &org_kde_plasma_shell_interface, 0147 &Registry::plasmaShellAnnounced, 0148 &Registry::plasmaShellRemoved 0149 }}, 0150 {Registry::Interface::PlasmaVirtualDesktopManagement, { 0151 2, 0152 QByteArrayLiteral("org_kde_plasma_virtual_desktop_management"), 0153 &org_kde_plasma_virtual_desktop_management_interface, 0154 &Registry::plasmaVirtualDesktopManagementAnnounced, 0155 &Registry::plasmaVirtualDesktopManagementRemoved 0156 }}, 0157 {Registry::Interface::PlasmaWindowManagement, { 0158 16, 0159 QByteArrayLiteral("org_kde_plasma_window_management"), 0160 &org_kde_plasma_window_management_interface, 0161 &Registry::plasmaWindowManagementAnnounced, 0162 &Registry::plasmaWindowManagementRemoved 0163 }}, 0164 {Registry::Interface::FakeInput, { 0165 4, 0166 QByteArrayLiteral("org_kde_kwin_fake_input"), 0167 &org_kde_kwin_fake_input_interface, 0168 &Registry::fakeInputAnnounced, 0169 &Registry::fakeInputRemoved 0170 }}, 0171 {Registry::Interface::Shadow, { 0172 2, 0173 QByteArrayLiteral("org_kde_kwin_shadow_manager"), 0174 &org_kde_kwin_shadow_manager_interface, 0175 &Registry::shadowAnnounced, 0176 &Registry::shadowRemoved 0177 }}, 0178 {Registry::Interface::Blur, { 0179 1, 0180 QByteArrayLiteral("org_kde_kwin_blur_manager"), 0181 &org_kde_kwin_blur_manager_interface, 0182 &Registry::blurAnnounced, 0183 &Registry::blurRemoved 0184 }}, 0185 {Registry::Interface::Contrast, { 0186 2, 0187 QByteArrayLiteral("org_kde_kwin_contrast_manager"), 0188 &org_kde_kwin_contrast_manager_interface, 0189 &Registry::contrastAnnounced, 0190 &Registry::contrastRemoved 0191 }}, 0192 {Registry::Interface::Slide, { 0193 1, 0194 QByteArrayLiteral("org_kde_kwin_slide_manager"), 0195 &org_kde_kwin_slide_manager_interface, 0196 &Registry::slideAnnounced, 0197 &Registry::slideRemoved 0198 }}, 0199 {Registry::Interface::Dpms, { 0200 1, 0201 QByteArrayLiteral("org_kde_kwin_dpms_manager"), 0202 &org_kde_kwin_dpms_manager_interface, 0203 &Registry::dpmsAnnounced, 0204 &Registry::dpmsRemoved 0205 }}, 0206 {Registry::Interface::TextInputManagerUnstableV0, { 0207 1, 0208 QByteArrayLiteral("wl_text_input_manager"), 0209 &wl_text_input_manager_interface, 0210 &Registry::textInputManagerUnstableV0Announced, 0211 &Registry::textInputManagerUnstableV0Removed 0212 }}, 0213 {Registry::Interface::TextInputManagerUnstableV2, { 0214 1, 0215 QByteArrayLiteral("zwp_text_input_manager_v2"), 0216 &zwp_text_input_manager_v2_interface, 0217 &Registry::textInputManagerUnstableV2Announced, 0218 &Registry::textInputManagerUnstableV2Removed 0219 }}, 0220 {Registry::Interface::XdgShellUnstableV5, { 0221 1, 0222 QByteArrayLiteral("xdg_shell"), 0223 &zxdg_shell_v5_interface, 0224 &Registry::xdgShellUnstableV5Announced, 0225 &Registry::xdgShellUnstableV5Removed 0226 }}, 0227 {Registry::Interface::RelativePointerManagerUnstableV1, { 0228 1, 0229 QByteArrayLiteral("zwp_relative_pointer_manager_v1"), 0230 &zwp_relative_pointer_manager_v1_interface, 0231 &Registry::relativePointerManagerUnstableV1Announced, 0232 &Registry::relativePointerManagerUnstableV1Removed 0233 }}, 0234 {Registry::Interface::PointerGesturesUnstableV1, { 0235 1, 0236 QByteArrayLiteral("zwp_pointer_gestures_v1"), 0237 &zwp_pointer_gestures_v1_interface, 0238 &Registry::pointerGesturesUnstableV1Announced, 0239 &Registry::pointerGesturesUnstableV1Removed 0240 }}, 0241 {Registry::Interface::PointerConstraintsUnstableV1, { 0242 1, 0243 QByteArrayLiteral("zwp_pointer_constraints_v1"), 0244 &zwp_pointer_constraints_v1_interface, 0245 &Registry::pointerConstraintsUnstableV1Announced, 0246 &Registry::pointerConstraintsUnstableV1Removed 0247 }}, 0248 {Registry::Interface::XdgExporterUnstableV2, { 0249 1, 0250 QByteArrayLiteral("zxdg_exporter_v2"), 0251 &zxdg_exporter_v2_interface, 0252 &Registry::exporterUnstableV2Announced, 0253 &Registry::exporterUnstableV2Removed 0254 }}, 0255 {Registry::Interface::XdgImporterUnstableV2, { 0256 1, 0257 QByteArrayLiteral("zxdg_importer_v2"), 0258 &zxdg_importer_v2_interface, 0259 &Registry::importerUnstableV2Announced, 0260 &Registry::importerUnstableV2Removed 0261 }}, 0262 {Registry::Interface::XdgShellUnstableV6, { 0263 1, 0264 QByteArrayLiteral("zxdg_shell_v6"), 0265 &zxdg_shell_v6_interface, 0266 &Registry::xdgShellUnstableV6Announced, 0267 &Registry::xdgShellUnstableV6Removed 0268 }}, 0269 {Registry::Interface::IdleInhibitManagerUnstableV1, { 0270 1, 0271 QByteArrayLiteral("zwp_idle_inhibit_manager_v1"), 0272 &zwp_idle_inhibit_manager_v1_interface, 0273 &Registry::idleInhibitManagerUnstableV1Announced, 0274 &Registry::idleInhibitManagerUnstableV1Removed 0275 }}, 0276 {Registry::Interface::AppMenu, { 0277 1, 0278 QByteArrayLiteral("org_kde_kwin_appmenu_manager"), 0279 &org_kde_kwin_appmenu_manager_interface, 0280 &Registry::appMenuAnnounced, 0281 &Registry::appMenuRemoved 0282 }}, 0283 {Registry::Interface::XdgOutputUnstableV1, { 0284 2, 0285 QByteArrayLiteral("zxdg_output_manager_v1"), 0286 &zxdg_output_manager_v1_interface, 0287 &Registry::xdgOutputAnnounced, 0288 &Registry::xdgOutputRemoved 0289 }}, 0290 {Registry::Interface::XdgShellStable, { 0291 1, 0292 QByteArrayLiteral("xdg_wm_base"), 0293 &xdg_wm_base_interface, 0294 &Registry::xdgShellStableAnnounced, 0295 &Registry::xdgShellStableRemoved 0296 }}, 0297 {Registry::Interface::XdgDecorationUnstableV1, { 0298 1, 0299 QByteArrayLiteral("zxdg_decoration_manager_v1"), 0300 &zxdg_decoration_manager_v1_interface, 0301 &Registry::xdgDecorationAnnounced, 0302 &Registry::xdgDecorationRemoved 0303 }}, 0304 {Registry::Interface::PlasmaActivationFeedback, { 0305 1, 0306 QByteArrayLiteral("org_kde_plasma_activation_feedback"), 0307 &org_kde_plasma_activation_feedback_interface, 0308 &Registry::plasmaActivationFeedbackAnnounced, 0309 &Registry::plasmaActivationFeedbackRemoved 0310 }}, 0311 }; 0312 // clang-format on 0313 0314 static quint32 maxVersion(const Registry::Interface &interface) 0315 { 0316 auto it = s_interfaces.find(interface); 0317 if (it != s_interfaces.end()) { 0318 return it.value().maxVersion; 0319 } 0320 return 0; 0321 } 0322 } 0323 0324 class Q_DECL_HIDDEN Registry::Private 0325 { 0326 public: 0327 Private(Registry *q); 0328 void setup(); 0329 bool hasInterface(Interface interface) const; 0330 AnnouncedInterface interface(Interface interface) const; 0331 QList<AnnouncedInterface> interfaces(Interface interface) const; 0332 Interface interfaceForName(quint32 name) const; 0333 template<typename T> 0334 T *bind(Interface interface, uint32_t name, uint32_t version) const; 0335 template<class T, typename WL> 0336 T *create(quint32 name, quint32 version, QObject *parent, WL *(Registry::*bindMethod)(uint32_t, uint32_t) const); 0337 0338 WaylandPointer<wl_registry, wl_registry_destroy> registry; 0339 static const struct wl_callback_listener s_callbackListener; 0340 WaylandPointer<wl_callback, wl_callback_destroy> callback; 0341 EventQueue *queue = nullptr; 0342 0343 private: 0344 void handleAnnounce(uint32_t name, const char *interface, uint32_t version); 0345 void handleRemove(uint32_t name); 0346 void handleGlobalSync(); 0347 static void globalAnnounce(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); 0348 static void globalRemove(void *data, struct wl_registry *registry, uint32_t name); 0349 static void globalSync(void *data, struct wl_callback *callback, uint32_t serial); 0350 0351 Registry *q; 0352 struct InterfaceData { 0353 Interface interface; 0354 uint32_t name; 0355 uint32_t version; 0356 }; 0357 QList<InterfaceData> m_interfaces; 0358 static const struct wl_registry_listener s_registryListener; 0359 }; 0360 0361 Registry::Private::Private(Registry *q) 0362 : q(q) 0363 { 0364 } 0365 0366 void Registry::Private::setup() 0367 { 0368 wl_registry_add_listener(registry, &s_registryListener, this); 0369 wl_callback_add_listener(callback, &s_callbackListener, this); 0370 } 0371 0372 Registry::Registry(QObject *parent) 0373 : QObject(parent) 0374 , d(new Private(this)) 0375 { 0376 } 0377 0378 Registry::~Registry() 0379 { 0380 release(); 0381 } 0382 0383 void Registry::release() 0384 { 0385 d->registry.release(); 0386 d->callback.release(); 0387 } 0388 0389 void Registry::destroy() 0390 { 0391 Q_EMIT registryDestroyed(); 0392 d->registry.destroy(); 0393 d->callback.destroy(); 0394 } 0395 0396 void Registry::create(wl_display *display) 0397 { 0398 Q_ASSERT(display); 0399 Q_ASSERT(!isValid()); 0400 d->registry.setup(wl_display_get_registry(display)); 0401 d->callback.setup(wl_display_sync(display)); 0402 if (d->queue) { 0403 d->queue->addProxy(d->registry); 0404 d->queue->addProxy(d->callback); 0405 } 0406 } 0407 0408 void Registry::create(ConnectionThread *connection) 0409 { 0410 create(connection->display()); 0411 connect(connection, &ConnectionThread::connectionDied, this, &Registry::destroy); 0412 } 0413 0414 void Registry::setup() 0415 { 0416 Q_ASSERT(isValid()); 0417 d->setup(); 0418 } 0419 0420 void Registry::setEventQueue(EventQueue *queue) 0421 { 0422 d->queue = queue; 0423 if (!queue) { 0424 return; 0425 } 0426 if (d->registry) { 0427 d->queue->addProxy(d->registry); 0428 } 0429 if (d->callback) { 0430 d->queue->addProxy(d->callback); 0431 } 0432 } 0433 0434 EventQueue *Registry::eventQueue() 0435 { 0436 return d->queue; 0437 } 0438 0439 #ifndef K_DOXYGEN 0440 const struct wl_registry_listener Registry::Private::s_registryListener = {globalAnnounce, globalRemove}; 0441 0442 const struct wl_callback_listener Registry::Private::s_callbackListener = {globalSync}; 0443 #endif 0444 0445 void Registry::Private::globalAnnounce(void *data, wl_registry *registry, uint32_t name, const char *interface, uint32_t version) 0446 { 0447 auto r = reinterpret_cast<Registry::Private *>(data); 0448 Q_ASSERT(registry == r->registry); 0449 r->handleAnnounce(name, interface, version); 0450 } 0451 0452 void Registry::Private::globalRemove(void *data, wl_registry *registry, uint32_t name) 0453 { 0454 auto r = reinterpret_cast<Registry::Private *>(data); 0455 Q_ASSERT(registry == r->registry); 0456 r->handleRemove(name); 0457 } 0458 0459 void Registry::Private::globalSync(void *data, wl_callback *callback, uint32_t serial) 0460 { 0461 Q_UNUSED(serial) 0462 auto r = reinterpret_cast<Registry::Private *>(data); 0463 Q_ASSERT(r->callback == callback); 0464 r->handleGlobalSync(); 0465 r->callback.release(); 0466 } 0467 0468 void Registry::Private::handleGlobalSync() 0469 { 0470 Q_EMIT q->interfacesAnnounced(); 0471 } 0472 0473 namespace 0474 { 0475 static Registry::Interface nameToInterface(const char *interface) 0476 { 0477 for (auto it = s_interfaces.constBegin(); it != s_interfaces.constEnd(); ++it) { 0478 if (qstrcmp(interface, it.value().name) == 0) { 0479 return it.key(); 0480 } 0481 } 0482 return Registry::Interface::Unknown; 0483 } 0484 } 0485 0486 void Registry::Private::handleAnnounce(uint32_t name, const char *interface, uint32_t version) 0487 { 0488 Interface i = nameToInterface(interface); 0489 Q_EMIT q->interfaceAnnounced(QByteArray(interface), name, version); 0490 if (i == Interface::Unknown) { 0491 qCDebug(KWAYLAND_CLIENT) << "Unknown interface announced: " << interface << "/" << name << "/" << version; 0492 return; 0493 } 0494 qCDebug(KWAYLAND_CLIENT) << "Wayland Interface: " << interface << "/" << name << "/" << version; 0495 m_interfaces.append({i, name, version}); 0496 auto it = s_interfaces.constFind(i); 0497 if (it != s_interfaces.end()) { 0498 Q_EMIT(q->*it.value().announcedSignal)(name, version); 0499 } 0500 } 0501 0502 void Registry::Private::handleRemove(uint32_t name) 0503 { 0504 auto it = std::find_if(m_interfaces.begin(), m_interfaces.end(), [name](const InterfaceData &data) { 0505 return data.name == name; 0506 }); 0507 if (it != m_interfaces.end()) { 0508 InterfaceData data = *(it); 0509 m_interfaces.erase(it); 0510 auto sit = s_interfaces.find(data.interface); 0511 if (sit != s_interfaces.end()) { 0512 Q_EMIT(q->*sit.value().removedSignal)(data.name); 0513 } 0514 } 0515 Q_EMIT q->interfaceRemoved(name); 0516 } 0517 0518 bool Registry::Private::hasInterface(Registry::Interface interface) const 0519 { 0520 auto it = std::find_if(m_interfaces.constBegin(), m_interfaces.constEnd(), [interface](const InterfaceData &data) { 0521 return data.interface == interface; 0522 }); 0523 return it != m_interfaces.constEnd(); 0524 } 0525 0526 QList<Registry::AnnouncedInterface> Registry::Private::interfaces(Interface interface) const 0527 { 0528 QList<Registry::AnnouncedInterface> retVal; 0529 for (auto it = m_interfaces.constBegin(); it != m_interfaces.constEnd(); ++it) { 0530 const auto &data = *it; 0531 if (data.interface == interface) { 0532 retVal << AnnouncedInterface{data.name, data.version}; 0533 } 0534 } 0535 return retVal; 0536 } 0537 0538 Registry::AnnouncedInterface Registry::Private::interface(Interface interface) const 0539 { 0540 const auto all = interfaces(interface); 0541 if (!all.isEmpty()) { 0542 return all.last(); 0543 } 0544 return AnnouncedInterface{0, 0}; 0545 } 0546 0547 Registry::Interface Registry::Private::interfaceForName(quint32 name) const 0548 { 0549 auto it = std::find_if(m_interfaces.constBegin(), m_interfaces.constEnd(), [name](const InterfaceData &data) { 0550 return data.name == name; 0551 }); 0552 if (it == m_interfaces.constEnd()) { 0553 return Interface::Unknown; 0554 } 0555 return (*it).interface; 0556 } 0557 0558 bool Registry::hasInterface(Registry::Interface interface) const 0559 { 0560 return d->hasInterface(interface); 0561 } 0562 0563 QList<Registry::AnnouncedInterface> Registry::interfaces(Interface interface) const 0564 { 0565 return d->interfaces(interface); 0566 } 0567 0568 Registry::AnnouncedInterface Registry::interface(Interface interface) const 0569 { 0570 return d->interface(interface); 0571 } 0572 0573 // clang-format off 0574 #define BIND2(__NAME__, __INAME__, __WL__) \ 0575 __WL__ *Registry::bind##__NAME__(uint32_t name, uint32_t version) const \ 0576 { \ 0577 return d->bind<__WL__>(Interface::__INAME__, name, qMin(maxVersion(Interface::__INAME__), version)); \ 0578 } 0579 0580 #define BIND(__NAME__, __WL__) BIND2(__NAME__, __NAME__, __WL__) 0581 // clang-format on 0582 0583 BIND(Compositor, wl_compositor) 0584 BIND(Output, wl_output) 0585 BIND(Seat, wl_seat) 0586 BIND(Shell, wl_shell) 0587 BIND(Shm, wl_shm) 0588 BIND(SubCompositor, wl_subcompositor) 0589 BIND(DataDeviceManager, wl_data_device_manager) 0590 BIND(PlasmaShell, org_kde_plasma_shell) 0591 BIND(PlasmaActivationFeedback, org_kde_plasma_activation_feedback) 0592 BIND(PlasmaVirtualDesktopManagement, org_kde_plasma_virtual_desktop_management) 0593 BIND(PlasmaWindowManagement, org_kde_plasma_window_management) 0594 BIND(FakeInput, org_kde_kwin_fake_input) 0595 BIND(TextInputManagerUnstableV0, wl_text_input_manager) 0596 BIND(TextInputManagerUnstableV2, zwp_text_input_manager_v2) 0597 BIND(XdgShellUnstableV5, xdg_shell) 0598 BIND(XdgShellUnstableV6, zxdg_shell_v6) 0599 BIND(XdgShellStable, xdg_wm_base) 0600 BIND(RelativePointerManagerUnstableV1, zwp_relative_pointer_manager_v1) 0601 BIND(PointerGesturesUnstableV1, zwp_pointer_gestures_v1) 0602 BIND(PointerConstraintsUnstableV1, zwp_pointer_constraints_v1) 0603 BIND(XdgExporterUnstableV2, zxdg_exporter_v2) 0604 BIND(XdgImporterUnstableV2, zxdg_importer_v2) 0605 BIND(IdleInhibitManagerUnstableV1, zwp_idle_inhibit_manager_v1) 0606 BIND2(ShadowManager, Shadow, org_kde_kwin_shadow_manager) 0607 BIND2(BlurManager, Blur, org_kde_kwin_blur_manager) 0608 BIND2(ContrastManager, Contrast, org_kde_kwin_contrast_manager) 0609 BIND2(SlideManager, Slide, org_kde_kwin_slide_manager) 0610 BIND2(DpmsManager, Dpms, org_kde_kwin_dpms_manager) 0611 BIND2(AppMenuManager, AppMenu, org_kde_kwin_appmenu_manager) 0612 BIND(XdgOutputUnstableV1, zxdg_output_manager_v1) 0613 BIND(XdgDecorationUnstableV1, zxdg_decoration_manager_v1) 0614 0615 #undef BIND 0616 #undef BIND2 0617 0618 template<class T, typename WL> 0619 T *Registry::Private::create(quint32 name, quint32 version, QObject *parent, WL *(Registry::*bindMethod)(uint32_t, uint32_t) const) 0620 { 0621 T *t = new T(parent); 0622 t->setEventQueue(queue); 0623 t->setup((q->*bindMethod)(name, version)); 0624 QObject::connect(q, &Registry::interfaceRemoved, t, [t, name](quint32 removed) { 0625 if (name == removed) { 0626 Q_EMIT t->removed(); 0627 } 0628 }); 0629 QObject::connect(q, &Registry::registryDestroyed, t, &T::destroy); 0630 return t; 0631 } 0632 0633 // clang-format off 0634 #define CREATE2(__NAME__, __BINDNAME__) \ 0635 __NAME__ *Registry::create##__NAME__(quint32 name, quint32 version, QObject *parent) \ 0636 { \ 0637 return d->create<__NAME__>(name, version, parent, &Registry::bind##__BINDNAME__); \ 0638 } 0639 0640 #define CREATE(__NAME__) CREATE2(__NAME__, __NAME__) 0641 // clang-format on 0642 0643 CREATE(Compositor) 0644 CREATE(Seat) 0645 CREATE(Shell) 0646 CREATE(SubCompositor) 0647 CREATE(Output) 0648 CREATE(DataDeviceManager) 0649 CREATE(PlasmaShell) 0650 CREATE(PlasmaActivationFeedback) 0651 CREATE(PlasmaVirtualDesktopManagement) 0652 CREATE(PlasmaWindowManagement) 0653 CREATE(FakeInput) 0654 CREATE(ShadowManager) 0655 CREATE(BlurManager) 0656 CREATE(ContrastManager) 0657 CREATE(SlideManager) 0658 CREATE(DpmsManager) 0659 CREATE2(ShmPool, Shm) 0660 CREATE(AppMenuManager) 0661 0662 #undef CREATE 0663 #undef CREATE2 0664 0665 XdgExporter *Registry::createXdgExporter(quint32 name, quint32 version, QObject *parent) 0666 { 0667 // only V1 supported for now 0668 return d->create<XdgExporterUnstableV2>(name, version, parent, &Registry::bindXdgExporterUnstableV2); 0669 } 0670 0671 XdgImporter *Registry::createXdgImporter(quint32 name, quint32 version, QObject *parent) 0672 { 0673 // only V1 supported for now 0674 return d->create<XdgImporterUnstableV2>(name, version, parent, &Registry::bindXdgImporterUnstableV2); 0675 } 0676 0677 TextInputManager *Registry::createTextInputManager(quint32 name, quint32 version, QObject *parent) 0678 { 0679 switch (d->interfaceForName(name)) { 0680 case Interface::TextInputManagerUnstableV0: 0681 return d->create<TextInputManagerUnstableV0>(name, version, parent, &Registry::bindTextInputManagerUnstableV0); 0682 case Interface::TextInputManagerUnstableV2: 0683 return d->create<TextInputManagerUnstableV2>(name, version, parent, &Registry::bindTextInputManagerUnstableV2); 0684 default: 0685 return nullptr; 0686 } 0687 } 0688 0689 XdgShell *Registry::createXdgShell(quint32 name, quint32 version, QObject *parent) 0690 { 0691 switch (d->interfaceForName(name)) { 0692 case Interface::XdgShellUnstableV5: 0693 return d->create<XdgShellUnstableV5>(name, version, parent, &Registry::bindXdgShellUnstableV5); 0694 case Interface::XdgShellUnstableV6: 0695 return d->create<XdgShellUnstableV6>(name, version, parent, &Registry::bindXdgShellUnstableV6); 0696 case Interface::XdgShellStable: 0697 return d->create<XdgShellStable>(name, version, parent, &Registry::bindXdgShellStable); 0698 default: 0699 return nullptr; 0700 } 0701 } 0702 0703 RelativePointerManager *Registry::createRelativePointerManager(quint32 name, quint32 version, QObject *parent) 0704 { 0705 switch (d->interfaceForName(name)) { 0706 case Interface::RelativePointerManagerUnstableV1: 0707 return d->create<RelativePointerManager>(name, version, parent, &Registry::bindRelativePointerManagerUnstableV1); 0708 default: 0709 return nullptr; 0710 } 0711 } 0712 0713 PointerGestures *Registry::createPointerGestures(quint32 name, quint32 version, QObject *parent) 0714 { 0715 switch (d->interfaceForName(name)) { 0716 case Interface::PointerGesturesUnstableV1: 0717 return d->create<PointerGestures>(name, version, parent, &Registry::bindPointerGesturesUnstableV1); 0718 default: 0719 return nullptr; 0720 } 0721 } 0722 0723 PointerConstraints *Registry::createPointerConstraints(quint32 name, quint32 version, QObject *parent) 0724 { 0725 switch (d->interfaceForName(name)) { 0726 case Interface::PointerConstraintsUnstableV1: 0727 return d->create<PointerConstraints>(name, version, parent, &Registry::bindPointerConstraintsUnstableV1); 0728 default: 0729 return nullptr; 0730 } 0731 } 0732 0733 IdleInhibitManager *Registry::createIdleInhibitManager(quint32 name, quint32 version, QObject *parent) 0734 { 0735 switch (d->interfaceForName(name)) { 0736 case Interface::IdleInhibitManagerUnstableV1: 0737 return d->create<IdleInhibitManager>(name, version, parent, &Registry::bindIdleInhibitManagerUnstableV1); 0738 default: 0739 return nullptr; 0740 } 0741 } 0742 0743 XdgOutputManager *Registry::createXdgOutputManager(quint32 name, quint32 version, QObject *parent) 0744 { 0745 switch (d->interfaceForName(name)) { 0746 case Interface::XdgOutputUnstableV1: 0747 return d->create<XdgOutputManager>(name, version, parent, &Registry::bindXdgOutputUnstableV1); 0748 default: 0749 return nullptr; 0750 } 0751 } 0752 0753 XdgDecorationManager *Registry::createXdgDecorationManager(quint32 name, quint32 version, QObject *parent) 0754 { 0755 switch (d->interfaceForName(name)) { 0756 case Interface::XdgDecorationUnstableV1: 0757 return d->create<XdgDecorationManager>(name, version, parent, &Registry::bindXdgDecorationUnstableV1); 0758 default: 0759 return nullptr; 0760 } 0761 } 0762 0763 namespace 0764 { 0765 static const wl_interface *wlInterface(Registry::Interface interface) 0766 { 0767 auto it = s_interfaces.find(interface); 0768 if (it != s_interfaces.end()) { 0769 return it.value().interface; 0770 } 0771 return nullptr; 0772 } 0773 } 0774 0775 template<typename T> 0776 T *Registry::Private::bind(Registry::Interface interface, uint32_t name, uint32_t version) const 0777 { 0778 auto it = std::find_if(m_interfaces.constBegin(), m_interfaces.constEnd(), [=](const InterfaceData &data) { 0779 return data.interface == interface && data.name == name && data.version >= version; 0780 }); 0781 if (it == m_interfaces.constEnd()) { 0782 qCDebug(KWAYLAND_CLIENT) << "Don't have interface " << int(interface) << "with name " << name << "and minimum version" << version; 0783 return nullptr; 0784 } 0785 auto t = reinterpret_cast<T *>(wl_registry_bind(registry, name, wlInterface(interface), version)); 0786 if (queue) { 0787 queue->addProxy(t); 0788 } 0789 return t; 0790 } 0791 0792 bool Registry::isValid() const 0793 { 0794 return d->registry.isValid(); 0795 } 0796 0797 wl_registry *Registry::registry() 0798 { 0799 return d->registry; 0800 } 0801 0802 Registry::operator wl_registry *() const 0803 { 0804 return d->registry; 0805 } 0806 0807 Registry::operator wl_registry *() 0808 { 0809 return d->registry; 0810 } 0811 0812 } 0813 } 0814 0815 #include "moc_registry.cpp"