all callbacks are in
This commit is contained in:
105
src/main.cpp
105
src/main.cpp
@@ -1,4 +1,5 @@
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <wayland-client-core.h>
|
||||
@@ -6,6 +7,91 @@
|
||||
#include <wayland-egl-core.h>
|
||||
#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<state::Output*>(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<state::Output*>(data);
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
out.width = static_cast<uint32_t>(width);
|
||||
out.height = static_cast<uint32_t>(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<state::LockScreenState*>(data);
|
||||
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
ctx.compostier = static_cast<wl_compositor*>(
|
||||
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<state::Output>();
|
||||
output->output = static_cast<wl_output*>(
|
||||
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<ext_session_lock_manager_v1*>(
|
||||
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<state::LockScreenState*>(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<state::LockScreenState> application_state = std::make_shared<state::LockScreenState>();
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,38 @@
|
||||
#include <wayland-client-core.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-egl-core.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user