Skip to content

Commit c154649

Browse files
committed
Window/Wayland: Fix Window
1 parent 5858773 commit c154649

5 files changed

Lines changed: 249 additions & 120 deletions

File tree

modules/System/System.mpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,49 @@ export namespace CppUtils::System
7373
return fileDescriptor;
7474
}
7575

76-
[[nodiscard]] inline auto mapSharedMemory(FileDescriptor& fileDescriptor, std::size_t size) -> std::expected<std::uint8_t*, std::string_view>
76+
struct MappedSharedMemory final
7777
{
78-
using namespace std::literals;
79-
auto* data = static_cast<std::uint8_t*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor.get(), 0));
80-
if (data == MAP_FAILED)
81-
return std::unexpected{"Failed to mmap"sv};
82-
return data;
83-
}
78+
inline MappedSharedMemory() = default;
79+
80+
inline MappedSharedMemory(FileDescriptor& fileDescriptor, std::size_t size):
81+
m_sharedMemory{static_cast<std::byte*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor.get(), 0)), size}
82+
{
83+
if (std::data(m_sharedMemory) == MAP_FAILED)
84+
throw std::runtime_error{"Failed to mmap"};
85+
}
86+
87+
inline MappedSharedMemory(std::byte* data, std::size_t size):
88+
m_sharedMemory{data, size}
89+
{}
90+
91+
inline MappedSharedMemory(const MappedSharedMemory&) = delete;
92+
inline MappedSharedMemory(MappedSharedMemory&& other) noexcept:
93+
m_sharedMemory{std::exchange(other.m_sharedMemory, {})}
94+
{}
95+
96+
inline MappedSharedMemory& operator=(const MappedSharedMemory&) = delete;
97+
inline MappedSharedMemory& operator=(MappedSharedMemory&& other) noexcept
98+
{
99+
m_sharedMemory = std::exchange(other.m_sharedMemory, {});
100+
return *this;
101+
}
102+
103+
inline ~MappedSharedMemory()
104+
{
105+
munmap(std::data(m_sharedMemory), std::size(m_sharedMemory));
106+
}
107+
108+
[[nodiscard]] inline auto get() const noexcept -> auto*
109+
{
110+
return std::data(m_sharedMemory);
111+
}
112+
113+
[[nodiscard]] inline auto size() const noexcept -> auto
114+
{
115+
return std::size(m_sharedMemory);
116+
}
84117

118+
std::span<std::byte> m_sharedMemory;
119+
};
85120
#endif
86121
}

modules/Window/Wayland.mpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
module;
2+
3+
#include <CppUtils/System/OS.hpp>
4+
5+
#if defined(OS_LINUX)
6+
# include <unistd.h>
7+
# include <sys/types.h>
8+
# include <sys/mman.h>
9+
10+
# include <wayland-client-core.h>
11+
# include <wayland-client-protocol.h>
12+
# include <xdg-shell.h>
13+
// # include <wayland-cursor.h>
14+
#endif
15+
16+
export module CppUtils.Window.Wayland;
17+
18+
import std;
19+
20+
import CppUtils.Container.Size2d;
21+
import CppUtils.Logger;
22+
import CppUtils.Memory;
23+
import CppUtils.String;
24+
import CppUtils.System;
25+
26+
#if defined(OS_LINUX)
27+
export namespace CppUtils::Window::Wayland
28+
{
29+
using Display = Memory::UniquePtrWithDestructor<wl_display>;
30+
using Registry = Memory::UniquePtrWithDestructor<wl_registry>;
31+
using Compositor = Memory::UniquePtrWithDestructor<wl_compositor>;
32+
using SharedMemory = Memory::UniquePtrWithDestructor<wl_shm>;
33+
using SharedMemoryPool = Memory::UniquePtrWithDestructor<wl_shm_pool>;
34+
using Surface = Memory::UniquePtrWithDestructor<wl_surface>;
35+
using ShellSurface = Memory::UniquePtrWithDestructor<xdg_surface>;
36+
using TopLevel = Memory::UniquePtrWithDestructor<xdg_toplevel>;
37+
using Buffer = Memory::UniquePtrWithDestructor<wl_buffer>;
38+
using WindowManagerBase = Memory::UniquePtrWithDestructor<xdg_wm_base>;
39+
40+
struct Globals final
41+
{
42+
Display display = {nullptr, wl_display_disconnect};
43+
Registry registry = {nullptr, wl_registry_destroy};
44+
Compositor compositor = {nullptr, wl_compositor_destroy};
45+
SharedMemory sharedMemory = {nullptr, wl_shm_destroy};
46+
WindowManagerBase windowManagerBase = {nullptr, xdg_wm_base_destroy};
47+
};
48+
inline auto globals = Globals{};
49+
50+
using RegisterHandler = std::function<void(wl_registry*, std::uint32_t, std::uint32_t)>;
51+
52+
template<class T>
53+
inline auto makeHandlerPair(
54+
const wl_interface& interface,
55+
Memory::UniquePtrWithDestructor<T>& registerContainer,
56+
std::uint32_t minVersion,
57+
std::uint32_t maxVersion,
58+
std::function<void()>&& callback = {}) -> std::pair<std::string_view, RegisterHandler>
59+
{
60+
return {
61+
std::string_view{interface.name},
62+
[&registerContainer,
63+
&interface,
64+
minVersion,
65+
maxVersion,
66+
callback = std::forward<decltype(callback)>(callback)](auto* registry, auto id, auto serverVersion) -> void {
67+
using namespace std::literals;
68+
if (serverVersion < minVersion)
69+
throw std::runtime_error{interface.name + " trop ancien"s};
70+
registerContainer.reset(static_cast<T*>(wl_registry_bind(registry, id, &interface, std::min(serverVersion, maxVersion))));
71+
if (callback)
72+
callback();
73+
}};
74+
}
75+
}
76+
#endif

0 commit comments

Comments
 (0)