Add cursor API
This commit is contained in:
parent
aa046f8f02
commit
192dfca0ca
7 changed files with 331 additions and 37 deletions
|
@ -15,12 +15,31 @@ struct kiwmi_cursor {
|
|||
struct kiwmi_server *server;
|
||||
struct wlr_cursor *cursor;
|
||||
struct wlr_xcursor_manager *xcursor_manager;
|
||||
|
||||
struct wl_listener cursor_motion;
|
||||
struct wl_listener cursor_motion_absolute;
|
||||
struct wl_listener cursor_button;
|
||||
struct wl_listener cursor_axis;
|
||||
struct wl_listener cursor_frame;
|
||||
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(
|
||||
|
|
16
include/luak/kiwmi_cursor.h
Normal file
16
include/luak/kiwmi_cursor.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_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 */
|
|
@ -62,9 +62,19 @@ cursor_motion_notify(struct wl_listener *listener, void *data)
|
|||
struct kiwmi_server *server = cursor->server;
|
||||
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(
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -76,8 +86,18 @@ cursor_motion_absolute_notify(struct wl_listener *listener, void *data)
|
|||
struct kiwmi_server *server = cursor->server;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -90,9 +110,22 @@ cursor_button_notify(struct wl_listener *listener, void *data)
|
|||
struct kiwmi_input *input = &server->input;
|
||||
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(
|
||||
input->seat, event->time_msec, event->button, event->state);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_axis_notify(struct wl_listener *listener, void *data)
|
||||
|
@ -196,5 +229,9 @@ cursor_create(
|
|||
&server->input.seat->events.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;
|
||||
}
|
||||
|
|
235
kiwmi/luak/kiwmi_cursor.c
Normal file
235
kiwmi/luak/kiwmi_cursor.c
Normal 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;
|
||||
}
|
|
@ -18,12 +18,29 @@
|
|||
|
||||
#include "desktop/view.h"
|
||||
#include "input/cursor.h"
|
||||
#include "luak/kiwmi_cursor.h"
|
||||
#include "luak/kiwmi_keyboard.h"
|
||||
#include "luak/kiwmi_lua_callback.h"
|
||||
#include "luak/kiwmi_output.h"
|
||||
#include "luak/kiwmi_view.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
|
||||
l_kiwmi_server_focused_view(lua_State *L)
|
||||
{
|
||||
|
@ -77,46 +94,12 @@ l_kiwmi_server_spawn(lua_State *L)
|
|||
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[] = {
|
||||
{"cursor", l_kiwmi_server_cursor},
|
||||
{"focused_view", l_kiwmi_server_focused_view},
|
||||
{"on", luaK_callback_register_dispatch},
|
||||
{"quit", l_kiwmi_server_quit},
|
||||
{"spawn", l_kiwmi_server_spawn},
|
||||
{"view_under_cursor", l_kiwmi_server_view_under_cursor},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <wlr/util/log.h>
|
||||
|
||||
#include "luak/ipc.h"
|
||||
#include "luak/kiwmi_cursor.h"
|
||||
#include "luak/kiwmi_keyboard.h"
|
||||
#include "luak/kiwmi_lua_callback.h"
|
||||
#include "luak/kiwmi_output.h"
|
||||
|
@ -66,6 +67,8 @@ luaK_create(struct kiwmi_server *server)
|
|||
// register types
|
||||
int error = 0;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_cursor_register);
|
||||
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);
|
||||
|
|
|
@ -9,6 +9,7 @@ kiwmi_sources = files(
|
|||
'input/input.c',
|
||||
'input/keyboard.c',
|
||||
'luak/ipc.c',
|
||||
'luak/kiwmi_cursor.c',
|
||||
'luak/kiwmi_keyboard.c',
|
||||
'luak/kiwmi_lua_callback.c',
|
||||
'luak/kiwmi_output.c',
|
||||
|
|
Loading…
Reference in a new issue