From 3c2a9f50d554bb4856144787140116f67624af23 Mon Sep 17 00:00:00 2001 From: cinder <> Date: Fri, 19 Apr 2024 16:47:35 -0700 Subject: [PATCH] start work on a livedisk init.lua should run correctly in the absence of any other file (except a user-created /etc/init.lua), so things like the terminal and lua repl will come with the livedisk instead --- build.lua | 13 ++++++-- src/bin/tty.lua | 72 +++++++++++++++++++++++++++++++++++++++++++ src/livedisk/init.lua | 28 +++++++++++++++++ 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/bin/tty.lua create mode 100644 src/livedisk/init.lua diff --git a/build.lua b/build.lua index f92f2d8..3145b19 100644 --- a/build.lua +++ b/build.lua @@ -158,7 +158,16 @@ end fs.makeDirectory(outdir) exportFile('boot.lua') -fs.makeDirectory(outdir .. 'kitn-core/') -exportFile('src/init.lua', outdir .. 'kitn-core/init.lua') +fs.makeDirectory(outdir .. 'core/') +exportFile('src/init.lua', outdir .. 'core/init.lua') +fs.makeDirectory(outdir .. 'core/bin') +exportFile('src/bin/tty.lua', outdir .. 'core/bin/tty.lua') + +fs.makeDirectory(outdir .. 'livedisk/') +assert(fs.copy(outdir .. 'core/init.lua', outdir .. 'livedisk/init.lua')) +fs.makeDirectory(outdir .. 'livedisk/bin/') +assert(fs.copy(outdir .. 'core/bin/tty.lua', outdir .. 'livedisk/bin/tty.lua')) +fs.makeDirectory(outdir .. 'livedisk/etc/') +exportFile('src/livedisk/init.lua', outdir .. 'livedisk/etc/init.lua') -- vi: set ts=2: diff --git a/src/bin/tty.lua b/src/bin/tty.lua new file mode 100644 index 0000000..62b9a2b --- /dev/null +++ b/src/bin/tty.lua @@ -0,0 +1,72 @@ +local gpu, screen = ... +checkArg(1, gpu, 'string') +checkArg(2, screen, 'string') + +local keyboards = component.invoke(screen, 'getKeyboards') +local function isAttachedKeyboard(address) + checkArg(1, address, 'string') + for i, kb in ipairs(keyboards) do + if kb == address then + return i + end + end + return false +end + +gpu = component.proxy(gpu) +gpu.bind(screen) +gpu.setForeground(0xffffff) +gpu.setBackground(0x000000) +local w, h = gpu.getResolution() +gpu.fill(1, 1, w, h, ' ') +gpu.set(1, 1, string.format('%s // %s', _VERSION, _OSVERSION)) + + +local cmd, x, y = '', 1, 2 + +local function onKey(ch, code) + gpu.bind(screen) + if code == 14 then --backspace + if cmd == '' then return end + local last = cmd:sub(-1) + local widthLast = unicode.charWidth(last) + gpu.fill(x - widthLast, y, widthLast, 1, ' ') + x = x - widthLast + cmd = cmd:sub(1, -2) + elseif code == 28 then --enter + gpu.set(1, y + 1, '> ') + gpu.set(3, y + 1, cmd) + cmd = '' + x, y = 1, y + 2 + else + ch = unicode.char(ch) + gpu.set(x, y, ch) + cmd = cmd .. ch + x = x + unicode.charWidth(ch) + end +end + +local function tick(signal, addr, ...) + if signal == 'component_removed' then + if addr == screen then + return --screen went away, exit + elseif (...) == 'keyboard' then + --intentionally don't call getKeyboards here; if the screen was removed at the same time but the keyboard's + --component_removed signal was delivered first, invoking a method on the screen will crash + local idx = isAttachedKeyboard(addr) + if idx then table.remove(keyboards, idx) end + end + elseif signal == 'component_added' then + if (...) == 'keyboard' then + keyboards = component.invoke(screen, 'getKeyboards') + end + elseif signal == 'key_down' and isAttachedKeyboard(addr) then + onKey(...) + end + + return tick(computer.pullSignal()) +end + +return tick(computer.pullSignal()) + +-- vi: set ts=2: diff --git a/src/livedisk/init.lua b/src/livedisk/init.lua new file mode 100644 index 0000000..0ea28b1 --- /dev/null +++ b/src/livedisk/init.lua @@ -0,0 +1,28 @@ +--/etc/init.lua for the kitn livedisk and installer + +--find highest-tier gpu available +local bestGpu, bestMem +for addr in component.list('gpu') do + local mem = component.invoke(addr, 'totalMemory') + if mem > (bestMem or 0) then + bestGpu, bestMem = addr, mem + end +end + +assert(bestGpu, 'please install a gpu or apu to continue') + +for screen in component.list('screen') do + local proc, err = kitn.createProcess('/bin/tty.lua', bestGpu, screen) + if not proc then error('spawn for ' .. screen:sub(1, 4) .. ' failed: ' .. err) end +end + +local function tick(signal, addr, ty) + if signal == 'component_added' and ty == 'screen' then + local proc, err = kitn.createProcess('/bin/tty.lua', bestGpu, addr) + if not proc then error('spawn for ' .. screen:sub(1, 4) .. ' failed: ' .. err) end + end + + return tick(computer.pullSignal()) +end + +return tick(computer.pullSignal())