|
- 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}
|