mirror of
https://github.com/kepler155c/opus
synced 2024-12-24 15:40:26 +00:00
transition to kernel
This commit is contained in:
parent
bd37b57780
commit
9de9452dd3
@ -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
|
||||
|
@ -25,7 +25,7 @@ local page = UI.Page {
|
||||
{ heading = 'Time', key = 'timestamp' },
|
||||
},
|
||||
values = multishell.getTabs(),
|
||||
sortColumn = 'title',
|
||||
sortColumn = 'uid',
|
||||
autospace = true,
|
||||
},
|
||||
accelerators = {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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'
|
@ -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)
|
11
sys/extensions/3.network.lua
Normal file
11
sys/extensions/3.network.lua
Normal 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)
|
@ -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)
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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',
|
||||
|
@ -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]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user