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
|
#ifndef LUPI_H
|
||||||
#define 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
|
//TODO: move to utils
|
||||||
#define pushstuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3)
|
#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)
|
#define pushctuple(state, name, value) lua_pushstring((state), (name)); lua_pushcfunction((state), (value)); lua_settable((state), -3)
|
||||||
|
|
||||||
|
lua_State* getL();
|
||||||
|
|
||||||
void run_init();
|
void run_init();
|
||||||
void luanative_start(lua_State *L);
|
void luanative_start(lua_State *L);
|
||||||
void setup_modules(lua_State *L);
|
void setup_modules(lua_State *L);
|
||||||
void termutils_start(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
|
#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 <lua.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
@ -17,9 +18,9 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/kd.h>
|
#include <linux/kd.h>
|
||||||
|
|
||||||
|
//Enable in lupi.h
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
void logn (const char *message) {
|
void logn(const char *message) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
file = fopen("lupi.log", "a");
|
file = fopen("lupi.log", "a");
|
||||||
@ -33,7 +34,7 @@ void logn (const char *message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logi (int message) {
|
void logi(int message) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
file = fopen("lupi.log", "a");
|
file = fopen("lupi.log", "a");
|
||||||
@ -48,7 +49,7 @@ void logi (int message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logm (const char *message) {
|
void logm(const char *message) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
file = fopen("lupi.log", "a");
|
file = fopen("lupi.log", "a");
|
||||||
@ -273,6 +274,11 @@ static int l_fs_size (lua_State *L) {
|
|||||||
static int l_fs_read (lua_State *L) {
|
static int l_fs_read (lua_State *L) {
|
||||||
unsigned int fd = lua_tonumber(L, 1);
|
unsigned int fd = lua_tonumber(L, 1);
|
||||||
unsigned int count = lua_tonumber(L, 2);
|
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);
|
void* buf = malloc(count);
|
||||||
size_t res = read(fd, buf, count);
|
size_t res = read(fd, buf, count);
|
||||||
logm("read(");
|
logm("read(");
|
||||||
@ -282,6 +288,7 @@ static int l_fs_read (lua_State *L) {
|
|||||||
logm(" of ");
|
logm(" of ");
|
||||||
logi(count);
|
logi(count);
|
||||||
logn("");
|
logn("");
|
||||||
|
|
||||||
if(res > 0) {
|
if(res > 0) {
|
||||||
lua_pushlstring(L, buf, res);
|
lua_pushlstring(L, buf, res);
|
||||||
free(buf);
|
free(buf);
|
||||||
@ -339,6 +346,10 @@ static int l_freeMemory (lua_State *L) {
|
|||||||
return 1;
|
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) {
|
void luanative_start(lua_State *L) {
|
||||||
lua_createtable (L, 0, 1);
|
lua_createtable (L, 0, 1);
|
||||||
@ -365,6 +376,7 @@ void luanative_start(lua_State *L) {
|
|||||||
pushctuple(L, "uptime", l_uptime);
|
pushctuple(L, "uptime", l_uptime);
|
||||||
pushctuple(L, "totalMemory", l_totalMemory);
|
pushctuple(L, "totalMemory", l_totalMemory);
|
||||||
pushctuple(L, "freeMemory", l_freeMemory);
|
pushctuple(L, "freeMemory", l_freeMemory);
|
||||||
|
pushctuple(L, "pull", l_pull);
|
||||||
|
|
||||||
lua_setglobal(L, "native");
|
lua_setglobal(L, "native");
|
||||||
}
|
}
|
@ -14,14 +14,20 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static lua_State* L = NULL;
|
||||||
|
|
||||||
|
lua_State* getL() {
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
void run_init() {
|
void run_init() {
|
||||||
lua_State *L;
|
|
||||||
L = luaL_newstate();
|
L = luaL_newstate();
|
||||||
|
|
||||||
luaL_openlibs (L);
|
luaL_openlibs (L);
|
||||||
setup_modules (L);
|
setup_modules (L);
|
||||||
luanative_start (L);
|
luanative_start (L);
|
||||||
termutils_start (L);
|
termutils_start (L);
|
||||||
|
epoll_prepare();
|
||||||
|
|
||||||
//int status = luaL_loadstring(L, lua_init);
|
//int status = luaL_loadstring(L, lua_init);
|
||||||
int status = luaL_loadbuffer(L, lua_init, strlen(lua_init), "=INIT");
|
int status = luaL_loadbuffer(L, lua_init, strlen(lua_init), "=INIT");
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <termios.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -27,6 +28,14 @@ static int l_get_term_sz (lua_State *L) {
|
|||||||
void termutils_start(lua_State *L) {
|
void termutils_start(lua_State *L) {
|
||||||
signal(SIGWINCH, handle_winch);
|
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);
|
lua_createtable (L, 0, 1);
|
||||||
pushctuple(L, "getSize", l_get_term_sz);
|
pushctuple(L, "getSize", l_get_term_sz);
|
||||||
|
|
||||||
|
@ -13,18 +13,120 @@ function api.address()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local signalQueue = {}
|
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
|
end
|
||||||
|
|
||||||
function api.pullSignal(timeout)
|
function api.pullSignal(timeout)
|
||||||
if signalQueue[1] then return table.remove(signalQueue, 1) end
|
if signalQueue[1] then return table.unpack(table.remove(signalQueue, 1)) end
|
||||||
if type(timeout) == "number" then
|
local timeoutuptime = math.huge
|
||||||
native.sleep(timeout * 1000000);
|
|
||||||
|
if not timeout then
|
||||||
|
timeout = -1
|
||||||
|
else
|
||||||
|
timeout = timeout * 1000
|
||||||
|
timeoutuptime = native.uptime() + timeout
|
||||||
end
|
end
|
||||||
if signalQueue[1] then return table.remove(signalQueue, 1) end
|
local nevts = 0
|
||||||
--print(debug.traceback())
|
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
|
end
|
||||||
|
|
||||||
function api.uptime()
|
function api.uptime()
|
||||||
|
@ -137,7 +137,7 @@ function filesystem.register(basePath)
|
|||||||
end
|
end
|
||||||
function fs.close(handle)
|
function fs.close(handle)
|
||||||
checkArg(1, handle, "number")
|
checkArg(1, handle, "number")
|
||||||
return native.fs_close()
|
return native.fs_close(handle)
|
||||||
end
|
end
|
||||||
function fs.size(path)
|
function fs.size(path)
|
||||||
checkArg(1, path, "string")
|
checkArg(1, path, "string")
|
||||||
|
@ -64,6 +64,7 @@ function main()
|
|||||||
--Setup core modules
|
--Setup core modules
|
||||||
modules.component.prepare()
|
modules.component.prepare()
|
||||||
modules.computer.prepare()
|
modules.computer.prepare()
|
||||||
|
_G.pushEvent = modules.computer.api.pushSignal
|
||||||
|
|
||||||
modules.eeprom.register()
|
modules.eeprom.register()
|
||||||
modules.filesystem.register("root")
|
modules.filesystem.register("root")
|
||||||
|
@ -164,11 +164,11 @@ sandbox = {
|
|||||||
char = utf8.char,
|
char = utf8.char,
|
||||||
charWidth = function(c)
|
charWidth = function(c)
|
||||||
checkArg(1, c, "string")
|
checkArg(1, c, "string")
|
||||||
return modules.utf8.utf8charbytes(c)
|
return modules.utf8.charbytes(c)
|
||||||
end,
|
end,
|
||||||
isWide = function(c)
|
isWide = function(c)
|
||||||
checkArg(1, c, "string")
|
checkArg(1, c, "string")
|
||||||
return modules.utf8.utf8charbytes(c) > 1
|
return modules.utf8.charbytes(c) > 1
|
||||||
end,
|
end,
|
||||||
len = utf8.len,
|
len = utf8.len,
|
||||||
lower = modules.utf8.lower,
|
lower = modules.utf8.lower,
|
||||||
|
@ -51,9 +51,11 @@ function textgpu.start()
|
|||||||
if isPaletteIndex then
|
if isPaletteIndex then
|
||||||
return --TODO: Maybe?
|
return --TODO: Maybe?
|
||||||
end
|
end
|
||||||
|
local old = foreground
|
||||||
background = tostring(math.floor(modules.color.nearest(color, mapping)))
|
background = tostring(math.floor(modules.color.nearest(color, mapping)))
|
||||||
io.write("\x1b[4" .. background .. "m")
|
io.write("\x1b[4" .. background .. "m")
|
||||||
io.flush()
|
io.flush()
|
||||||
|
return mapping[old]
|
||||||
end
|
end
|
||||||
function gpu.setForeground(color, isPaletteIndex)
|
function gpu.setForeground(color, isPaletteIndex)
|
||||||
checkArg(1, color, "number")
|
checkArg(1, color, "number")
|
||||||
@ -61,9 +63,11 @@ function textgpu.start()
|
|||||||
if isPaletteIndex then
|
if isPaletteIndex then
|
||||||
return --TODO: Maybe?
|
return --TODO: Maybe?
|
||||||
end
|
end
|
||||||
|
local old = foreground
|
||||||
foreground = tostring(math.floor(modules.color.nearest(color, mapping)))
|
foreground = tostring(math.floor(modules.color.nearest(color, mapping)))
|
||||||
io.write("\x1b[3" .. foreground .. "m")
|
io.write("\x1b[3" .. foreground .. "m")
|
||||||
io.flush()
|
io.flush()
|
||||||
|
return mapping[old]
|
||||||
end
|
end
|
||||||
function gpu.getBackground()
|
function gpu.getBackground()
|
||||||
return mapping[background], false
|
return mapping[background], false
|
||||||
@ -92,6 +96,14 @@ function textgpu.start()
|
|||||||
function gpu.getResolution()
|
function gpu.getResolution()
|
||||||
return termutils.getSize()
|
return termutils.getSize()
|
||||||
end
|
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)
|
function gpu.setResolution(w, h)
|
||||||
checkArg(1, w, "number")
|
checkArg(1, w, "number")
|
||||||
checkArg(2, h, "number")
|
checkArg(2, h, "number")
|
||||||
|
Loading…
Reference in New Issue
Block a user