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
phoen
Daniel Barlow 2022-05-21 20:30:54 +01:00
parent 3628e93d18
commit 49229c75f3
4 changed files with 71 additions and 13 deletions

View File

@ -54,6 +54,7 @@ struct kiwmi_view {
int x;
int y;
float matrix[9];
bool mapped;
bool hidden;

View File

@ -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);
}

View File

@ -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);

View File

@ -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},