package cleanup
This commit is contained in:
6
monitor/.package
Normal file
6
monitor/.package
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
title = 'Various monitor related programs',
|
||||
repository = 'kepler155c/opus-apps/{{OPUS_BRANCH}}/monitor',
|
||||
description = [[Mirror terminal to monitor, Monitor Window Manager (mwm), and more]],
|
||||
licence = 'MIT',
|
||||
}
|
||||
13
monitor/etc/opus.db
Normal file
13
monitor/etc/opus.db
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
[ "58ec8d6e36e346d9f42eb43935652e3e58e2c829" ] = {
|
||||
title = "Mwm",
|
||||
category = "Apps",
|
||||
icon = "\030f\031f \0304 \
|
||||
\030f\031dshell]\0304\0314 \
|
||||
\0304\031f ",
|
||||
iconExt = "\030 \031f\0305\031f\155\030f\128\031d\152\140\030d\031f\151\030f\128\128\0304\0314\128\
|
||||
\030 \031f\030f\0315\152\129\030d\031f\141\030f\031d\153\030d\031f\149\030f\031d\131\148\0304\0314\128\
|
||||
\030 \031f\0304\031f\131\131\131\131\131\131\131\030e\0314\131",
|
||||
run = "mwm.lua usr/config/mwm",
|
||||
},
|
||||
}
|
||||
52
monitor/mirror.lua
Normal file
52
monitor/mirror.lua
Normal file
@@ -0,0 +1,52 @@
|
||||
_G.requireInjector()
|
||||
|
||||
local Terminal = require('terminal')
|
||||
local Util = require('util')
|
||||
|
||||
local shell = _ENV.shell
|
||||
local term = _G.term
|
||||
|
||||
local options = {
|
||||
scale = { arg = 's', type = 'flag', value = false,
|
||||
desc = 'Set monitor to .5 text scaling' },
|
||||
resize = { arg = 'r', type = 'flag', value = false,
|
||||
desc = 'Resize terminal to monitor size' },
|
||||
execute = { arg = 'e', type = 'string',
|
||||
desc = 'Execute a program' },
|
||||
monitor = { arg = 'm', type = 'string', value = 'monitor',
|
||||
desc = 'Name of monitor' },
|
||||
help = { arg = 'h', type = 'flag', value = false,
|
||||
desc = 'Displays the options' },
|
||||
}
|
||||
|
||||
local args = { ... }
|
||||
if not Util.getOptions(options, args) then
|
||||
return
|
||||
end
|
||||
|
||||
local mon = _G.device[options.monitor.value]
|
||||
if not mon then
|
||||
error('mirror: Invalid device')
|
||||
end
|
||||
|
||||
mon.clear()
|
||||
|
||||
if options.scale.value then
|
||||
mon.setTextScale(.5)
|
||||
end
|
||||
mon.setCursorPos(1, 1)
|
||||
|
||||
local oterm = Terminal.copy(term.current())
|
||||
Terminal.mirror(term.current(), mon)
|
||||
|
||||
if options.resize.value then
|
||||
term.current().getSize = mon.getSize
|
||||
end
|
||||
|
||||
if options.execute.value then
|
||||
-- TODO: allow args to be passed
|
||||
shell.run(options.execute.value) -- unpack(args))
|
||||
Terminal.copy(oterm, term.current())
|
||||
|
||||
mon.setCursorBlink(false)
|
||||
end
|
||||
88
monitor/mirrorClient.lua
Normal file
88
monitor/mirrorClient.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
_G.requireInjector()
|
||||
|
||||
local Event = require('event')
|
||||
local Logger = require('logger')
|
||||
local Socket = require('socket')
|
||||
local Util = require('util')
|
||||
|
||||
local multishell = _ENV.multishell
|
||||
local os = _G.os
|
||||
|
||||
Logger.setScreenLogging()
|
||||
|
||||
local remoteId
|
||||
local args = { ... }
|
||||
if #args == 1 then
|
||||
remoteId = tonumber(args[1])
|
||||
else
|
||||
print('Enter host ID')
|
||||
remoteId = tonumber(_G.read())
|
||||
end
|
||||
|
||||
if not remoteId then
|
||||
error('Syntax: mirrorClient <host ID>')
|
||||
end
|
||||
|
||||
local function wrapTerm(socket)
|
||||
local methods = { 'blit', 'clear', 'clearLine', 'setCursorPos', 'write',
|
||||
'setTextColor', 'setTextColour', 'setBackgroundColor',
|
||||
'setBackgroundColour', 'scroll', 'setCursorBlink', }
|
||||
|
||||
socket.term = multishell.term
|
||||
socket.oldTerm = Util.shallowCopy(socket.term)
|
||||
|
||||
for _,k in pairs(methods) do
|
||||
socket.term[k] = function(...)
|
||||
if not socket.queue then
|
||||
socket.queue = { }
|
||||
Event.onTimeout(0, function()
|
||||
if socket.queue then
|
||||
socket:write(socket.queue)
|
||||
socket.queue = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
table.insert(socket.queue, {
|
||||
f = k,
|
||||
args = { ... },
|
||||
})
|
||||
socket.oldTerm[k](...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while true do
|
||||
print('connecting...')
|
||||
local socket
|
||||
|
||||
while true do
|
||||
socket = Socket.connect(remoteId, 5901)
|
||||
if socket then
|
||||
break
|
||||
end
|
||||
os.sleep(3)
|
||||
end
|
||||
|
||||
print('connected')
|
||||
|
||||
wrapTerm(socket)
|
||||
|
||||
os.queueEvent('term_resize')
|
||||
|
||||
while true do
|
||||
local e = Event.pullEvent()
|
||||
if e[1] == 'terminate' then
|
||||
break
|
||||
end
|
||||
if not socket.connected then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(socket.oldTerm) do
|
||||
socket.term[k] = v
|
||||
end
|
||||
|
||||
socket:close()
|
||||
|
||||
end
|
||||
52
monitor/mirrorHost.lua
Normal file
52
monitor/mirrorHost.lua
Normal file
@@ -0,0 +1,52 @@
|
||||
_G.requireInjector()
|
||||
|
||||
local Event = require('event')
|
||||
local Logger = require('logger')
|
||||
local Socket = require('socket')
|
||||
|
||||
local colors = _G.colors
|
||||
local term = _G.term
|
||||
|
||||
Logger.setScreenLogging()
|
||||
|
||||
local mon = term.current()
|
||||
local args = { ... }
|
||||
if args[1] then
|
||||
mon = _G.device[args[1]]
|
||||
end
|
||||
|
||||
if not mon then
|
||||
error('Invalid monitor')
|
||||
end
|
||||
|
||||
mon.setBackgroundColor(colors.black)
|
||||
mon.clear()
|
||||
|
||||
while true do
|
||||
local socket = Socket.server(5901)
|
||||
|
||||
print('mirror: connection from ' .. socket.dhost)
|
||||
|
||||
Event.addRoutine(function()
|
||||
while true do
|
||||
local data = socket:read()
|
||||
if not data then
|
||||
break
|
||||
end
|
||||
for _,v in ipairs(data) do
|
||||
mon[v.f](unpack(v.args))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
while true do
|
||||
Event.pullEvent()
|
||||
if not socket.connected then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
print('connection lost')
|
||||
|
||||
socket:close()
|
||||
end
|
||||
538
monitor/mwm.lua
Normal file
538
monitor/mwm.lua
Normal file
@@ -0,0 +1,538 @@
|
||||
local injector = _G.requireInjector or load(http.get('https://raw.githubusercontent.com/kepler155c/opus/develop/sys/apis/injector.lua').readAll())()
|
||||
injector()
|
||||
|
||||
local Canvas = require('ui.canvas')
|
||||
local Util = require('util')
|
||||
|
||||
local colors = _G.colors
|
||||
local os = _G.os
|
||||
local peripheral = _G.peripheral
|
||||
local printError = _G.printError
|
||||
local shell = _ENV.shell
|
||||
local term = _G.term
|
||||
local window = _G.window
|
||||
|
||||
local function syntax()
|
||||
printError('Syntax:')
|
||||
error('mwm sessionName [monitor]')
|
||||
end
|
||||
|
||||
local args = { ... }
|
||||
local UID = 0
|
||||
local multishell = { }
|
||||
local processes = { }
|
||||
local parentTerm = term.current()
|
||||
local sessionFile = args[1] or 'usr/config/mwm'
|
||||
local running
|
||||
local monitor
|
||||
|
||||
local defaultEnv = Util.shallowCopy(_ENV)
|
||||
defaultEnv.multishell = multishell
|
||||
if args[3] then
|
||||
monitor = _G.device[args[3]]
|
||||
elseif args[2] then
|
||||
monitor = peripheral.wrap(args[2]) or syntax()
|
||||
else
|
||||
monitor = peripheral.find('monitor') or syntax()
|
||||
end
|
||||
|
||||
monitor.setTextScale(.5)
|
||||
monitor.clear()
|
||||
|
||||
local monDim, termDim = { }, { }
|
||||
monDim.width, monDim.height = monitor.getSize()
|
||||
termDim.width, termDim.height = parentTerm.getSize()
|
||||
|
||||
local function nextUID()
|
||||
UID = UID + 1
|
||||
return UID
|
||||
end
|
||||
|
||||
local function write(win, x, y, text)
|
||||
win.setCursorPos(x, y)
|
||||
win.write(text)
|
||||
end
|
||||
|
||||
local function redraw()
|
||||
monitor.clear()
|
||||
for k,process in ipairs(processes) do
|
||||
process.container.canvas:dirty()
|
||||
process:focus(k == #processes)
|
||||
end
|
||||
end
|
||||
|
||||
local function getProcessAt(x, y)
|
||||
for k = #processes, 1, -1 do
|
||||
local process = processes[k]
|
||||
if x >= process.x and
|
||||
y >= process.y and
|
||||
x <= process.x + process.width - 1 and
|
||||
y <= process.y + process.height - 1 then
|
||||
return k, process
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[ A runnable process ]]--
|
||||
local Process = { }
|
||||
|
||||
function Process:new(args)
|
||||
|
||||
args.env = args.env or Util.shallowCopy(defaultEnv)
|
||||
args.width = args.width or termDim.width
|
||||
args.height = args.height or termDim.height
|
||||
|
||||
local self = setmetatable({
|
||||
uid = nextUID(),
|
||||
x = args.x or 1,
|
||||
y = args.y or 1,
|
||||
width = args.width + 2,
|
||||
height = args.height + 3,
|
||||
path = args.path,
|
||||
args = args.args or { },
|
||||
title = args.title or 'shell',
|
||||
}, { __index = Process })
|
||||
|
||||
self:adjustDimensions()
|
||||
|
||||
self.container = window.create(monitor, self.x, self.y, self.width, self.height, false)
|
||||
self.window = window.create(self.container, 2, 3, args.width, args.height, true)
|
||||
|
||||
self.terminal = self.window
|
||||
Canvas.convertWindow(self.container, monitor, self.x, self.y)
|
||||
|
||||
self.co = coroutine.create(function()
|
||||
|
||||
local result, err
|
||||
|
||||
if args.fn then
|
||||
result, err = Util.runFunction(args.env, args.fn, table.unpack(self.args))
|
||||
elseif args.path then
|
||||
result, err = Util.run(args.env, args.path, table.unpack(self.args))
|
||||
end
|
||||
|
||||
if not result and err and err ~= 'Terminated' then
|
||||
printError('\n' .. tostring(err))
|
||||
os.pullEventRaw('terminate')
|
||||
end
|
||||
multishell.removeProcess(self)
|
||||
end)
|
||||
|
||||
self:focus(false)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Process:focus(focused)
|
||||
if focused then
|
||||
self.container.setBackgroundColor(colors.yellow)
|
||||
else
|
||||
self.container.setBackgroundColor(colors.gray)
|
||||
end
|
||||
self.container.setTextColor(colors.black)
|
||||
write(self.container, 2, 2, string.rep(' ', self.width - 2))
|
||||
write(self.container, 3, 2, self.title)
|
||||
write(self.container, self.width - 2, 2, '*')
|
||||
|
||||
if focused then
|
||||
self.window.restoreCursor()
|
||||
elseif self.showSizers then
|
||||
self:drawSizers(false)
|
||||
end
|
||||
end
|
||||
|
||||
function Process:drawSizers(showSizers)
|
||||
|
||||
local sizeChars = {
|
||||
'\135', '\139', '\141', '\142'
|
||||
}
|
||||
|
||||
if Util.getVersion() < 1.8 then
|
||||
sizeChars = {
|
||||
'#', '#', '#', '#'
|
||||
}
|
||||
end
|
||||
|
||||
self.showSizers = showSizers
|
||||
|
||||
self.container.setBackgroundColor(colors.black)
|
||||
self.container.setTextColor(colors.white)
|
||||
|
||||
if self.showSizers then
|
||||
write(self.container, 1, 1, sizeChars[1])
|
||||
write(self.container, self.width, 1, sizeChars[2])
|
||||
write(self.container, 1, self.height, sizeChars[3])
|
||||
write(self.container, self.width, self.height, sizeChars[4])
|
||||
|
||||
self.container.setTextColor(colors.yellow)
|
||||
write(self.container, 1, 3, '+')
|
||||
write(self.container, 1, 5, '-')
|
||||
write(self.container, 3, 1, '+')
|
||||
write(self.container, 5, 1, '-')
|
||||
|
||||
local str = string.format('%d x %d', self.width - 2, self.height - 3)
|
||||
write(self.container, (self.width - #str) / 2, 1, str)
|
||||
|
||||
else
|
||||
write(self.container, 1, 1, string.rep(' ', self.width))
|
||||
write(self.container, self.width, 1, ' ')
|
||||
write(self.container, 1, self.height, ' ')
|
||||
write(self.container, self.width, self.height, ' ')
|
||||
write(self.container, 1, 3, ' ')
|
||||
write(self.container, 1, 5, ' ')
|
||||
end
|
||||
end
|
||||
|
||||
function Process:adjustDimensions()
|
||||
|
||||
self.width = math.min(self.width, monDim.width)
|
||||
self.height = math.min(self.height, monDim.height)
|
||||
|
||||
self.x = math.max(1, self.x)
|
||||
self.y = math.max(1, self.y)
|
||||
self.x = math.min(self.x, monDim.width - self.width + 1)
|
||||
self.y = math.min(self.y, monDim.height - self.height + 1)
|
||||
end
|
||||
|
||||
function Process:reposition()
|
||||
|
||||
self:adjustDimensions()
|
||||
self.container.reposition(self.x, self.y, self.width, self.height)
|
||||
self.container.setBackgroundColor(colors.black)
|
||||
self.container.clear()
|
||||
|
||||
self.window.reposition(2, 3, self.width - 2, self.height - 3)
|
||||
|
||||
redraw()
|
||||
end
|
||||
|
||||
function Process:click(x, y)
|
||||
if y == 2 then -- title bar
|
||||
if x == self.width - 2 then
|
||||
self:resume('terminate')
|
||||
else
|
||||
self:drawSizers(not self.showSizers)
|
||||
end
|
||||
|
||||
elseif x == 1 or y == 1 then -- sizers
|
||||
self:resizeClick(x, y)
|
||||
|
||||
elseif x > 1 and x < self.width then
|
||||
if self.showSizers then
|
||||
self:drawSizers(false)
|
||||
end
|
||||
self:resume('mouse_click', 1, x - 1, y - 2)
|
||||
self:resume('mouse_up', 1, x - 1, y - 2)
|
||||
end
|
||||
end
|
||||
|
||||
function Process:resizeClick(x, y)
|
||||
if x == 1 and y == 3 then
|
||||
self.height = self.height + 1
|
||||
elseif x == 1 and y == 5 then
|
||||
self.height = self.height - 1
|
||||
elseif x == 3 and y == 1 then
|
||||
self.width = self.width + 1
|
||||
elseif x == 5 and y == 1 then
|
||||
self.width = self.width - 1
|
||||
else
|
||||
return
|
||||
end
|
||||
self:reposition()
|
||||
self:resume('term_resize')
|
||||
self:drawSizers(true)
|
||||
multishell.saveSession(sessionFile)
|
||||
end
|
||||
|
||||
function Process:resume(event, ...)
|
||||
if coroutine.status(self.co) == 'dead' then
|
||||
return
|
||||
end
|
||||
|
||||
if not self.filter or self.filter == event or event == "terminate" then
|
||||
term.redirect(self.terminal)
|
||||
|
||||
local previous = running
|
||||
running = self -- stupid shell set title
|
||||
local ok, result = coroutine.resume(self.co, event, ...)
|
||||
running = previous
|
||||
|
||||
self.terminal = term.current()
|
||||
if ok then
|
||||
self.filter = result
|
||||
else
|
||||
printError(result)
|
||||
end
|
||||
return ok, result
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Install a multishell manager for the monitor ]]--
|
||||
function multishell.getFocus()
|
||||
return processes[#processes].uid
|
||||
end
|
||||
|
||||
function multishell.setFocus(uid)
|
||||
local process = Util.find(processes, 'uid', uid)
|
||||
|
||||
if process then
|
||||
local lastFocused = processes[#processes]
|
||||
if lastFocused ~= process then
|
||||
|
||||
if lastFocused then
|
||||
lastFocused:focus(false)
|
||||
end
|
||||
|
||||
Util.removeByValue(processes, process)
|
||||
table.insert(processes, process)
|
||||
multishell.restack()
|
||||
|
||||
process:focus(true)
|
||||
process.container.canvas:dirty()
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function multishell.getTitle(uid)
|
||||
local process = Util.find(processes, 'uid', uid)
|
||||
if process then
|
||||
return process.title
|
||||
end
|
||||
end
|
||||
|
||||
function multishell.setTitle(uid, title)
|
||||
local process = Util.find(processes, 'uid', uid)
|
||||
if process then
|
||||
process.title = title or ''
|
||||
process:focus(process == processes[#processes])
|
||||
end
|
||||
end
|
||||
|
||||
function multishell.getCurrent()
|
||||
if running then
|
||||
return running.uid
|
||||
end
|
||||
end
|
||||
|
||||
function multishell.getCount()
|
||||
return #processes
|
||||
end
|
||||
|
||||
function multishell.getTabs()
|
||||
return processes
|
||||
end
|
||||
|
||||
function multishell.launch(env, file, ...)
|
||||
return multishell.openTab({
|
||||
path = file,
|
||||
env = env,
|
||||
title = 'shell',
|
||||
args = { ... },
|
||||
})
|
||||
end
|
||||
|
||||
function multishell.openTab(tabInfo)
|
||||
local process = Process:new(tabInfo)
|
||||
|
||||
table.insert(processes, 1, process)
|
||||
multishell.restack()
|
||||
|
||||
process.container.setVisible(true)
|
||||
|
||||
local previousTerm = term.current()
|
||||
process:resume()
|
||||
term.redirect(previousTerm)
|
||||
|
||||
multishell.saveSession(sessionFile)
|
||||
return process.uid
|
||||
end
|
||||
|
||||
function multishell.restack() -- reset the stacking order
|
||||
for k,v in ipairs(processes) do
|
||||
v.container.canvas.layers = { }
|
||||
for l = k + 1, #processes do
|
||||
table.insert(v.container.canvas.layers, processes[l].container.canvas)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function multishell.removeProcess(process)
|
||||
Util.removeByValue(processes, process)
|
||||
multishell.restack()
|
||||
multishell.saveSession(sessionFile)
|
||||
redraw()
|
||||
end
|
||||
|
||||
function multishell.saveSession(filename)
|
||||
local t = { }
|
||||
for _,process in pairs(processes) do
|
||||
if process.path and not process.isShell then
|
||||
table.insert(t, {
|
||||
x = process.x,
|
||||
y = process.y,
|
||||
width = process.width - 2,
|
||||
height = process.height - 3,
|
||||
path = process.path,
|
||||
args = process.args,
|
||||
})
|
||||
end
|
||||
end
|
||||
Util.writeTable(filename, t)
|
||||
end
|
||||
|
||||
function multishell.loadSession(filename)
|
||||
local config = Util.readTable(filename)
|
||||
if config then
|
||||
for _,v in pairs(config) do
|
||||
multishell.openTab(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function multishell.stop()
|
||||
multishell._stop = true
|
||||
end
|
||||
|
||||
function multishell.start()
|
||||
while not multishell._stop do
|
||||
|
||||
local event = { os.pullEventRaw() }
|
||||
|
||||
if event[1] == 'terminate' then
|
||||
local focused = processes[#processes]
|
||||
if focused.isShell then
|
||||
focused:resume('terminate')
|
||||
else
|
||||
break
|
||||
end
|
||||
|
||||
elseif event[1] == 'monitor_touch' then
|
||||
local x, y = event[3], event[4]
|
||||
|
||||
local key, process = getProcessAt(x, y)
|
||||
if process then
|
||||
if key ~= #processes then
|
||||
multishell.setFocus(process.uid)
|
||||
end
|
||||
process:click(x - process.x + 1, y - process.y + 1)
|
||||
|
||||
else
|
||||
process = processes[#processes]
|
||||
if process and process.showSizers then
|
||||
process.x = math.floor(x - (process.width) / 2)
|
||||
process.y = y
|
||||
process:reposition()
|
||||
process:drawSizers(true)
|
||||
multishell.saveSession(sessionFile)
|
||||
end
|
||||
end
|
||||
|
||||
elseif event[1] == 'mouse_click' or
|
||||
event[1] == 'mouse_up' then
|
||||
|
||||
local focused = processes[#processes]
|
||||
if not focused.isShell then
|
||||
multishell.setFocus(1) -- shell is always 1
|
||||
else
|
||||
focused:resume(unpack(event))
|
||||
end
|
||||
|
||||
elseif event[1] == 'char' or
|
||||
event[1] == 'key' or
|
||||
event[1] == 'key_up' or
|
||||
event[1] == 'paste' then
|
||||
|
||||
local focused = processes[#processes]
|
||||
if focused then
|
||||
focused:resume(unpack(event))
|
||||
end
|
||||
|
||||
else
|
||||
for _,process in pairs(Util.shallowCopy(processes)) do
|
||||
process:resume(unpack(event))
|
||||
end
|
||||
end
|
||||
|
||||
local didRedraw
|
||||
for _,process in pairs(processes) do
|
||||
if process.container.canvas:isDirty() then
|
||||
process.container.canvas:redraw(monitor)
|
||||
didRedraw = true
|
||||
end
|
||||
end
|
||||
|
||||
local focused = processes[#processes]
|
||||
if didRedraw and focused then
|
||||
--focused.container.canvas:dirty()
|
||||
--focused.container.canvas:redraw(parentTerm)
|
||||
focused.window.restoreCursor()
|
||||
local cx, cy = focused.container.getCursorPos()
|
||||
monitor.setCursorPos(
|
||||
focused.container.canvas.x + cx - 1,
|
||||
focused.container.canvas.y + cy - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Special shell process for launching programs ]]--
|
||||
local function addShell()
|
||||
|
||||
local process = setmetatable({
|
||||
x = monDim.width,
|
||||
y = monDim.height,
|
||||
width = 1,
|
||||
height = 1,
|
||||
isShell = true,
|
||||
uid = nextUID(),
|
||||
title = 'Terminal',
|
||||
}, { __index = Process })
|
||||
|
||||
function process:focus(focused)
|
||||
self.window.setVisible(focused)
|
||||
if focused then
|
||||
self.window.restoreCursor()
|
||||
else
|
||||
parentTerm.clear()
|
||||
parentTerm.setCursorBlink(false)
|
||||
local str = 'Click screen for shell'
|
||||
write(parentTerm,
|
||||
math.floor((termDim.width - #str) / 2),
|
||||
math.floor(termDim.height / 2),
|
||||
str)
|
||||
end
|
||||
end
|
||||
|
||||
function process:click()
|
||||
end
|
||||
|
||||
process.container = window.create(monitor, process.x, process.y+1, process.width, process.height, true)
|
||||
process.window = window.create(parentTerm, 1, 1, termDim.width, termDim.height, true)
|
||||
process.terminal = process.window
|
||||
|
||||
Canvas.convertWindow(process.container, monitor, process.x, process.y)
|
||||
|
||||
process.co = coroutine.create(function()
|
||||
print('To run a program on the monitor, type "fg <program>"')
|
||||
print('To quit, type "exit"')
|
||||
os.run(Util.shallowCopy(defaultEnv), shell.resolveProgram('shell'))
|
||||
multishell.stop()
|
||||
end)
|
||||
|
||||
table.insert(processes, process)
|
||||
process:focus(true)
|
||||
|
||||
local previousTerm = term.current()
|
||||
process:resume()
|
||||
term.redirect(previousTerm)
|
||||
end
|
||||
|
||||
addShell()
|
||||
|
||||
multishell.loadSession(sessionFile)
|
||||
multishell.start()
|
||||
|
||||
term.redirect(parentTerm)
|
||||
parentTerm.clear()
|
||||
parentTerm.setCursorPos(1, 1)
|
||||
22
monitor/termShare.lua
Normal file
22
monitor/termShare.lua
Normal file
@@ -0,0 +1,22 @@
|
||||
local device = _G.device
|
||||
local multishell = _ENV.multishell
|
||||
local os = _G.os
|
||||
local term = _G.term
|
||||
|
||||
-- list this terminal in the devices list so it's available via
|
||||
-- peripheral sharing
|
||||
|
||||
local args = { ... }
|
||||
local name = args[1] or error('Syntax: termShare [device name] <title>')
|
||||
local title = args[2]
|
||||
|
||||
device[name] = term.current()
|
||||
device[name].name = name
|
||||
device[name].side = name
|
||||
device[name].type = 'terminal'
|
||||
|
||||
if title then
|
||||
multishell.setTitle(multishell.getCurrent(), title)
|
||||
end
|
||||
os.pullEventRaw('terminate')
|
||||
os.queueEvent('peripheral_detach', name)
|
||||
Reference in New Issue
Block a user