Add object lifetimes (invalidate references, free listeners)
This commit is contained in:
parent
a0f53a31ce
commit
1d755a8a74
13 changed files with 860 additions and 249 deletions
|
@ -20,7 +20,5 @@ struct kiwmi_lua_callback {
|
|||
};
|
||||
|
||||
int luaK_kiwmi_lua_callback_new(lua_State *L);
|
||||
int luaK_kiwmi_lua_callback_register(lua_State *L);
|
||||
void luaK_kiwmi_lua_callback_cleanup(struct kiwmi_lua *lua);
|
||||
|
||||
#endif /* KIWMI_LUAK_KIWMI_LUA_CALLBACK_H */
|
||||
|
|
|
@ -16,10 +16,30 @@
|
|||
|
||||
struct kiwmi_lua {
|
||||
lua_State *L;
|
||||
struct wl_list callbacks; // lua_callback::link
|
||||
int objects;
|
||||
struct wl_global *global;
|
||||
};
|
||||
|
||||
struct kiwmi_object {
|
||||
struct kiwmi_lua *lua;
|
||||
|
||||
void *object;
|
||||
size_t refcount;
|
||||
bool valid;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct wl_list callbacks; // struct kiwmi_lua_callback::link
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
};
|
||||
|
||||
int luaK_kiwmi_object_gc(lua_State *L);
|
||||
struct kiwmi_object *luaK_get_kiwmi_object(
|
||||
struct kiwmi_lua *lua,
|
||||
void *ptr,
|
||||
struct wl_signal *destroy);
|
||||
int luaK_callback_register_dispatch(lua_State *L);
|
||||
int luaK_usertype_ref_equal(lua_State *L);
|
||||
struct kiwmi_lua *luaK_create(struct kiwmi_server *server);
|
||||
|
|
277
kiwmi/desktop/.output.c.kak.pRsrnt
Normal file
277
kiwmi/desktop/.output.c.kak.pRsrnt
Normal file
|
@ -0,0 +1,277 @@
|
|||
wow such kakoune/* 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 "desktop/output.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <wayland-server.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "desktop/desktop.h"
|
||||
#include "desktop/layer_shell.h"
|
||||
#include "desktop/view.h"
|
||||
#include "input/cursor.h"
|
||||
#include "input/input.h"
|
||||
#include "server.h"
|
||||
|
||||
static void
|
||||
render_layer_surface(struct wlr_surface *surface, int x, int y, void *data)
|
||||
{
|
||||
struct kiwmi_render_data *rdata = data;
|
||||
struct wlr_output *output = rdata->output;
|
||||
struct wlr_box *geom = rdata->data;
|
||||
|
||||
struct wlr_texture *texture = wlr_surface_get_texture(surface);
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ox = rdata->output_lx + x + geom->x;
|
||||
int oy = rdata->output_ly + y + geom->y;
|
||||
|
||||
struct wlr_box box = {
|
||||
.x = ox * output->scale,
|
||||
.y = oy * output->scale,
|
||||
.width = surface->current.width * output->scale,
|
||||
.height = surface->current.height * 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, output->transform_matrix);
|
||||
|
||||
wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
|
||||
|
||||
wlr_surface_send_frame_done(surface, rdata->when);
|
||||
}
|
||||
|
||||
static void
|
||||
render_layer(struct wl_list *layer, struct kiwmi_render_data *rdata)
|
||||
{
|
||||
struct kiwmi_layer *surface;
|
||||
wl_list_for_each (surface, layer, link) {
|
||||
rdata->data = &surface->geom;
|
||||
|
||||
wlr_layer_surface_v1_for_each_surface(
|
||||
surface->layer_surface, render_layer_surface, rdata);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
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 *output = rdata->output;
|
||||
|
||||
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;
|
||||
|
||||
struct wlr_box box = {
|
||||
.x = ox * output->scale,
|
||||
.y = oy * output->scale,
|
||||
.width = surface->current.width * output->scale,
|
||||
.height = surface->current.height * 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, output->transform_matrix);
|
||||
|
||||
wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
|
||||
|
||||
wlr_surface_send_frame_done(surface, rdata->when);
|
||||
}
|
||||
|
||||
static void
|
||||
output_frame_notify(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct kiwmi_output *output = wl_container_of(listener, output, frame);
|
||||
struct wlr_output *wlr_output = data;
|
||||
struct kiwmi_desktop *desktop = output->desktop;
|
||||
struct wlr_output_layout *output_layout = desktop->output_layout;
|
||||
struct wlr_renderer *renderer =
|
||||
wlr_backend_get_renderer(wlr_output->backend);
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
if (!wlr_output_attach_render(wlr_output, NULL)) {
|
||||
wlr_log(WLR_ERROR, "Failed to attach renderer to output");
|
||||
return;
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||
|
||||
wlr_renderer_begin(renderer, width, height);
|
||||
wlr_renderer_clear(renderer, (float[]){0.0f, 1.0f, 0.0f, 1.0f});
|
||||
|
||||
double output_lx;
|
||||
double output_ly;
|
||||
wlr_output_layout_output_coords(
|
||||
output_layout, wlr_output, &output_lx, &output_ly);
|
||||
|
||||
struct kiwmi_render_data rdata = {
|
||||
.output = output->wlr_output,
|
||||
.output_lx = output_lx,
|
||||
.output_ly = output_ly,
|
||||
.renderer = renderer,
|
||||
.when = &now,
|
||||
};
|
||||
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &rdata);
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &rdata);
|
||||
|
||||
struct kiwmi_view *view;
|
||||
wl_list_for_each_reverse (view, &desktop->views, link) {
|
||||
if (view->hidden || !view->mapped) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rdata.data = view;
|
||||
|
||||
wl_signal_emit(&view->events.pre_render, &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_OVERLAY], &rdata);
|
||||
|
||||
wlr_output_render_software_cursors(wlr_output, NULL);
|
||||
wlr_renderer_end(renderer);
|
||||
|
||||
wlr_output_commit(wlr_output);
|
||||
}
|
||||
|
||||
static void
|
||||
output_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||
{
|
||||
struct kiwmi_output *output = wl_container_of(listener, output, destroy);
|
||||
|
||||
wlr_output_layout_remove(
|
||||
output->desktop->output_layout, output->wlr_output);
|
||||
|
||||
wl_signal_emit(&output->events.destroy, output);
|
||||
|
||||
wl_list_remove(&output->link);
|
||||
wl_list_remove(&output->frame.link);
|
||||
wl_list_remove(&output->destroy.link);
|
||||
|
||||
free(output);
|
||||
}
|
||||
|
||||
static void
|
||||
output_mode_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||
{
|
||||
struct kiwmi_output *output = wl_container_of(listener, output, mode);
|
||||
|
||||
arrange_layers(output);
|
||||
|
||||
wl_signal_emit(&output->events.resize, output);
|
||||
}
|
||||
|
||||
static void
|
||||
output_transform_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||
{
|
||||
struct kiwmi_output *output = wl_container_of(listener, output, transform);
|
||||
|
||||
arrange_layers(output);
|
||||
|
||||
wl_signal_emit(&output->events.resize, output);
|
||||
}
|
||||
|
||||
static struct kiwmi_output *
|
||||
output_create(struct wlr_output *wlr_output, struct kiwmi_desktop *desktop)
|
||||
{
|
||||
struct kiwmi_output *output = calloc(1, sizeof(*output));
|
||||
if (!output) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
output->wlr_output = wlr_output;
|
||||
output->desktop = desktop;
|
||||
|
||||
output->frame.notify = output_frame_notify;
|
||||
wl_signal_add(&wlr_output->events.frame, &output->frame);
|
||||
|
||||
output->destroy.notify = output_destroy_notify;
|
||||
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
||||
|
||||
output->mode.notify = output_mode_notify;
|
||||
wl_signal_add(&wlr_output->events.mode, &output->mode);
|
||||
|
||||
output->transform.notify = output_transform_notify;
|
||||
wl_signal_add(&wlr_output->events.transform, &output->transform);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void
|
||||
new_output_notify(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct kiwmi_desktop *desktop =
|
||||
wl_container_of(listener, desktop, new_output);
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
struct wlr_output *wlr_output = data;
|
||||
|
||||
wlr_log(WLR_DEBUG, "New output %p: %s", wlr_output, wlr_output->name);
|
||||
|
||||
if (!wl_list_empty(&wlr_output->modes)) {
|
||||
struct wlr_output_mode *mode =
|
||||
wl_container_of(wlr_output->modes.prev, mode, link);
|
||||
wlr_output_set_mode(wlr_output, mode);
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = output_create(wlr_output, desktop);
|
||||
if (!output) {
|
||||
wlr_log(WLR_ERROR, "Failed to create output");
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_output->data = output;
|
||||
|
||||
struct kiwmi_cursor *cursor = server->input.cursor;
|
||||
|
||||
wlr_xcursor_manager_load(cursor->xcursor_manager, wlr_output->scale);
|
||||
|
||||
wl_list_insert(&desktop->outputs, &output->link);
|
||||
|
||||
wlr_output_layout_add_auto(desktop->output_layout, wlr_output);
|
||||
|
||||
wlr_output_create_global(wlr_output);
|
||||
|
||||
size_t len_outputs = sizeof(output->layers) / sizeof(output->layers[0]);
|
||||
for (size_t i = 0; i < len_outputs; ++i) {
|
||||
wl_list_init(&output->layers[i]);
|
||||
}
|
||||
|
||||
wl_signal_init(&output->events.destroy);
|
||||
wl_signal_init(&output->events.resize);
|
||||
|
||||
wl_signal_emit(&desktop->events.new_output, output);
|
||||
}
|
|
@ -33,9 +33,12 @@ static void
|
|||
xdg_surface_unmap_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||
{
|
||||
struct kiwmi_view *view = wl_container_of(listener, view, unmap);
|
||||
|
||||
if (view->mapped) {
|
||||
view->mapped = false;
|
||||
|
||||
wl_signal_emit(&view->events.unmap, view);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
static int
|
||||
l_kiwmi_cursor_pos(lua_State *L)
|
||||
{
|
||||
struct kiwmi_cursor *cursor =
|
||||
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
|
||||
struct kiwmi_cursor *cursor = obj->object;
|
||||
|
||||
lua_pushnumber(L, cursor->cursor->x);
|
||||
lua_pushnumber(L, cursor->cursor->y);
|
||||
|
@ -35,9 +37,11 @@ l_kiwmi_cursor_pos(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_cursor_view_at_pos(lua_State *L)
|
||||
{
|
||||
struct kiwmi_cursor *cursor =
|
||||
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
|
||||
struct kiwmi_lua *lua = obj->lua;
|
||||
struct kiwmi_cursor *cursor = obj->object;
|
||||
struct kiwmi_server *server = cursor->server;
|
||||
|
||||
struct wlr_surface *surface;
|
||||
|
@ -54,8 +58,9 @@ l_kiwmi_cursor_view_at_pos(lua_State *L)
|
|||
|
||||
if (view) {
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
@ -130,10 +135,11 @@ kiwmi_cursor_on_motion_notify(struct wl_listener *listener, void *data)
|
|||
static int
|
||||
l_kiwmi_cursor_on_button_down(lua_State *L)
|
||||
{
|
||||
struct kiwmi_cursor *cursor =
|
||||
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_cursor *cursor = obj->object;
|
||||
struct kiwmi_server *server = cursor->server;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
|
@ -141,22 +147,24 @@ l_kiwmi_cursor_on_button_down(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_cursor_on_button_down_or_up_notify);
|
||||
lua_pushlightuserdata(L, &cursor->events.button_down);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_cursor_on_button_up(lua_State *L)
|
||||
{
|
||||
struct kiwmi_cursor *cursor =
|
||||
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_cursor *cursor = obj->object;
|
||||
struct kiwmi_server *server = cursor->server;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
|
@ -164,22 +172,24 @@ l_kiwmi_cursor_on_button_up(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_cursor_on_button_down_or_up_notify);
|
||||
lua_pushlightuserdata(L, &cursor->events.button_up);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_cursor_on_motion(lua_State *L)
|
||||
{
|
||||
struct kiwmi_cursor *cursor =
|
||||
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_cursor *cursor = obj->object;
|
||||
struct kiwmi_server *server = cursor->server;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
|
@ -187,13 +197,14 @@ l_kiwmi_cursor_on_motion(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_cursor_on_motion_notify);
|
||||
lua_pushlightuserdata(L, &cursor->events.motion);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg kiwmi_cursor_events[] = {
|
||||
|
@ -206,15 +217,19 @@ static const luaL_Reg kiwmi_cursor_events[] = {
|
|||
int
|
||||
luaK_kiwmi_cursor_new(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_cursor
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_lua
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // kiwmi_cursor
|
||||
|
||||
struct kiwmi_cursor *cursor = lua_touserdata(L, 1);
|
||||
struct kiwmi_lua *lua = lua_touserdata(L, 1);
|
||||
struct kiwmi_cursor *cursor = lua_touserdata(L, 2);
|
||||
|
||||
struct kiwmi_cursor **cursor_ud = lua_newuserdata(L, sizeof(*cursor_ud));
|
||||
struct kiwmi_object *obj = luaK_get_kiwmi_object(lua, cursor, NULL);
|
||||
|
||||
struct kiwmi_object **cursor_ud = lua_newuserdata(L, sizeof(*cursor_ud));
|
||||
luaL_getmetatable(L, "kiwmi_cursor");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*cursor_ud = cursor;
|
||||
*cursor_ud = obj;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -234,5 +249,8 @@ luaK_kiwmi_cursor_register(lua_State *L)
|
|||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_object_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,14 @@
|
|||
static int
|
||||
l_kiwmi_keyboard_modifiers(lua_State *L)
|
||||
{
|
||||
struct kiwmi_keyboard *keyboard =
|
||||
*(struct kiwmi_keyboard **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_keyboard no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_keyboard *keyboard = obj->object;
|
||||
|
||||
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
||||
|
||||
|
@ -70,8 +76,9 @@ kiwmi_keyboard_on_destroy_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_keyboard_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, keyboard);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -116,8 +123,9 @@ kiwmi_keyboard_on_key_down_or_up_notify(
|
|||
lua_setfield(L, -2, "key");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_keyboard_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, keyboard);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -138,33 +146,44 @@ kiwmi_keyboard_on_key_down_or_up_notify(
|
|||
static int
|
||||
l_kiwmi_keyboard_on_destroy(lua_State *L)
|
||||
{
|
||||
struct kiwmi_keyboard *keyboard =
|
||||
*(struct kiwmi_keyboard **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_keyboard no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_keyboard *keyboard = obj->object;
|
||||
struct kiwmi_server *server = keyboard->server;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_keyboard_on_destroy_notify);
|
||||
lua_pushlightuserdata(L, &keyboard->events.destroy);
|
||||
lua_pushlightuserdata(L, &obj->events.destroy);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_keyboard_on_key_down(lua_State *L)
|
||||
{
|
||||
struct kiwmi_keyboard *keyboard =
|
||||
*(struct kiwmi_keyboard **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_keyboard no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_keyboard *keyboard = obj->object;
|
||||
struct kiwmi_server *server = keyboard->server;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
|
@ -172,22 +191,28 @@ l_kiwmi_keyboard_on_key_down(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_keyboard_on_key_down_or_up_notify);
|
||||
lua_pushlightuserdata(L, &keyboard->events.key_down);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_keyboard_on_key_up(lua_State *L)
|
||||
{
|
||||
struct kiwmi_keyboard *keyboard =
|
||||
*(struct kiwmi_keyboard **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_keyboard");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_keyboard no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_keyboard *keyboard = obj->object;
|
||||
struct kiwmi_server *server = keyboard->server;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
|
@ -195,13 +220,14 @@ l_kiwmi_keyboard_on_key_up(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_keyboard_on_key_down_or_up_notify);
|
||||
lua_pushlightuserdata(L, &keyboard->events.key_up);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg kiwmi_keyboard_events[] = {
|
||||
|
@ -214,16 +240,21 @@ static const luaL_Reg kiwmi_keyboard_events[] = {
|
|||
int
|
||||
luaK_kiwmi_keyboard_new(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_keyboard
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_lua
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // kiwmi_keyboard
|
||||
|
||||
struct kiwmi_keyboard *keyboard = lua_touserdata(L, 1);
|
||||
struct kiwmi_lua *lua = lua_touserdata(L, 1);
|
||||
struct kiwmi_keyboard *keyboard = lua_touserdata(L, 2);
|
||||
|
||||
struct kiwmi_keyboard **keyboard_ud =
|
||||
struct kiwmi_object *obj =
|
||||
luaK_get_kiwmi_object(lua, keyboard, &keyboard->events.destroy);
|
||||
|
||||
struct kiwmi_object **keyboard_ud =
|
||||
lua_newuserdata(L, sizeof(*keyboard_ud));
|
||||
luaL_getmetatable(L, "kiwmi_keyboard");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*keyboard_ud = keyboard;
|
||||
*keyboard_ud = obj;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -243,5 +274,8 @@ luaK_kiwmi_keyboard_register(lua_State *L)
|
|||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_object_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,27 +12,6 @@
|
|||
#include <lauxlib.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
static int
|
||||
l_kiwmi_lua_callback_cancel(lua_State *L)
|
||||
{
|
||||
struct kiwmi_lua_callback *lc =
|
||||
*(struct kiwmi_lua_callback **)luaL_checkudata(
|
||||
L, 1, "kiwmi_lua_callback");
|
||||
|
||||
wl_list_remove(&lc->listener.link);
|
||||
wl_list_remove(&lc->link);
|
||||
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
free(lc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg kiwmi_lua_callback_methods[] = {
|
||||
{"cancel", l_kiwmi_lua_callback_cancel},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
int
|
||||
luaK_kiwmi_lua_callback_new(lua_State *L)
|
||||
{
|
||||
|
@ -40,18 +19,13 @@ luaK_kiwmi_lua_callback_new(lua_State *L)
|
|||
luaL_checktype(L, 2, LUA_TFUNCTION); // callback
|
||||
luaL_checktype(L, 3, LUA_TLIGHTUSERDATA); // event_handler
|
||||
luaL_checktype(L, 4, LUA_TLIGHTUSERDATA); // signal
|
||||
|
||||
struct kiwmi_lua_callback **lc_ud = lua_newuserdata(L, sizeof(*lc_ud));
|
||||
luaL_getmetatable(L, "kiwmi_lua_callback");
|
||||
lua_setmetatable(L, -2);
|
||||
luaL_checktype(L, 5, LUA_TLIGHTUSERDATA); // object
|
||||
|
||||
struct kiwmi_lua_callback *lc = malloc(sizeof(*lc));
|
||||
if (!lc) {
|
||||
return luaL_error(L, "failed to allocate kiwmi_lua_callback");
|
||||
}
|
||||
|
||||
*lc_ud = lc;
|
||||
|
||||
struct kiwmi_server *server = lua_touserdata(L, 1);
|
||||
|
||||
lc->server = server;
|
||||
|
@ -62,37 +36,9 @@ luaK_kiwmi_lua_callback_new(lua_State *L)
|
|||
lc->listener.notify = lua_touserdata(L, 3);
|
||||
wl_signal_add(lua_touserdata(L, 4), &lc->listener);
|
||||
|
||||
wl_list_insert(&server->lua->callbacks, &lc->link);
|
||||
struct kiwmi_object *object = lua_touserdata(L, 5);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
luaK_kiwmi_lua_callback_register(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, "kiwmi_lua_callback");
|
||||
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
luaL_setfuncs(L, kiwmi_lua_callback_methods, 0);
|
||||
|
||||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
wl_list_insert(&object->callbacks, &lc->link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
luaK_kiwmi_lua_callback_cleanup(struct kiwmi_lua *lua)
|
||||
{
|
||||
struct kiwmi_lua_callback *lc;
|
||||
struct kiwmi_lua_callback *tmp;
|
||||
wl_list_for_each_safe (lc, tmp, &lua->callbacks, link) {
|
||||
wl_list_remove(&lc->listener.link);
|
||||
wl_list_remove(&lc->link);
|
||||
|
||||
luaL_unref(lua->L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
free(lc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,14 @@
|
|||
static int
|
||||
l_kiwmi_output_auto(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
struct wlr_output_layout *output_layout = output->desktop->output_layout;
|
||||
|
||||
wlr_output_layout_add_auto(output_layout, output->wlr_output);
|
||||
|
@ -33,11 +38,16 @@ l_kiwmi_output_auto(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_output_move(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
luaL_checktype(L, 2, LUA_TNUMBER); // x
|
||||
luaL_checktype(L, 3, LUA_TNUMBER); // y
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
struct wlr_output_layout *output_layout = output->desktop->output_layout;
|
||||
|
||||
int lx = lua_tonumber(L, 2);
|
||||
|
@ -51,8 +61,14 @@ l_kiwmi_output_move(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_output_name(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
|
||||
lua_pushstring(L, output->wlr_output->name);
|
||||
|
||||
|
@ -62,9 +78,14 @@ l_kiwmi_output_name(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_output_pos(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
struct wlr_output_layout *output_layout = output->desktop->output_layout;
|
||||
|
||||
struct wlr_box *box =
|
||||
|
@ -79,8 +100,14 @@ l_kiwmi_output_pos(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_output_size(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
|
||||
lua_pushinteger(L, output->wlr_output->width);
|
||||
lua_pushinteger(L, output->wlr_output->height);
|
||||
|
@ -109,9 +136,10 @@ kiwmi_output_on_destroy_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_output_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, output);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -140,9 +168,10 @@ kiwmi_output_on_resize_notify(struct wl_listener *listener, void *data)
|
|||
lua_newtable(L);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_output_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, output);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -165,10 +194,15 @@ kiwmi_output_on_resize_notify(struct wl_listener *listener, void *data)
|
|||
static int
|
||||
l_kiwmi_output_on_destroy(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
struct kiwmi_desktop *desktop = output->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -176,23 +210,29 @@ l_kiwmi_output_on_destroy(lua_State *L)
|
|||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_output_on_destroy_notify);
|
||||
lua_pushlightuserdata(L, &output->events.destroy);
|
||||
lua_pushlightuserdata(L, &obj->events.destroy);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_output_on_resize(lua_State *L)
|
||||
{
|
||||
struct kiwmi_output *output =
|
||||
*(struct kiwmi_output **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_output no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_output *output = obj->object;
|
||||
struct kiwmi_desktop *desktop = output->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -201,13 +241,14 @@ l_kiwmi_output_on_resize(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_output_on_resize_notify);
|
||||
lua_pushlightuserdata(L, &output->events.resize);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg kiwmi_output_events[] = {
|
||||
|
@ -219,15 +260,20 @@ static const luaL_Reg kiwmi_output_events[] = {
|
|||
int
|
||||
luaK_kiwmi_output_new(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_output
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_lua
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // kiwmi_output
|
||||
|
||||
struct kiwmi_output *output = lua_touserdata(L, 1);
|
||||
struct kiwmi_lua *lua = lua_touserdata(L, 1);
|
||||
struct kiwmi_output *output = lua_touserdata(L, 2);
|
||||
|
||||
struct kiwmi_output **output_ud = lua_newuserdata(L, sizeof(*output_ud));
|
||||
struct kiwmi_object *obj =
|
||||
luaK_get_kiwmi_object(lua, output, &output->events.destroy);
|
||||
|
||||
struct kiwmi_object **output_ud = lua_newuserdata(L, sizeof(*output_ud));
|
||||
luaL_getmetatable(L, "kiwmi_output");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*output_ud = output;
|
||||
*output_ud = obj;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -247,5 +293,8 @@ luaK_kiwmi_output_register(lua_State *L)
|
|||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_object_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -93,11 +93,13 @@ static const luaL_Reg kiwmi_renderer_methods[] = {
|
|||
int
|
||||
luaK_kiwmi_renderer_new(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // wlr_renderer
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // wlr_output
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_lua
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // wlr_renderer
|
||||
luaL_checktype(L, 3, LUA_TLIGHTUSERDATA); // wlr_output
|
||||
|
||||
struct wlr_renderer *wlr_renderer = lua_touserdata(L, 1);
|
||||
struct kiwmi_output *output = lua_touserdata(L, 2);
|
||||
struct kiwmi_lua *UNUSED(lua) = lua_touserdata(L, 1);
|
||||
struct wlr_renderer *wlr_renderer = lua_touserdata(L, 2);
|
||||
struct kiwmi_output *output = lua_touserdata(L, 3);
|
||||
|
||||
struct kiwmi_renderer *renderer_ud =
|
||||
lua_newuserdata(L, sizeof(*renderer_ud));
|
||||
|
@ -122,5 +124,8 @@ luaK_kiwmi_renderer_register(lua_State *L)
|
|||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_object_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,12 +30,15 @@
|
|||
static int
|
||||
l_kiwmi_server_cursor(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_cursor_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, server->input.cursor);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
@ -46,16 +49,19 @@ l_kiwmi_server_cursor(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_server_focused_view(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
if (!server->input.seat->focused_view) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, server->input.seat->focused_view);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
@ -66,8 +72,10 @@ l_kiwmi_server_focused_view(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_server_quit(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
wl_display_terminate(server->wl_display);
|
||||
|
||||
|
@ -101,8 +109,10 @@ l_kiwmi_server_spawn(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_server_stop_interactive(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
server->input.cursor->cursor_mode = KIWMI_CURSOR_PASSTHROUGH;
|
||||
|
||||
|
@ -112,11 +122,13 @@ l_kiwmi_server_stop_interactive(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_server_view_at(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
luaL_checktype(L, 2, LUA_TNUMBER); // x
|
||||
luaL_checktype(L, 3, LUA_TNUMBER); // y
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
double x = lua_tonumber(L, 2);
|
||||
double y = lua_tonumber(L, 3);
|
||||
|
||||
|
@ -129,8 +141,9 @@ l_kiwmi_server_view_at(lua_State *L)
|
|||
|
||||
if (view) {
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, obj->lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
@ -163,8 +176,9 @@ kiwmi_server_on_keyboard_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_keyboard_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, keyboard);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -187,8 +201,9 @@ kiwmi_server_on_output_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_output_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, output);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -211,8 +226,9 @@ kiwmi_server_on_view_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -227,64 +243,73 @@ kiwmi_server_on_view_notify(struct wl_listener *listener, void *data)
|
|||
static int
|
||||
l_kiwmi_server_on_keyboard(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_server_on_keyboard_notify);
|
||||
lua_pushlightuserdata(L, &server->input.events.keyboard_new);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_server_on_output(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_server_on_output_notify);
|
||||
lua_pushlightuserdata(L, &server->desktop.events.new_output);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_server_on_view(lua_State *L)
|
||||
{
|
||||
struct kiwmi_server *server =
|
||||
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_server_on_view_notify);
|
||||
lua_pushlightuserdata(L, &server->desktop.events.view_map);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg kiwmi_server_events[] = {
|
||||
|
@ -297,15 +322,19 @@ static const luaL_Reg kiwmi_server_events[] = {
|
|||
int
|
||||
luaK_kiwmi_server_new(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_server
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_lua
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // kiwmi_server
|
||||
|
||||
struct kiwmi_server *server = lua_touserdata(L, 1);
|
||||
struct kiwmi_lua *lua = lua_touserdata(L, 1);
|
||||
struct kiwmi_server *server = lua_touserdata(L, 2);
|
||||
|
||||
struct kiwmi_server **server_ud = lua_newuserdata(L, sizeof(*server_ud));
|
||||
struct kiwmi_object *obj = luaK_get_kiwmi_object(lua, server, NULL);
|
||||
|
||||
struct kiwmi_object **server_ud = lua_newuserdata(L, sizeof(*server_ud));
|
||||
luaL_getmetatable(L, "kiwmi_server");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*server_ud = server;
|
||||
*server_ud = obj;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -325,5 +354,8 @@ luaK_kiwmi_server_register(lua_State *L)
|
|||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_object_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,14 @@
|
|||
static int
|
||||
l_kiwmi_view_app_id(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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_pushstring(L, view_get_app_id(view));
|
||||
|
||||
|
@ -38,8 +44,14 @@ l_kiwmi_view_app_id(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_close(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
|
||||
view_close(view);
|
||||
|
||||
|
@ -49,10 +61,16 @@ l_kiwmi_view_close(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_csd(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TBOOLEAN);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
|
||||
struct kiwmi_xdg_decoration *decoration = view->decoration;
|
||||
if (!decoration) {
|
||||
return 0;
|
||||
|
@ -73,9 +91,14 @@ l_kiwmi_view_csd(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_focus(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
struct kiwmi_seat *seat = server->input.seat;
|
||||
|
@ -88,8 +111,14 @@ l_kiwmi_view_focus(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_hidden(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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_pushboolean(L, view->hidden);
|
||||
|
||||
|
@ -99,8 +128,14 @@ l_kiwmi_view_hidden(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_hide(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
|
||||
view->hidden = true;
|
||||
|
||||
|
@ -110,8 +145,14 @@ l_kiwmi_view_hide(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_imove(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
|
||||
view_move(view);
|
||||
|
||||
|
@ -121,10 +162,16 @@ l_kiwmi_view_imove(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_iresize(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
|
||||
enum wlr_edges edges = WLR_EDGE_NONE;
|
||||
|
||||
lua_pushnil(L);
|
||||
|
@ -162,8 +209,14 @@ l_kiwmi_view_iresize(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_move(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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_TNUMBER);
|
||||
luaL_checktype(L, 3, LUA_TNUMBER);
|
||||
|
@ -177,8 +230,14 @@ l_kiwmi_view_move(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_pid(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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_pushinteger(L, view_get_pid(view));
|
||||
|
||||
|
@ -188,8 +247,14 @@ l_kiwmi_view_pid(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_pos(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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_pushinteger(L, view->x);
|
||||
lua_pushinteger(L, view->y);
|
||||
|
@ -200,11 +265,17 @@ l_kiwmi_view_pos(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_resize(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TNUMBER); // w
|
||||
luaL_checktype(L, 3, LUA_TNUMBER); // h
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
|
||||
double w = lua_tonumber(L, 2);
|
||||
double h = lua_tonumber(L, 3);
|
||||
|
||||
|
@ -216,8 +287,14 @@ l_kiwmi_view_resize(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_show(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
|
||||
view->hidden = false;
|
||||
|
||||
|
@ -227,8 +304,14 @@ l_kiwmi_view_show(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_size(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
@ -243,8 +326,14 @@ l_kiwmi_view_size(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_tiled(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
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;
|
||||
|
||||
if (lua_isboolean(L, 2)) {
|
||||
enum wlr_edges edges = WLR_EDGE_NONE;
|
||||
|
@ -300,10 +389,16 @@ l_kiwmi_view_tiled(lua_State *L)
|
|||
static int
|
||||
l_kiwmi_view_title(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
|
||||
lua_pushstring(L, view_get_app_id(view));
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
|
||||
lua_pushstring(L, view_get_title(view));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -340,9 +435,10 @@ kiwmi_view_on_destroy_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -371,9 +467,10 @@ kiwmi_view_on_render_notify(struct wl_listener *listener, void *data)
|
|||
lua_newtable(L);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -382,9 +479,10 @@ kiwmi_view_on_render_notify(struct wl_listener *listener, void *data)
|
|||
lua_setfield(L, -2, "view");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_output_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, output);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -393,10 +491,11 @@ kiwmi_view_on_render_notify(struct wl_listener *listener, void *data)
|
|||
lua_setfield(L, -2, "output");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_renderer_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, renderer);
|
||||
lua_pushlightuserdata(L, output);
|
||||
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
if (lua_pcall(L, 3, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -421,9 +520,10 @@ kiwmi_view_on_request_move_notify(struct wl_listener *listener, void *data)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -450,9 +550,10 @@ kiwmi_view_on_request_resize_notify(struct wl_listener *listener, void *data)
|
|||
lua_newtable(L);
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_view_new);
|
||||
lua_pushlightuserdata(L, server->lua);
|
||||
lua_pushlightuserdata(L, view);
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
|
@ -494,10 +595,15 @@ kiwmi_view_on_request_resize_notify(struct wl_listener *listener, void *data)
|
|||
static int
|
||||
l_kiwmi_view_on_destroy(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -505,23 +611,29 @@ l_kiwmi_view_on_destroy(lua_State *L)
|
|||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_view_on_destroy_notify);
|
||||
lua_pushlightuserdata(L, &view->events.unmap);
|
||||
lua_pushlightuserdata(L, &obj->events.destroy);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_view_on_post_render(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -530,22 +642,28 @@ l_kiwmi_view_on_post_render(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_view_on_render_notify);
|
||||
lua_pushlightuserdata(L, &view->events.post_render);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_view_on_pre_render(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -554,22 +672,28 @@ l_kiwmi_view_on_pre_render(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_view_on_render_notify);
|
||||
lua_pushlightuserdata(L, &view->events.pre_render);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_view_on_request_move(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -578,22 +702,28 @@ l_kiwmi_view_on_request_move(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_view_on_request_move_notify);
|
||||
lua_pushlightuserdata(L, &view->events.request_move);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_view_on_request_resize(lua_State *L)
|
||||
{
|
||||
struct kiwmi_view *view =
|
||||
*(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_view");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
if (!obj->valid) {
|
||||
return luaL_error(L, "kiwmi_view no longer valid");
|
||||
}
|
||||
|
||||
struct kiwmi_view *view = obj->object;
|
||||
struct kiwmi_desktop *desktop = view->desktop;
|
||||
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
|
||||
|
||||
|
@ -602,13 +732,14 @@ l_kiwmi_view_on_request_resize(lua_State *L)
|
|||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_view_on_request_resize_notify);
|
||||
lua_pushlightuserdata(L, &view->events.request_resize);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
|
||||
if (lua_pcall(L, 4, 1, 0)) {
|
||||
if (lua_pcall(L, 5, 0, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg kiwmi_view_events[] = {
|
||||
|
@ -623,15 +754,20 @@ static const luaL_Reg kiwmi_view_events[] = {
|
|||
int
|
||||
luaK_kiwmi_view_new(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_view
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_lua
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA); // kiwmi_view
|
||||
|
||||
struct kiwmi_view *view = lua_touserdata(L, 1);
|
||||
struct kiwmi_lua *lua = lua_touserdata(L, 1);
|
||||
struct kiwmi_view *view = lua_touserdata(L, 2);
|
||||
|
||||
struct kiwmi_view **view_ud = lua_newuserdata(L, sizeof(*view_ud));
|
||||
struct kiwmi_object *obj =
|
||||
luaK_get_kiwmi_object(lua, view, &view->events.unmap);
|
||||
|
||||
struct kiwmi_object **view_ud = lua_newuserdata(L, sizeof(*view_ud));
|
||||
luaL_getmetatable(L, "kiwmi_view");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*view_ud = view;
|
||||
*view_ud = obj;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -651,5 +787,8 @@ luaK_kiwmi_view_register(lua_State *L)
|
|||
lua_pushcfunction(L, luaK_usertype_ref_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_object_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,108 @@
|
|||
#include "luak/kiwmi_server.h"
|
||||
#include "luak/kiwmi_view.h"
|
||||
|
||||
int
|
||||
luaK_kiwmi_object_gc(lua_State *L)
|
||||
{
|
||||
struct kiwmi_object *obj = *(struct kiwmi_object **)lua_touserdata(L, 1);
|
||||
|
||||
--obj->refcount;
|
||||
|
||||
if (obj->refcount == 0 && wl_list_empty(&obj->callbacks)) {
|
||||
free(obj);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
kiwmi_object_destroy_notify(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct kiwmi_object *obj = wl_container_of(listener, obj, destroy);
|
||||
|
||||
wl_signal_emit(&obj->events.destroy, data);
|
||||
|
||||
struct kiwmi_lua_callback *lc;
|
||||
struct kiwmi_lua_callback *tmp;
|
||||
wl_list_for_each_safe (lc, tmp, &obj->callbacks, link) {
|
||||
wl_list_remove(&lc->listener.link);
|
||||
wl_list_remove(&lc->link);
|
||||
|
||||
luaL_unref(lc->server->lua->L, LUA_REGISTRYINDEX, lc->callback_ref);
|
||||
|
||||
free(lc);
|
||||
}
|
||||
|
||||
wl_list_remove(&obj->destroy.link);
|
||||
|
||||
lua_State *L = obj->lua->L;
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, obj->lua->objects);
|
||||
lua_pushlightuserdata(L, obj->object);
|
||||
lua_pushnil(L);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 1);
|
||||
|
||||
obj->valid = false;
|
||||
|
||||
if (obj->refcount == 0) {
|
||||
free(obj);
|
||||
}
|
||||
}
|
||||
|
||||
struct kiwmi_object *
|
||||
luaK_get_kiwmi_object(
|
||||
struct kiwmi_lua *lua,
|
||||
void *ptr,
|
||||
struct wl_signal *destroy)
|
||||
{
|
||||
lua_State *L = lua->L;
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lua->objects);
|
||||
lua_pushlightuserdata(L, ptr);
|
||||
lua_gettable(L, -2);
|
||||
|
||||
struct kiwmi_object *obj = lua_touserdata(L, -1);
|
||||
|
||||
lua_pop(L, 2);
|
||||
|
||||
if (obj) {
|
||||
++obj->refcount;
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj = malloc(sizeof(*obj));
|
||||
if (!obj) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate kiwmi_object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj->lua = lua;
|
||||
obj->object = ptr;
|
||||
obj->refcount = 1;
|
||||
obj->valid = true;
|
||||
|
||||
if (destroy) {
|
||||
obj->destroy.notify = kiwmi_object_destroy_notify;
|
||||
wl_signal_add(destroy, &obj->destroy);
|
||||
|
||||
wl_signal_init(&obj->events.destroy);
|
||||
}
|
||||
|
||||
wl_list_init(&obj->callbacks);
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lua->objects);
|
||||
lua_pushlightuserdata(L, ptr);
|
||||
lua_pushlightuserdata(L, obj);
|
||||
lua_settable(L, -3);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
int
|
||||
luaK_callback_register_dispatch(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA); // server
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA); // object
|
||||
luaL_checktype(L, 2, LUA_TSTRING); // type
|
||||
luaL_checktype(L, 3, LUA_TFUNCTION); // callback
|
||||
|
||||
|
@ -77,8 +175,14 @@ luaK_create(struct kiwmi_server *server)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lua->L = L;
|
||||
|
||||
luaL_openlibs(L);
|
||||
|
||||
// init object registry
|
||||
lua_newtable(L);
|
||||
lua->objects = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
// register types
|
||||
int error = 0;
|
||||
|
||||
|
@ -86,8 +190,6 @@ luaK_create(struct kiwmi_server *server)
|
|||
error |= lua_pcall(L, 0, 0, 0);
|
||||
lua_pushcfunction(L, luaK_kiwmi_keyboard_register);
|
||||
error |= lua_pcall(L, 0, 0, 0);
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_register);
|
||||
error |= lua_pcall(L, 0, 0, 0);
|
||||
lua_pushcfunction(L, luaK_kiwmi_output_register);
|
||||
error |= lua_pcall(L, 0, 0, 0);
|
||||
lua_pushcfunction(L, luaK_kiwmi_renderer_register);
|
||||
|
@ -100,14 +202,14 @@ luaK_create(struct kiwmi_server *server)
|
|||
if (error) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_close(L);
|
||||
free(lua);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create kiwmi global
|
||||
lua_pushcfunction(L, luaK_kiwmi_server_new);
|
||||
lua_pushlightuserdata(L, lua);
|
||||
lua_pushlightuserdata(L, server);
|
||||
if (lua_pcall(L, 1, 1, 0)) {
|
||||
if (lua_pcall(L, 2, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
lua_close(L);
|
||||
free(lua);
|
||||
|
@ -115,10 +217,6 @@ luaK_create(struct kiwmi_server *server)
|
|||
}
|
||||
lua_setglobal(L, "kiwmi");
|
||||
|
||||
lua->L = L;
|
||||
|
||||
wl_list_init(&lua->callbacks);
|
||||
|
||||
if (!luaK_ipc_init(server, lua)) {
|
||||
wlr_log(WLR_ERROR, "Failed to initialize IPC");
|
||||
lua_close(L);
|
||||
|
@ -148,8 +246,6 @@ luaK_dofile(struct kiwmi_lua *lua, const char *config_path)
|
|||
void
|
||||
luaK_destroy(struct kiwmi_lua *lua)
|
||||
{
|
||||
luaK_kiwmi_lua_callback_cleanup(lua);
|
||||
|
||||
lua_close(lua->L);
|
||||
|
||||
free(lua);
|
||||
|
|
|
@ -143,12 +143,6 @@ The compositor will not forward it to the focused view in that case.
|
|||
|
||||
A handle to a registered callback.
|
||||
|
||||
### Methods
|
||||
|
||||
#### callback:cancel()
|
||||
|
||||
Unregisters the callback.
|
||||
|
||||
## kiwmi_output
|
||||
|
||||
Represents an output (most often a display).
|
||||
|
|
Loading…
Reference in a new issue