Sunshine v2026.319.132152
Self-hosted game stream host for Moonlight.
wayland.h
Go to the documentation of this file.
1
5#pragma once
6
7// standard includes
8#include <bitset>
9
10#ifdef SUNSHINE_BUILD_WAYLAND
11 #include <linux-dmabuf-unstable-v1.h>
12 #include <wlr-screencopy-unstable-v1.h>
13 #include <xdg-output-unstable-v1.h>
14#endif
15
16// local includes
17#include "graphics.h"
18
23#ifdef SUNSHINE_BUILD_WAYLAND
24
25namespace wl {
27
28 class frame_t {
29 public:
30 frame_t();
31 void destroy();
32
34 std::optional<std::chrono::steady_clock::time_point> frame_timestamp;
35 };
36
37 class dmabuf_t {
38 public:
44
45 dmabuf_t();
46 ~dmabuf_t();
47
48 dmabuf_t(dmabuf_t &&) = delete;
49 dmabuf_t(const dmabuf_t &) = delete;
50 dmabuf_t &operator=(const dmabuf_t &) = delete;
51 dmabuf_t &operator=(dmabuf_t &&) = delete;
52
53 void listen(zwlr_screencopy_manager_v1 *screencopy_manager, zwp_linux_dmabuf_v1 *dmabuf_interface, wl_output *output, bool blend_cursor = false);
54 static void buffer_params_created(void *data, struct zwp_linux_buffer_params_v1 *params, struct wl_buffer *wl_buffer);
55 static void buffer_params_failed(void *data, struct zwp_linux_buffer_params_v1 *params);
56 void buffer(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
57 void linux_dmabuf(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height);
58 void buffer_done(zwlr_screencopy_frame_v1 *frame);
59 void flags(zwlr_screencopy_frame_v1 *frame, std::uint32_t flags);
60 void damage(zwlr_screencopy_frame_v1 *frame, std::uint32_t x, std::uint32_t y, std::uint32_t width, std::uint32_t height);
61 void ready(zwlr_screencopy_frame_v1 *frame, std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec);
62 void failed(zwlr_screencopy_frame_v1 *frame);
63
64 frame_t *get_next_frame() {
65 return current_frame == &frames[0] ? &frames[1] : &frames[0];
66 }
67
68 status_e status;
69 std::array<frame_t, 2> frames;
70 frame_t *current_frame;
71 zwlr_screencopy_frame_v1_listener listener;
72
73 private:
74 bool init_gbm();
75 void cleanup_gbm();
76 void create_and_copy_dmabuf(zwlr_screencopy_frame_v1 *frame);
77
78 zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
79
80 struct {
81 bool supported {false};
82 std::uint32_t format;
83 std::uint32_t width;
84 std::uint32_t height;
85 std::uint32_t stride;
86 } shm_info;
87
88 struct {
89 bool supported {false};
90 std::uint32_t format;
91 std::uint32_t width;
92 std::uint32_t height;
93 } dmabuf_info;
94
95 struct gbm_device *gbm_device {nullptr};
96 struct gbm_bo *current_bo {nullptr};
97 struct wl_buffer *current_wl_buffer {nullptr};
98 bool y_invert {false};
99 };
100
101 class monitor_t {
102 public:
103 explicit monitor_t(wl_output *output);
104
105 monitor_t(monitor_t &&) = delete;
106 monitor_t(const monitor_t &) = delete;
107 monitor_t &operator=(const monitor_t &) = delete;
108 monitor_t &operator=(monitor_t &&) = delete;
109
110 void listen(zxdg_output_manager_v1 *output_manager);
111 void xdg_name(zxdg_output_v1 *, const char *name);
112 void xdg_description(zxdg_output_v1 *, const char *description);
113 void xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y);
114 void xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height);
115
116 void xdg_done(zxdg_output_v1 *) {}
117
118 void wl_geometry(wl_output *wl_output, std::int32_t x, std::int32_t y, std::int32_t physical_width, std::int32_t physical_height, std::int32_t subpixel, const char *make, const char *model, std::int32_t transform) {}
119
120 void wl_mode(wl_output *wl_output, std::uint32_t flags, std::int32_t width, std::int32_t height, std::int32_t refresh);
121
122 void wl_done(wl_output *wl_output) {}
123
124 void wl_scale(wl_output *wl_output, std::int32_t factor) {}
125
126 wl_output *output;
127 std::string name;
128 std::string description;
129 platf::touch_port_t viewport;
130 wl_output_listener wl_listener;
131 zxdg_output_v1_listener xdg_listener;
132 };
133
135 struct bind_t {
136 std::uint32_t id;
137 std::uint32_t version;
138 };
139
140 public:
147
148 interface_t() noexcept;
149
150 interface_t(interface_t &&) = delete;
151 interface_t(const interface_t &) = delete;
152 interface_t &operator=(const interface_t &) = delete;
153 interface_t &operator=(interface_t &&) = delete;
154
155 void listen(wl_registry *registry);
156
157 bool operator[](interface_e bit) const {
158 return interface[bit];
159 }
160
161 std::vector<std::unique_ptr<monitor_t>> monitors;
162 zwlr_screencopy_manager_v1 *screencopy_manager {nullptr};
163 zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
164 zxdg_output_manager_v1 *output_manager {nullptr};
165
166 private:
167 void add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version);
168 void del_interface(wl_registry *registry, uint32_t id);
169
170 std::bitset<MAX_INTERFACES> interface;
171 wl_registry_listener listener;
172 };
173
174 class display_t {
175 public:
182 int init(const char *display_name = nullptr);
183
184 // Roundtrip with Wayland connection
185 void roundtrip();
186
187 // Wait up to the timeout to read and dispatch new events
188 bool dispatch(std::chrono::milliseconds timeout);
189
190 // Get the registry associated with the display
191 // No need to manually free the registry
192 wl_registry *registry();
193
194 inline display_internal_t::pointer get() {
195 return display_internal.get();
196 }
197
198 private:
199 display_internal_t display_internal;
200 };
201
202 std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr);
203 int init();
204} // namespace wl
205#else
206
207struct wl_output;
208struct zxdg_output_manager_v1;
209
210namespace wl {
211 class monitor_t {
212 public:
213 monitor_t(wl_output *output);
214
215 monitor_t(monitor_t &&) = delete;
216 monitor_t(const monitor_t &) = delete;
217 monitor_t &operator=(const monitor_t &) = delete;
218 monitor_t &operator=(monitor_t &&) = delete;
219
220 void listen(zxdg_output_manager_v1 *output_manager);
221
222 wl_output *output;
223 std::string name;
224 std::string description;
225 platf::touch_port_t viewport;
226 };
227
228 inline std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr) {
229 return {};
230 }
231
232 inline int init() {
233 return -1;
234 }
235} // namespace wl
236#endif
Definition utility.h:530
Definition wayland.h:174
int init(const char *display_name=nullptr)
Initialize display. If display_name == nullptr -> display_name = std::getenv("WAYLAND_DISPLAY")
Definition wayland.cpp:51
bool dispatch(std::chrono::milliseconds timeout)
Waits up to the specified timeout to dispatch new events on the wl_display.
Definition wayland.cpp:81
Definition wayland.h:37
status_e
Definition wayland.h:39
@ WAITING
Waiting for a frame.
Definition wayland.h:40
@ READY
Frame is ready.
Definition wayland.h:41
@ REINIT
Reinitialize the frame.
Definition wayland.h:42
Definition wayland.h:28
Definition wayland.h:134
interface_e
Definition wayland.h:141
@ WLR_EXPORT_DMABUF
screencopy manager
Definition wayland.h:143
@ LINUX_DMABUF
linux-dmabuf protocol
Definition wayland.h:144
@ MAX_INTERFACES
Maximum number of interfaces.
Definition wayland.h:145
@ XDG_OUTPUT
xdg-output
Definition wayland.h:142
Definition wayland.h:101
std::unique_ptr< platf::deinit_t > init(const std::filesystem::path &persistence_filepath, const config::video_t &video_config)
Initialize the implementation and perform the initial state recovery (if needed).
Definition display_device.cpp:704
Declarations for graphics related functions.
Definition wayland.cpp:35
Definition graphics.h:237
Definition common.h:270