From 49229c75f3a85b72a7073a68a5a6fe38218b6357 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sat, 21 May 2022 20:30:54 +0100 Subject: [PATCH] add per-view transformation matrices Note that this breaks output layout. Would prefer to deal with that stuff ("monitor 1 is left of monitor 2") in Lua for more flexibility --- kiwmi/include/desktop/view.h | 1 + kiwmi/kiwmi/desktop/output.c | 33 +++++++++++++++---------- kiwmi/kiwmi/desktop/view.c | 5 ++++ kiwmi/kiwmi/luak/kiwmi_view.c | 45 +++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/kiwmi/include/desktop/view.h b/kiwmi/include/desktop/view.h index 3055304..90a4ad6 100644 --- a/kiwmi/include/desktop/view.h +++ b/kiwmi/include/desktop/view.h @@ -54,6 +54,7 @@ struct kiwmi_view { int x; int y; + float matrix[9]; bool mapped; bool hidden; diff --git a/kiwmi/kiwmi/desktop/output.c b/kiwmi/kiwmi/desktop/output.c index 2f2564a..9b2bcac 100644 --- a/kiwmi/kiwmi/desktop/output.c +++ b/kiwmi/kiwmi/desktop/output.c @@ -101,29 +101,36 @@ render_surface(struct wlr_surface *surface, int sx, int sy, void *data) struct kiwmi_render_data *rdata = data; struct kiwmi_view *view = rdata->data; struct wlr_output *wlr_output = rdata->output; + float mat[9] = { 1,0,0, 0,1,0, 0,0,1 }; struct wlr_texture *texture = wlr_surface_get_texture(surface); if (!texture) { return; } - int ox = rdata->output_lx + sx + view->x - view->geom.x; - int oy = rdata->output_ly + sy + view->y - view->geom.y; + wlr_matrix_translate(mat, + sx + view->x - view->geom.x, + sy + view->y - view->geom.y); + wlr_matrix_scale(mat, surface->current.width, surface->current.height); + wlr_matrix_multiply(mat, view->matrix, mat); - struct wlr_box box = { - .x = ox * wlr_output->scale, - .y = oy * wlr_output->scale, - .width = surface->current.width * wlr_output->scale, - .height = surface->current.height * wlr_output->scale, - }; - - float matrix[9]; enum wl_output_transform transform = wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box( - matrix, &box, transform, 0, wlr_output->transform_matrix); - wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1); + if (transform != WL_OUTPUT_TRANSFORM_NORMAL) { + wlr_matrix_translate(mat, 0.5, 0.5); + wlr_matrix_transform(mat, transform); + wlr_matrix_translate(mat, -0.5, -0.5); + } + + /* looking at the definition of wlr_matrix_project_box, + * wlr_output->transform_matrix would be + * better named wlr_output->projection_matrix + */ + + wlr_matrix_multiply(mat, wlr_output->transform_matrix, mat); + + wlr_render_texture_with_matrix(rdata->renderer, texture, mat, 1); wlr_surface_send_frame_done(surface, rdata->when); } diff --git a/kiwmi/kiwmi/desktop/view.c b/kiwmi/kiwmi/desktop/view.c index c741d8d..6fa6f46 100644 --- a/kiwmi/kiwmi/desktop/view.c +++ b/kiwmi/kiwmi/desktop/view.c @@ -293,6 +293,11 @@ view_create( view->x = 0; view->y = 0; + for(int r=0; r < 3; r++) { + for(int c=0; c < 3; c++) { + view->matrix[r*3+c] = (r == c) ? 1 : 0; + } + } wl_list_init(&view->children); diff --git a/kiwmi/kiwmi/luak/kiwmi_view.c b/kiwmi/kiwmi/luak/kiwmi_view.c index 791347b..f856665 100644 --- a/kiwmi/kiwmi/luak/kiwmi_view.c +++ b/kiwmi/kiwmi/luak/kiwmi_view.c @@ -247,6 +247,49 @@ l_kiwmi_view_move(lua_State *L) return 0; } +static int +l_kiwmi_view_matrix(lua_State *L) +{ + struct kiwmi_object *obj = + *(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view"); + + if (!obj->valid) { + return luaL_error(L, "kiwmi_view no longer valid"); + } + + struct kiwmi_view *view = obj->object; + + lua_newtable(L); + for(int i=0; i< 9; i++) { + lua_pushnumber(L, view->matrix[i]); + lua_seti(L, -2, 1 + i); + } + + return 1; +} + +static int +l_kiwmi_view_set_matrix(lua_State *L) +{ + struct kiwmi_object *obj = + *(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view"); + + if (!obj->valid) { + return luaL_error(L, "kiwmi_view no longer valid"); + } + + struct kiwmi_view *view = obj->object; + + luaL_checktype(L, 2, LUA_TTABLE); + + for(int i=0; i< 9; i++) { + lua_geti(L, 2, 1 + i); + view->matrix[i] = lua_tonumber(L, -1); + } + + return 0; +} + static int l_kiwmi_view_pid(lua_State *L) { @@ -434,6 +477,8 @@ static const luaL_Reg kiwmi_view_methods[] = { {"imove", l_kiwmi_view_imove}, {"iresize", l_kiwmi_view_iresize}, {"move", l_kiwmi_view_move}, + {"matrix", l_kiwmi_view_matrix}, + {"set_matrix", l_kiwmi_view_set_matrix}, {"on", luaK_callback_register_dispatch}, {"pid", l_kiwmi_view_pid}, {"pos", l_kiwmi_view_pos},