Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.3KB

  1. local gpus,screens,ttyn,pids = {}, {}, 0, {}
  2. local basepid = nil
  3. local shell = require "shell"
  4. local vtansi = require "vtansi"
  5. local function scan()
  6. local w,di = pcall(computer.getDeviceInfo)
  7. if w then
  8. for a,t in pairs(component.list()) do
  9. if t == "gpu" then
  10. gpus[a] = gpus[a] or {false, tonumber(di[a].capacity)}
  11. elseif t == "screen" then
  12. screens[a] = screens[a] or {false, tonumber(di[a].capacity)}
  13. end
  14. end
  15. else
  16. dprint("no getDevInfo")
  17. for a,t in pairs(component.list()) do
  18. if t == "gpu" then
  19. gpus[a] = gpus[a] or {false, 8000}
  20. elseif t == "screen" then
  21. screens[a] = screens[a] or {false, 8000}
  22. end
  23. end
  24. end
  25. end
  26. local function nextScreen(n)
  27. local rt = {}
  28. for k,v in pairs(screens) do
  29. if not v[1] then
  30. rt[v[2]] = rt[v[2]] or k
  31. end
  32. end
  33. return rt[n] or rt[8000] or rt[2000] or rt[600]
  34. end
  35. local function spawnShell(fin,fout)
  36. io.input(fin)
  37. io.output(fout):setvbuf("no")
  38. print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
  39. print((os.getenv("HOSTNAME") or "unknown") .. " on " .. fin)
  40. return os.spawn(shell.interactive, "shell: "..tostring(fin))
  41. end
  42. local function allocate()
  43. for k,v in pairs(gpus) do
  44. dprint("Setting up display "..k)
  45. local sA = nextScreen(v[2])
  46. if v[1] == false and sA then
  47. local terminals = 1
  48. local gpu = component.proxy(k)
  49. gpu.bind(sA)
  50. if gpu.buffers then
  51. gpu.freeAllBuffers()
  52. local mw, mh = gpu.maxResolution()
  53. terminals = math.floor(gpu.freeMemory() / (mw * mh))
  54. end
  55. for i = 1, terminals do
  56. local r,w = vtansi.vtsession(k,sA)
  57. devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
  58. pids["tty"..tostring(ttyn)] = {-1}
  59. ttyn = ttyn + 1
  60. end
  61. gpus[k][1] = true
  62. screens[sA][1] = true
  63. end
  64. end
  65. end
  66. function start()
  67. basepid = os.spawn(function()
  68. scan()
  69. allocate()
  70. dprint("Display setup complete.")
  71. while true do
  72. coroutine.yield()
  73. for k,v in pairs(pids) do
  74. if not os.taskInfo(v[1]) then
  75. dprint("Spawning new shell for "..k)
  76. pids[k][1] = spawnShell(v[2] or "/dev/"..k, v[3] or "/dev/"..k)
  77. pids[k][2], pids[k][3] = pids[k][2] or "/dev/"..k, pids[k][3] or "/dev/"..k
  78. coroutine.yield()
  79. end
  80. end
  81. end
  82. end,"getty")
  83. return basepid
  84. end
  85. function stop()
  86. os.kill(basepid)
  87. basepid = nil
  88. end
  89. return {start=start,stop=stop}