transition to kernel

This commit is contained in:
kepler155c@gmail.com 2018-01-13 23:40:53 -05:00
parent bd37b57780
commit 9de9452dd3
15 changed files with 157 additions and 180 deletions

View File

@ -1,23 +1,21 @@
local Util = require('util')
local colors = _G.colors
local term = _G.term
local _gsub = string.gsub
local Terminal = { }
function Terminal.scrollable(win, size)
function Terminal.scrollable(win, parent)
local w, h = win.getSize()
local _, ph = parent.getSize()
local scrollPos = 0
local scp = win.setCursorPos
win.setCursorPos = function(x, y)
_G._p = y
if y > scrollPos + ph then
win.scrollTo(y - ph)
end
scp(x, y)
if y > scrollPos + h then
win.scrollTo(y - h)
elseif y < scrollPos then
win.scrollTo(y - 2)
end
end
win.scrollUp = function()
@ -29,75 +27,15 @@ function Terminal.scrollable(win, size)
end
win.scrollTo = function(p)
p = math.min(math.max(p, 0), size)
p = math.min(math.max(p, 0), h - ph)
if p ~= scrollPos then
scrollPos = p
win.reposition(1, -scrollPos + 1, w, h + size)
win.reposition(1, -scrollPos + 1, w, h)
end
end
win.reposition(1, 1, w, h + size, true)
end
function Terminal.scrollable2(ct, size)
local w, h = ct.getSize()
local win = _G.window.create(ct, 1, 1, w, h + size, true)
local oldWin = Util.shallowCopy(win)
local scrollPos = 0
local function drawScrollbar(oldPos, newPos)
local x, y = oldWin.getCursorPos()
local pos = math.floor(oldPos / size * (h - 1))
oldWin.setCursorPos(w, oldPos + pos + 1)
oldWin.write(' ')
pos = math.floor(newPos / size * (h - 1))
oldWin.setCursorPos(w, newPos + pos + 1)
oldWin.write('#')
oldWin.setCursorPos(x, y)
end
win.setCursorPos = function(x, y)
oldWin.setCursorPos(x, y)
if y > scrollPos + h then
win.scrollTo(y - h)
elseif y < scrollPos then
win.scrollTo(y - 2)
end
end
win.scrollUp = function()
win.scrollTo(scrollPos - 1)
end
win.scrollDown = function()
win.scrollTo(scrollPos + 1)
end
win.scrollTo = function(p)
p = math.min(math.max(p, 0), size)
if p ~= scrollPos then
drawScrollbar(scrollPos, p)
scrollPos = p
--local w, h = win.getSize()
win.reposition(1, -scrollPos + 1, w, h + size)
end
end
win.clear = function()
oldWin.clear()
scrollPos = 0
end
drawScrollbar(0, 0)
return win
end
function Terminal.toGrayscale(ct)
local scolors = {
[ colors.white ] = colors.white,
[ colors.orange ] = colors.lightGray,
@ -183,7 +121,7 @@ function Terminal.mirror(ct, dt)
if dt[k] then
dt[k](...)
end
return unpack(ret)
return table.unpack(ret)
end
end
end

View File

@ -25,7 +25,7 @@ local page = UI.Page {
{ heading = 'Time', key = 'timestamp' },
},
values = multishell.getTabs(),
sortColumn = 'title',
sortColumn = 'uid',
autospace = true,
},
accelerators = {

View File

@ -14,7 +14,7 @@ local shell = _ENV.shell
local term = _G.term
local window = _G.window
local parentTerm = term.current()
local parentTerm = kernel.terminal.parent -- term.current()
local w,h = parentTerm.getSize()
local overviewId
local tabsDirty = false
@ -128,6 +128,7 @@ function multishell.openTab(tab)
end
printError('Press enter to close')
tab.isDead = true
tab.hidden = false
while true do
local e, code = os.pullEventRaw('key')
if e == 'terminate' or e == 'key' and code == keys.enter then
@ -137,7 +138,7 @@ function multishell.openTab(tab)
end
end)
kernel.run(routine)
kernel.launch(routine)
if tab.focused then
multishell.setFocus(tab.uid)

View File

