epoll event pulling, basic input

This commit is contained in:
Łukasz Magiera 2016-01-14 22:44:49 +01:00
parent ffc3705ea8
commit 47656b9240
10 changed files with 250 additions and 15 deletions

View File

@ -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
View 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;
}

View File

@ -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,7 +18,7 @@
#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;
@ -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");
} }

View File

@ -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");

View File

@ -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);

View File

@ -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()

View File

@ -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")

View File

@ -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")

View File

@ -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,

View File

@ -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")