forked from izaya/LuPPC
epoll event pulling, basic input
This commit is contained in:
parent
ffc3705ea8
commit
47656b9240
@ -4,12 +4,35 @@
|
||||
#ifndef LUPI_H
|
||||
#define LUPI_H
|
||||
|
||||
//#define LOGGING
|
||||
#ifdef LOGGING
|
||||
void logn(const char *message);
|
||||
void logi(int message);
|
||||
void logm(const char *message);
|
||||
#else
|
||||
#define logn(m)
|
||||
#define logi(m)
|
||||
#define logm(m)
|
||||
#endif
|
||||
|
||||
//TODO: move to utils
|
||||
#define pushstuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3)
|
||||
#define pushctuple(state, name, value) lua_pushstring((state), (name)); lua_pushcfunction((state), (value)); lua_settable((state), -3)
|
||||
|
||||
lua_State* getL();
|
||||
|
||||
void run_init();
|
||||
void luanative_start(lua_State *L);
|
||||
void setup_modules(lua_State *L);
|
||||
void termutils_start(lua_State *L);
|
||||
void epoll_prepare();
|
||||
int epoll_pull(int timeout);
|
||||
|
||||
struct lupi_event_handler {
|
||||
int (*handler)(int, void*); //FD, data, return number of pushed events
|
||||
//TODO: doc?
|
||||
int fd;
|
||||
void* data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
70
src/c/epoll.c
Normal file
70
src/c/epoll.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include "lupi.h"
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int epollfd;
|
||||
|
||||
static int handleStdin(int fd, void* data) {
|
||||
char buf;
|
||||
int r = read(fd, &buf, 1); //TODO: Wide chars?
|
||||
if(r > 0) {
|
||||
if(buf == 10) buf = 13;
|
||||
lua_State* L = getL();
|
||||
|
||||
lua_getglobal(L, "pushEvent");
|
||||
lua_pushstring(L, "key_down");
|
||||
lua_pushstring(L, "TODO:SetThisUuid");
|
||||
lua_pushnumber(L, buf);
|
||||
lua_pushnumber(L, -1);
|
||||
lua_pushstring(L, "user");
|
||||
lua_call(L, 5, 0);
|
||||
|
||||
lua_getglobal(L, "pushEvent");
|
||||
lua_pushstring(L, "key_up");
|
||||
lua_pushstring(L, "TODO:SetThisUuid");
|
||||
lua_pushnumber(L, buf);
|
||||
lua_pushnumber(L, -1);
|
||||
lua_pushstring(L, "user");
|
||||
lua_call(L, 5, 0);
|
||||
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void epoll_prepare() {
|
||||
if ((epollfd = epoll_create1(0)) < 0) {
|
||||
perror("epoll_create");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct lupi_event_handler* stdin_handler = malloc(sizeof(struct lupi_event_handler));
|
||||
stdin_handler->data = NULL;
|
||||
stdin_handler->handler = handleStdin;
|
||||
stdin_handler->fd = STDIN_FILENO;
|
||||
|
||||
struct epoll_event stdinEvent;
|
||||
stdinEvent.events = EPOLLIN | EPOLLPRI;
|
||||
stdinEvent.data.ptr = stdin_handler;
|
||||
|
||||
if ((epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &stdinEvent) < 0)) {
|
||||
perror("epoll_ctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int epoll_pull(int timeout) {
|
||||
struct epoll_event evBuffer;
|
||||
int pushed = 0;
|
||||
|
||||
int eres = epoll_wait(epollfd, &evBuffer, 1, timeout);
|
||||
if(eres > 0) {
|
||||
struct lupi_event_handler* handler = (struct lupi_event_handler*)evBuffer.data.ptr;
|
||||
pushed = handler->handler(handler->fd, handler->data);
|
||||
}
|
||||
return pushed;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
@ -17,7 +18,7 @@
|
||||
#include <limits.h>
|
||||
#include <linux/kd.h>
|
||||
|
||||
|
||||
//Enable in lupi.h
|
||||
#ifdef LOGGING
|
||||
void logn(const char *message) {
|
||||
FILE *file;
|
||||
@ -273,6 +274,11 @@ static int l_fs_size (lua_State *L) {
|
||||
static int l_fs_read (lua_State *L) {
|
||||
unsigned int fd = lua_tonumber(L, 1);
|
||||
unsigned int count = lua_tonumber(L, 2);
|
||||
size_t cur = lseek(fd, 0, SEEK_CUR);
|
||||
size_t end = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, cur, SEEK_SET);
|
||||
if(count > end - cur)
|
||||
count = end - cur;
|
||||
void* buf = malloc(count);
|
||||
size_t res = read(fd, buf, count);
|
||||
logm("read(");
|
||||
@ -282,6 +288,7 @@ static int l_fs_read (lua_State *L) {
|
||||
logm(" of ");
|
||||
logi(count);
|
||||
logn("");
|
||||
|
||||
if(res > 0) {
|
||||
lua_pushlstring(L, buf, res);
|
||||
free(buf);
|
||||
@ -339,6 +346,10 @@ static int l_freeMemory (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_pull (lua_State *L) {
|
||||
lua_pushnumber(L, epoll_pull(lua_tonumber(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void luanative_start(lua_State *L) {
|
||||
lua_createtable (L, 0, 1);
|
||||
@ -365,6 +376,7 @@ void luanative_start(lua_State *L) {
|
||||
pushctuple(L, "uptime", l_uptime);
|
||||
pushctuple(L, "totalMemory", l_totalMemory);
|
||||
pushctuple(L, "freeMemory", l_freeMemory);
|
||||
pushctuple(L, "pull", l_pull);
|
||||
|
||||
lua_setglobal(L, "native");
|
||||
}
|
@ -14,14 +14,20 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static lua_State* L = NULL;
|
||||
|
||||
lua_State* getL() {
|
||||
return L;
|
||||
}
|
||||
|
||||
void run_init() {
|
||||
lua_State *L;
|
||||
L = luaL_newstate();
|
||||
|
||||
luaL_openlibs (L);
|
||||
setup_modules (L);
|
||||
luanative_start (L);
|
||||
termutils_start (L);
|
||||
epoll_prepare();
|
||||
|
||||
//int status = luaL_loadstring(L, lua_init);
|
||||
int status = luaL_loadbuffer(L, lua_init, strlen(lua_init), "=INIT");
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -27,6 +28,14 @@ static int l_get_term_sz (lua_State *L) {
|
||||
void termutils_start(lua_State *L) {
|
||||
signal(SIGWINCH, handle_winch);
|
||||
|
||||
struct termios old, new;
|
||||
if (tcgetattr (STDOUT_FILENO, &old) != 0)
|
||||
return;
|
||||
new = old;
|
||||
new.c_lflag &= ~ECHO;
|
||||
if (tcsetattr (STDOUT_FILENO, TCSAFLUSH, &new) != 0)
|
||||
return;
|
||||
|
||||
lua_createtable (L, 0, 1);
|
||||
pushctuple(L, "getSize", l_get_term_sz);
|
||||
|
||||
|
@ -13,18 +13,120 @@ function api.address()
|
||||
end
|
||||
|
||||
local signalQueue = {}
|
||||
computer.signalTransformers = setmetatable({}, {__index = function(t, k)
|
||||
return function(...)
|
||||
return ...
|
||||
end
|
||||
end})
|
||||
|
||||
function api.pushSignal(...)
|
||||
signalQueue[#signalQueue + 1] = {...}
|
||||
-----
|
||||
--TODO: Move this out
|
||||
local keymap = {
|
||||
[48] = 0x2,
|
||||
[49] = 0x3,
|
||||
[50] = 0x4,
|
||||
[51] = 0x5,
|
||||
[52] = 0x6,
|
||||
[53] = 0x7,
|
||||
[54] = 0x8,
|
||||
[55] = 0x9,
|
||||
[56] = 0xA,
|
||||
[57] = 0xB,
|
||||
|
||||
[0x40 + 0x01] = 0x1E,
|
||||
[0x40 + 0x02] = 0x30,
|
||||
[0x40 + 0x04] = 0x2E,
|
||||
[0x40 + 0x05] = 0x20,
|
||||
[0x40 + 0x06] = 0x12,
|
||||
[0x40 + 0x07] = 0x21,
|
||||
[0x40 + 0x08] = 0x22,
|
||||
[0x40 + 0x09] = 0x23,
|
||||
[0x40 + 0x0A] = 0x17,
|
||||
[0x40 + 0x0B] = 0x24,
|
||||
[0x40 + 0x0C] = 0x25,
|
||||
[0x40 + 0x0D] = 0x26,
|
||||
[0x40 + 0x0E] = 0x32,
|
||||
[0x40 + 0x0F] = 0x31,
|
||||
[0x40 + 0x11] = 0x18,
|
||||
[0x40 + 0x12] = 0x19,
|
||||
[0x40 + 0x13] = 0x10,
|
||||
[0x40 + 0x14] = 0x13,
|
||||
[0x40 + 0x15] = 0x1F,
|
||||
[0x40 + 0x16] = 0x14,
|
||||
[0x40 + 0x17] = 0x16,
|
||||
[0x40 + 0x18] = 0x2F,
|
||||
[0x40 + 0x19] = 0x11,
|
||||
[0x40 + 0x1A] = 0x2D,
|
||||
[0x40 + 0x1B] = 0x15,
|
||||
[0x40 + 0x1C] = 0x2C,
|
||||
|
||||
[0x60 + 0x01] = 0x1E,
|
||||
[0x60 + 0x02] = 0x30,
|
||||
[0x60 + 0x04] = 0x2E,
|
||||
[0x60 + 0x05] = 0x20,
|
||||
[0x60 + 0x06] = 0x12,
|
||||
[0x60 + 0x07] = 0x21,
|
||||
[0x60 + 0x08] = 0x22,
|
||||
[0x60 + 0x09] = 0x23,
|
||||
[0x60 + 0x0A] = 0x17,
|
||||
[0x60 + 0x0B] = 0x24,
|
||||
[0x60 + 0x0C] = 0x25,
|
||||
[0x60 + 0x0D] = 0x26,
|
||||
[0x60 + 0x0E] = 0x32,
|
||||
[0x60 + 0x0F] = 0x31,
|
||||
[0x60 + 0x11] = 0x18,
|
||||
[0x60 + 0x12] = 0x19,
|
||||
[0x60 + 0x13] = 0x10,
|
||||
[0x60 + 0x14] = 0x13,
|
||||
[0x60 + 0x15] = 0x1F,
|
||||
[0x60 + 0x16] = 0x14,
|
||||
[0x60 + 0x17] = 0x16,
|
||||
[0x60 + 0x18] = 0x2F,
|
||||
[0x60 + 0x19] = 0x11,
|
||||
[0x60 + 0x1A] = 0x2D,
|
||||
[0x60 + 0x1B] = 0x15,
|
||||
[0x60 + 0x1C] = 0x2C,
|
||||
|
||||
[13] = 28,
|
||||
|
||||
}
|
||||
|
||||
function computer.signalTransformers.key_down(s, a, ascii, key, user)
|
||||
if key ~= -1 then
|
||||
return s, a, ascii, key, user
|
||||
end
|
||||
return s, a, ascii, keymap[ascii] or key, user
|
||||
end
|
||||
|
||||
function computer.signalTransformers.key_up(s, a, ascii, key, user)
|
||||
if key ~= -1 then
|
||||
return s, a, ascii, key, user
|
||||
end
|
||||
return s, a, ascii, keymap[ascii] or key, user
|
||||
end
|
||||
|
||||
-----
|
||||
|
||||
function api.pushSignal(s, ...)
|
||||
io.stderr:write("pushSignal "..s.."\n")
|
||||
signalQueue[#signalQueue + 1] = {computer.signalTransformers[s](s, ...)}
|
||||
end
|
||||
|
||||
function api.pullSignal(timeout)
|
||||
if signalQueue[1] then return table.remove(signalQueue, 1) end
|
||||
if type(timeout) == "number" then
|
||||
native.sleep(timeout * 1000000);
|
||||
if signalQueue[1] then return table.unpack(table.remove(signalQueue, 1)) end
|
||||
local timeoutuptime = math.huge
|
||||
|
||||
if not timeout then
|
||||
timeout = -1
|
||||
else
|
||||
timeout = timeout * 1000
|
||||
timeoutuptime = native.uptime() + timeout
|
||||
end
|
||||
if signalQueue[1] then return table.remove(signalQueue, 1) end
|
||||
--print(debug.traceback())
|
||||
local nevts = 0
|
||||
repeat
|
||||
nevts = native.pull(timeout)
|
||||
until nevts > 0 or native.uptime() > timeoutuptime
|
||||
if signalQueue[1] then return table.unpack(table.remove(signalQueue, 1)) end
|
||||
end
|
||||
|
||||
function api.uptime()
|
||||
|
@ -137,7 +137,7 @@ function filesystem.register(basePath)
|
||||
end
|
||||
function fs.close(handle)
|
||||
checkArg(1, handle, "number")
|
||||
return native.fs_close()
|
||||
return native.fs_close(handle)
|
||||
end
|
||||
function fs.size(path)
|
||||
checkArg(1, path, "string")
|
||||
|
@ -64,6 +64,7 @@ function main()
|
||||
--Setup core modules
|
||||
modules.component.prepare()
|
||||
modules.computer.prepare()
|
||||
_G.pushEvent = modules.computer.api.pushSignal
|
||||
|
||||
modules.eeprom.register()
|
||||
modules.filesystem.register("root")
|
||||
|
@ -164,11 +164,11 @@ sandbox = {
|
||||
char = utf8.char,
|
||||
charWidth = function(c)
|
||||
checkArg(1, c, "string")
|
||||
return modules.utf8.utf8charbytes(c)
|
||||
return modules.utf8.charbytes(c)
|
||||
end,
|
||||
isWide = function(c)
|
||||
checkArg(1, c, "string")
|
||||
return modules.utf8.utf8charbytes(c) > 1
|
||||
return modules.utf8.charbytes(c) > 1
|
||||
end,
|
||||
len = utf8.len,
|
||||
lower = modules.utf8.lower,
|
||||
|
@ -51,9 +51,11 @@ function textgpu.start()
|
||||
if isPaletteIndex then
|
||||
return --TODO: Maybe?
|
||||
end
|
||||
local old = foreground
|
||||
background = tostring(math.floor(modules.color.nearest(color, mapping)))
|
||||
io.write("\x1b[4" .. background .. "m")
|
||||
io.flush()
|
||||
return mapping[old]
|
||||
end
|
||||
function gpu.setForeground(color, isPaletteIndex)
|
||||
checkArg(1, color, "number")
|
||||
@ -61,9 +63,11 @@ function textgpu.start()
|
||||
if isPaletteIndex then
|
||||
return --TODO: Maybe?
|
||||
end
|
||||
local old = foreground
|
||||
foreground = tostring(math.floor(modules.color.nearest(color, mapping)))
|
||||
io.write("\x1b[3" .. foreground .. "m")
|
||||
io.flush()
|
||||
return mapping[old]
|
||||
end
|
||||
function gpu.getBackground()
|
||||
return mapping[background], false
|
||||
@ -92,6 +96,14 @@ function textgpu.start()
|
||||
function gpu.getResolution()
|
||||
return termutils.getSize()
|
||||
end
|
||||
function gpu.getViewport()
|
||||
return termutils.getSize()
|
||||
end
|
||||
function gpu.setViewport(w, h)
|
||||
checkArg(1, w, "number")
|
||||
checkArg(2, h, "number")
|
||||
return false, "Viewport not supported for this gpu"
|
||||
end
|
||||
function gpu.setResolution(w, h)
|
||||
checkArg(1, w, "number")
|
||||
checkArg(2, h, "number")
|
||||
|
Loading…
Reference in New Issue
Block a user