@ -26,7 +26,6 @@ if options.title then
multishell.setTitle(multishell.getCurrent(), options.title)
end
print('connecting...')
local socket, msg = Socket.connect(remoteId, 23)
if not socket then
@ -44,6 +43,7 @@ socket:write({
height = h,
isColor = ct.isColor(),
program = args,
pos = { ct.getCursorPos() },
})
Event.addRoutine(function()
@ -58,8 +58,8 @@ Event.addRoutine(function()
end
end)
ct.clear()
ct.setCursorPos(1, 1)
--ct.clear()
--ct.setCursorPos(1, 1)
local filter = Util.transpose {
'char', 'paste', 'key', 'key_up', 'terminate',
@ -77,10 +77,10 @@ while true do
end
if not socket.connected then
print()
print('Connection lost')
print('Press enter to exit')
pcall(read)
-- print()
-- print('Connection lost')
-- print('Press enter to exit')
-- pcall(read)
break
end
end

View File

@ -23,6 +23,7 @@ local terminal = term.current()
local w, h = term.getSize()
local kernelWindow = window.create(terminal, 1, 1, w, h, false)
term.redirect(kernelWindow)
kernelWindow.parent = terminal
local splashWindow
local function showStatus(status, ...)
@ -152,11 +153,19 @@ local function createShellEnvironment(Util)
sandboxEnv.LUA_PATH = config.lua_path
end
local function loadExtensions(Util)
local function loadExtensions()
local dir = 'sys/extensions'
for _,file in ipairs(fs.list(dir)) do
local files = fs.list(dir)
table.sort(files)
for _,file in ipairs(files) do
showStatus('Loading ' .. file)
local s, m = Util.run(makeEnv(), 'sys/apps/shell', fs.combine(dir, file))
local s, m = kernel.run({
title = file:match('%d.(%S+).lua'),
hidden = true,
path = 'sys/apps/shell',
args = { fs.combine(dir, file) },
terminal = kernelWindow,
})
if not s then
error(m)
end
@ -191,7 +200,7 @@ local s, m = pcall(function()
showStatus('Reticulating splines')
Util.run(makeEnv(), 'sys/kernel.lua')
loadExtensions(Util)
loadExtensions()
showStatus('Mounting file systems')
fs.loadTab('usr/etc/fstab')
@ -199,15 +208,15 @@ local s, m = pcall(function()
splashWindow.setVisible(false)
if args[1] then
kernelWindow.setVisible(true)
kernelWindow.setVisible(false)
end
--term.clear()
--term.redirect(terminal)
_G.kernel.run(_G.kernel.newRoutine({
term.redirect(terminal)
_G.kernel.run({
path = 'sys/apps/shell',
args = args[1] and args or { 'sys/apps/multishell' },
terminal = terminal,
}))
})
end)
if not s then
@ -217,7 +226,7 @@ if not s then
_G.printError(m .. '\n')
else
if _G.kernel.routines[1] then
_G.kernel.start(terminal, kernelWindow)
_G.kernel.start()
end
end

View File

@ -4,7 +4,7 @@ local Peripheral = require('peripheral')
_G.device = Peripheral.getList()
_G.device.terminal = _G.term.current()
_G.device.terminal = _G.kernel.terminal.parent
_G.device.terminal.side = 'terminal'
_G.device.terminal.type = 'terminal'
_G.device.terminal.name = 'terminal'

View File

@ -3,45 +3,40 @@ _G.requireInjector()
local Event = require('event')
local Util = require('util')
_G.network = { }
local device = _G.device
local fs = _G.fs
local multishell = _ENV.multishell
local network = _G.network
local os = _G.os
local printError = _G.printError
if not device.wireless_modem then
return
end
if multishell and multishell.setTitle then
multishell.setTitle(multishell.getCurrent(), 'Net Daemon')
return
end
print('Net daemon started')
for _,file in pairs(fs.list('sys/network')) do
local fn, msg = Util.run(_ENV, 'sys/network/' .. file)
if not fn then
printError(msg)
end
local fn, msg = Util.run(_ENV, 'sys/network/' .. file)
if not fn then
printError(msg)
end
end
Event.on('device_detach', function()
if not device.wireless_modem then
Event.exitPullEvents()
end
if not device.wireless_modem then
Event.exitPullEvents()
end
end)
Event.pullEvents()
for _,c in pairs(network) do
c.active = false
os.queueEvent('network_detach', c)
c.active = false
os.queueEvent('network_detach', c)
end
os.queueEvent('network_down')
Event.pullEvent('network_down')
Util.clear(_G.network)
print('Net daemon stopped')
Util.clear(network)

View File

@ -0,0 +1,11 @@
local kernel = _G.kernel
kernel.hook('device_attach', function(_, eventData)
if eventData[1] == 'wireless_modem' then
kernel.run({
title = 'Net daemon',
path = 'sys/extensions/netdaemon.lua',
hidden = true,
})
end
end)

View File

@ -1,13 +0,0 @@
local kernel = _G.kernel
_G.network = { }
kernel.hook('device_attach', function(_, eventData)
if eventData[1] == 'wireless_modem' then
local routine = kernel.newRoutine({
path = 'sys/services/network.lua',
hidden = true
})
kernel.run(routine)
end
end)

View File

@ -12,6 +12,7 @@ _G.kernel = {
hooks = { },
routines = { },
terminal = _G.term.current(),
window = _G.term.current(),
}
local kernel = _G.kernel
@ -25,7 +26,7 @@ local focusedRoutineEvents = Util.transpose {
}
_G.debug = function(pattern, ...)
local oldTerm = term.redirect(kernel.terminal)
local oldTerm = term.redirect(kernel.window)
Util.print(pattern, ...)
term.redirect(oldTerm)
end
@ -65,7 +66,7 @@ function Routine:resume(event, ...)
end
if not self.filter or self.filter == event or event == "terminate" then
term.redirect(self.terminal)
local previousTerm = term.redirect(self.terminal)
local previous = kernel.running
kernel.running = self -- stupid shell set title
@ -73,6 +74,8 @@ function Routine:resume(event, ...)
kernel.running = previous
self.terminal = term.current()
term.redirect(previousTerm)
if ok then
self.filter = result
else
@ -103,16 +106,15 @@ function kernel.newRoutine(args)
local routine = setmetatable(args, { __index = Routine })
routine.uid = kernel.UID
routine.timestamp = os.clock()
routine.env = args.env or Util.shallowCopy(sandboxEnv)
routine.terminal = args.terminal or kernel.terminal
routine.window = args.window or kernel.window
return routine
end
function kernel.run(routine)
routine.timestamp = os.clock()
routine.terminal = routine.terminal or kernel.terminal
routine.window = routine.window or kernel.window
routine.env = Util.shallowCopy(routine.env or sandboxEnv)
function kernel.launch(routine)
routine.co = routine.co or coroutine.create(function()
local result, err
@ -131,11 +133,15 @@ function kernel.run(routine)
table.insert(kernel.routines, routine)
local previousTerm = term.current()
local s, m = routine:resume()
term.redirect(previousTerm)
return s, m
return not s and s or routine.uid, m
end
function kernel.run(args)
local routine = kernel.newRoutine(args)
kernel.launch(routine)
return routine
end
function kernel.raise(uid)
@ -207,10 +213,7 @@ function kernel.event(event, eventData)
end
end
function kernel.start(terminal, kernelWindow)
kernel.window = kernelWindow
kernel.terminal = kernel.window
function kernel.start()
local s, m = pcall(function()
repeat
local eventData = { os.pullEventRaw() }
@ -221,9 +224,8 @@ function kernel.start(terminal, kernelWindow)
kernel.window.setVisible(true)
if not s then
term.redirect(kernel.window)
print('\nCrash detected\n')
_G.printError(m)
end
term.redirect(terminal)
term.redirect(kernel.terminal)
end

View File

@ -2,15 +2,11 @@ local Event = require('event')
local Socket = require('socket')
local Util = require('util')
local multishell = _ENV.multishell
local os = _G.os
local term = _G.term
local kernel = _G.kernel
local term = _G.term
local window = _G.window
local function telnetHost(socket)
_G.requireInjector()
local Event = require('event')
local methods = { 'clear', 'clearLine', 'setCursorPos', 'write', 'blit',
'setTextColor', 'setTextColour', 'setBackgroundColor',
'setBackgroundColour', 'scroll', 'setCursorBlink', }
@ -21,11 +17,12 @@ local function telnetHost(socket)
return
end
socket.term = term.current()
local oldWindow = Util.shallowCopy(socket.term)
local win = window.create(_G.device.terminal, 1, 1, termInfo.width, termInfo.height, false)
win.setCursorPos(table.unpack(termInfo.pos))
for _,k in pairs(methods) do
socket.term[k] = function(...)
local fn = win[k]
win[k] = function(...)
if not socket.queue then
socket.queue = { }
@ -39,34 +36,36 @@ local function telnetHost(socket)
f = k,
args = { ... },
})
oldWindow[k](...)
fn(...)
end
end
socket.term.getSize = function()
return termInfo.width, termInfo.height
end
local shellThread = Event.addRoutine(function()
os.run(_ENV, 'sys/apps/shell', table.unpack(termInfo.program))
Event.exitPullEvents()
end)
local shellThread = kernel.run({
terminal = win,
window = win,
title = 'Telnet client',
hidden = true,
co = coroutine.create(function()
Util.run(_ENV, 'sys/apps/shell', table.unpack(termInfo.program))
if socket.queue then
socket:write(socket.queue)
end
socket:close()
end)
})
Event.addRoutine(function()
while true do
local data = socket:read()
if not data then
Event.exitPullEvents()
shellThread:resume('terminate')
break
end
local previousTerm = term.current()
shellThread:resume(table.unpack(data))
term.redirect(previousTerm)
end
end)
Event.pullEvents()
socket:close()
shellThread:terminate()
end
Event.addRoutine(function()
@ -76,11 +75,8 @@ Event.addRoutine(function()
print('telnet: connection from ' .. socket.dhost)
multishell.openTab({
fn = telnetHost,
args = { socket },
title = 'Telnet Client',
hidden = true,
})
Event.addRoutine(function()
telnetHost(socket)
end)
end
end)

View File

@ -3,7 +3,7 @@ local Socket = require('socket')
local Util = require('util')
local os = _G.os
local terminal = _ENV.multishell.term
local terminal = _G.device.terminal
local function vncHost(socket)
local methods = { 'blit', 'clear', 'clearLine', 'setCursorPos', 'write',

View File

@ -11,22 +11,60 @@ local keyboard = _G.device.keyboard
local multishell = _ENV.multishell
local os = _G.os
local term = _G.term
local window = _G.window
if multishell and multishell.setTitle then
multishell.setTitle(multishell.getCurrent(), 'System Log')
end
-- jump through a lot of hoops to get around window api limitations
-- mainly failing to provide access to window buffer or knowledge of parent
-- need: window.getParent()
-- window.copy(target)
local terminal = _G.kernel.terminal.parent
local w, h = kernel.window.getSize()
local win = window.create(kernel.window, 1, 1, w, h + 50, false)
-- copy windows contents from parent window to child
local oblit, oscp = terminal.blit, terminal.setCursorPos
kernel.window.setVisible(false)
terminal.blit = function(...)
win.blit(...)
end
terminal.setCursorPos = function(...)
win.setCursorPos(...)
end
kernel.window.setVisible(true)
-- position and resize window for multishell (but don't update screen)
terminal.blit = function() end
terminal.setCursorPos = function() end
kernel.window.reposition(1, 2, w, h - 1)
-- restore original terminal
terminal.blit = oblit
terminal.setCursorPos = oscp
-- add scrolling methods
Terminal.scrollable(win, kernel.window)
-- update kernel with new window, set this tab with the new kernal window
local routine = kernel.getCurrent()
local previousId
kernel.window.reposition(1, 2)
Terminal.scrollable(kernel.window, 50)
routine.terminal = kernel.window
routine.window = kernel.window
for _,r in pairs(kernel.routines) do
if r.terminal == kernel.terminal then
r.terminal = win
r.window = win
end
end
kernel.terminal = win
kernel.window = win
routine.terminal = win
routine.window = win
term.redirect(routine.window)
local previousId
kernel.hook('mouse_scroll', function(_, eventData)
local dir, y = eventData[1], eventData[3]