From 68b737512e06dc5edeff5a098946f3ec08da1f1d Mon Sep 17 00:00:00 2001 From: Aki-7 Date: Sat, 1 Apr 2023 20:05:28 +0900 Subject: [PATCH] refactor immersive backend --- .../include/zen-common/cpp-util.h | 4 + common/include/zen-common/util.h | 16 +-- desktop/include/zen-desktop/shell.h | 1 + desktop/include/zen-desktop/xr-system.h | 18 +++ desktop/meson.build | 4 + desktop/src/shell.c | 17 +++ desktop/src/xr-system.c | 97 +++++++++++++++ meson.build | 3 +- protocol/meson.build | 16 ++- zen-xr/include/zen-xr/system.h | 19 --- zen-xr/include/zen-xr/xr.h | 27 ----- zen-xr/meson.build | 31 ----- zen-xr/src/common.h | 9 -- zen-xr/src/remote-system.cc | 21 ---- zen-xr/src/remote-system.h | 28 ----- zen-xr/src/xr.cc | 111 ------------------ zen-xr/src/xr.h | 44 ------- zen/include/zen/xr-system.h | 4 - zen/src/backend/default-backend.c | 4 +- .../src/backend/immersive/remote}/loop.cc | 4 +- .../src/backend/immersive/remote}/loop.h | 6 +- zen/src/backend/immersive/remote/meson.build | 24 ++++ .../src/backend/immersive/remote}/pch/pch.h | 0 .../immersive/remote/xr-system-manager.cc | 107 +++++++++++++++++ .../immersive/remote/xr-system-manager.h | 41 +++++++ zen/src/backend/immersive/remote/xr-system.cc | 36 ++++++ zen/src/backend/immersive/remote/xr-system.h | 42 +++++++ zen/src/backend/immersive/xr-private.h | 34 ------ zen/src/backend/immersive/xr-system-manager.h | 35 ++++++ zen/src/backend/immersive/xr-system-private.h | 36 ------ zen/src/backend/immersive/xr-system.cc | 23 ---- zen/src/backend/immersive/xr.c | 36 ++++++ zen/src/backend/immersive/xr.cc | 69 ----------- zen/src/backend/immersive/xr.h | 16 +-- zen/src/backend/meson.build | 14 ++- zen/src/backend/pch/pch.h | 9 -- 36 files changed, 496 insertions(+), 510 deletions(-) rename zen/src/backend/immersive/common.h => common/include/zen-common/cpp-util.h (91%) create mode 100644 desktop/include/zen-desktop/xr-system.h create mode 100644 desktop/src/xr-system.c delete mode 100644 zen-xr/include/zen-xr/system.h delete mode 100644 zen-xr/include/zen-xr/xr.h delete mode 100644 zen-xr/meson.build delete mode 100644 zen-xr/src/common.h delete mode 100644 zen-xr/src/remote-system.cc delete mode 100644 zen-xr/src/remote-system.h delete mode 100644 zen-xr/src/xr.cc delete mode 100644 zen-xr/src/xr.h rename {zen-xr/src => zen/src/backend/immersive/remote}/loop.cc (94%) rename {zen-xr/src => zen/src/backend/immersive/remote}/loop.h (74%) create mode 100644 zen/src/backend/immersive/remote/meson.build rename {zen-xr => zen/src/backend/immersive/remote}/pch/pch.h (100%) create mode 100644 zen/src/backend/immersive/remote/xr-system-manager.cc create mode 100644 zen/src/backend/immersive/remote/xr-system-manager.h create mode 100644 zen/src/backend/immersive/remote/xr-system.cc create mode 100644 zen/src/backend/immersive/remote/xr-system.h delete mode 100644 zen/src/backend/immersive/xr-private.h create mode 100644 zen/src/backend/immersive/xr-system-manager.h delete mode 100644 zen/src/backend/immersive/xr-system-private.h delete mode 100644 zen/src/backend/immersive/xr-system.cc create mode 100644 zen/src/backend/immersive/xr.c delete mode 100644 zen/src/backend/immersive/xr.cc delete mode 100644 zen/src/backend/pch/pch.h diff --git a/zen/src/backend/immersive/common.h b/common/include/zen-common/cpp-util.h similarity index 91% rename from zen/src/backend/immersive/common.h rename to common/include/zen-common/cpp-util.h index 8e4fc40b..0022ecb6 100644 --- a/zen/src/backend/immersive/common.h +++ b/common/include/zen-common/cpp-util.h @@ -1,5 +1,7 @@ #pragma once +#ifdef __cplusplus + // NOLINTBEGIN(bugprone-macro-parentheses) #define DISABLE_MOVE_AND_COPY(Class) \ Class(const Class &) = delete; \ @@ -7,3 +9,5 @@ Class &operator=(const Class &) = delete; \ Class &operator=(Class &&) = delete // NOLINTEND(bugprone-macro-parentheses) + +#endif diff --git a/common/include/zen-common/util.h b/common/include/zen-common/util.h index 8fa52bea..b9baab49 100644 --- a/common/include/zen-common/util.h +++ b/common/include/zen-common/util.h @@ -4,7 +4,7 @@ #include #ifdef __cplusplus -extern "C" { +#error "This header is not for C++" #endif /** Visibility attribute */ @@ -41,17 +41,3 @@ zalloc(size_t size) /** Retrieve a pointer to a containing struct */ #define zn_container_of(ptr, sample, member) \ (__typeof__(sample))((char *)(ptr)-offsetof(__typeof__(*(sample)), member)) - -#ifdef __cplusplus - -#define DISABLE_MOVE_AND_COPY(Class) \ - Class(const Class &) = delete; \ - Class(Class &&) = delete; \ - Class &operator=(const Class &) = delete; \ - Class &operator=(Class &&) = delete - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/desktop/include/zen-desktop/shell.h b/desktop/include/zen-desktop/shell.h index 50f45fd9..cfd2fc5b 100644 --- a/desktop/include/zen-desktop/shell.h +++ b/desktop/include/zen-desktop/shell.h @@ -12,6 +12,7 @@ struct zn_desktop_shell { struct zn_theme *theme; // @nonnull, @owning + struct wl_listener new_xr_system_listener; struct wl_listener new_screen_listener; struct wl_listener seat_capabilities_listener; struct wl_listener pointer_motion_listener; diff --git a/desktop/include/zen-desktop/xr-system.h b/desktop/include/zen-desktop/xr-system.h new file mode 100644 index 00000000..01a2e737 --- /dev/null +++ b/desktop/include/zen-desktop/xr-system.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +struct zn_xr_system; +struct zn_desktop_server_xr_system; + +struct zn_desktop_xr_system { + struct zn_xr_system *zn_xr_system; // @nonnull, @outlive + + struct wl_global *global; // @nonnull, @owning + struct wl_list resource_list; // wl_resource::link of zen_xr_system + + struct wl_listener zn_xr_system_destroy_listener; +}; + +struct zn_desktop_xr_system *zn_desktop_xr_system_create( + struct zn_xr_system *zn_xr_system, struct wl_display *display); diff --git a/desktop/meson.build b/desktop/meson.build index 86c5bfdf..0a1de69c 100644 --- a/desktop/meson.build +++ b/desktop/meson.build @@ -20,6 +20,10 @@ _zen_desktop_srcs = [ 'src/ui/decoration/shadow.c', 'src/view.c', + 'src/xr-system.c', + + protocols_code['zen-desktop'], + protocols_server_header['zen-desktop'], ] _zen_desktop_inc = include_directories('include') diff --git a/desktop/src/shell.c b/desktop/src/shell.c index b4b788ae..e0ca9319 100644 --- a/desktop/src/shell.c +++ b/desktop/src/shell.c @@ -10,6 +10,7 @@ #include "zen-desktop/screen.h" #include "zen-desktop/theme.h" #include "zen-desktop/view.h" +#include "zen-desktop/xr-system.h" #include "zen/backend.h" #include "zen/screen.h" #include "zen/seat.h" @@ -20,6 +21,17 @@ // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) static struct zn_desktop_shell *desktop_shell_singleton = NULL; +static void +zn_desktop_shell_handle_new_xr_system( + struct wl_listener *listener UNUSED, void *data) +{ + struct zn_server *server = zn_server_get_singleton(); + + struct zn_xr_system *zn_xr_system = data; + + zn_desktop_xr_system_create(zn_xr_system, server->display); +} + static void zn_desktop_shell_handle_new_screen(struct wl_listener *listener, void *data) { @@ -174,6 +186,10 @@ zn_desktop_shell_create(void) } self->cursor_grab = &cursor_default_grab->base; + self->new_xr_system_listener.notify = zn_desktop_shell_handle_new_xr_system; + wl_signal_add( + &server->backend->events.new_xr_system, &self->new_xr_system_listener); + self->new_screen_listener.notify = zn_desktop_shell_handle_new_screen; wl_signal_add( &server->backend->events.new_screen, &self->new_screen_listener); @@ -229,6 +245,7 @@ zn_desktop_shell_destroy(struct zn_desktop_shell *self) wl_list_remove(&self->pointer_motion_listener.link); wl_list_remove(&self->seat_capabilities_listener.link); wl_list_remove(&self->new_screen_listener.link); + wl_list_remove(&self->new_xr_system_listener.link); zn_cursor_grab_destroy(self->cursor_grab); zn_screen_layout_destroy(self->screen_layout); zn_theme_destroy(self->theme); diff --git a/desktop/src/xr-system.c b/desktop/src/xr-system.c new file mode 100644 index 00000000..6e5c4c58 --- /dev/null +++ b/desktop/src/xr-system.c @@ -0,0 +1,97 @@ +#include "zen-desktop/xr-system.h" + +#include + +#include "zen-common/log.h" +#include "zen-common/util.h" +#include "zen/xr-system.h" + +static void zn_desktop_xr_system_destroy(struct zn_desktop_xr_system *self); + +static void +zn_desktop_xr_system_handle_destroy(struct wl_resource *resource) +{ + wl_list_remove(wl_resource_get_link(resource)); +} + +static void +zn_desktop_xr_system_protocol_connect( + struct wl_client *client UNUSED, struct wl_resource *resource UNUSED) +{} + +static const struct zen_xr_system_interface implementation = { + .connect = zn_desktop_xr_system_protocol_connect, +}; + +static void +zn_desktop_xr_system_bind( + struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct zn_desktop_xr_system *self = data; + + struct wl_resource *resource = + wl_resource_create(client, &zen_xr_system_interface, (int)version, id); + if (resource == NULL) { + zn_error("Failed to create a wl_resource"); + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation( + resource, &implementation, self, zn_desktop_xr_system_handle_destroy); + + wl_list_insert(&self->resource_list, wl_resource_get_link(resource)); +} + +static void +zn_desktop_xr_system_handle_xr_system_destroy( + struct wl_listener *listener, void *data UNUSED) +{ + struct zn_desktop_xr_system *self = + zn_container_of(listener, self, zn_xr_system_destroy_listener); + + zn_desktop_xr_system_destroy(self); +} + +struct zn_desktop_xr_system * +zn_desktop_xr_system_create( + struct zn_xr_system *zn_xr_system, struct wl_display *display) +{ + struct zn_desktop_xr_system *self = zalloc(sizeof *self); + if (self == NULL) { + zn_error("Failed to allocate memory"); + goto err; + } + + self->zn_xr_system = zn_xr_system; + wl_list_init(&self->resource_list); + + self->global = wl_global_create( + display, &zen_xr_system_interface, 1, self, zn_desktop_xr_system_bind); + if (self->global == NULL) { + zn_error("Failed to create a wl_global"); + goto err_free; + } + + self->zn_xr_system_destroy_listener.notify = + zn_desktop_xr_system_handle_xr_system_destroy; + wl_signal_add( + &zn_xr_system->events.destroy, &self->zn_xr_system_destroy_listener); + + return self; + +err_free: + free(self); + +err: + return NULL; +} + +static void +zn_desktop_xr_system_destroy(struct zn_desktop_xr_system *self) +{ + wl_list_remove(&self->zn_xr_system_destroy_listener.link); + wl_global_destroy(self->global); + wl_list_remove(&self->resource_list); + free(self); +} diff --git a/meson.build b/meson.build index 8ea57092..8effedc9 100644 --- a/meson.build +++ b/meson.build @@ -120,6 +120,7 @@ configure_file( wayland_req = '>= 1.18.0' wayland_protocols_req = '>= 1.24' wlroots_req = ['>= 0.15', '< 0.16'] +zen_protocols_req = '0.1.0' zen_remote_server_req = '0.1.1' @@ -143,6 +144,7 @@ wayland_protocols_dep = dependency('wayland-protocols', version: wayland_protoco wayland_scanner_dep = dependency('wayland-scanner', native: true) wayland_server_dep = dependency('wayland-server', version: wayland_req) xkbcommon_dep = dependency('xkbcommon') +zen_protocols_dep = dependency('zen-protocols', version: zen_protocols_req) zen_remote_server_dep = dependency('zen-remote-server', version: zen_remote_server_req) subdir('protocol') @@ -163,7 +165,6 @@ if get_option('tests') subdir('test-harness') endif subdir('common') -subdir('zen-xr') subdir('zen-wlr-glew-renderer') subdir('zen') subdir('desktop') diff --git a/protocol/meson.build b/protocol/meson.build index f2856347..c919f8b2 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -1,4 +1,5 @@ wl_protocol_dir = wayland_protocols_dep.get_variable('pkgdatadir') +zen_protocol_dir = zen_protocols_dep.get_variable('pkgdatadir') wayland_scanner = find_program( wayland_scanner_dep.get_variable('wayland_scanner'), @@ -8,11 +9,11 @@ wayland_scanner = find_program( protocols = { 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', + 'zen-desktop': zen_protocol_dir / 'unstable/zen-desktop.xml', + 'wlr-layer-shell-unstable-v1': 'wlr-layer-shell-unstable-v1.xml', } -wlroots_srcs = [] - protocols_code = {} protocols_server_header = {} protocols_client_header = {} @@ -24,8 +25,6 @@ foreach name, path : protocols command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], ) - wlroots_srcs += code - server_header = custom_target( name.underscorify() + '_server_h', input: path, @@ -33,8 +32,6 @@ foreach name, path : protocols command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'], ) - wlroots_srcs += server_header - client_header = custom_target( name.underscorify() + '_client_h', input: path, @@ -47,3 +44,10 @@ foreach name, path : protocols protocols_server_header += { name: server_header } protocols_client_header += { name: client_header } endforeach + +wlroots_srcs = [ + protocols_code['wlr-layer-shell-unstable-v1'], + protocols_code['xdg-shell'], + protocols_server_header['wlr-layer-shell-unstable-v1'], + protocols_server_header['xdg-shell'], +] diff --git a/zen-xr/include/zen-xr/system.h b/zen-xr/include/zen-xr/system.h deleted file mode 100644 index 2798285b..00000000 --- a/zen-xr/include/zen-xr/system.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -namespace zen::xr { - -struct System { - enum Type { - kNone, - kRemote, - }; - - virtual ~System() = default; - - virtual uint64_t handle() = 0; - virtual Type type() = 0; -}; - -} // namespace zen::xr diff --git a/zen-xr/include/zen-xr/xr.h b/zen-xr/include/zen-xr/xr.h deleted file mode 100644 index 5bc9d04b..00000000 --- a/zen-xr/include/zen-xr/xr.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -#include - -namespace zen::xr { - -struct System; - -struct Xr { - virtual ~Xr() = default; -}; - -struct XrDelegate { - virtual ~XrDelegate() = default; - - virtual void NotifySystemAdded(uint64_t handle) = 0; - - virtual void NotifySystemRemoved(std::unique_ptr &system) = 0; -}; - -/// @returns nullptr if failed -/// @param delegate can be NULL -std::unique_ptr CreateXr(wl_display *display, XrDelegate *delegate); - -} // namespace zen::xr diff --git a/zen-xr/meson.build b/zen-xr/meson.build deleted file mode 100644 index 65a86479..00000000 --- a/zen-xr/meson.build +++ /dev/null @@ -1,31 +0,0 @@ -_zen_xr_srcs = [ - 'src/loop.cc', - 'src/remote-system.cc', - 'src/xr.cc', -] - -_zen_xr_public_deps = [ -] - -_zen_xr_deps = [ - wayland_server_dep, - zen_common_dep, - zen_remote_server_dep, -] + _zen_xr_public_deps - -_zen_xr_inc = include_directories('include') - -_zen_xr_lib = static_library( - 'zen-xr', - _zen_xr_srcs, - install: false, - cpp_args: ['-include', 'pch/pch.h'], - include_directories: _zen_xr_inc, - dependencies: _zen_xr_deps, - cpp_pch: 'pch/pch.h', -) - -zen_xr_dep = declare_dependency( - link_with: _zen_xr_lib, - include_directories: _zen_xr_inc, -) diff --git a/zen-xr/src/common.h b/zen-xr/src/common.h deleted file mode 100644 index 8e4fc40b..00000000 --- a/zen-xr/src/common.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -// NOLINTBEGIN(bugprone-macro-parentheses) -#define DISABLE_MOVE_AND_COPY(Class) \ - Class(const Class &) = delete; \ - Class(Class &&) = delete; \ - Class &operator=(const Class &) = delete; \ - Class &operator=(Class &&) = delete -// NOLINTEND(bugprone-macro-parentheses) diff --git a/zen-xr/src/remote-system.cc b/zen-xr/src/remote-system.cc deleted file mode 100644 index a2707375..00000000 --- a/zen-xr/src/remote-system.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "remote-system.h" - -namespace zen::xr { - -RemoteSystem::RemoteSystem(uint64_t handle, uint64_t peer_id) - : handle_(handle), peer_id_(peer_id) -{} - -uint64_t -RemoteSystem::handle() -{ - return handle_; -} - -System::Type -RemoteSystem::type() -{ - return kRemote; -} - -} // namespace zen::xr diff --git a/zen-xr/src/remote-system.h b/zen-xr/src/remote-system.h deleted file mode 100644 index c3d52326..00000000 --- a/zen-xr/src/remote-system.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "xr.h" -#include "zen-xr/system.h" - -namespace zen::xr { - -class RemoteSystem : public System -{ - public: - DISABLE_MOVE_AND_COPY(RemoteSystem); - explicit RemoteSystem(uint64_t handle, uint64_t peer_id); - ~RemoteSystem() override = default; - - uint64_t handle() override; - Type type() override; - [[nodiscard]] inline uint64_t peer_id() const; - - private: - const uint64_t handle_; - const uint64_t peer_id_; -}; - -inline uint64_t -RemoteSystem::peer_id() const -{ - return peer_id_; -} - -} // namespace zen::xr diff --git a/zen-xr/src/xr.cc b/zen-xr/src/xr.cc deleted file mode 100644 index 8b927611..00000000 --- a/zen-xr/src/xr.cc +++ /dev/null @@ -1,111 +0,0 @@ -#include "xr.h" - -#include "loop.h" -#include "remote-system.h" -#include "zen-common/log.h" - -namespace zen::xr { - -std::unique_ptr -CreateXr(wl_display *display, XrDelegate *delegate) -{ - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - auto *xr = new XrImpl(display, delegate); - - if (!xr->Init()) { - delete xr; // NOLINT(cppcoreguidelines-owning-memory) - return nullptr; - } - - return std::unique_ptr(xr); -} - -XrImpl::XrImpl(wl_display *display, XrDelegate *delegate) - : display_(display), delegate_(delegate) -{} - -XrImpl::~XrImpl() = default; - -bool -XrImpl::Init() -{ - wl_event_loop *wl_loop = wl_display_get_event_loop(display_); - - auto loop = std::make_unique(wl_loop); - - peer_manager_ = zen::remote::server::CreatePeerManager(std::move(loop)); - if (!peer_manager_) { - zn_error("Failed to create a peer manager"); - return false; - } - - peer_manager_->on_peer_discover.Connect( - [this](uint64_t id) { HandleRemotePeerDiscover(id); }); - - peer_manager_->on_peer_lost.Connect( - [this](uint64_t id) { HandleRemotePeerLost(id); }); - - return true; -} - -uint64_t -XrImpl::NextHandle() -{ - return ++next_handle_; -} - -void -XrImpl::RemoveSystemIf(std::function &)> pred) -{ - auto result = - std::remove_if(systems_.begin(), systems_.end(), std::move(pred)); - - std::vector> systems_to_remove( - std::make_move_iterator(result), std::make_move_iterator(systems_.end())); - - systems_.erase(result, systems_.end()); - - if (delegate_ != nullptr) { - for (auto &system : systems_to_remove) { - delegate_->NotifySystemRemoved(system); - } - } -} - -void -XrImpl::HandleRemotePeerDiscover(uint64_t id) -{ - RemoveSystemIf([id](std::unique_ptr &system) { - if (system->type() != System::kRemote) { - return false; - } - - auto *remote_system = dynamic_cast(system.get()); - - return remote_system != nullptr && remote_system->peer_id() == id; - }); - - auto handle = NextHandle(); - auto system = std::unique_ptr(new RemoteSystem(handle, id)); - systems_.emplace_back(std::move(system)); - - if (delegate_ != nullptr) { - delegate_->NotifySystemAdded(handle); - } -} - -void -XrImpl::HandleRemotePeerLost(uint64_t id) -{ - RemoveSystemIf([id](std::unique_ptr &system) { - if (system->type() != System::kRemote) { - return false; - } - - auto *remote_system = dynamic_cast(system.get()); - - return remote_system != nullptr && remote_system->peer_id() == id; - }); -} - -} // namespace zen::xr diff --git a/zen-xr/src/xr.h b/zen-xr/src/xr.h deleted file mode 100644 index 385fd3e9..00000000 --- a/zen-xr/src/xr.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "common.h" -#include "zen-xr/xr.h" - -namespace zen::xr { - -struct System; - -class XrImpl : public Xr -{ - public: - DISABLE_MOVE_AND_COPY(XrImpl); - ~XrImpl() override; - - private: - friend std::unique_ptr CreateXr( - wl_display *display, XrDelegate *delegate); - - XrImpl(wl_display *display, XrDelegate *delegate); - - void RemoveSystemIf(std::function &)> pred); - - void HandleRemotePeerDiscover(uint64_t id); - - void HandleRemotePeerLost(uint64_t id); - - bool Init(); - - /// @return value must not be 0 - uint64_t NextHandle(); - - std::vector> systems_; - - std::unique_ptr peer_manager_; // @nonnull - - wl_display *display_; // @nonnull, @outlive - - XrDelegate *delegate_; // @nullable, @outlive if exists - - uint64_t next_handle_ = 0; -}; - -} // namespace zen::xr diff --git a/zen/include/zen/xr-system.h b/zen/include/zen/xr-system.h index 1fffb296..1545db50 100644 --- a/zen/include/zen/xr-system.h +++ b/zen/include/zen/xr-system.h @@ -7,10 +7,6 @@ extern "C" { #endif struct zn_xr_system { - void *impl_data; - - uint64_t handle; - struct { struct wl_signal destroy; } events; diff --git a/zen/src/backend/default-backend.c b/zen/src/backend/default-backend.c index 8b8c97e4..1191cfef 100644 --- a/zen/src/backend/default-backend.c +++ b/zen/src/backend/default-backend.c @@ -7,6 +7,7 @@ #include #include +#include "immersive/xr-system-manager.h" #include "immersive/xr.h" #include "screen/compositor.h" #include "screen/keyboard.h" @@ -257,7 +258,8 @@ zn_default_backend_create(struct wl_display *display, struct zn_seat *zn_seat) &self->wlr_backend->events.new_input, &self->new_input_listener); self->new_xr_system_listener.notify = zn_default_backend_handle_new_xr_system; - wl_signal_add(&self->xr->events.new_system, &self->new_xr_system_listener); + wl_signal_add(&self->xr->xr_system_manager->events.new_system, + &self->new_xr_system_listener); return &self->base; diff --git a/zen-xr/src/loop.cc b/zen/src/backend/immersive/remote/loop.cc similarity index 94% rename from zen-xr/src/loop.cc rename to zen/src/backend/immersive/remote/loop.cc index 155e465d..bc53c588 100644 --- a/zen-xr/src/loop.cc +++ b/zen/src/backend/immersive/remote/loop.cc @@ -2,7 +2,7 @@ #include "zen-common/terminate.h" -namespace zen::xr { +namespace zen::backend::immersive::remote { namespace { @@ -74,4 +74,4 @@ Loop::Terminate() zn_terminate(EXIT_FAILURE); } -} // namespace zen::xr +} // namespace zen::backend::immersive::remote diff --git a/zen-xr/src/loop.h b/zen/src/backend/immersive/remote/loop.h similarity index 74% rename from zen-xr/src/loop.h rename to zen/src/backend/immersive/remote/loop.h index a16439fa..481ba302 100644 --- a/zen-xr/src/loop.h +++ b/zen/src/backend/immersive/remote/loop.h @@ -1,8 +1,8 @@ #pragma once -#include "common.h" +#include "zen-common/cpp-util.h" -namespace zen::xr { +namespace zen::backend::immersive::remote { class Loop : public zen::remote::ILoop { @@ -19,4 +19,4 @@ class Loop : public zen::remote::ILoop wl_event_loop *wl_loop_; // @nonnull, @outlive }; -} // namespace zen::xr +} // namespace zen::backend::immersive::remote diff --git a/zen/src/backend/immersive/remote/meson.build b/zen/src/backend/immersive/remote/meson.build new file mode 100644 index 00000000..b15ea819 --- /dev/null +++ b/zen/src/backend/immersive/remote/meson.build @@ -0,0 +1,24 @@ +_zen_remote_immersive_backend_srcs = [ + 'loop.cc', + 'xr-system.cc', + 'xr-system-manager.cc', +] + +_zen_remote_immersive_backend_deps = [ + _zen_deps, + zen_remote_server_dep, +] + +_zen_remote_immersive_backend_lib = static_library( + 'zen-remote-immersive-backend', + _zen_remote_immersive_backend_srcs, + install: false, + cpp_args: [ '-include', 'pch/pch.h' ], + include_directories: zen_private_inc, + dependencies: _zen_remote_immersive_backend_deps, + cpp_pch: 'pch/pch.h', +) + +zen_remote_immersive_backend_dep = declare_dependency( + link_with: _zen_remote_immersive_backend_lib, +) diff --git a/zen-xr/pch/pch.h b/zen/src/backend/immersive/remote/pch/pch.h similarity index 100% rename from zen-xr/pch/pch.h rename to zen/src/backend/immersive/remote/pch/pch.h diff --git a/zen/src/backend/immersive/remote/xr-system-manager.cc b/zen/src/backend/immersive/remote/xr-system-manager.cc new file mode 100644 index 00000000..8173284b --- /dev/null +++ b/zen/src/backend/immersive/remote/xr-system-manager.cc @@ -0,0 +1,107 @@ +#include "xr-system-manager.h" + +#include "loop.h" +#include "xr-system.h" +#include "zen-common/log.h" + +static void zn_xr_system_manager_destroy_remote( + struct zn_xr_system_manager *c_obj); + +namespace zen::backend::immersive::remote { + +XrSystemManager::XrSystemManager(wl_display *display) : display_(display) {} + +static const struct zn_xr_system_manager_interface implementation = { + XrSystemManager::HandleDestroy, +}; + +bool +XrSystemManager::Init() +{ + auto loop = std::make_unique(wl_display_get_event_loop(display_)); + + peer_manager_ = zen::remote::server::CreatePeerManager(std::move(loop)); + if (!peer_manager_) { + zn_error("Failed to create a peer manager"); + return false; + } + + c_obj_.impl_data = this; + c_obj_.impl = &implementation; + wl_signal_init(&c_obj_.events.new_system); + + peer_manager_->on_peer_discover.Connect( + [this](uint64_t id) { HandleRemotePeerDiscover(id); }); + + peer_manager_->on_peer_lost.Connect( + [this](uint64_t id) { HandleRemotePeerLost(id); }); + + return true; +} + +void +XrSystemManager::HandleDestroy(zn_xr_system_manager *c_obj) +{ + zn_xr_system_manager_destroy_remote(c_obj); +} + +void +XrSystemManager::RemoveXrSystem(uint64_t peer_id) +{ + auto result = std::remove_if(xr_systems_.begin(), xr_systems_.end(), + [peer_id](std::unique_ptr &xr_system) { + return xr_system->peer_id() == peer_id; + }); + + xr_systems_.erase(result, xr_systems_.end()); +} + +void +XrSystemManager::HandleRemotePeerDiscover(uint64_t peer_id) +{ + RemoveXrSystem(peer_id); + + auto xr_system = XrSystem::New(peer_id); + + auto *xr_system_c_obj = xr_system->c_obj(); + + xr_systems_.push_back(std::move(xr_system)); + + wl_signal_emit(&c_obj_.events.new_system, xr_system_c_obj); +} + +void +XrSystemManager::HandleRemotePeerLost(uint64_t peer_id) +{ + RemoveXrSystem(peer_id); +} + +} // namespace zen::backend::immersive::remote + +struct zn_xr_system_manager * +zn_xr_system_manager_create_remote(struct wl_display *display) +{ + using XrSystemManager = zen::backend::immersive::remote::XrSystemManager; + + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) + auto *self = new XrSystemManager(display); + + if (!self->Init()) { + zn_error("Failed to initialize remote XrSystemManager"); + delete self; // NOLINT(cppcoreguidelines-owning-memory) + return nullptr; + } + + return &self->c_obj_; +} + +static void +zn_xr_system_manager_destroy_remote(struct zn_xr_system_manager *c_obj) +{ + using XrSystemManager = zen::backend::immersive::remote::XrSystemManager; + + auto *self = static_cast(c_obj->impl_data); + + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) + delete self; +} diff --git a/zen/src/backend/immersive/remote/xr-system-manager.h b/zen/src/backend/immersive/remote/xr-system-manager.h new file mode 100644 index 00000000..eef3bfb3 --- /dev/null +++ b/zen/src/backend/immersive/remote/xr-system-manager.h @@ -0,0 +1,41 @@ +#pragma once + +#include "backend/immersive/xr-system-manager.h" +#include "zen-common/cpp-util.h" + +namespace zen::backend::immersive::remote { + +class XrSystem; + +class XrSystemManager +{ + public: + DISABLE_MOVE_AND_COPY(XrSystemManager); + ~XrSystemManager() = default; + + static void HandleDestroy(zn_xr_system_manager *c_obj); + + private: + friend struct zn_xr_system_manager * ::zn_xr_system_manager_create_remote( + struct wl_display *display); + + explicit XrSystemManager(wl_display *display); + + bool Init(); + + void RemoveXrSystem(uint64_t peer_id); + + void HandleRemotePeerDiscover(uint64_t peer_id); + + void HandleRemotePeerLost(uint64_t peer_id); + + zn_xr_system_manager c_obj_{}; + + wl_display *display_; // @nonnull, @outlive + + std::unique_ptr peer_manager_; // @nonnull + + std::vector> xr_systems_; +}; + +} // namespace zen::backend::immersive::remote diff --git a/zen/src/backend/immersive/remote/xr-system.cc b/zen/src/backend/immersive/remote/xr-system.cc new file mode 100644 index 00000000..5137d861 --- /dev/null +++ b/zen/src/backend/immersive/remote/xr-system.cc @@ -0,0 +1,36 @@ +#include "xr-system.h" + +#include "zen-common/log.h" + +namespace zen::backend::immersive::remote { + +XrSystem::XrSystem(uint64_t peer_id) : peer_id_(peer_id) {} + +XrSystem::~XrSystem() { wl_signal_emit(&c_obj_.events.destroy, nullptr); } + +std::unique_ptr +XrSystem::New(uint64_t peer_id) +{ + auto self = std::unique_ptr(new XrSystem(peer_id)); + if (!self) { + zn_error("Failed to allocate memory"); + return nullptr; + } + + if (!self->Init()) { + zn_error("Failed to initialize remote XrSystem"); + return nullptr; + } + + return self; +} + +bool +XrSystem::Init() +{ + wl_signal_init(&c_obj_.events.destroy); + + return true; +} + +} // namespace zen::backend::immersive::remote diff --git a/zen/src/backend/immersive/remote/xr-system.h b/zen/src/backend/immersive/remote/xr-system.h new file mode 100644 index 00000000..6782e20a --- /dev/null +++ b/zen/src/backend/immersive/remote/xr-system.h @@ -0,0 +1,42 @@ +#pragma once + +#include "zen-common/cpp-util.h" +#include "zen/xr-system.h" + +namespace zen::backend::immersive::remote { + +class XrSystem +{ + public: + DISABLE_MOVE_AND_COPY(XrSystem); + ~XrSystem(); + + static std::unique_ptr New(uint64_t peer_id); + + inline uint64_t peer_id() const; + + inline zn_xr_system *c_obj(); + + private: + explicit XrSystem(uint64_t peer_id); + + bool Init(); + + const uint64_t peer_id_; + + zn_xr_system c_obj_{}; +}; + +inline uint64_t +XrSystem::peer_id() const +{ + return peer_id_; +} + +inline zn_xr_system * +XrSystem::c_obj() +{ + return &c_obj_; +} + +} // namespace zen::backend::immersive::remote diff --git a/zen/src/backend/immersive/xr-private.h b/zen/src/backend/immersive/xr-private.h deleted file mode 100644 index c18a5c24..00000000 --- a/zen/src/backend/immersive/xr-private.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "common.h" -#include "xr.h" - -namespace zen::xr::proxy { - -class XrSystemProxy; - -class XrProxy : public zen::xr::XrDelegate -{ - public: - DISABLE_MOVE_AND_COPY(XrProxy); - ~XrProxy() override; - - void NotifySystemAdded(uint64_t handle) override; - - void NotifySystemRemoved(std::unique_ptr &system) override; - - private: - friend zn_xr * ::zn_xr_create(struct wl_display *display); - - XrProxy(); - - bool Init(wl_display *display); - - std::unique_ptr xr_; - - zn_xr zn_xr_{}; - - std::vector> systems_; -}; - -} // namespace zen::xr::proxy diff --git a/zen/src/backend/immersive/xr-system-manager.h b/zen/src/backend/immersive/xr-system-manager.h new file mode 100644 index 00000000..63d5e8b5 --- /dev/null +++ b/zen/src/backend/immersive/xr-system-manager.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct zn_xr_system_manager; + +struct zn_xr_system_manager_interface { + void (*destroy)(struct zn_xr_system_manager *self); +}; + +struct zn_xr_system_manager { + void *impl_data; // @nullable, @outlive if exists + const struct zn_xr_system_manager_interface *impl; // @nonnull, @outlive + + struct { + struct wl_signal new_system; // (struct zn_xr_system *) + } events; +}; + +struct zn_xr_system_manager *zn_xr_system_manager_create_remote( + struct wl_display *display); + +inline void +zn_xr_system_manager_destroy(struct zn_xr_system_manager *self) +{ + self->impl->destroy(self); +} + +#ifdef __cplusplus +} +#endif diff --git a/zen/src/backend/immersive/xr-system-private.h b/zen/src/backend/immersive/xr-system-private.h deleted file mode 100644 index e0a9bf3c..00000000 --- a/zen/src/backend/immersive/xr-system-private.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "common.h" -#include "zen/xr-system.h" - -namespace zen::xr::proxy { - -class XrSystemProxy -{ - public: - DISABLE_MOVE_AND_COPY(XrSystemProxy); - explicit XrSystemProxy(uint64_t handle); - ~XrSystemProxy(); - - bool Init(); - - inline uint64_t handle() const; - inline zn_xr_system *zn_xr_system(); - - private: - struct zn_xr_system zn_xr_system_ {}; -}; - -inline uint64_t -XrSystemProxy::handle() const -{ - return zn_xr_system_.handle; -} - -inline zn_xr_system * -XrSystemProxy::zn_xr_system() -{ - return &zn_xr_system_; -} - -} // namespace zen::xr::proxy diff --git a/zen/src/backend/immersive/xr-system.cc b/zen/src/backend/immersive/xr-system.cc deleted file mode 100644 index 13939339..00000000 --- a/zen/src/backend/immersive/xr-system.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "xr-system-private.h" - -namespace zen::xr::proxy { - -XrSystemProxy::XrSystemProxy(uint64_t handle) { zn_xr_system_.handle = handle; } - -bool -XrSystemProxy::Init() -{ - zn_xr_system_.impl_data = this; - - wl_signal_init(&zn_xr_system_.events.destroy); - - return true; -} - -XrSystemProxy::~XrSystemProxy() -{ - wl_signal_emit(&zn_xr_system_.events.destroy, nullptr); - wl_list_remove(&zn_xr_system_.events.destroy.listener_list); -} - -} // namespace zen::xr::proxy diff --git a/zen/src/backend/immersive/xr.c b/zen/src/backend/immersive/xr.c new file mode 100644 index 00000000..92a3e06e --- /dev/null +++ b/zen/src/backend/immersive/xr.c @@ -0,0 +1,36 @@ +#include "xr.h" + +#include "xr-system-manager.h" +#include "zen-common/log.h" +#include "zen-common/util.h" + +struct zn_xr * +zn_xr_create(struct wl_display *display) +{ + struct zn_xr *self = zalloc(sizeof *self); + if (self == NULL) { + zn_error("Failed to allocate memory"); + goto err; + } + + self->xr_system_manager = zn_xr_system_manager_create_remote(display); + if (self->xr_system_manager == NULL) { + zn_error("Failed to create zn_xr_system_manager"); + goto err_free; + } + + return self; + +err_free: + free(self); + +err: + return NULL; +} + +void +zn_xr_destroy(struct zn_xr *self) +{ + zn_xr_system_manager_destroy(self->xr_system_manager); + free(self); +} diff --git a/zen/src/backend/immersive/xr.cc b/zen/src/backend/immersive/xr.cc deleted file mode 100644 index 424a6cc1..00000000 --- a/zen/src/backend/immersive/xr.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include "xr-private.h" -#include "xr-system-private.h" -#include "zen-common/log.h" - -namespace zen::xr::proxy { - -XrProxy::XrProxy() = default; - -bool -XrProxy::Init(wl_display *display) -{ - zn_xr_.impl_data = this; - wl_signal_init(&zn_xr_.events.new_system); - xr_ = zen::xr::CreateXr(display, this); - return true; -} - -XrProxy::~XrProxy() { wl_list_remove(&zn_xr_.events.new_system.listener_list); } - -void -XrProxy::NotifySystemAdded(uint64_t handle) -{ - auto system = std::make_unique(handle); - if (!system->Init()) { - zn_warn("Failed to init XrSystemProxy"); - return; - } - auto *zn_xr_system = system->zn_xr_system(); - systems_.push_back(std::move(system)); - - wl_signal_emit(&zn_xr_.events.new_system, zn_xr_system); -} - -void -XrProxy::NotifySystemRemoved(std::unique_ptr &system) -{ - auto result = std::remove_if(systems_.begin(), systems_.end(), - [handle = system->handle()]( - std::unique_ptr &system_proxy) { - return system_proxy->handle() == handle; - }); - - systems_.erase(result, systems_.end()); -} - -} // namespace zen::xr::proxy - -zn_xr * -zn_xr_create(struct wl_display *display) -{ - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - auto *proxy = new zen::xr::proxy::XrProxy; - - if (!proxy->Init(display)) { - zn_error("Failed to initialize XrProxy"); - delete proxy; // NOLINT(cppcoreguidelines-owning-memory) - return nullptr; - } - - return &proxy->zn_xr_; -} - -void -zn_xr_destroy(zn_xr *self) -{ - auto *proxy = static_cast(self->impl_data); - - delete proxy; // NOLINT(cppcoreguidelines-owning-memory) -} diff --git a/zen/src/backend/immersive/xr.h b/zen/src/backend/immersive/xr.h index e1419d13..d8b102a8 100644 --- a/zen/src/backend/immersive/xr.h +++ b/zen/src/backend/immersive/xr.h @@ -1,21 +1,13 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif +#include -struct zn_xr { - void *impl_data; // used by the impl object +struct zn_xr_system_manager; - struct { - struct wl_signal new_system; // (struct zn_xr_system *) - } events; +struct zn_xr { + struct zn_xr_system_manager *xr_system_manager; // @nonnull, @owning }; struct zn_xr *zn_xr_create(struct wl_display *display); void zn_xr_destroy(struct zn_xr *self); - -#ifdef __cplusplus -} -#endif diff --git a/zen/src/backend/meson.build b/zen/src/backend/meson.build index bcce219c..1be5625a 100644 --- a/zen/src/backend/meson.build +++ b/zen/src/backend/meson.build @@ -1,8 +1,9 @@ +subdir('immersive/remote') + _zen_backend_srcs = [ 'default-backend.c', - 'immersive/xr.cc', - 'immersive/xr-system.cc', + 'immersive/xr.c', 'screen/compositor.c', 'screen/keyboard.c', @@ -14,14 +15,17 @@ _zen_backend_srcs = [ 'screen/xwayland-surface.c', ] +_zen_backend_deps = [ + _zen_deps, + zen_remote_immersive_backend_dep, +] + _zen_backend_lib = static_library( 'zen-backend', _zen_backend_srcs, install: false, - cpp_args: [ '-include', 'pch/pch.h' ], include_directories: zen_private_inc, - dependencies: [ _zen_deps, zen_xr_dep ], - cpp_pch: 'pch/pch.h', + dependencies: _zen_backend_deps, ) zen_backend_dep = declare_dependency( diff --git a/zen/src/backend/pch/pch.h b/zen/src/backend/pch/pch.h deleted file mode 100644 index 7e3adab4..00000000 --- a/zen/src/backend/pch/pch.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include