Add cursor API

This commit is contained in:
buffet 2020-01-07 14:48:55 +00:00
parent aa046f8f02
commit 192dfca0ca
7 changed files with 331 additions and 37 deletions

View file

@ -15,12 +15,31 @@ struct kiwmi_cursor {
struct kiwmi_server *server; struct kiwmi_server *server;
struct wlr_cursor *cursor; struct wlr_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager; struct wlr_xcursor_manager *xcursor_manager;
struct wl_listener cursor_motion; struct wl_listener cursor_motion;
struct wl_listener cursor_motion_absolute; struct wl_listener cursor_motion_absolute;
struct wl_listener cursor_button; struct wl_listener cursor_button;
struct wl_listener cursor_axis; struct wl_listener cursor_axis;
struct wl_listener cursor_frame; struct wl_listener cursor_frame;
struct wl_listener seat_request_set_cursor; struct wl_listener seat_request_set_cursor;
struct {
struct wl_signal button_down;
struct wl_signal button_up;
struct wl_signal motion;
} events;
};
struct kiwmi_cursor_button_event {
struct wlr_event_pointer_button *wlr_event;
bool handled;
};
struct kiwmi_cursor_motion_event {
double oldx;
double oldy;
double newx;
double newy;
}; };
struct kiwmi_cursor *cursor_create( struct kiwmi_cursor *cursor_create(

View 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_CURSOR_H
#define KIWMI_LUAK_KIWMI_CURSOR_H
#include <lua.h>
int luaK_kiwmi_cursor_new(lua_State *L);
int luaK_kiwmi_cursor_register(lua_State *L);
#endif /* KIWMI_LUAK_KIWMI_CURSOR_H */

View file

@ -62,9 +62,19 @@ cursor_motion_notify(struct wl_listener *listener, void *data)
struct kiwmi_server *server = cursor->server; struct kiwmi_server *server = cursor->server;
struct wlr_event_pointer_motion *event = data; struct wlr_event_pointer_motion *event = data;
struct kiwmi_cursor_motion_event new_event = {
.oldx = cursor->cursor->x,
.oldy = cursor->cursor->y,
};
wlr_cursor_move( wlr_cursor_move(
cursor->cursor, event->device, event->delta_x, event->delta_y); cursor->cursor, event->device, event->delta_x, event->delta_y);
new_event.newx = cursor->cursor->x;
new_event.newy = cursor->cursor->y;
wl_signal_emit(&cursor->events.motion, &new_event);
process_cursor_motion(server, event->time_msec); process_cursor_motion(server, event->time_msec);
} }
@ -76,8 +86,18 @@ cursor_motion_absolute_notify(struct wl_listener *listener, void *data)
struct kiwmi_server *server = cursor->server; struct kiwmi_server *server = cursor->server;
struct wlr_event_pointer_motion_absolute *event = data; struct wlr_event_pointer_motion_absolute *event = data;
struct kiwmi_cursor_motion_event new_event = {
.oldx = cursor->cursor->x,
.oldy = cursor->cursor->y,
};
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
new_event.newx = cursor->cursor->x;
new_event.newy = cursor->cursor->y;
wl_signal_emit(&cursor->events.motion, &new_event);
process_cursor_motion(server, event->time_msec); process_cursor_motion(server, event->time_msec);
} }
@ -90,9 +110,22 @@ cursor_button_notify(struct wl_listener *listener, void *data)
struct kiwmi_input *input = &server->input; struct kiwmi_input *input = &server->input;
struct wlr_event_pointer_button *event = data; struct wlr_event_pointer_button *event = data;
struct kiwmi_cursor_button_event new_event = {
.wlr_event = event,
.handled = false,
};
if (event->state == WLR_BUTTON_PRESSED) {
wl_signal_emit(&cursor->events.button_down, &new_event);
} else {
wl_signal_emit(&cursor->events.button_up, &new_event);
}
if (!new_event.handled) {
wlr_seat_pointer_notify_button( wlr_seat_pointer_notify_button(
input->seat, event->time_msec, event->button, event->state); input->seat, event->time_msec, event->button, event->state);
} }
}
static void static void
cursor_axis_notify(struct wl_listener *listener, void *data) cursor_axis_notify(struct wl_listener *listener, void *data)
@ -196,5 +229,9 @@ cursor_create(
&server->input.seat->events.request_set_cursor, &server->input.seat->events.request_set_cursor,
&cursor->seat_request_set_cursor); &cursor->seat_request_set_cursor);
wl_signal_init(&cursor->events.button_down);
wl_signal_init(&cursor->events.button_up);
wl_signal_init(&cursor->events.motion);
return cursor; return cursor;
} }

