MythTV master
mythwaylandextras.cpp
Go to the documentation of this file.
1// Qt
2#include <QWidget>
3#include <QtGlobal>
4#include <QGuiApplication>
5// N.B. Private headers
6#include <qpa/qplatformnativeinterface.h>
7
8// MythTV
11
12// Wayland
13#include <wayland-client.h>
14
15#define LOC QString("Wayland: ")
16
27{
28 if (!Widget)
29 return;
30
31 QWindow* window = Widget->windowHandle();
32 if (!window)
33 {
34 LOG(VB_GENERAL, LOG_WARNING, LOC + "Failed to retrieve native window");
35 return;
36 }
37
38 QPlatformNativeInterface* interface = QGuiApplication::platformNativeInterface();
39 m_display = reinterpret_cast<wl_display*>(interface->nativeResourceForWindow("display", window));
40 m_surface = reinterpret_cast<wl_surface*>(interface->nativeResourceForWindow("surface", window));
41 m_compositor = reinterpret_cast<wl_compositor*>(interface->nativeResourceForWindow("compositor", window));
42
43 if (!(m_display && m_surface && m_compositor))
44 LOG(VB_GENERAL, LOG_WARNING, LOC + "Failed to retrieve Wayland resources");
45}
46
54bool MythWaylandDevice::SetOpaqueRegion(const QRect Region) const
55{
56 if (!(m_surface && m_compositor))
57 return false;
58
59 wl_region* region = wl_compositor_create_region(m_compositor);
60 if (!region)
61 return false;
62
63 wl_region_add(region, Region.left(), Region.top(), Region.width(), Region.height());
64 wl_surface_set_opaque_region(m_surface, region);
65 wl_surface_commit(m_surface);
66 wl_region_destroy(region);
67
68 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Set opaque region: %1x%2+%3+%4")
69 .arg(Region.width()).arg(Region.height()).arg(Region.left()).arg(Region.top()));
70 return true;
71}
72
73const struct wl_registry_listener MythWaylandExtras::kRegistryListener = { &MythWaylandExtras::AnnounceGlobal, nullptr };
74
80void MythWaylandExtras::AnnounceGlobal(void *Opaque, struct wl_registry *Reg,
81 uint32_t Name, const char *Interface, uint32_t Version)
82{
83 auto * registry = reinterpret_cast<MythWaylandRegistry*>(Opaque);
84 auto found = std::find_if(registry->begin(), registry->end(), [&](const auto IFace)
85 {
86 return (strcmp(Interface, IFace.first->name) == 0) && (IFace.first->version == static_cast<int>(Version));
87 });
88
89 if (found != registry->end())
90 {
91 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Found interface: %1 (v%2)")
92 .arg(found->first->name).arg(found->first->version));
93 found->second = wl_registry_bind(Reg, Name, found->first, static_cast<uint32_t>(found->first->version));
94 if (!found->second)
95 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to bind %1").arg(found->first->name));
96 }
97}
98
101{
102 static bool s_checked = false;
103 static bool s_available = false;
104 if (!s_checked)
105 {
106 s_checked = true;
107 auto waylanddisplay = qEnvironmentVariable("WAYLAND_DISPLAY");
108 const auto *name = waylanddisplay.isEmpty() ? nullptr : waylanddisplay.toLocal8Bit().constData();
109 if (auto *display = wl_display_connect(name); display)
110 {
111 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Available (WAYLAND_DISPLAY: '%1')")
112 .arg(waylanddisplay));
113 s_available = true;
114 wl_display_disconnect(display);
115 }
116 }
117 return s_available;
118}
bool SetOpaqueRegion(QRect Region) const
Provide a rendering optimisation hint to the compositor.
wl_display * m_display
static bool IsAvailable()
Check whether we can connect to a Wayland server.
wl_compositor * m_compositor
wl_surface * m_surface
MythWaylandDevice(QWidget *Widget)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
#define LOC
std::map< const wl_interface *, void * > MythWaylandRegistry
static void AnnounceGlobal(void *Opaque, struct wl_registry *Reg, uint32_t Name, const char *Interface, uint32_t Version)
MythTV implementation of the Wayland registry callback.