@@ -25,6 +25,7 @@ pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots-0.20)
|
|||||||
pkg_check_modules(XKBCOMMON REQUIRED IMPORTED_TARGET xkbcommon)
|
pkg_check_modules(XKBCOMMON REQUIRED IMPORTED_TARGET xkbcommon)
|
||||||
pkg_check_modules(OPENXR REQUIRED IMPORTED_TARGET openxr)
|
pkg_check_modules(OPENXR REQUIRED IMPORTED_TARGET openxr)
|
||||||
pkg_check_modules(LUA REQUIRED IMPORTED_TARGET lua)
|
pkg_check_modules(LUA REQUIRED IMPORTED_TARGET lua)
|
||||||
|
pkg_check_modules(PIXMAN REQUIRED IMPORTED_TARGET pixman-1)
|
||||||
|
|
||||||
find_program(WAYLAND_SCANNER_EXECUTABLE wayland-scanner REQUIRED)
|
find_program(WAYLAND_SCANNER_EXECUTABLE wayland-scanner REQUIRED)
|
||||||
message(STATUS "Found wayland-scanner at ${WAYLAND_SCANNER_EXECUTABLE}")
|
message(STATUS "Found wayland-scanner at ${WAYLAND_SCANNER_EXECUTABLE}")
|
||||||
@@ -67,6 +68,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
|||||||
PkgConfig::WLROOTS
|
PkgConfig::WLROOTS
|
||||||
PkgConfig::OPENXR
|
PkgConfig::OPENXR
|
||||||
PkgConfig::LUA
|
PkgConfig::LUA
|
||||||
|
PkgConfig::PIXMAN
|
||||||
|
|
||||||
raylib
|
raylib
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ typedef struct LunarWM {
|
|||||||
|
|
||||||
struct wlr_allocator *allocator;
|
struct wlr_allocator *allocator;
|
||||||
struct wlr_compositor *compositor;
|
struct wlr_compositor *compositor;
|
||||||
|
struct wl_listener new_surface_listener;
|
||||||
struct wlr_subcompositor *subcompositor;
|
struct wlr_subcompositor *subcompositor;
|
||||||
struct wlr_data_device_manager *data_device_manager;
|
struct wlr_data_device_manager *data_device_manager;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
#include <wlr/render/color.h>
|
#include <wlr/render/color.h>
|
||||||
#include <wlr/render/pass.h>
|
#include <wlr/render/pass.h>
|
||||||
|
|
||||||
@@ -37,6 +38,89 @@ static inline SphericalCoord get_forward_spherical_with_nearest(
|
|||||||
return Vector3ToSpherical(vec);
|
return Vector3ToSpherical(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SurfaceDamageListener {
|
||||||
|
struct wl_listener client_commit;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void surface_damage_client_commit(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
(void)listener;
|
||||||
|
struct wlr_surface *surface = data;
|
||||||
|
if (!surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!wlr_surface_state_has_buffer(&surface->pending)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pixman_region32_not_empty(&surface->pending.surface_damage)
|
||||||
|
|| pixman_region32_not_empty(&surface->pending.buffer_damage)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int surface_width = surface->pending.width > 0 ? surface->pending.width
|
||||||
|
: surface->current.width;
|
||||||
|
int surface_height = surface->pending.height > 0 ? surface->pending.height
|
||||||
|
: surface->current.height;
|
||||||
|
int buffer_width = surface->pending.buffer_width > 0
|
||||||
|
? surface->pending.buffer_width
|
||||||
|
: surface->current.buffer_width;
|
||||||
|
int buffer_height = surface->pending.buffer_height > 0
|
||||||
|
? surface->pending.buffer_height
|
||||||
|
: surface->current.buffer_height;
|
||||||
|
|
||||||
|
if (surface_width <= 0 || surface_height <= 0 || buffer_width <= 0
|
||||||
|
|| buffer_height <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixman_region32_union_rect(&surface->pending.surface_damage,
|
||||||
|
&surface->pending.surface_damage, 0, 0, surface_width, surface_height);
|
||||||
|
pixman_region32_union_rect(&surface->pending.buffer_damage,
|
||||||
|
&surface->pending.buffer_damage, 0, 0, buffer_width, buffer_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void surface_damage_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
struct SurfaceDamageListener *hook
|
||||||
|
= wl_container_of(listener, hook, destroy);
|
||||||
|
wl_list_remove(&hook->client_commit.link);
|
||||||
|
wl_list_remove(&hook->destroy.link);
|
||||||
|
free(hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void surface_damage_track(struct wlr_surface *surface)
|
||||||
|
{
|
||||||
|
if (!surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SurfaceDamageListener *hook = calloc(1, sizeof(*hook));
|
||||||
|
if (!hook) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to allocate surface damage listener");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook->client_commit.notify = surface_damage_client_commit;
|
||||||
|
wl_signal_add(&surface->events.client_commit, &hook->client_commit);
|
||||||
|
|
||||||
|
hook->destroy.notify = surface_damage_destroy;
|
||||||
|
wl_signal_add(&surface->events.destroy, &hook->destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compositor_new_surface_notify(
|
||||||
|
struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
(void)listener;
|
||||||
|
struct wlr_surface *surface = data;
|
||||||
|
if (!surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_damage_track(surface);
|
||||||
|
}
|
||||||
|
|
||||||
struct ExternalTexturePipeline {
|
struct ExternalTexturePipeline {
|
||||||
bool attempted_init;
|
bool attempted_init;
|
||||||
bool ready;
|
bool ready;
|
||||||
@@ -1776,6 +1860,10 @@ bool LunarWM_wayland_init(LunarWM *this)
|
|||||||
wlr_log(WLR_ERROR, "Failed to create compositor");
|
wlr_log(WLR_ERROR, "Failed to create compositor");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this->wayland.new_surface_listener.notify = compositor_new_surface_notify;
|
||||||
|
wl_signal_add(&this->wayland.compositor->events.new_surface,
|
||||||
|
&this->wayland.new_surface_listener);
|
||||||
|
|
||||||
|
|
||||||
this->wayland.subcompositor
|
this->wayland.subcompositor
|
||||||
= wlr_subcompositor_create(this->wayland.display);
|
= wlr_subcompositor_create(this->wayland.display);
|
||||||
@@ -1853,6 +1941,12 @@ void LunarWM_wayland_cleanup(LunarWM *this)
|
|||||||
this->wayland.new_output_listener.notify = NULL;
|
this->wayland.new_output_listener.notify = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->wayland.new_surface_listener.link.prev
|
||||||
|
|| this->wayland.new_surface_listener.link.next) {
|
||||||
|
wl_list_remove(&this->wayland.new_surface_listener.link);
|
||||||
|
this->wayland.new_surface_listener.notify = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->wayland.v_outputs) {
|
if (this->wayland.v_outputs) {
|
||||||
for (size_t i = 0; i < vector_size(this->wayland.v_outputs); ++i) {
|
for (size_t i = 0; i < vector_size(this->wayland.v_outputs); ++i) {
|
||||||
destroy_output(this->wayland.v_outputs[i]);
|
destroy_output(this->wayland.v_outputs[i]);
|
||||||
|
|||||||
Reference in New Issue
Block a user