Add renderer
This commit is contained in:
parent
39a77fadaa
commit
a2cd2f596a
8 changed files with 261 additions and 0 deletions
|
@ -59,6 +59,8 @@ struct kiwmi_view {
|
||||||
struct wl_signal unmap;
|
struct wl_signal unmap;
|
||||||
struct wl_signal request_move;
|
struct wl_signal request_move;
|
||||||
struct wl_signal request_resize;
|
struct wl_signal request_resize;
|
||||||
|
struct wl_signal post_render;
|
||||||
|
struct wl_signal pre_render;
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
struct kiwmi_xdg_decoration *decoration;
|
struct kiwmi_xdg_decoration *decoration;
|
||||||
|
|
16
include/luak/kiwmi_renderer.h
Normal file
16
include/luak/kiwmi_renderer.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/* Copyright (c), Charlotte Meyer <dev@buffet.sh>
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KIWMI_LUAK_KIWMI_RENDERER_H
|
||||||
|
#define KIWMI_LUAK_KIWMI_RENDERER_H
|
||||||
|
|
||||||
|
#include <lua.h>
|
||||||
|
|
||||||
|
int luaK_kiwmi_renderer_new(lua_State *L);
|
||||||
|
int luaK_kiwmi_renderer_register(lua_State *L);
|
||||||
|
|
||||||
|
#endif /* KIWMI_LUAK_KIWMI_RENDERER_H */
|
|
@ -154,7 +154,9 @@ output_frame_notify(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
rdata.data = view;
|
rdata.data = view;
|
||||||
|
|
||||||
|
wl_signal_emit(&view->events.pre_render, &rdata);
|
||||||
view_for_each_surface(view, render_surface, &rdata);
|
view_for_each_surface(view, render_surface, &rdata);
|
||||||
|
wl_signal_emit(&view->events.post_render, &rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &rdata);
|
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &rdata);
|
||||||
|
|
|
@ -237,6 +237,8 @@ view_create(
|
||||||
wl_signal_init(&view->events.unmap);
|
wl_signal_init(&view->events.unmap);
|
||||||
wl_signal_init(&view->events.request_move);
|
wl_signal_init(&view->events.request_move);
|
||||||
wl_signal_init(&view->events.request_resize);
|
wl_signal_init(&view->events.request_resize);
|
||||||
|
wl_signal_init(&view->events.post_render);
|
||||||
|
wl_signal_init(&view->events.pre_render);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
126
kiwmi/luak/kiwmi_renderer.c
Normal file
126
kiwmi/luak/kiwmi_renderer.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/* Copyright (c), Charlotte Meyer <dev@buffet.sh>
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "luak/kiwmi_renderer.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <wlr/render/wlr_renderer.h>
|
||||||
|
#include <wlr/types/wlr_output.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "desktop/output.h"
|
||||||
|
#include "luak/luak.h"
|
||||||
|
|
||||||
|
struct kiwmi_renderer {
|
||||||
|
struct wlr_renderer *wlr_renderer;
|
||||||
|
struct kiwmi_output *output;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_color(const char *hex, float color[static 4])
|
||||||
|
{
|
||||||
|
if (hex[0] == '#') {
|
||||||
|
++hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = strlen(hex);
|
||||||
|
if (len != 6 && len != 8) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rgba = (uint32_t)strtoul(hex, NULL, 16);
|
||||||
|
if (len == 6) {
|
||||||
|
rgba = (rgba << 8) | 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; ++i) {
|
||||||
|
color[3 - i] = (rgba & 0xff) / 255.0;
|
||||||
|
rgba >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// premultiply alpha
|
||||||
|
color[0] *= color[3];
|
||||||
|
color[1] *= color[3];
|
||||||
|
color[2] *= color[3];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
l_kiwmi_renderer_draw_rect(lua_State *L)
|
||||||
|
{
|
||||||
|
struct kiwmi_renderer *renderer =
|
||||||
|
(struct kiwmi_renderer *)luaL_checkudata(L, 1, "kiwmi_renderer");
|
||||||
|
luaL_checktype(L, 2, LUA_TSTRING); // color
|
||||||
|
luaL_checktype(L, 3, LUA_TNUMBER); // x
|
||||||
|
luaL_checktype(L, 4, LUA_TNUMBER); // y
|
||||||
|
luaL_checktype(L, 5, LUA_TNUMBER); // width
|
||||||
|
luaL_checktype(L, 6, LUA_TNUMBER); // height
|
||||||
|
|
||||||
|
struct wlr_renderer *wlr_renderer = renderer->wlr_renderer;
|
||||||
|
struct kiwmi_output *output = renderer->output;
|
||||||
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
|
|
||||||
|
float color[4];
|
||||||
|
if (!parse_color(lua_tostring(L, 2), color)) {
|
||||||
|
return luaL_argerror(L, 2, "not a valid color");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_box box = {
|
||||||
|
.x = lua_tonumber(L, 3),
|
||||||
|
.y = lua_tonumber(L, 4),
|
||||||
|
.width = lua_tonumber(L, 5),
|
||||||
|
.height = lua_tonumber(L, 6),
|
||||||
|
};
|
||||||
|
|
||||||
|
wlr_render_rect(wlr_renderer, &box, color, wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg kiwmi_renderer_methods[] = {
|
||||||
|
{"draw_rect", l_kiwmi_renderer_draw_rect},
|
||||||
|
{NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
luaK_kiwmi_renderer_new(lua_State *L)
|
||||||
|
{
|
||||||
|
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // wlr_renderer
|
||||||
|
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // wlr_output
|
||||||
|
|
||||||
|
struct wlr_renderer *wlr_renderer = lua_touserdata(L, 1);
|
||||||
|
struct kiwmi_output *output = lua_touserdata(L, 2);
|
||||||
|
|
||||||
|
struct kiwmi_renderer *renderer_ud =
|
||||||
|
lua_newuserdata(L, sizeof(*renderer_ud));
|
||||||
|
luaL_getmetatable(L, "kiwmi_renderer");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
|
renderer_ud->wlr_renderer = wlr_renderer;
|
||||||
|
renderer_ud->output = output;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
luaK_kiwmi_renderer_register(lua_State *L)
|
||||||
|
{
|
||||||
|
luaL_newmetatable(L, "kiwmi_renderer");
|
||||||
|
|
||||||
|
lua_pushvalue(L, -1);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
luaL_setfuncs(L, kiwmi_renderer_methods, 0);
|
||||||
|
|
||||||
|
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||||
|
lua_setfield(L, -2, "__eq");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -15,10 +15,13 @@
|
||||||
#include <wlr/util/edges.h>
|
#include <wlr/util/edges.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "desktop/output.h"
|
||||||
#include "desktop/view.h"
|
#include "desktop/view.h"
|
||||||
#include "desktop/xdg_shell.h"
|
#include "desktop/xdg_shell.h"
|
||||||
#include "input/seat.h"
|
#include "input/seat.h"
|
||||||
#include "luak/kiwmi_lua_callback.h"
|
#include "luak/kiwmi_lua_callback.h"
|
||||||
|
#include "luak/kiwmi_output.h"
|
||||||
|
#include "luak/kiwmi_renderer.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -351,6 +354,62 @@ kiwmi_view_on_destroy_notify(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kiwmi_view_on_render_notify(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener);
|
||||||
|
struct kiwmi_server *server = lc->server;
|
||||||
|
lua_State *L = server->lua->L;
|
||||||
|
struct kiwmi_render_data *rdata = data;
|
||||||
|
|
||||||
|
struct kiwmi_view *view = rdata->data;
|
||||||
|
struct wlr_renderer *renderer = rdata->renderer;
|
||||||
|
struct kiwmi_output *output = rdata->output->data;
|
||||||
|
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
|
||||||
|
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||||
|
lua_pushlightuserdata(L, view);
|
||||||
|
|
||||||
|
if (lua_pcall(L, 1, 1, 0)) {
|
||||||
|
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_setfield(L, -2, "view");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, luaK_kiwmi_output_new);
|
||||||
|
lua_pushlightuserdata(L, output);
|
||||||
|
|
||||||
|
if (lua_pcall(L, 1, 1, 0)) {
|
||||||
|
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_setfield(L, -2, "output");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, luaK_kiwmi_renderer_new);
|
||||||
|
lua_pushlightuserdata(L, renderer);
|
||||||
|
lua_pushlightuserdata(L, output);
|
||||||
|
|
||||||
|
if (lua_pcall(L, 2, 1, 0)) {
|
||||||
|
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_setfield(L, -2, "renderer");
|
||||||
|
|
||||||
|
if (lua_pcall(L, 1, 0, 0)) {
|
||||||
|
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kiwmi_view_on_request_move_notify(struct wl_listener *listener, void *data)
|
kiwmi_view_on_request_move_notify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
@ -456,6 +515,54 @@ l_kiwmi_view_on_destroy(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
l_kiwmi_view_on_post_render(lua_State *L)
|
||||||
|
{
|
||||||
|
struct kiwmi_view *view =
|
||||||
|
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||||
|
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||||
|
|
||||||
|
struct kiwmi_desktop *desktop = view->desktop;
|
||||||
|
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||||
|
|
||||||
|
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||||
|
lua_pushlightuserdata(L, server);
|
||||||
|
lua_pushvalue(L, 2);
|
||||||
|
lua_pushlightuserdata(L, kiwmi_view_on_render_notify);
|
||||||
|
lua_pushlightuserdata(L, &view->events.post_render);
|
||||||
|
|
||||||
|
if (lua_pcall(L, 4, 1, 0)) {
|
||||||
|
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
l_kiwmi_view_on_pre_render(lua_State *L)
|
||||||
|
{
|
||||||
|
struct kiwmi_view *view =
|
||||||
|
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||||
|
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||||
|
|
||||||
|
struct kiwmi_desktop *desktop = view->desktop;
|
||||||
|
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||||
|
|
||||||
|
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||||
|
lua_pushlightuserdata(L, server);
|
||||||
|
lua_pushvalue(L, 2);
|
||||||
|
lua_pushlightuserdata(L, kiwmi_view_on_render_notify);
|
||||||
|
lua_pushlightuserdata(L, &view->events.pre_render);
|
||||||
|
|
||||||
|
if (lua_pcall(L, 4, 1, 0)) {
|
||||||
|
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
l_kiwmi_view_on_request_move(lua_State *L)
|
l_kiwmi_view_on_request_move(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -506,6 +613,8 @@ l_kiwmi_view_on_request_resize(lua_State *L)
|
||||||
|
|
||||||
static const luaL_Reg kiwmi_view_events[] = {
|
static const luaL_Reg kiwmi_view_events[] = {
|
||||||
{"destroy", l_kiwmi_view_on_destroy},
|
{"destroy", l_kiwmi_view_on_destroy},
|
||||||
|
{"post_render", l_kiwmi_view_on_post_render},
|
||||||
|
{"pre_render", l_kiwmi_view_on_pre_render},
|
||||||
{"request_move", l_kiwmi_view_on_request_move},
|
{"request_move", l_kiwmi_view_on_request_move},
|
||||||
{"request_resize", l_kiwmi_view_on_request_resize},
|
{"request_resize", l_kiwmi_view_on_request_resize},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "luak/kiwmi_keyboard.h"
|
#include "luak/kiwmi_keyboard.h"
|
||||||
#include "luak/kiwmi_lua_callback.h"
|
#include "luak/kiwmi_lua_callback.h"
|
||||||
#include "luak/kiwmi_output.h"
|
#include "luak/kiwmi_output.h"
|
||||||
|
#include "luak/kiwmi_renderer.h"
|
||||||
#include "luak/kiwmi_server.h"
|
#include "luak/kiwmi_server.h"
|
||||||
#include "luak/kiwmi_view.h"
|
#include "luak/kiwmi_view.h"
|
||||||
|
|
||||||
|
@ -89,6 +90,8 @@ luaK_create(struct kiwmi_server *server)
|
||||||
error |= lua_pcall(L, 0, 0, 0);
|
error |= lua_pcall(L, 0, 0, 0);
|
||||||
lua_pushcfunction(L, luaK_kiwmi_output_register);
|
lua_pushcfunction(L, luaK_kiwmi_output_register);
|
||||||
error |= lua_pcall(L, 0, 0, 0);
|
error |= lua_pcall(L, 0, 0, 0);
|
||||||
|
lua_pushcfunction(L, luaK_kiwmi_renderer_register);
|
||||||
|
error |= lua_pcall(L, 0, 0, 0);
|
||||||
lua_pushcfunction(L, luaK_kiwmi_server_register);
|
lua_pushcfunction(L, luaK_kiwmi_server_register);
|
||||||
error |= lua_pcall(L, 0, 0, 0);
|
error |= lua_pcall(L, 0, 0, 0);
|
||||||
lua_pushcfunction(L, luaK_kiwmi_view_register);
|
lua_pushcfunction(L, luaK_kiwmi_view_register);
|
||||||
|
|
|
@ -15,6 +15,7 @@ kiwmi_sources = files(
|
||||||
'luak/kiwmi_keyboard.c',
|
'luak/kiwmi_keyboard.c',
|
||||||
'luak/kiwmi_lua_callback.c',
|
'luak/kiwmi_lua_callback.c',
|
||||||
'luak/kiwmi_output.c',
|
'luak/kiwmi_output.c',
|
||||||
|
'luak/kiwmi_renderer.c',
|
||||||
'luak/kiwmi_server.c',
|
'luak/kiwmi_server.c',
|
||||||
'luak/kiwmi_view.c',
|
'luak/kiwmi_view.c',
|
||||||
'luak/luak.c',
|
'luak/luak.c',
|
||||||
|
|
Loading…
Reference in a new issue