From 0d7a4f45e7dac232a4e47fa46911a90ca964b810 Mon Sep 17 00:00:00 2001 From: Mars Ultor Date: Sun, 21 Dec 2025 22:08:46 -0600 Subject: [PATCH] all callbacks are in --- src/main.cpp | 107 +++++++++++++++++++++++++++++++++++++++++++++++++- src/state.cpp | 43 +++++++++++++++----- src/state.hpp | 2 + 3 files changed, 141 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fc60da9..c85680e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include "spdlog/spdlog.h" +#include #include #include #include @@ -6,6 +7,91 @@ #include #include "state.hpp" +static void output_handle_geometry(void* data, wl_output* output, + int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, + int32_t subpixel, const char* make, const char* model, int32_t transform) +{ + auto& out = *static_cast(data); + spdlog::debug("Output: {} {}", make, model); +} + +static void output_handle_mode(void* data, wl_output* output, + uint32_t flags, int32_t width, int32_t height, int32_t refresh) +{ + auto& out = *static_cast(data); + if (flags & WL_OUTPUT_MODE_CURRENT) { + out.width = static_cast(width); + out.height = static_cast(height); + spdlog::info("Output mode: {}x{} @ {}Hz", width, height, refresh / 1000); + } +} + +static void output_handle_done(void* data, wl_output* output) {} +static void output_handle_scale(void* data, wl_output* output, int32_t factor) {} + +static const wl_output_listener output_listener = { + .geometry = output_handle_geometry, + .mode = output_handle_mode, + .done = output_handle_done, + .scale = output_handle_scale, +}; + +// Registry callbacks - discover globals +static void registry_handle_global( + void* data, + wl_registry* registry, + uint32_t name, + const char* interface, + uint32_t version) +{ + auto& ctx = *static_cast(data); + + if (strcmp(interface, wl_compositor_interface.name) == 0) { + ctx.compostier = static_cast( + wl_registry_bind(registry, name, &wl_compositor_interface, 6) + ); + spdlog::info("Bound to wl_compositor"); + } + else if (strcmp(interface, wl_output_interface.name) == 0) { + auto output = std::make_shared(); + output->output = static_cast( + wl_registry_bind(registry, name, &wl_output_interface, 4) + ); + output->registry_id = name; + + ctx.outputs.push_back(output); + + // Pass raw pointer to the Output object + wl_output_add_listener(output->output, &output_listener, output.get()); + + spdlog::info("Discovered output (registry_id={})", name); + } + else if (strcmp(interface, ext_session_lock_manager_v1_interface.name) == 0) { + ctx.lock_manager = static_cast( + wl_registry_bind(registry, name, &ext_session_lock_manager_v1_interface, 1) + ); + spdlog::info("Bound to ext_session_lock_manager_v1"); + } +} + +static void registry_handle_global_remove(void* data, wl_registry* registry, uint32_t name) { + auto& ctx = *static_cast(data); + + spdlog::debug("Global removed: {}", name); + + // Remove output if it matches + ctx.outputs.erase( + std::remove_if(ctx.outputs.begin(), ctx.outputs.end(), + [name](const auto& out) { return out->registry_id == name; }), + ctx.outputs.end() + ); +} + +static const wl_registry_listener registry_listener = { + .global = registry_handle_global, + .global_remove = registry_handle_global_remove, +}; + int main (int argc, char *argv[]) { std::shared_ptr application_state = std::make_shared(); @@ -16,6 +102,25 @@ int main (int argc, char *argv[]) { application_state->compositer_registry = wl_display_get_registry(application_state->display); - + application_state->compositer_registry = wl_display_get_registry(application_state->display); + wl_registry_add_listener(application_state->compositer_registry, ®istry_listener, application_state.get()); + + // Process all registry events + wl_display_roundtrip(application_state->display); + + // Validate we got what we need + if (!application_state->compostier) { + throw std::runtime_error("Compositor doesn't support wl_compositor"); + } + if (!application_state->lock_manager) { + throw std::runtime_error("Compositor doesn't support ext_session_lock_manager_v1"); + } + if (application_state->outputs.empty()) { + throw std::runtime_error("No outputs found"); + } + + spdlog::info("Found {} output(s)", application_state->outputs.size()); + + return 0; } diff --git a/src/state.cpp b/src/state.cpp index 2404a1d..d796f2d 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -3,15 +3,38 @@ #include #include #include + + namespace state{ - LockScreenState::~LockScreenState(){ - if(display) wl_display_disconnect(display); - if(lock_manager) ext_session_lock_manager_v1_destroy(lock_manager); - if(compostier) wl_compositor_destroy(compostier); - if(compositer_registry) wl_registry_destroy(compositer_registry); - running=false; - } - Output::~Output(){ - if(output) wl_output_destroy(output); - } + LockScreenState::~LockScreenState() { + // IMPORTANT: Clear outputs BEFORE destroying display + // This ensures Output destructors run while display is still valid + outputs.clear(); + if (lock_manager) { + ext_session_lock_manager_v1_destroy(lock_manager); + lock_manager = nullptr; + } + if (compostier) { + wl_compositor_destroy(compostier); + compostier = nullptr; + } + if (compositer_registry) { + wl_registry_destroy(compositer_registry); + compositer_registry = nullptr; + } + if (display) { + wl_display_flush(display); + wl_display_disconnect(display); + display = nullptr; + } + + running = false; + } + + Output::~Output() { + if (output) { + wl_output_destroy(output); + output = nullptr; + } + } } diff --git a/src/state.hpp b/src/state.hpp index 9750c5d..2ad9882 100644 --- a/src/state.hpp +++ b/src/state.hpp @@ -15,6 +15,8 @@ namespace state{ uint32_t registry_id = 0; uint32_t width = uint32_t {0}; uint32_t height = uint32_t {0}; + + wl_surface* wl_surface = nullptr; ~Output(); }; struct LockScreenState{