@@ -36,66 +36,69 @@ namespace CppUtils::Window
3636 inline constexpr const auto bytesPerPixel = std::size_t{4};
3737 }
3838
39- inline auto xdg_wm_base_ping([[maybe_unused]] void* data, xdg_wm_base* xdg_wm_base, std::uint32_t serial) -> void
39+ namespace
4040 {
41- xdg_wm_base_pong(xdg_wm_base, serial);
42- }
41+ auto xdg_wm_base_ping([[maybe_unused]] void* data, xdg_wm_base* xdg_wm_base, std::uint32_t serial) -> void
42+ {
43+ xdg_wm_base_pong(xdg_wm_base, serial);
44+ }
4345
44- inline const auto windowManagerBaseListener = xdg_wm_base_listener{
45- .ping = xdg_wm_base_ping,
46- };
46+ constexpr auto windowManagerBaseListener = xdg_wm_base_listener{
47+ .ping = xdg_wm_base_ping,
48+ };
4749
48- inline auto global_registry_handler(
49- void* data,
50- wl_registry* registry,
51- std::uint32_t id,
52- const char* interface,
53- std::uint32_t version) noexcept -> void
54- {
55- static const auto waylandRegistryHandlers = std::unordered_map<std::string_view, Wayland::RegisterHandler>{
56- Wayland::makeHandlerPair(wl_compositor_interface, Wayland::globals.compositor, 3, 4),
57- Wayland::makeHandlerPair(wl_shm_interface, Wayland::globals.sharedMemory, 1, 1),
58- Wayland::makeHandlerPair(xdg_wm_base_interface, Wayland::globals.windowManagerBase, 1, 1, [data]() -> void {
59- xdg_wm_base_add_listener(Wayland::globals.windowManagerBase.get(), &windowManagerBaseListener, data);
60- })};
61- auto interfaceName = std::string_view{interface};
62- if (const auto& iterator = waylandRegistryHandlers.find(interfaceName); iterator != std::cend(waylandRegistryHandlers))
50+ auto global_registry_handler(
51+ void* data,
52+ wl_registry* registry,
53+ std::uint32_t id,
54+ const char* interface,
55+ std::uint32_t version) noexcept -> void
6356 {
64- iterator->second(registry, id, version);
65- Logger::print<"success">("{}", interfaceName);
57+ static const auto waylandRegistryHandlers = std::unordered_map<std::string_view, Wayland::RegisterHandler>{
58+ Wayland::makeHandlerPair(wl_compositor_interface, Wayland::globals.compositor, 3, 4),
59+ Wayland::makeHandlerPair(wl_shm_interface, Wayland::globals.sharedMemory, 1, 1),
60+ Wayland::makeHandlerPair(xdg_wm_base_interface, Wayland::globals.windowManagerBase, 1, 1, [data]() -> void {
61+ xdg_wm_base_add_listener(Wayland::globals.windowManagerBase.get(), &windowManagerBaseListener, data);
62+ })};
63+ auto interfaceName = std::string_view{interface};
64+ if (const auto& iterator = waylandRegistryHandlers.find(interfaceName); iterator != std::cend(waylandRegistryHandlers))
65+ {
66+ iterator->second(registry, id, version);
67+ Logger::print<"success">("{}", interfaceName);
68+ }
69+ else
70+ Logger::print<"warning">("{}", interfaceName);
6671 }
67- else
68- Logger::print<"warning">("{}", interfaceName);
69- }
7072
71- inline auto global_registry_remover(
72- [[maybe_unused]] void* data,
73- [[maybe_unused]] wl_registry* registry,
74- [[maybe_unused]] std::uint32_t id) noexcept -> void
75- {}
73+ auto global_registry_remover(
74+ [[maybe_unused]] void* data,
75+ [[maybe_unused]] wl_registry* registry,
76+ [[maybe_unused]] std::uint32_t id) noexcept -> void
77+ {}
7678
77- inline const auto registryListener = wl_registry_listener{
78- .global = global_registry_handler,
79- .global_remove = global_registry_remover,
80- };
79+ constexpr auto registryListener = wl_registry_listener{
80+ .global = global_registry_handler,
81+ .global_remove = global_registry_remover,
82+ };
8183
82- inline auto wl_buffer_release([[maybe_unused]] void* data, [[maybe_unused]] wl_buffer* buffer) -> void
83- {
84- // Todo: basculer sur la frame suivante
85- }
84+ auto wl_buffer_release([[maybe_unused]] void* data, [[maybe_unused]] wl_buffer* buffer) -> void
85+ {
86+ // Todo: basculer sur la frame suivante
87+ }
8688
87- inline const auto bufferListener = wl_buffer_listener{
88- .release = wl_buffer_release,
89- };
89+ constexpr auto bufferListener = wl_buffer_listener{
90+ .release = wl_buffer_release,
91+ };
9092
91- inline auto xdg_surface_configure(
92- void* data,
93- xdg_surface* xdg_surface,
94- std::uint32_t serial) -> void;
93+ auto xdg_surface_configure(
94+ void* data,
95+ xdg_surface* xdg_surface,
96+ std::uint32_t serial) -> void;
9597
96- inline const auto surfaceListener = xdg_surface_listener{
97- .configure = xdg_surface_configure,
98- };
98+ constexpr auto surfaceListener = xdg_surface_listener{
99+ .configure = xdg_surface_configure,
100+ };
101+ }
99102#endif
100103
101104 export class Window final
@@ -123,7 +126,10 @@ namespace CppUtils::Window
123126 const auto screenBufferSize = strideSize * m_size.height();
124127 const auto bufferSize = screenBufferSize * 3; // triple buffering
125128
126- m_fileDescriptor = System::FileDescriptor{System::allocateSharedMemory(bufferSize, "WaylandBuffer").value()};
129+ auto sharedMemory = System::allocateSharedMemory(bufferSize, "WaylandBuffer");
130+ if (not sharedMemory)
131+ throw std::runtime_error{std::string{sharedMemory.error()}};
132+ m_fileDescriptor = System::FileDescriptor{std::move(sharedMemory).value()};
127133 pixels = System::MappedSharedMemory{m_fileDescriptor, bufferSize};
128134 pool.reset(wl_shm_create_pool(Wayland::globals.sharedMemory.get(), m_fileDescriptor.get(), static_cast<std::int32_t>(bufferSize)));
129135 buffer.reset(
@@ -158,7 +164,7 @@ namespace CppUtils::Window
158164#endif
159165
160166#if defined(OS_WINDOWS)
161- [[nodiscard]] static inline auto generateStyle(Style style) const noexcept -> DWORD
167+ [[nodiscard]] static inline auto generateStyle(Style style) noexcept -> DWORD
162168 {
163169 auto windowStyle = DWORD{0};
164170 if (style & Style::HasBorder)
@@ -190,6 +196,10 @@ namespace CppUtils::Window
190196 wl_display_roundtrip(display);
191197 if (not Wayland::globals.compositor)
192198 return std::unexpected{"Failed to find a Wayland compositor"s};
199+ if (not Wayland::globals.sharedMemory)
200+ return std::unexpected{"Failed to find Wayland shared memory interface (wl_shm)"s};
201+ if (not Wayland::globals.windowManagerBase)
202+ return std::unexpected{"Failed to find xdg_wm_base interface"s};
193203#endif
194204 return {};
195205 }
@@ -204,6 +214,10 @@ namespace CppUtils::Window
204214 if (m_window == nullptr)
205215 return std::unexpected{"Window creation failed."sv};
206216#elif defined(OS_LINUX)
217+ if (not Wayland::globals.compositor)
218+ return std::unexpected{"Wayland compositor is not initialized"sv};
219+ if (not Wayland::globals.windowManagerBase)
220+ return std::unexpected{"Wayland window manager base is not initialized"sv};
207221 surface.reset(wl_compositor_create_surface(Wayland::globals.compositor.get()));
208222 if (not surface)
209223 return std::unexpected{"Failed to create a Wayland surface"sv};
@@ -223,14 +237,21 @@ namespace CppUtils::Window
223237 m_style{style},
224238 m_size{size}
225239 {
226- initWindowManager();
240+ #if defined(OS_LINUX)
241+ if (auto result = initWindowManager(); not result)
242+ throw std::runtime_error{result.error()};
243+
227244 wl_display_roundtrip(Wayland::globals.display.get());
228245 // m_imageStorage = ImageStorage{size};
229- openWindow();
246+ if (auto result = openWindow(); not result)
247+ throw std::runtime_error{std::string{result.error()}};
248+
249+ m_isOpen = true;
230250 wl_surface_commit(surface.get());
231251 wl_display_roundtrip(Wayland::globals.display.get());
232252 // wl_display_dispatch(Wayland::globals.display.get());
233253 wl_display_flush(Wayland::globals.display.get());
254+ #endif
234255 }
235256
236257 inline ~Window()
@@ -269,30 +290,43 @@ namespace CppUtils::Window
269290
270291 [[nodiscard]] inline auto getPixels() const noexcept -> auto*
271292 {
293+ #if defined(OS_LINUX)
272294 return reinterpret_cast<std::uint32_t*>(m_imageStorage.pixels.get());
295+ #else
296+ return static_cast<std::uint32_t*>(nullptr);
297+ #endif
273298 }
274299
275300 inline auto runLoop() -> void
276301 {
302+ #if defined(OS_LINUX)
303+ if (not m_isOpen)
304+ return;
277305 auto result = 0;
278306 while ((result = wl_display_dispatch(Wayland::globals.display.get())) != -1)
279307 Logger::print<"detail">("Event received, result = {}", result);
280308 Logger::print<"warning">("Wayland dispatch exited with {}", result);
309+ #endif
281310 }
282311
283312 inline auto update() -> void
284313 {
314+ #if defined(OS_LINUX)
315+ if (not m_isOpen or not m_imageStorage.buffer)
316+ return;
285317 Logger::print<"detail">("update");
286318 wl_surface_attach(surface.get(), m_imageStorage.buffer.get(), 0, 0);
287319 wl_surface_damage(surface.get(), 0, 0, std::numeric_limits<std::int32_t>::max(), std::numeric_limits<std::int32_t>::max());
288320 wl_surface_commit(surface.get());
289321 wl_display_flush(Wayland::globals.display.get());
322+ #endif
290323 }
291324
292325 private:
293326 std::string m_title;
294327 [[maybe_unused]] Style m_style;
295328 Container::Size2 m_size;
329+ bool m_isOpen = false;
296330#if defined(OS_WINDOWS)
297331 static inline constexpr auto windowClassName = L"Window";
298332 HWND m_window;
@@ -306,8 +340,9 @@ namespace CppUtils::Window
306340#endif
307341 };
308342
309- export inline auto drawFrame(Window& window) -> void
343+ export inline auto drawFrame([[maybe_unused]] Window& window) -> void
310344 {
345+ #if defined(OS_LINUX)
311346 Logger::print<"detail">("drawFrame");
312347 const auto& imageSize = window.getSize();
313348 if (not window.m_imageStorage.buffer)
@@ -324,18 +359,24 @@ namespace CppUtils::Window
324359 else
325360 pixels[y * imageSize.width() + x] = 0xFF'EE'EE'EE;
326361 }
362+ #endif
327363 }
328364
329- inline auto xdg_surface_configure(
330- void* data,
331- xdg_surface* xdg_surface,
332- std::uint32_t serial) -> void
365+ #if defined(OS_LINUX)
366+ namespace
333367 {
334- Logger::print<"detail">("Surface configure !");
335- auto& window = *static_cast<Window*>(data);
336- xdg_surface_ack_configure(xdg_surface, serial);
368+ auto xdg_surface_configure(
369+ void* data,
370+ xdg_surface* xdg_surface,
371+ std::uint32_t serial) -> void
372+ {
373+ Logger::print<"detail">("Surface configure !");
374+ auto& window = *static_cast<Window*>(data);
375+ xdg_surface_ack_configure(xdg_surface, serial);
337376
338- drawFrame(window);
339- window.update();
377+ drawFrame(window);
378+ window.update();
379+ }
340380 }
381+ #endif
341382}
0 commit comments