Sunshine latest
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 };
35
36 class dmabuf_t {
37 public:
43
44 dmabuf_t();
45 ~dmabuf_t();
46
47 dmabuf_t(dmabuf_t &&) = delete;
48 dmabuf_t(const dmabuf_t &) = delete;
49 dmabuf_t &operator=(const dmabuf_t &) = delete;
50 dmabuf_t &operator=(dmabuf_t &&) = delete;
51
52 void listen(zwlr_screencopy_manager_v1 *screencopy_manager, zwp_linux_dmabuf_v1 *dmabuf_interface, wl_output *output, bool blend_cursor = false);
53 static void buffer_params_created(void *data, struct zwp_linux_buffer_params_v1 *params, struct wl_buffer *wl_buffer);
54 static void buffer_params_failed(void *data, struct zwp_linux_buffer_params_v1 *params);
55 void buffer(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
56 void linux_dmabuf(zwlr_screencopy_frame_v1 *frame, std::uint32_t format, std::uint32_t width, std::uint32_t height);
57 void buffer_done(zwlr_screencopy_frame_v1 *frame);
58 void flags(zwlr_screencopy_frame_v1 *frame, std::uint32_t flags);
59 void damage(zwlr_screencopy_frame_v1 *frame, std::uint32_t x, std::uint32_t y, std::uint32_t width, std::uint32_t height);
60 void ready(zwlr_screencopy_frame_v1 *frame, std::uint32_t tv_sec_hi, std::uint32_t tv_sec_lo, std::uint32_t tv_nsec);
61 void failed(zwlr_screencopy_frame_v1 *frame);
62
63 frame_t *get_next_frame() {
64 return current_frame == &frames[0] ? &frames[1] : &frames[0];
65 }
66
67 status_e status;
68 std::array<frame_t, 2> frames;
69 frame_t *current_frame;
70 zwlr_screencopy_frame_v1_listener listener;
71
72 private:
73 bool init_gbm();
74 void cleanup_gbm();
75 void create_and_copy_dmabuf(zwlr_screencopy_frame_v1 *frame);
76
77 zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
78
79 struct {
80 bool supported {false};
81 std::uint32_t format;
82 std::uint32_t width;
83 std::uint32_t height;
84 std::uint32_t stride;
85 } shm_info;
86
87 struct {
88 bool supported {false};
89 std::uint32_t format;
90 std::uint32_t width;
91 std::uint32_t height;
92 } dmabuf_info;
93
94 struct gbm_device *gbm_device {nullptr};
95 struct gbm_bo *current_bo {nullptr};
96 struct wl_buffer *current_wl_buffer {nullptr};
97 bool y_invert {false};
98 };
99
100 class monitor_t {
101 public:
102 explicit monitor_t(wl_output *output);
103
104 monitor_t(monitor_t &&) = delete;
105 monitor_t(const monitor_t &) = delete;
106 monitor_t &operator=(const monitor_t &) = delete;
107 monitor_t &operator=(monitor_t &&) = delete;
108
109 void listen(zxdg_output_manager_v1 *output_manager);
110 void xdg_name(zxdg_output_v1 *, const char *name);
111 void xdg_description(zxdg_output_v1 *, const char *description);
112 void xdg_position(zxdg_output_v1 *, std::int32_t x, std::int32_t y);
113 void xdg_size(zxdg_output_v1 *, std::int32_t width, std::int32_t height);
114
115 void xdg_done(zxdg_output_v1 *) {}
116
117 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) {}
118
119 void wl_mode(wl_output *wl_output, std::uint32_t flags, std::int32_t width, std::int32_t height, std::int32_t refresh);
120
121 void wl_done(wl_output *wl_output) {}
122
123 void wl_scale(wl_output *wl_output, std::int32_t factor) {}
124
125 wl_output *output;
126 std::string name;
127 std::string description;
128 platf::touch_port_t viewport;
129 wl_output_listener wl_listener;
130 zxdg_output_v1_listener xdg_listener;
131 };
132
134 struct bind_t {
135 std::uint32_t id;
136 std::uint32_t version;
137 };
138
139 public:
146
147 interface_t() noexcept;
148
149 interface_t(interface_t &&) = delete;
150 interface_t(const interface_t &) = delete;
151 interface_t &operator=(const interface_t &) = delete;
152 interface_t &operator=(interface_t &&) = delete;
153
154 void listen(wl_registry *registry);
155
156 bool operator[](interface_e bit) const {
157 return interface[bit];
158 }
159
160 std::vector<std::unique_ptr<monitor_t>> monitors;
161 zwlr_screencopy_manager_v1 *screencopy_manager {nullptr};
162 zwp_linux_dmabuf_v1 *dmabuf_interface {nullptr};
163 zxdg_output_manager_v1 *output_manager {nullptr};
164
165 private:
166 void add_interface(wl_registry *registry, std::uint32_t id, const char *interface, std::uint32_t version);
167 void del_interface(wl_registry *registry, uint32_t id);
168
169 std::bitset<MAX_INTERFACES> interface;
170 wl_registry_listener listener;
171 };
172
173 class display_t {
174 public:
181 int init(const char *display_name = nullptr);
182
183 // Roundtrip with Wayland connection
184 void roundtrip();
185
186 // Wait up to the timeout to read and dispatch new events
187 bool dispatch(std::chrono::milliseconds timeout);
188
189 // Get the registry associated with the display
190 // No need to manually free the registry
191 wl_registry *registry();
192
193 inline display_internal_t::pointer get() {
194 return display_internal.get();
195 }
196
197 private:
198 display_internal_t display_internal;
199 };
200
201 std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr);
202 int init();
203} // namespace wl
204#else
205
206struct wl_output;
207struct zxdg_output_manager_v1;
208
209namespace wl {
210 class monitor_t {
211 public:
212 monitor_t(wl_output *output);
213
214 monitor_t(monitor_t &&) = delete;
215 monitor_t(const monitor_t &) = delete;
216 monitor_t &operator=(const monitor_t &) = delete;
217 monitor_t &operator=(monitor_t &&) = delete;
218
219 void listen(zxdg_output_manager_v1 *output_manager);
220
221 wl_output *output;
222 std::string name;
223 std::string description;
224 platf::touch_port_t viewport;
225 };
226
227 inline std::vector<std::unique_ptr<monitor_t>> monitors(const char *display_name = nullptr) {
228 return {};
229 }
230
231 inline int init() {
232 return -1;
233 }
234} // namespace wl
235#endif
Definition utility.h:530
Definition wayland.h:173
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:36
status_e
Definition wayland.h:38
@ WAITING
Waiting for a frame.
Definition wayland.h:39
@ READY
Frame is ready.
Definition wayland.h:40
@ REINIT
Reinitialize the frame.
Definition wayland.h:41
Definition wayland.h:28
Definition wayland.h:133
interface_e
Definition wayland.h:140
@ WLR_EXPORT_DMABUF
screencopy manager
Definition wayland.h:142
@ LINUX_DMABUF
linux-dmabuf protocol
Definition wayland.h:143
@ MAX_INTERFACES
Maximum number of interfaces.
Definition wayland.h:144
@ XDG_OUTPUT
xdg-output
Definition wayland.h:141
Definition wayland.h:100
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:230
Definition common.h:270