406
src/LunarWM.c
406
src/LunarWM.c
@@ -43,9 +43,14 @@ void toplevel_commit_notify(struct wl_listener *l, void *)
|
||||
{
|
||||
auto *tl = wl_container_of(l, (LunarWM_Toplevel *)(NULL), commit);
|
||||
|
||||
if (tl->xdg_toplevel->base->initial_commit) {
|
||||
wlr_xdg_toplevel_set_size(tl->xdg_toplevel, 0, 0);
|
||||
if (!tl || !tl->surface)
|
||||
return;
|
||||
|
||||
if (!tl->is_xwayland) {
|
||||
if (tl->u.xdg && tl->u.xdg->base->initial_commit) {
|
||||
wlr_xdg_toplevel_set_size(tl->u.xdg, 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LunarWM_Toplevel_update(tl);
|
||||
@@ -65,12 +70,13 @@ void toplevel_destroy_notify(struct wl_listener *l, void *)
|
||||
free(tl);
|
||||
}
|
||||
|
||||
bool LunarWM_Toplevel_init(
|
||||
LunarWM_Toplevel *tl, struct LunarWM *wm, struct wlr_xdg_toplevel *xdg)
|
||||
bool LunarWM_Toplevel_init_xdg(
|
||||
LunarWM_Toplevel *tl, LunarWM *wm, struct wlr_xdg_toplevel *xdg)
|
||||
{
|
||||
tl->id = vector_size(wm->wayland.v_toplevels) + 1;
|
||||
tl->server = wm;
|
||||
tl->xdg_toplevel = xdg;
|
||||
tl->is_xwayland = false;
|
||||
tl->u.xdg = xdg;
|
||||
tl->surface = xdg->base->surface;
|
||||
|
||||
assert(tl->surface);
|
||||
@@ -84,6 +90,26 @@ bool LunarWM_Toplevel_init(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LunarWM_Toplevel_init_xwayland(
|
||||
LunarWM_Toplevel *tl, LunarWM *wm, struct wlr_xwayland_surface *xwl)
|
||||
{
|
||||
tl->id = vector_size(wm->wayland.v_toplevels) + 1;
|
||||
tl->server = wm;
|
||||
tl->is_xwayland = true;
|
||||
tl->u.xwl = xwl;
|
||||
tl->surface = xwl->surface;
|
||||
|
||||
assert(tl->surface);
|
||||
|
||||
tl->commit.notify = toplevel_commit_notify;
|
||||
wl_signal_add(&tl->surface->events.commit, &tl->commit);
|
||||
|
||||
tl->destroy.notify = toplevel_destroy_notify;
|
||||
wl_signal_add(&tl->surface->events.destroy, &tl->destroy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LunarWM_Toplevel_destroy(LunarWM_Toplevel *this)
|
||||
{
|
||||
wl_list_remove(&this->commit.link);
|
||||
@@ -131,6 +157,278 @@ bool LunarWM_Toplevel_update(LunarWM_Toplevel *this)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void clamp_to_hints(
|
||||
const struct wlr_xwayland_surface *x, uint16_t *w, uint16_t *h)
|
||||
{
|
||||
xcb_size_hints_t *hints = x->size_hints;
|
||||
if (!hints)
|
||||
return;
|
||||
|
||||
if ((hints->flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)) {
|
||||
if (*w < hints->min_width)
|
||||
*w = hints->min_width;
|
||||
if (*h < hints->min_height)
|
||||
*h = hints->min_height;
|
||||
}
|
||||
if ((hints->flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)) {
|
||||
if (hints->max_width > 0 && *w > hints->max_width)
|
||||
*w = hints->max_width;
|
||||
if (hints->max_height > 0 && *h > hints->max_height)
|
||||
*h = hints->max_height;
|
||||
}
|
||||
if ((hints->flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)) {
|
||||
if (hints->width_inc > 0)
|
||||
*w = (*w / hints->width_inc) * hints->width_inc;
|
||||
if (hints->height_inc > 0)
|
||||
*h = (*h / hints->height_inc) * hints->height_inc;
|
||||
}
|
||||
if ((hints->flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE)) {
|
||||
if (*w < hints->base_width)
|
||||
*w = hints->base_width;
|
||||
if (*h < hints->base_height)
|
||||
*h = hints->base_height;
|
||||
}
|
||||
}
|
||||
|
||||
struct XwlHooks {
|
||||
LunarWM *wm;
|
||||
struct wlr_xwayland_surface *xwl;
|
||||
struct wl_listener associate;
|
||||
struct wl_listener dissociate;
|
||||
struct wl_listener destroy;
|
||||
|
||||
struct wl_listener req_configure;
|
||||
struct wl_listener req_maximize;
|
||||
struct wl_listener req_fullscreen;
|
||||
struct wl_listener set_geometry;
|
||||
};
|
||||
|
||||
static void xwayland_ready_notify(struct wl_listener *l, void *data)
|
||||
{
|
||||
LunarWM *wm = wl_container_of(l, wm, wayland.xwayland_ready);
|
||||
wlr_xwayland_set_seat(wm->wayland.xwayland, wm->wayland.seat);
|
||||
setenv("DISPLAY", wm->wayland.xwayland->display_name, 1);
|
||||
}
|
||||
|
||||
static void handle_associate(struct wl_listener *ll, void *d)
|
||||
{
|
||||
struct wlr_xwayland_surface *x = d;
|
||||
LunarWM *wm2 = wl_container_of(ll, wm2, wayland.xwayland_associate_tmp);
|
||||
if (!x->surface)
|
||||
return;
|
||||
|
||||
LunarWM_Toplevel *tl = calloc(1, sizeof *tl);
|
||||
if (!tl)
|
||||
return;
|
||||
|
||||
if (LunarWM_Toplevel_init_xwayland(tl, wm2, x)) {
|
||||
vector_add(&wm2->wayland.v_toplevels, tl);
|
||||
} else {
|
||||
free(tl);
|
||||
}
|
||||
wl_list_remove(&wm2->wayland.xwayland_associate_tmp.link);
|
||||
}
|
||||
|
||||
static void handle_dissociate(struct wl_listener *ll, void *d)
|
||||
{
|
||||
struct wlr_xwayland_surface *x = d;
|
||||
LunarWM *wm2 = wl_container_of(ll, wm2, wayland.xwayland_dissociate_tmp);
|
||||
for (size_t i = 0; i < vector_size(wm2->wayland.v_toplevels); ++i) {
|
||||
LunarWM_Toplevel *tl = wm2->wayland.v_toplevels[i];
|
||||
if (tl->is_xwayland && tl->u.xwl == x) {
|
||||
vector_remove(wm2->wayland.v_toplevels, i);
|
||||
LunarWM_Toplevel_destroy(tl);
|
||||
free(tl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
wl_list_remove(&wm2->wayland.xwayland_dissociate_tmp.link);
|
||||
}
|
||||
|
||||
static void xwl_hooks_destroy(struct XwlHooks *h)
|
||||
{
|
||||
if (!h)
|
||||
return;
|
||||
if (h->associate.link.prev || h->associate.link.next)
|
||||
wl_list_remove(&h->associate.link);
|
||||
if (h->dissociate.link.prev || h->dissociate.link.next)
|
||||
wl_list_remove(&h->dissociate.link);
|
||||
if (h->destroy.link.prev || h->destroy.link.next)
|
||||
wl_list_remove(&h->destroy.link);
|
||||
free(h);
|
||||
}
|
||||
|
||||
static void xwl_on_associate(struct wl_listener *ll, void *data)
|
||||
{
|
||||
struct XwlHooks *h = wl_container_of(ll, h, associate);
|
||||
struct wlr_xwayland_surface *x = h->xwl;
|
||||
if (!x || !x->surface)
|
||||
return;
|
||||
|
||||
LunarWM_Toplevel *tl = calloc(1, sizeof *tl);
|
||||
if (!tl)
|
||||
return;
|
||||
if (LunarWM_Toplevel_init_xwayland(tl, h->wm, x)) {
|
||||
vector_add(&h->wm->wayland.v_toplevels, tl);
|
||||
} else {
|
||||
free(tl);
|
||||
}
|
||||
}
|
||||
|
||||
static void xwl_unmap_toplevel(LunarWM_Toplevel *tl)
|
||||
{
|
||||
if (!tl)
|
||||
return;
|
||||
|
||||
if (tl->commit.link.prev || tl->commit.link.next)
|
||||
wl_list_remove(&tl->commit.link);
|
||||
if (tl->destroy.link.prev || tl->destroy.link.next)
|
||||
wl_list_remove(&tl->destroy.link);
|
||||
|
||||
if (tl->locked_buffer) {
|
||||
wlr_buffer_unlock(tl->locked_buffer);
|
||||
tl->locked_buffer = NULL;
|
||||
}
|
||||
|
||||
tl->texture = NULL;
|
||||
tl->gles_texture = NULL;
|
||||
tl->rl_texture = (Texture) { 0 };
|
||||
tl->surface = NULL;
|
||||
}
|
||||
|
||||
static void xwl_on_dissociate(struct wl_listener *ll, void *data)
|
||||
{
|
||||
struct XwlHooks *h = wl_container_of(ll, h, dissociate);
|
||||
LunarWM *wm = h->wm;
|
||||
struct wlr_xwayland_surface *x = h->xwl;
|
||||
|
||||
for (size_t i = 0; i < vector_size(wm->wayland.v_toplevels); ++i) {
|
||||
LunarWM_Toplevel *tl = wm->wayland.v_toplevels[i];
|
||||
if (tl->is_xwayland && tl->u.xwl == x) {
|
||||
xwl_unmap_toplevel(tl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void xwl_on_request_configure(struct wl_listener *ll, void *data)
|
||||
{
|
||||
struct XwlHooks *xh = wl_container_of(ll, xh, req_configure);
|
||||
struct wlr_xwayland_surface_configure_event *ev = data;
|
||||
if (!xh->xwl)
|
||||
return;
|
||||
|
||||
int16_t x = xh->xwl->x, y = xh->xwl->y;
|
||||
uint16_t w = xh->xwl->width, h = xh->xwl->height;
|
||||
|
||||
if (ev->mask & XCB_CONFIG_WINDOW_X)
|
||||
x = ev->x;
|
||||
if (ev->mask & XCB_CONFIG_WINDOW_Y)
|
||||
y = ev->y;
|
||||
if (ev->mask & XCB_CONFIG_WINDOW_WIDTH)
|
||||
w = ev->width;
|
||||
if (ev->mask & XCB_CONFIG_WINDOW_HEIGHT)
|
||||
h = ev->height;
|
||||
|
||||
clamp_to_hints(xh->xwl, &w, &h);
|
||||
|
||||
wlr_xwayland_surface_configure(xh->xwl, x, y, w, h);
|
||||
}
|
||||
|
||||
static void xwl_on_request_maximize(struct wl_listener *ll, void *data)
|
||||
{
|
||||
struct XwlHooks *xh = wl_container_of(ll, xh, req_maximize);
|
||||
wlr_xwayland_surface_set_maximized(xh->xwl, true, true);
|
||||
}
|
||||
|
||||
static void xwl_on_request_fullscreen(struct wl_listener *ll, void *data)
|
||||
{
|
||||
struct XwlHooks *xh = wl_container_of(ll, xh, req_fullscreen);
|
||||
wlr_xwayland_surface_set_fullscreen(xh->xwl, true);
|
||||
}
|
||||
|
||||
static void xwl_on_set_geometry(struct wl_listener *ll, void *data)
|
||||
{
|
||||
(void)ll;
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void xwl_on_destroy(struct wl_listener *ll, void *data)
|
||||
{
|
||||
struct XwlHooks *xh = wl_container_of(ll, xh, destroy);
|
||||
LunarWM *wm = xh->wm;
|
||||
struct wlr_xwayland_surface *x = xh->xwl;
|
||||
|
||||
if (xh->req_configure.link.prev)
|
||||
wl_list_remove(&xh->req_configure.link);
|
||||
if (xh->req_maximize.link.prev)
|
||||
wl_list_remove(&xh->req_maximize.link);
|
||||
if (xh->req_fullscreen.link.prev)
|
||||
wl_list_remove(&xh->req_fullscreen.link);
|
||||
if (xh->set_geometry.link.prev)
|
||||
wl_list_remove(&xh->set_geometry.link);
|
||||
if (xh->associate.link.prev)
|
||||
wl_list_remove(&xh->associate.link);
|
||||
if (xh->dissociate.link.prev)
|
||||
wl_list_remove(&xh->dissociate.link);
|
||||
if (xh->destroy.link.prev)
|
||||
wl_list_remove(&xh->destroy.link);
|
||||
|
||||
for (size_t i = 0; i < vector_size(wm->wayland.v_toplevels); ++i) {
|
||||
LunarWM_Toplevel *tl = wm->wayland.v_toplevels[i];
|
||||
if (tl->is_xwayland && tl->u.xwl == x) {
|
||||
vector_remove(wm->wayland.v_toplevels, i);
|
||||
free(tl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(xh);
|
||||
}
|
||||
|
||||
static void xwayland_new_surface_notify(struct wl_listener *l, void *data)
|
||||
{
|
||||
LunarWM *wm = wl_container_of(l, wm, wayland.xwayland_new_surface);
|
||||
struct wlr_xwayland_surface *xwl = data;
|
||||
|
||||
if (xwl->surface) {
|
||||
LunarWM_Toplevel *tl = calloc(1, sizeof *tl);
|
||||
if (tl && LunarWM_Toplevel_init_xwayland(tl, wm, xwl))
|
||||
vector_add(&wm->wayland.v_toplevels, tl);
|
||||
else
|
||||
free(tl);
|
||||
}
|
||||
|
||||
struct XwlHooks *h = calloc(1, sizeof *h);
|
||||
if (!h)
|
||||
return;
|
||||
h->wm = wm;
|
||||
h->xwl = xwl;
|
||||
|
||||
h->associate.notify = xwl_on_associate;
|
||||
wl_signal_add(&xwl->events.associate, &h->associate);
|
||||
|
||||
h->dissociate.notify = xwl_on_dissociate;
|
||||
wl_signal_add(&xwl->events.dissociate, &h->dissociate);
|
||||
|
||||
h->req_configure.notify = xwl_on_request_configure;
|
||||
wl_signal_add(&xwl->events.request_configure, &h->req_configure);
|
||||
|
||||
h->req_maximize.notify = xwl_on_request_maximize;
|
||||
wl_signal_add(&xwl->events.request_maximize, &h->req_maximize);
|
||||
|
||||
h->req_fullscreen.notify = xwl_on_request_fullscreen;
|
||||
wl_signal_add(&xwl->events.request_fullscreen, &h->req_fullscreen);
|
||||
|
||||
h->set_geometry.notify = xwl_on_set_geometry;
|
||||
wl_signal_add(&xwl->events.set_geometry, &h->set_geometry);
|
||||
|
||||
h->destroy.notify = xwl_on_destroy;
|
||||
wl_signal_add(&xwl->events.destroy, &h->destroy);
|
||||
|
||||
xwl->data = h;
|
||||
}
|
||||
|
||||
void LunarWM_Toplevel_focus(LunarWM_Toplevel *this)
|
||||
{
|
||||
if (!this)
|
||||
@@ -139,19 +437,29 @@ void LunarWM_Toplevel_focus(LunarWM_Toplevel *this)
|
||||
LunarWM *wm = this->server;
|
||||
struct wlr_seat *seat = wm->wayland.seat;
|
||||
struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface;
|
||||
struct wlr_surface *surface = this->xdg_toplevel->base->surface;
|
||||
struct wlr_surface *surface = this->surface;
|
||||
if (prev_surface == surface) {
|
||||
return;
|
||||
}
|
||||
if (prev_surface) {
|
||||
struct wlr_xdg_toplevel *prev_toplevel
|
||||
struct wlr_xdg_toplevel *prev_tl
|
||||
= wlr_xdg_toplevel_try_from_wlr_surface(prev_surface);
|
||||
if (prev_toplevel != NULL) {
|
||||
wlr_xdg_toplevel_set_activated(prev_toplevel, false);
|
||||
}
|
||||
if (prev_tl)
|
||||
wlr_xdg_toplevel_set_activated(prev_tl, false);
|
||||
struct wlr_xwayland_surface *prev_x
|
||||
= wlr_xwayland_surface_try_from_wlr_surface(prev_surface);
|
||||
if (prev_x)
|
||||
wlr_xwayland_surface_activate(prev_x, false);
|
||||
}
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat);
|
||||
wlr_xdg_toplevel_set_activated(this->xdg_toplevel, true);
|
||||
|
||||
if (this->is_xwayland) {
|
||||
wlr_xwayland_surface_offer_focus(this->u.xwl);
|
||||
wlr_xwayland_surface_activate(this->u.xwl, true);
|
||||
} else {
|
||||
wlr_xdg_toplevel_set_activated(this->u.xdg, true);
|
||||
}
|
||||
|
||||
if (keyboard != NULL) {
|
||||
wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes,
|
||||
keyboard->num_keycodes, &keyboard->modifiers);
|
||||
@@ -338,7 +646,7 @@ static void new_xdg_toplevel_listener_notify(
|
||||
return;
|
||||
}
|
||||
|
||||
if (LunarWM_Toplevel_init(tl, wm, xdg_tl)) {
|
||||
if (LunarWM_Toplevel_init_xdg(tl, wm, xdg_tl)) {
|
||||
vector_add(&wm->wayland.v_toplevels, tl);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Failed to initialize Toplevel.");
|
||||
@@ -454,7 +762,13 @@ static bool init_wayland(LunarWM *this)
|
||||
this->wayland.xwayland = wlr_xwayland_create(this->wayland.display,
|
||||
this->wayland.compositor, this->cman->cfg.xwayland.lazy);
|
||||
|
||||
setenv("DISPLAY", this->wayland.xwayland->display_name, 1);
|
||||
this->wayland.xwayland_ready.notify = xwayland_ready_notify;
|
||||
wl_signal_add(&this->wayland.xwayland->events.ready,
|
||||
&this->wayland.xwayland_ready);
|
||||
|
||||
this->wayland.xwayland_new_surface.notify = xwayland_new_surface_notify;
|
||||
wl_signal_add(&this->wayland.xwayland->events.new_surface,
|
||||
&this->wayland.xwayland_new_surface);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1576,34 +1890,34 @@ static void DrawBillboardNoShear(
|
||||
|
||||
// pass yFlip from tl->attribs.invert_y
|
||||
static void DrawTexture3D(
|
||||
Texture2D tex, Vector3 position, Vector3 target, float scale, bool yFlip)
|
||||
Texture2D tex, Vector3 position, Vector3 target, float scale, bool y_flip)
|
||||
{
|
||||
if (!tex.id)
|
||||
return;
|
||||
|
||||
Vector3 fwd = Vector3Normalize(Vector3Subtract(target, position));
|
||||
Vector3 upRef = (fabsf(fwd.y) > 0.99f) ? (Vector3) { 0, 0, 1 }
|
||||
: (Vector3) { 0, 1, 0 };
|
||||
Vector3 right = Vector3Normalize(Vector3CrossProduct(fwd, upRef));
|
||||
Vector3 up_ref = (fabsf(fwd.y) > 0.99f) ? (Vector3) { 0, 0, 1 }
|
||||
: (Vector3) { 0, 1, 0 };
|
||||
Vector3 right = Vector3Normalize(Vector3CrossProduct(fwd, up_ref));
|
||||
Vector3 up = Vector3CrossProduct(right, fwd);
|
||||
|
||||
float halfW = 0.5f * (float)tex.width * scale;
|
||||
float halfH = 0.5f * (float)tex.height * scale;
|
||||
float half_w = 0.5f * (float)tex.width * scale;
|
||||
float half_h = 0.5f * (float)tex.height * scale;
|
||||
|
||||
Vector3 tl
|
||||
= Vector3Add(Vector3Subtract(position, Vector3Scale(right, halfW)),
|
||||
Vector3Scale(up, halfH));
|
||||
Vector3 tr = Vector3Add(Vector3Add(position, Vector3Scale(right, halfW)),
|
||||
Vector3Scale(up, halfH));
|
||||
= Vector3Add(Vector3Subtract(position, Vector3Scale(right, half_w)),
|
||||
Vector3Scale(up, half_h));
|
||||
Vector3 tr = Vector3Add(Vector3Add(position, Vector3Scale(right, half_w)),
|
||||
Vector3Scale(up, half_h));
|
||||
Vector3 br
|
||||
= Vector3Subtract(Vector3Add(position, Vector3Scale(right, halfW)),
|
||||
Vector3Scale(up, halfH));
|
||||
Vector3 bl
|
||||
= Vector3Subtract(Vector3Subtract(position, Vector3Scale(right, halfW)),
|
||||
Vector3Scale(up, halfH));
|
||||
= Vector3Subtract(Vector3Add(position, Vector3Scale(right, half_w)),
|
||||
Vector3Scale(up, half_h));
|
||||
Vector3 bl = Vector3Subtract(
|
||||
Vector3Subtract(position, Vector3Scale(right, half_w)),
|
||||
Vector3Scale(up, half_h));
|
||||
|
||||
float vt = yFlip ? 1.0f : 0.0f;
|
||||
float vb = yFlip ? 0.0f : 1.0f;
|
||||
float vt = y_flip ? 1.0f : 0.0f;
|
||||
float vb = y_flip ? 0.0f : 1.0f;
|
||||
|
||||
rlDisableBackfaceCulling(); // ensure visible regardless of winding
|
||||
rlSetTexture(tex.id);
|
||||
@@ -1755,30 +2069,32 @@ static bool render_layer(LunarWM *this, LunarWM_RenderLayerInfo *info, float dt)
|
||||
RL_ATTACHMENT_TEXTURE2D, 0);
|
||||
assert(rlFramebufferComplete(this->renderer.fbo));
|
||||
|
||||
uint32_t const eyeW
|
||||
uint32_t const eye_w
|
||||
= this->xr.a_view_configuration_views[0].recommendedImageRectWidth;
|
||||
uint32_t const eyeH
|
||||
uint32_t const eye_h
|
||||
= this->xr.a_view_configuration_views[0].recommendedImageRectHeight;
|
||||
|
||||
this->renderer.tmp_rt = (RenderTexture2D) {
|
||||
.id = this->renderer.fbo,
|
||||
.texture = { color_tex, (int)eyeW * view_count, (int)eyeH, 1, -1 },
|
||||
.depth = { depth_tex, (int)eyeW * view_count, (int)eyeH, 1, -1 },
|
||||
.texture = { color_tex, (int)eye_w * view_count, (int)eye_h, 1, -1 },
|
||||
.depth = { depth_tex, (int)eye_w * view_count, (int)eye_h, 1, -1 },
|
||||
};
|
||||
|
||||
// head-space view matrix (matches rlOpenXR)
|
||||
XrSpaceLocation headLoc = { .type = XR_TYPE_SPACE_LOCATION };
|
||||
xrLocateSpace(this->xr.view_space, this->xr.local_space,
|
||||
info->predicted_display_time, &headLoc);
|
||||
auto const headView = MatrixInvert(xr_matrix(headLoc.pose));
|
||||
auto const head_view = MatrixInvert(xr_matrix(headLoc.pose));
|
||||
|
||||
// per-eye projection + view-offset
|
||||
Matrix const projR = xr_projection_matrix(views[0].fov);
|
||||
Matrix const projL = xr_projection_matrix(views[1].fov);
|
||||
Matrix const viewOffL = MatrixMultiply(xr_matrix(views[0].pose), headView);
|
||||
Matrix const viewOffR = MatrixMultiply(xr_matrix(views[1].pose), headView);
|
||||
Matrix const proj_r = xr_projection_matrix(views[0].fov);
|
||||
Matrix const proj_l = xr_projection_matrix(views[1].fov);
|
||||
Matrix const view_off_l
|
||||
= MatrixMultiply(xr_matrix(views[0].pose), head_view);
|
||||
Matrix const view_off_r
|
||||
= MatrixMultiply(xr_matrix(views[1].pose), head_view);
|
||||
|
||||
int const hud_size = eyeH * 0.3;
|
||||
int const hud_size = eye_h * 0.3;
|
||||
if (!IsTextureValid(this->renderer.hud_rt.texture)) {
|
||||
this->renderer.hud_rt = LoadRenderTexture(hud_size, hud_size);
|
||||
}
|
||||
@@ -1795,10 +2111,10 @@ static bool render_layer(LunarWM *this, LunarWM_RenderLayerInfo *info, float dt)
|
||||
BeginTextureMode(this->renderer.tmp_rt);
|
||||
|
||||
rlEnableStereoRender();
|
||||
rlSetMatrixProjectionStereo(projR, projL); // right, left (yes)
|
||||
rlSetMatrixViewOffsetStereo(viewOffR, viewOffL);
|
||||
rlSetMatrixProjectionStereo(proj_r, proj_l); // right, left (yes)
|
||||
rlSetMatrixViewOffsetStereo(view_off_r, view_off_l);
|
||||
|
||||
glViewport(0, 0, (GLsizei)eyeW * view_count, (GLsizei)eyeH);
|
||||
glViewport(0, 0, (GLsizei)eye_w * view_count, (GLsizei)eye_h);
|
||||
ClearBackground((Color) { 0, 0, 10, 255 });
|
||||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
@@ -1850,14 +2166,14 @@ static bool render_layer(LunarWM *this, LunarWM_RenderLayerInfo *info, float dt)
|
||||
info->layer_projection_views_count = view_count;
|
||||
|
||||
for (uint32_t i = 0; i < view_count; ++i) {
|
||||
int32_t const xOff = i * eyeW;
|
||||
int32_t const xOff = i * eye_w;
|
||||
auto *pv = &info->layer_projection_views[i];
|
||||
pv->pose = views[i].pose;
|
||||
pv->fov = views[i].fov;
|
||||
pv->subImage.swapchain = color_sc->swapchain;
|
||||
pv->subImage.imageRect.offset = (XrOffset2Di) { .x = xOff, .y = 0 };
|
||||
pv->subImage.imageRect.extent
|
||||
= (XrExtent2Di) { .width = eyeW, .height = eyeH };
|
||||
= (XrExtent2Di) { .width = eye_w, .height = eye_h };
|
||||
pv->subImage.imageArrayIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,12 +50,18 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
|
||||
bool is_xwayland;
|
||||
|
||||
struct LunarWM *server;
|
||||
|
||||
struct wl_listener commit;
|
||||
struct wl_listener destroy;
|
||||
|
||||
struct wlr_xdg_toplevel *xdg_toplevel;
|
||||
union {
|
||||
struct wlr_xdg_toplevel *xdg;
|
||||
struct wlr_xwayland_surface *xwl;
|
||||
} u;
|
||||
|
||||
struct wlr_surface *surface;
|
||||
struct wlr_texture *texture;
|
||||
|
||||
@@ -65,8 +71,10 @@ typedef struct {
|
||||
Texture2D rl_texture;
|
||||
} LunarWM_Toplevel;
|
||||
|
||||
bool LunarWM_Toplevel_init(
|
||||
bool LunarWM_Toplevel_init_xdg(
|
||||
LunarWM_Toplevel *tl, struct LunarWM *wm, struct wlr_xdg_toplevel *xdg);
|
||||
bool LunarWM_Toplevel_init_xwayland(
|
||||
LunarWM_Toplevel *tl, struct LunarWM *wm, struct wlr_xwayland_surface *xwl);
|
||||
bool LunarWM_Toplevel_destroy(LunarWM_Toplevel *this);
|
||||
|
||||
bool LunarWM_Toplevel_update(LunarWM_Toplevel *this);
|
||||
@@ -130,6 +138,11 @@ typedef struct LunarWM {
|
||||
|
||||
struct wlr_xwayland *xwayland;
|
||||
|
||||
struct wl_listener xwayland_ready;
|
||||
struct wl_listener xwayland_new_surface;
|
||||
struct wl_listener xwayland_associate_tmp; // per-surface temp
|
||||
struct wl_listener xwayland_dissociate_tmp; // per-surface temp
|
||||
|
||||
LunarWM_Toplevel **v_toplevels;
|
||||
int current_focus;
|
||||
} wayland;
|
||||
|
||||
Reference in New Issue
Block a user