commit 49229c75f3a85b72a7073a68a5a6fe38218b6357
parent 3628e93d1886b311fbd7a5c22bb5ff09d57d7609
Author: Daniel Barlow <dan@telent.net>
Date: Sat, 21 May 2022 20:30:54 +0100
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
Diffstat:
4 files changed, 71 insertions(+), 13 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -248,6 +248,49 @@ l_kiwmi_view_move(lua_State *L)
}
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)
{
struct kiwmi_object *obj =
@@ -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},