235
kiwmi/luak/kiwmi_cursor.c Normal file
View file

@ -0,0 +1,235 @@
/* 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_cursor.h"
#include <linux/input-event-codes.h>
#include <lauxlib.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/util/log.h>
#include "desktop/view.h"
#include "input/cursor.h"
#include "luak/kiwmi_lua_callback.h"
#include "luak/kiwmi_view.h"
#include "luak/luak.h"
static int
l_kiwmi_cursor_pos(lua_State *L)
{
struct kiwmi_cursor *cursor =
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
lua_pushnumber(L, cursor->cursor->x);
lua_pushnumber(L, cursor->cursor->y);
return 2;
}
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_server *server = cursor->server;
struct wlr_surface *surface;
double sx;
double sy;
struct kiwmi_view *view = view_at(
&server->desktop,
cursor->cursor->x,
cursor->cursor->y,
&surface,
&sx,
&sy);
if (view) {
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));
return 0;
}
} else {
lua_pushnil(L);
}
return 1;
}
static const luaL_Reg kiwmi_cursor_methods[] = {
{"on", luaK_callback_register_dispatch},
{"pos", l_kiwmi_cursor_pos},
{"view_at_pos", l_kiwmi_cursor_view_at_pos},
{NULL, NULL},
};
static void
kiwmi_cursor_on_button_down_or_up_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_cursor_button_event *event = data;
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
lua_pushinteger(L, event->wlr_event->button - BTN_LEFT + 1);
if (lua_pcall(L, 1, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
event->handled |= lua_toboolean(L, -1);
lua_pop(L, 1);
}
static void
kiwmi_cursor_on_motion_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_cursor_motion_event *event = data;
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);
lua_newtable(L);
lua_pushnumber(L, event->oldx);
lua_setfield(L, -2, "oldx");
lua_pushnumber(L, event->oldy);
lua_setfield(L, -2, "oldy");
lua_pushnumber(L, event->newx);
lua_setfield(L, -2, "newx");
lua_pushnumber(L, event->newy);
lua_setfield(L, -2, "newy");
if (lua_pcall(L, 1, 0, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
}
static int
l_kiwmi_cursor_on_button_down(lua_State *L)
{
struct kiwmi_cursor *cursor =
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
luaL_checktype(L, 2, LUA_TFUNCTION);
struct kiwmi_server *server = cursor->server;
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
lua_pushlightuserdata(L, server);
lua_pushvalue(L, 2);
lua_pushlightuserdata(L, kiwmi_cursor_on_button_down_or_up_notify);
lua_pushlightuserdata(L, &cursor->events.button_down);
if (lua_pcall(L, 4, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
return 0;
}
return 1;
}
static int
l_kiwmi_cursor_on_button_up(lua_State *L)
{
struct kiwmi_cursor *cursor =
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
luaL_checktype(L, 2, LUA_TFUNCTION);
struct kiwmi_server *server = cursor->server;
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
lua_pushlightuserdata(L, server);
lua_pushvalue(L, 2);
lua_pushlightuserdata(L, kiwmi_cursor_on_button_down_or_up_notify);
lua_pushlightuserdata(L, &cursor->events.button_up);
if (lua_pcall(L, 4, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
return 0;
}
return 1;
}
static int
l_kiwmi_cursor_on_motion(lua_State *L)
{
struct kiwmi_cursor *cursor =
*(struct kiwmi_cursor **)luaL_checkudata(L, 1, "kiwmi_cursor");
luaL_checktype(L, 2, LUA_TFUNCTION);
struct kiwmi_server *server = cursor->server;
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
lua_pushlightuserdata(L, server);
lua_pushvalue(L, 2);
lua_pushlightuserdata(L, kiwmi_cursor_on_motion_notify);
lua_pushlightuserdata(L, &cursor->events.motion);
if (lua_pcall(L, 4, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
return 0;
}
return 1;
}
static const luaL_Reg kiwmi_cursor_events[] = {
{"button_down", l_kiwmi_cursor_on_button_down},
{"button_up", l_kiwmi_cursor_on_button_up},
{"motion", l_kiwmi_cursor_on_motion},
{NULL, NULL},
};
int
luaK_kiwmi_cursor_new(lua_State *L)
{
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // kiwmi_cursor
struct kiwmi_cursor *cursor = lua_touserdata(L, 1);
struct kiwmi_cursor **cursor_ud = lua_newuserdata(L, sizeof(*cursor_ud));
luaL_getmetatable(L, "kiwmi_cursor");
lua_setmetatable(L, -2);
*cursor_ud = cursor;
return 1;
}
int
luaK_kiwmi_cursor_register(lua_State *L)
{
luaL_newmetatable(L, "kiwmi_cursor");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
luaL_setfuncs(L, kiwmi_cursor_methods, 0);
luaL_newlib(L, kiwmi_cursor_events);
lua_setfield(L, -2, "__events");
return 0;
}

View file

@ -18,12 +18,29 @@
#include "desktop/view.h" #include "desktop/view.h"
#include "input/cursor.h" #include "input/cursor.h"
#include "luak/kiwmi_cursor.h"
#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_view.h" #include "luak/kiwmi_view.h"
#include "server.h" #include "server.h"
static int
l_kiwmi_server_cursor(lua_State *L)
{
struct kiwmi_server *server =
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
lua_pushcfunction(L, luaK_kiwmi_cursor_new);
lua_pushlightuserdata(L, server->input.cursor);
if (lua_pcall(L, 1, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
return 0;
}
return 1;
}
static int static int
l_kiwmi_server_focused_view(lua_State *L) l_kiwmi_server_focused_view(lua_State *L)
{ {
@ -77,46 +94,12 @@ l_kiwmi_server_spawn(lua_State *L)
return 0; return 0;
} }
static int
l_kiwmi_server_view_under_cursor(lua_State *L)
{
struct kiwmi_server *server =
*(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server");
struct kiwmi_cursor *cursor = server->input.cursor;
struct wlr_surface *surface;
double sx;
double sy;
struct kiwmi_view *view = view_at(
&server->desktop,
cursor->cursor->x,
cursor->cursor->y,
&surface,
&sx,
&sy);
if (view) {
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));
return 0;
}
} else {
lua_pushnil(L);
}
return 1;
}
static const luaL_Reg kiwmi_server_methods[] = { static const luaL_Reg kiwmi_server_methods[] = {
{"cursor", l_kiwmi_server_cursor},
{"focused_view", l_kiwmi_server_focused_view}, {"focused_view", l_kiwmi_server_focused_view},
{"on", luaK_callback_register_dispatch}, {"on", luaK_callback_register_dispatch},
{"quit", l_kiwmi_server_quit}, {"quit", l_kiwmi_server_quit},
{"spawn", l_kiwmi_server_spawn}, {"spawn", l_kiwmi_server_spawn},
{"view_under_cursor", l_kiwmi_server_view_under_cursor},
{NULL, NULL}, {NULL, NULL},
}; };

View file

@ -14,6 +14,7 @@
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "luak/ipc.h" #include "luak/ipc.h"
#include "luak/kiwmi_cursor.h"
#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"
@ -66,6 +67,8 @@ luaK_create(struct kiwmi_server *server)
// register types // register types
int error = 0; int error = 0;
lua_pushcfunction(L, luaK_kiwmi_cursor_register);
error |= lua_pcall(L, 0, 0, 0);
lua_pushcfunction(L, luaK_kiwmi_keyboard_register); lua_pushcfunction(L, luaK_kiwmi_keyboard_register);
error |= lua_pcall(L, 0, 0, 0); error |= lua_pcall(L, 0, 0, 0);
lua_pushcfunction(L, luaK_kiwmi_lua_callback_register); lua_pushcfunction(L, luaK_kiwmi_lua_callback_register);

View file

@ -9,6 +9,7 @@ kiwmi_sources = files(
'input/input.c', 'input/input.c',
'input/keyboard.c', 'input/keyboard.c',
'luak/ipc.c', 'luak/ipc.c',
'luak/kiwmi_cursor.c',
'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',