OC-PsychOS2/service/getty.lua
2023-06-07 00:19:09 +10:00

93 lines
2.3 KiB
Lua

local gpus,screens,ttyn,pids = {}, {}, 0, {}
local basepid = nil
local shell = require "shell"
local vtansi = require "vtansi"
local function scan()
local w,di = pcall(computer.getDeviceInfo)
if w then
for a,t in pairs(component.list()) do
if t == "gpu" then
gpus[a] = gpus[a] or {false, tonumber(di[a].capacity)}
elseif t == "screen" then
screens[a] = screens[a] or {false, tonumber(di[a].capacity)}
end
end
else
dprint("no getDevInfo")
for a,t in pairs(component.list()) do
if t == "gpu" then
gpus[a] = gpus[a] or {false, 8000}
elseif t == "screen" then
screens[a] = screens[a] or {false, 8000}
end
end
end
end
local function nextScreen(n)
local rt = {}
for k,v in pairs(screens) do
if not v[1] then
rt[v[2]] = rt[v[2]] or k
end
end
return rt[n] or rt[8000] or rt[2000] or rt[600]
end
local function spawnShell(fin,fout)
io.input(fin)
io.output(fout):setvbuf("no")
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
print((os.getenv("HOSTNAME") or "unknown") .. " on " .. fin)
return os.spawn(shell.interactive, "shell: "..tostring(fin))
end
local function allocate()
for k,v in pairs(gpus) do
dprint("Setting up display "..k)
local sA = nextScreen(v[2])
if v[1] == false and sA then
local terminals = 1
local gpu = component.proxy(k)
gpu.bind(sA)
if gpu.buffers then
gpu.freeAllBuffers()
local mw, mh = gpu.maxResolution()
terminals = math.floor(gpu.freeMemory() / (mw * mh))
end
for i = 1, terminals do
local r,w = vtansi.vtsession(k,sA)
devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
pids["tty"..tostring(ttyn)] = {-1}
ttyn = ttyn + 1
end
gpus[k][1] = true
screens[sA][1] = true
end
end
end
function start()
basepid = os.spawn(function()
scan()
allocate()
dprint("Display setup complete.")
while true do
coroutine.yield()
for k,v in pairs(pids) do
if not os.taskInfo(v[1]) then
dprint("Spawning new shell for "..k)
pids[k][1] = spawnShell(v[2] or "/dev/"..k, v[3] or "/dev/"..k)
pids[k][2], pids[k][3] = pids[k][2] or "/dev/"..k, pids[k][3] or "/dev/"..k
coroutine.yield()
end
end
end
end,"getty")
return basepid
end
function stop()
os.kill(basepid)
basepid = nil
end
return {start=start,stop=stop}