mirror of
https://github.com/20kdc/OC-KittenOS.git
synced 2025-04-12 22:48:14 +10:00
All the fixes, and app-klogo
This commit is contained in:
parent
c2b373f261
commit
8e0c74c41b
@ -4,6 +4,10 @@
|
|||||||
local event = require("event")(neo)
|
local event = require("event")(neo)
|
||||||
local neoux = require("neoux")(event, neo)
|
local neoux = require("neoux")(event, neo)
|
||||||
|
|
||||||
-- label
|
-- 1234567890123456789012345
|
||||||
-- [ ]
|
-- ABCDEF12 Lua BIOS
|
||||||
-- <read><write>
|
-- <get><set> <data> <label>
|
||||||
|
-- 21FEDCBA Nuclear Disk
|
||||||
|
-- <get><set> <data> <label>
|
||||||
|
|
||||||
|
|
||||||
|
50
code/apps/app-klogo.lua
Normal file
50
code/apps/app-klogo.lua
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
-- This is released into the public domain.
|
||||||
|
-- No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
|
local event = require("event")(neo)
|
||||||
|
local neoux = require("neoux")(event, neo)
|
||||||
|
local braille = require("braille")
|
||||||
|
local icecap = neo.requireAccess("x.neo.pub.base", "loadimg")
|
||||||
|
local qt = icecap.open("/logo.data", false)
|
||||||
|
|
||||||
|
local lc = {}
|
||||||
|
local lcdq = {}
|
||||||
|
local queueSize = 4
|
||||||
|
if os.totalMemory() > (256 * 1024) then
|
||||||
|
queueSize = 40
|
||||||
|
end
|
||||||
|
for i = 1, queueSize do
|
||||||
|
lcdq[i] = 0
|
||||||
|
end
|
||||||
|
local function getLine(y)
|
||||||
|
if not lc[y] then
|
||||||
|
local idx = (y - 1) * 120
|
||||||
|
qt.seek("set", idx)
|
||||||
|
if lcdq[1] then
|
||||||
|
lc[table.remove(lcdq, 1)] = nil
|
||||||
|
end
|
||||||
|
table.insert(lcdq, y)
|
||||||
|
lc[y] = qt.read(120) or ""
|
||||||
|
end
|
||||||
|
return lc[y]
|
||||||
|
end
|
||||||
|
|
||||||
|
local running = true
|
||||||
|
|
||||||
|
neoux.create(20, 10, nil, neoux.tcwindow(20, 10, {
|
||||||
|
braille.new(1, 1, 20, 10, {
|
||||||
|
selectable = true,
|
||||||
|
get = function (window, x, y, bg, fg, selected, colour)
|
||||||
|
local data = getLine(y)
|
||||||
|
local idx = ((x - 1) * 3) + 1
|
||||||
|
return data:byte(idx) or 255, data:byte(idx + 1) or 0, data:byte(idx + 2) or 255
|
||||||
|
end
|
||||||
|
}, 1)
|
||||||
|
}, function (w)
|
||||||
|
w.close()
|
||||||
|
running = false
|
||||||
|
end, 0xFFFFFF, 0))
|
||||||
|
|
||||||
|
while running do
|
||||||
|
event.pull()
|
||||||
|
end
|
@ -62,20 +62,25 @@ local lIM = 1
|
|||||||
local shuttingDown = false
|
local shuttingDown = false
|
||||||
|
|
||||||
local savingThrow = neo.requestAccess("x.neo.sys.manage")
|
local savingThrow = neo.requestAccess("x.neo.sys.manage")
|
||||||
|
local function dying()
|
||||||
|
local primary = (monitors[1] or {})[2] or ""
|
||||||
|
for _, v in ipairs(monitors) do
|
||||||
|
pcall(screens.disclaim, v[2])
|
||||||
|
end
|
||||||
|
monitors = {}
|
||||||
|
neo.executeAsync("sys-init", primary)
|
||||||
|
-- In this case the surfaces are leaked and hold references here. They have to be removed manually.
|
||||||
|
-- Do this via a "primary event" (k.deregistration) and "deathtrap events"
|
||||||
|
-- If a process evades the deathtrap then it clearly has reason to stay alive regardless of Everest status.
|
||||||
|
-- Also note, should savingThrow fail, neo.dead is now a thing.
|
||||||
|
for _, v in ipairs(surfaces) do
|
||||||
|
pcall(v[6], "line", 1)
|
||||||
|
pcall(v[6], "line", 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
if savingThrow then
|
if savingThrow then
|
||||||
savingThrow.registerForShutdownEvent()
|
savingThrow.registerForShutdownEvent()
|
||||||
savingThrow.registerSavingThrow(function ()
|
savingThrow.registerSavingThrow(dying)
|
||||||
neo.executeAsync("sys-init", monitors[1][2])
|
|
||||||
-- In this case the surfaces are leaked and hold references here. They have to be removed manually.
|
|
||||||
-- Do this via a "primary event" (k.deregistration) and "deathtrap events"
|
|
||||||
-- If a process evades the deathtrap then it clearly has reason to stay alive regardless of Everest status.
|
|
||||||
-- Also note, should savingThrow fail, neo.dead is now a thing.
|
|
||||||
monitors = {}
|
|
||||||
for _, v in ipairs(surfaces) do
|
|
||||||
pcall(v[6], "line", 1)
|
|
||||||
pcall(v[6], "line", 2)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function renderingAllowed()
|
local function renderingAllowed()
|
||||||
@ -165,8 +170,8 @@ local function updateRegion(monitorId, x, y, w, h, surfaceSpanCache)
|
|||||||
doBackgroundLine(m, mg, bdx, bdy, bdl)
|
doBackgroundLine(m, mg, bdx, bdy, bdl)
|
||||||
backgroundMarkStart = nil
|
backgroundMarkStart = nil
|
||||||
end
|
end
|
||||||
if not surfaceSpanCache[monitorId .. t .. "_" .. ty] then
|
if not surfaceSpanCache[monitorId .. "_" .. t .. "_" .. ty] then
|
||||||
surfaceSpanCache[monitorId .. t .. "_" .. ty] = true
|
surfaceSpanCache[monitorId .. "_" .. t .. "_" .. ty] = true
|
||||||
surfaces[t][6]("line", ty)
|
surfaces[t][6]("line", ty)
|
||||||
end
|
end
|
||||||
elseif not backgroundMarkStart then
|
elseif not backgroundMarkStart then
|
||||||
@ -211,15 +216,26 @@ local function reconcileAll()
|
|||||||
-- About to update whole screen anyway so avoid the wait.
|
-- About to update whole screen anyway so avoid the wait.
|
||||||
v[1], v[2], v[3] = ensureOnscreen(v[1], v[2], v[3], v[4], v[5])
|
v[1], v[2], v[3] = ensureOnscreen(v[1], v[2], v[3], v[4], v[5])
|
||||||
end
|
end
|
||||||
for k, v in ipairs(monitors) do
|
local k = 1
|
||||||
|
while k <= #monitors do
|
||||||
|
local v = monitors[k]
|
||||||
local mon, rb = v[1]()
|
local mon, rb = v[1]()
|
||||||
if rb then
|
if rb then
|
||||||
monitorResetBF(v)
|
monitorResetBF(v)
|
||||||
end
|
end
|
||||||
if mon then
|
if mon then
|
||||||
|
-- This *can* return null if something went wonky. Let's detect that
|
||||||
v[3], v[4] = mon.getResolution()
|
v[3], v[4] = mon.getResolution()
|
||||||
|
if not v[3] then
|
||||||
|
neo.emergency("everest: monitor went AWOL and nobody told me u.u")
|
||||||
|
table.remove(monitors, k)
|
||||||
|
v = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if v then
|
||||||
|
updateRegion(k, 1, 1, v[3], v[4], {})
|
||||||
|
k = k + 1
|
||||||
end
|
end
|
||||||
updateRegion(k, 1, 1, v[3], v[4], {})
|
|
||||||
end
|
end
|
||||||
updateStatus()
|
updateStatus()
|
||||||
end
|
end
|
||||||
@ -246,6 +262,14 @@ local function moveSurface(surface, m, x, y, w, h, force)
|
|||||||
end
|
end
|
||||||
if cb then
|
if cb then
|
||||||
cb.copy(ox, oy, w, h, x - ox, y - oy)
|
cb.copy(ox, oy, w, h, x - ox, y - oy)
|
||||||
|
if surface == surfaces[1] then
|
||||||
|
local cacheControl = {}
|
||||||
|
for i = 1, h do
|
||||||
|
cacheControl[om .. "_1_" .. i] = true
|
||||||
|
end
|
||||||
|
updateRegion(om, ox, oy, ow, oh, cacheControl)
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -445,6 +469,17 @@ everestProvider(function (pkg, pid, sendSig)
|
|||||||
moveSurface(surf, nil, x, y, w, h, true)
|
moveSurface(surf, nil, x, y, w, h, true)
|
||||||
return w, (h - 1)
|
return w, (h - 1)
|
||||||
end,
|
end,
|
||||||
|
getDepth = function ()
|
||||||
|
if neo.dead then return false end
|
||||||
|
local m = monitors[surf[1]]
|
||||||
|
if not m then return false end
|
||||||
|
local cb, rb = m[1]()
|
||||||
|
if not cb then return false end
|
||||||
|
if rb then
|
||||||
|
monitorResetBF(m)
|
||||||
|
end
|
||||||
|
return cb.getDepth()
|
||||||
|
end,
|
||||||
span = function (x, y, text, bg, fg)
|
span = function (x, y, text, bg, fg)
|
||||||
if neo.dead then error("everest died") end
|
if neo.dead then error("everest died") end
|
||||||
if type(x) ~= "number" then error("X must be number.") end
|
if type(x) ~= "number" then error("X must be number.") end
|
||||||
@ -481,8 +516,7 @@ everestSessionProvider(function (pkg, pid, sendSig)
|
|||||||
endSession = function (gotoBristol)
|
endSession = function (gotoBristol)
|
||||||
shuttingDown = true
|
shuttingDown = true
|
||||||
if gotoBristol then
|
if gotoBristol then
|
||||||
-- Notably, savingThrow only triggers for error-death...
|
dying()
|
||||||
neo.executeAsync("sys-init", (monitors[1] or {})[2])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
@ -545,14 +579,16 @@ local function key(ka, kc, down)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if focus then
|
if focus then
|
||||||
lIM = focus[1]
|
if kc ~= 56 then
|
||||||
|
lIM = focus[1]
|
||||||
|
end
|
||||||
focus[6]("key", ka, kc, down)
|
focus[6]("key", ka, kc, down)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- take all displays!
|
-- take all displays!
|
||||||
local function performClaim(s3)
|
local function performClaim(s3)
|
||||||
local gpu = screens.claim(s3)
|
local gpu, _ = screens.claim(s3)
|
||||||
local gpucb = gpu and (gpu())
|
local gpucb = gpu and (gpu())
|
||||||
if gpucb then
|
if gpucb then
|
||||||
local w, h = gpucb.getResolution()
|
local w, h = gpucb.getResolution()
|
||||||
@ -571,6 +607,12 @@ while not shuttingDown do
|
|||||||
local s = {coroutine.yield()}
|
local s = {coroutine.yield()}
|
||||||
if renderingAllowed() then
|
if renderingAllowed() then
|
||||||
if s[1] == "h.key_down" then
|
if s[1] == "h.key_down" then
|
||||||
|
local m = screens.getMonitorByKeyboard(s[2])
|
||||||
|
for k, v in ipairs(monitors) do
|
||||||
|
if v[2] == m then
|
||||||
|
lIM = k
|
||||||
|
end
|
||||||
|
end
|
||||||
key(s[3], s[4], true)
|
key(s[3], s[4], true)
|
||||||
end
|
end
|
||||||
if s[1] == "h.key_up" then
|
if s[1] == "h.key_up" then
|
||||||
|
@ -43,7 +43,7 @@ local settings = {
|
|||||||
["pub.clipboard"] = "",
|
["pub.clipboard"] = "",
|
||||||
["sys-init.shell"] = "sys-everest",
|
["sys-init.shell"] = "sys-everest",
|
||||||
["run.sys-icecap"] = "yes",
|
["run.sys-icecap"] = "yes",
|
||||||
-- scr.w/h/d.<uuid>
|
-- scr.w/h/d/t.<uuid>
|
||||||
}
|
}
|
||||||
|
|
||||||
local function loadSettings()
|
local function loadSettings()
|
||||||
@ -96,8 +96,9 @@ local function getGPU(monitor)
|
|||||||
local bestD = 0
|
local bestD = 0
|
||||||
for v in gpus.list() do
|
for v in gpus.list() do
|
||||||
v.bind(monitor.address, false)
|
v.bind(monitor.address, false)
|
||||||
currentGPUBinding[v.address] = monitor.address
|
currentGPUBinding[v.address] = nil
|
||||||
local d = v.maxDepth()
|
local w, h = v.maxResolution()
|
||||||
|
local d = v.maxDepth() * w * h
|
||||||
if d > bestD then
|
if d > bestD then
|
||||||
bestG = v
|
bestG = v
|
||||||
bestD = d
|
bestD = d
|
||||||
@ -131,22 +132,27 @@ local function getMonitorSettings(a)
|
|||||||
local w = tonumber(settings["scr.w." .. a]) or 80
|
local w = tonumber(settings["scr.w." .. a]) or 80
|
||||||
local h = tonumber(settings["scr.h." .. a]) or 25
|
local h = tonumber(settings["scr.h." .. a]) or 25
|
||||||
local d = tonumber(settings["scr.d." .. a]) or 8
|
local d = tonumber(settings["scr.d." .. a]) or 8
|
||||||
|
local t = ((settings["scr.t." .. a] == "yes") and "yes") or "no"
|
||||||
w, h, d = math.floor(w), math.floor(h), math.floor(d)
|
w, h, d = math.floor(w), math.floor(h), math.floor(d)
|
||||||
return w, h, d
|
return w, h, d, t
|
||||||
end
|
end
|
||||||
local function setupMonitor(gpu, monitor)
|
local function setupMonitor(gpu, monitor)
|
||||||
|
monitor.setPrecise(true)
|
||||||
|
monitor.turnOn()
|
||||||
gpu.bind(monitor.address, false)
|
gpu.bind(monitor.address, false)
|
||||||
currentGPUBinding[gpu.address] = monitor.address
|
currentGPUBinding[gpu.address] = monitor.address
|
||||||
local maxW, maxH = gpu.maxResolution()
|
local maxW, maxH = gpu.maxResolution()
|
||||||
local maxD = gpu.maxDepth()
|
local maxD = gpu.maxDepth()
|
||||||
local w, h, d = getMonitorSettings(monitor.address)
|
local w, h, d, t = getMonitorSettings(monitor.address)
|
||||||
w, h, d = math.min(w, maxW), math.min(h, maxH), math.min(d, maxD)
|
w, h, d = math.min(w, maxW), math.min(h, maxH), math.min(d, maxD)
|
||||||
|
monitor.setTouchModeInverted(t == "yes")
|
||||||
settings["scr.w." .. monitor.address] = tostring(w)
|
settings["scr.w." .. monitor.address] = tostring(w)
|
||||||
settings["scr.h." .. monitor.address] = tostring(h)
|
settings["scr.h." .. monitor.address] = tostring(h)
|
||||||
settings["scr.d." .. monitor.address] = tostring(d)
|
settings["scr.d." .. monitor.address] = tostring(d)
|
||||||
sRattle("scr.w." .. monitor.address, tostring(w))
|
sRattle("scr.w." .. monitor.address, tostring(w))
|
||||||
sRattle("scr.h." .. monitor.address, tostring(h))
|
sRattle("scr.h." .. monitor.address, tostring(h))
|
||||||
sRattle("scr.d." .. monitor.address, tostring(d))
|
sRattle("scr.d." .. monitor.address, tostring(d))
|
||||||
|
sRattle("scr.t." .. monitor.address, t)
|
||||||
gpu.setResolution(w, h)
|
gpu.setResolution(w, h)
|
||||||
gpu.setDepth(d)
|
gpu.setDepth(d)
|
||||||
pcall(saveSettings)
|
pcall(saveSettings)
|
||||||
@ -226,6 +232,15 @@ donkonitRDProvider(function (pkg, pid, sendSig)
|
|||||||
end
|
end
|
||||||
end}
|
end}
|
||||||
return {
|
return {
|
||||||
|
getMonitorByKeyboard = function (kb)
|
||||||
|
for v in screens.list() do
|
||||||
|
for _, v2 in ipairs(v.getKeyboards()) do
|
||||||
|
if v2 == kb then
|
||||||
|
return v.address
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
getClaimable = function ()
|
getClaimable = function ()
|
||||||
local c = {}
|
local c = {}
|
||||||
-- do we have gpu?
|
-- do we have gpu?
|
||||||
@ -272,7 +287,7 @@ donkonitRDProvider(function (pkg, pid, sendSig)
|
|||||||
return v, didBind
|
return v, didBind
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end, v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -329,10 +329,10 @@ local function initializeSystem()
|
|||||||
if gpu then
|
if gpu then
|
||||||
screen = screen.address
|
screen = screen.address
|
||||||
gpu.bind(screen, true)
|
gpu.bind(screen, true)
|
||||||
gpu.setDepth(gpu.maxDepth())
|
|
||||||
local gW, gH = gpu.maxResolution()
|
local gW, gH = gpu.maxResolution()
|
||||||
gW, gH = math.min(80, gW), math.min(25, gH)
|
gW, gH = math.min(80, gW), math.min(25, gH)
|
||||||
gpu.setResolution(gW, gH)
|
gpu.setResolution(gW, gH)
|
||||||
|
pcall(gpu.setDepth, gpu.maxDepth()) -- can crash on OCEmu if done at the "wrong time"
|
||||||
gpu.setForeground(0x000000)
|
gpu.setForeground(0x000000)
|
||||||
end
|
end
|
||||||
local w = 1
|
local w = 1
|
||||||
@ -420,12 +420,6 @@ end
|
|||||||
-- Actual sequence
|
-- Actual sequence
|
||||||
|
|
||||||
if callerPkg ~= nil then
|
if callerPkg ~= nil then
|
||||||
-- Everest can call into this to force a login screen
|
|
||||||
-- In this case Everest dies, then starts Bristol.
|
|
||||||
--
|
|
||||||
if callerPkg ~= "sys-everest" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
screen = callerScr
|
screen = callerScr
|
||||||
-- Skip to "System initialized" (Everest either logged off, or died & used a Saving Throw to restart)
|
-- Skip to "System initialized" (Everest either logged off, or died & used a Saving Throw to restart)
|
||||||
else
|
else
|
||||||
|
@ -15,6 +15,7 @@ return {
|
|||||||
"libs/event.lua",
|
"libs/event.lua",
|
||||||
"libs/serial.lua",
|
"libs/serial.lua",
|
||||||
"libs/neoux.lua",
|
"libs/neoux.lua",
|
||||||
|
"libs/braille.lua",
|
||||||
"libs/sys-filewrap.lua"
|
"libs/sys-filewrap.lua"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -103,6 +104,22 @@ return {
|
|||||||
"apps/app-taskmgr.lua"
|
"apps/app-taskmgr.lua"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
["app-klogo"] = {
|
||||||
|
desc = "KittenOS NEO Logo",
|
||||||
|
v = 0,
|
||||||
|
deps = {
|
||||||
|
"neo"
|
||||||
|
},
|
||||||
|
dirs = {
|
||||||
|
"apps",
|
||||||
|
"data",
|
||||||
|
"data/app-klogo"
|
||||||
|
},
|
||||||
|
files = {
|
||||||
|
"apps/app-klogo.lua",
|
||||||
|
"data/app-klogo/logo.data"
|
||||||
|
},
|
||||||
|
},
|
||||||
["app-flash"] = {
|
["app-flash"] = {
|
||||||
desc = "KittenOS NEO EEPROM Flasher",
|
desc = "KittenOS NEO EEPROM Flasher",
|
||||||
v = 0,
|
v = 0,
|
||||||
@ -142,6 +159,7 @@ return {
|
|||||||
"neo-icecap",
|
"neo-icecap",
|
||||||
"neo-secpolicy",
|
"neo-secpolicy",
|
||||||
"neo-coreapps",
|
"neo-coreapps",
|
||||||
|
"app-klogo",
|
||||||
"app-flash",
|
"app-flash",
|
||||||
"app-claw"
|
"app-claw"
|
||||||
},
|
},
|
||||||
|
BIN
code/data/app-klogo/logo.data
Normal file
BIN
code/data/app-klogo/logo.data
Normal file
Binary file not shown.
@ -209,21 +209,11 @@ local function execEvent(k, ...)
|
|||||||
local r, reason = coroutine.resume(v.co, ...)
|
local r, reason = coroutine.resume(v.co, ...)
|
||||||
-- Mostly reliable accounting
|
-- Mostly reliable accounting
|
||||||
v.cpuUsage = v.cpuUsage + (computer.uptime() - timerA)
|
v.cpuUsage = v.cpuUsage + (computer.uptime() - timerA)
|
||||||
local dead = not r
|
reason = ((not r) and tostring(reason)) or nil
|
||||||
local hasReason = dead
|
local dead = (not not reason) or coroutine.status(v.co) == "dead"
|
||||||
if not dead then
|
|
||||||
if coroutine.status(v.co) == "dead" then
|
|
||||||
dead = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if dead then
|
if dead then
|
||||||
if hasReason then
|
|
||||||
reason = tostring(reason)
|
|
||||||
else
|
|
||||||
reason = nil
|
|
||||||
end
|
|
||||||
termProc(k, reason)
|
termProc(k, reason)
|
||||||
return hasReason
|
return not not reason
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -349,6 +339,7 @@ function runProgramPolicy(ipkg, pkg, pid, ...)
|
|||||||
return nil, "non-sys app trying to start sys app"
|
return nil, "non-sys app trying to start sys app"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function retrieveAccess(perm, pkg, pid)
|
function retrieveAccess(perm, pkg, pid)
|
||||||
@ -459,22 +450,26 @@ end
|
|||||||
local start = nil
|
local start = nil
|
||||||
|
|
||||||
function start(pkg, ...)
|
function start(pkg, ...)
|
||||||
local args = {...}
|
|
||||||
local proc = {}
|
local proc = {}
|
||||||
local pid = lastPID
|
local pid = lastPID
|
||||||
lastPID = lastPID + 1
|
lastPID = lastPID + 1
|
||||||
|
|
||||||
local function startFromUser(ipkg, ...)
|
local function startFromUser(ipkg, ...)
|
||||||
ensureType(pkg, "string")
|
ensureType(ipkg, "string")
|
||||||
ensurePathComponent(pkg .. ".lua")
|
ensurePathComponent(ipkg .. ".lua")
|
||||||
runProgramPolicy(ipkg, pkg, pid, ...)
|
local k, r = runProgramPolicy(ipkg, pkg, pid, ...)
|
||||||
return start(ipkg, pkg, pid, ...)
|
if k then
|
||||||
|
return start(ipkg, pkg, pid, ...)
|
||||||
|
else
|
||||||
|
return k, r
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function osExecuteCore(handler, ...)
|
local function osExecuteCore(handler, ...)
|
||||||
local pid, err = startFromUser(...)
|
local pid, err = startFromUser(...)
|
||||||
while pid do
|
while pid do
|
||||||
local sig = {coroutine.yield()}
|
local sig = {coroutine.yield()}
|
||||||
|
handler(table.unpack(sig))
|
||||||
if sig[1] == "k.procdie" then
|
if sig[1] == "k.procdie" then
|
||||||
if sig[3] == pid then
|
if sig[3] == pid then
|
||||||
return 0, sig[4]
|
return 0, sig[4]
|
||||||
@ -528,11 +523,11 @@ function start(pkg, ...)
|
|||||||
if not handler then handler = function() end end
|
if not handler then handler = function() end end
|
||||||
while true do
|
while true do
|
||||||
local n = {coroutine.yield()}
|
local n = {coroutine.yield()}
|
||||||
|
handler(table.unpack(n))
|
||||||
if n[1] == "k.securityresponse" then
|
if n[1] == "k.securityresponse" then
|
||||||
-- Security response - if it involves the permission, then take it
|
-- Security response - if it involves the permission, then take it
|
||||||
if n[2] == perm then return n[3] end
|
if n[2] == perm then return n[3] end
|
||||||
end
|
end
|
||||||
handler(table.unpack(n))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
env.neo.requireAccess = function (perm, reason)
|
env.neo.requireAccess = function (perm, reason)
|
||||||
@ -552,7 +547,7 @@ function start(pkg, ...)
|
|||||||
if not appfunc then
|
if not appfunc then
|
||||||
return nil, r
|
return nil, r
|
||||||
end
|
end
|
||||||
proc.co = coroutine.create(function (...) local r = {xpcall(appfunc, debug.traceback)} if not r[1] then error(table.unpack(r, 2)) end return table.unpack(r, 2) end)
|
proc.co = coroutine.create(function (...) local r = {xpcall(appfunc, debug.traceback, ...)} if not r[1] then error(table.unpack(r, 2)) end return table.unpack(r, 2) end)
|
||||||
proc.pkg = pkg
|
proc.pkg = pkg
|
||||||
proc.access = {
|
proc.access = {
|
||||||
-- These permissions are the "critical set".
|
-- These permissions are the "critical set".
|
||||||
|
177
code/libs/braille.lua
Normal file
177
code/libs/braille.lua
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
-- This is released into the public domain.
|
||||||
|
-- No warranty is provided, implied or otherwise.
|
||||||
|
|
||||||
|
-- Braille Neoux Component
|
||||||
|
-- Callbacks :
|
||||||
|
-- selectable (boolean)
|
||||||
|
-- key(window, update, a, c, d)
|
||||||
|
-- touch(window, update, x, y, button)
|
||||||
|
-- drag(window, update, x, y, button)
|
||||||
|
-- drop(window, update, x, y, button)
|
||||||
|
-- scroll(window, update, x, y, button)
|
||||||
|
-- get(window, x, y, bg, fg, selected) -> r,g,b (REQUIRED)
|
||||||
|
-- REMINDER:
|
||||||
|
-- 03
|
||||||
|
-- 14
|
||||||
|
-- 25
|
||||||
|
-- 67
|
||||||
|
local function dotDist(ra, ga, ba, rb, gb, bb)
|
||||||
|
local dR, dG, dB = math.abs(ra - rb), math.abs(ga - gb), math.abs(ba - bb)
|
||||||
|
return (dR * 0.299) + (dG * 0.587) + (dB * 0.114)
|
||||||
|
end
|
||||||
|
local function dotGet(p, ra, ga, ba, rb, gb, bb, rc, gc, bc, pos, col)
|
||||||
|
if not col then
|
||||||
|
-- Use our own magic
|
||||||
|
local res = false
|
||||||
|
local luma = (ra * 0.299) + (ga * 0.587) + (ba * 0.114)
|
||||||
|
if luma > 96 and luma < 160 then
|
||||||
|
res = pos
|
||||||
|
elseif luma >= 160 then
|
||||||
|
res = true
|
||||||
|
end
|
||||||
|
return (res and p) or 0
|
||||||
|
end
|
||||||
|
local distA = dotDist(ra, ga, ba, rb, gb, bb)
|
||||||
|
local distB = dotDist(ra, ga, ba, rc, gc, bc)
|
||||||
|
local distAB = dotDist(rb, gb, bb, rc, gc, bc)
|
||||||
|
local distC = dotDist(ra, ga, ba, (rb + rc) / 2, (gb + gc) / 2, (bb + bc) / 2)
|
||||||
|
-- If A and B are close,
|
||||||
|
if (distAB < 32) and (distC < (math.min(distA, distB) * 4)) then
|
||||||
|
return (pos and p) or 0
|
||||||
|
end
|
||||||
|
return ((distB < distA) and p) or 0
|
||||||
|
end
|
||||||
|
local function cTransform(core)
|
||||||
|
return function (window, update, x, y, xI, yI, blah)
|
||||||
|
x = x + math.ceil(xI - 0.5)
|
||||||
|
y = y + math.ceil((yI - 0.25) * 4)
|
||||||
|
core(window, update, x, y, blah)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function colourize(mark, ...)
|
||||||
|
local t = {...}
|
||||||
|
local bCR = 0
|
||||||
|
local bCG = 0
|
||||||
|
local bCB = 0
|
||||||
|
if not mark then
|
||||||
|
local nLuma = -1
|
||||||
|
for i = 1, #t do
|
||||||
|
local luma = (t[i][1] * 0.299) + (t[i][2] * 0.587) + (t[i][3] * 0.114)
|
||||||
|
if luma > nLuma then
|
||||||
|
bCR = t[i][1]
|
||||||
|
bCG = t[i][2]
|
||||||
|
bCB = t[i][3]
|
||||||
|
nLuma = luma
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return bCR, bCG, bCB
|
||||||
|
else
|
||||||
|
local bCTS = math.huge
|
||||||
|
for i = 1, #t do
|
||||||
|
local ts = -dotDist(mark[1], mark[2], mark[3], table.unpack(t[i]))
|
||||||
|
if ts < bCTS then
|
||||||
|
bCR = t[i][1]
|
||||||
|
bCG = t[i][2]
|
||||||
|
bCB = t[i][3]
|
||||||
|
bCTS = ts
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return bCR, bCG, bCB
|
||||||
|
end
|
||||||
|
local function packRGB(r, g, b)
|
||||||
|
return (r * 65536) + (g * 256) + b
|
||||||
|
end
|
||||||
|
heldRef = neo.wrapMeta({
|
||||||
|
new = function (x, y, w, h, cbs, colour)
|
||||||
|
local control
|
||||||
|
control = {
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
w = w,
|
||||||
|
h = h,
|
||||||
|
selectable = cbs.selectable,
|
||||||
|
key = cbs.key,
|
||||||
|
touch = cbs.touch and cTransform(cbs.touch),
|
||||||
|
drag = cbs.drag and cTransform(cbs.drag),
|
||||||
|
drop = cbs.drop and cTransform(cbs.drop),
|
||||||
|
scroll = cbs.scroll and cTransform(cbs.scroll),
|
||||||
|
line = function (window, x, y, iy, bg, fg, selected)
|
||||||
|
local colour = (window.getDepth() > 1) and colour
|
||||||
|
local str = ""
|
||||||
|
local bgR = 0
|
||||||
|
local bgG = 0
|
||||||
|
local bgB = 0
|
||||||
|
local fgR = 255
|
||||||
|
local fgG = 255
|
||||||
|
local fgB = 255
|
||||||
|
bg = 0
|
||||||
|
fg = 0xFFFFFF
|
||||||
|
local ca = 0
|
||||||
|
for p = 1, control.w do
|
||||||
|
local i = 0x2800
|
||||||
|
local xb = (p * 2) - 1
|
||||||
|
local yb = (iy * 4) - 3
|
||||||
|
local dot0R, dot0G, dot0B = cbs.get(window, xb, yb, bg, fg, selected, colour)
|
||||||
|
local dot1R, dot1G, dot1B = cbs.get(window, xb, yb + 1, bg, fg, selected, colour)
|
||||||
|
local dot2R, dot2G, dot2B = cbs.get(window, xb, yb + 2, bg, fg, selected, colour)
|
||||||
|
local dot3R, dot3G, dot3B = cbs.get(window, xb + 1, yb, bg, fg, selected, colour)
|
||||||
|
local dot4R, dot4G, dot4B = cbs.get(window, xb + 1, yb + 1, bg, fg, selected, colour)
|
||||||
|
local dot5R, dot5G, dot5B = cbs.get(window, xb + 1, yb + 2, bg, fg, selected, colour)
|
||||||
|
local dot6R, dot6G, dot6B = cbs.get(window, xb, yb + 3, bg, fg, selected, colour)
|
||||||
|
local dot7R, dot7G, dot7B = cbs.get(window, xb + 1, yb + 3, bg, fg, selected, colour)
|
||||||
|
if colour then
|
||||||
|
local obgR, obgG, obgB = colourize(nil,
|
||||||
|
{dot0R, dot0G, dot0B},
|
||||||
|
{dot1R, dot1G, dot1B},
|
||||||
|
{dot2R, dot2G, dot2B},
|
||||||
|
{dot3R, dot3G, dot3B},
|
||||||
|
{dot4R, dot4G, dot4B},
|
||||||
|
{dot5R, dot5G, dot5B},
|
||||||
|
{dot6R, dot6G, dot6B},
|
||||||
|
{dot7R, dot7G, dot7B}
|
||||||
|
)
|
||||||
|
local ofgR, ofgG, ofgB = colourize({obgR, obgG, obgB},
|
||||||
|
{dot0R, dot0G, dot0B},
|
||||||
|
{dot1R, dot1G, dot1B},
|
||||||
|
{dot2R, dot2G, dot2B},
|
||||||
|
{dot3R, dot3G, dot3B},
|
||||||
|
{dot4R, dot4G, dot4B},
|
||||||
|
{dot5R, dot5G, dot5B},
|
||||||
|
{dot6R, dot6G, dot6B},
|
||||||
|
{dot7R, dot7G, dot7B}
|
||||||
|
)
|
||||||
|
if ((dotDist(obgR, obgG, obgB, bgR, bgG, bgB) > colour) and
|
||||||
|
(dotDist(obgR, obgG, obgB, fgR, fgG, fgB) > colour)) or
|
||||||
|
((dotDist(ofgR, ofgG, ofgB, bgR, bgG, bgB) > colour) and
|
||||||
|
(dotDist(ofgR, ofgG, ofgB, fgR, fgG, fgB) > colour)) then
|
||||||
|
if ca ~= 0 then
|
||||||
|
window.span(x, y, str, bg, fg)
|
||||||
|
str = ""
|
||||||
|
end
|
||||||
|
x = x + ca
|
||||||
|
ca = 0
|
||||||
|
bg = packRGB(obgR, obgG, obgB)
|
||||||
|
fg = packRGB(ofgR, ofgG, ofgB)
|
||||||
|
bgR, bgG, bgB = obgR, obgG, obgB
|
||||||
|
fgR, fgG, fgB = ofgR, ofgG, ofgB
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i = i + dotGet(1, dot0R, dot0G, dot0B, bgR, bgG, bgB, fgR, fgG, fgB, true, colour)
|
||||||
|
i = i + dotGet(2, dot1R, dot1G, dot1B, bgR, bgG, bgB, fgR, fgG, fgB, false, colour)
|
||||||
|
i = i + dotGet(4, dot2R, dot2G, dot2B, bgR, bgG, bgB, fgR, fgG, fgB, true, colour)
|
||||||
|
i = i + dotGet(8, dot3R, dot3G, dot3B, bgR, bgG, bgB, fgR, fgG, fgB, false, colour)
|
||||||
|
i = i + dotGet(16, dot4R, dot4G, dot4B, bgR, bgG, bgB, fgR, fgG, fgB, true, colour)
|
||||||
|
i = i + dotGet(32, dot5R, dot5G, dot5B, bgR, bgG, bgB, fgR, fgG, fgB, false, colour)
|
||||||
|
i = i + dotGet(64, dot6R, dot6G, dot6B, bgR, bgG, bgB, fgR, fgG, fgB, false, colour)
|
||||||
|
i = i + dotGet(128, dot7R, dot7G, dot7B, bgR, bgG, bgB, fgR, fgG, fgB, true, colour)
|
||||||
|
str = str .. unicode.char(i)
|
||||||
|
ca = ca + 1
|
||||||
|
end
|
||||||
|
window.span(x, y, str, bg, fg)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
return control
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
return heldRef
|
@ -4,6 +4,15 @@
|
|||||||
-- neoux: Implements utilities on top of Everest & event:
|
-- neoux: Implements utilities on top of Everest & event:
|
||||||
-- Everest crash protection
|
-- Everest crash protection
|
||||||
|
|
||||||
|
-- Control reference
|
||||||
|
-- x/y/w/h: ints, position/size, 1,1 TL
|
||||||
|
-- selectable: boolean
|
||||||
|
-- key(window, update, char, code, down)
|
||||||
|
-- touch(window, update, x, y, xI, yI, button)
|
||||||
|
-- drag(window, update, x, y, xI, yI, button)
|
||||||
|
-- drop(window, update, x, y, xI, yI, button)
|
||||||
|
-- scroll(window, update, x, y, xI, yI, amount)
|
||||||
|
|
||||||
-- Global forces reference. Otherwise, nasty duplication happens.
|
-- Global forces reference. Otherwise, nasty duplication happens.
|
||||||
newNeoux = function (event, neo)
|
newNeoux = function (event, neo)
|
||||||
-- this is why neo access is 'needed'
|
-- this is why neo access is 'needed'
|
||||||
@ -106,6 +115,12 @@ newNeoux = function (event, neo)
|
|||||||
window.getSize = function ()
|
window.getSize = function ()
|
||||||
return windowCore[2], windowCore[3]
|
return windowCore[2], windowCore[3]
|
||||||
end
|
end
|
||||||
|
window.getDepth = function ()
|
||||||
|
if windowCore[1] then
|
||||||
|
return windowCore[1].getDepth()
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
window.setSize = function (w, h)
|
window.setSize = function (w, h)
|
||||||
windowCore[2] = w
|
windowCore[2] = w
|
||||||
windowCore[3] = h
|
windowCore[3] = h
|
||||||
@ -286,7 +301,10 @@ newNeoux = function (event, neo)
|
|||||||
if c1 then doZone(window, c1, cache) end
|
if c1 then doZone(window, c1, cache) end
|
||||||
if c2 then doZone(window, c2, cache) end
|
if c2 then doZone(window, c2, cache) end
|
||||||
end
|
end
|
||||||
|
-- Attach .update for external interference
|
||||||
|
for k, v in ipairs(controls) do
|
||||||
|
v.update = function (window) doZone(window, v, {}) end
|
||||||
|
end
|
||||||
return function (window, ev, a, b, c, d, e)
|
return function (window, ev, a, b, c, d, e)
|
||||||
-- X,Y,Xi,Yi,B
|
-- X,Y,Xi,Yi,B
|
||||||
if ev == "touch" then
|
if ev == "touch" then
|
||||||
@ -372,7 +390,7 @@ newNeoux = function (event, neo)
|
|||||||
selectable = false,
|
selectable = false,
|
||||||
line = function (window, x, y, lined, bg, fg, selected)
|
line = function (window, x, y, lined, bg, fg, selected)
|
||||||
-- Can't be selected normally so ignore that flag
|
-- Can't be selected normally so ignore that flag
|
||||||
window.span(x, y, lines[lined], bg, fg)
|
window.span(x, y, lines[lined], bg, fg)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -401,7 +419,7 @@ newNeoux = function (event, neo)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
touch = function (window, update, x, y)
|
touch = function (window, update, x, y, button)
|
||||||
callback(window)
|
callback(window)
|
||||||
end,
|
end,
|
||||||
line = function (window, x, y, lind, bg, fg, selected)
|
line = function (window, x, y, lind, bg, fg, selected)
|
||||||
|
@ -46,7 +46,7 @@ local function prepareNodeI(node)
|
|||||||
if a <= 1 then
|
if a <= 1 then
|
||||||
return true, true, node.name
|
return true, true, node.name
|
||||||
end
|
end
|
||||||
local camY = math.max(1, selection - 4)
|
local camY = math.max(1, selection - 3)
|
||||||
local idx = a + camY - 2
|
local idx = a + camY - 2
|
||||||
if node.unknownAvailable then
|
if node.unknownAvailable then
|
||||||
if idx == #l + 1 then
|
if idx == #l + 1 then
|
||||||
@ -131,7 +131,7 @@ local function prepareNodeI(node)
|
|||||||
key(wnd, a, b, c)
|
key(wnd, a, b, c)
|
||||||
end
|
end
|
||||||
if evt == "touch" then
|
if evt == "touch" then
|
||||||
local ns = b + math.max(1, selection - 4) - 2
|
local ns = b + math.max(1, selection - 3) - 2
|
||||||
local max = #l
|
local max = #l
|
||||||
if node.unknownAvailable then
|
if node.unknownAvailable then
|
||||||
max = max + 1
|
max = max + 1
|
||||||
|
@ -14,9 +14,14 @@ return function(dev, file, mode)
|
|||||||
dev.close(handle)
|
dev.close(handle)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
local function seeker(whence, point)
|
||||||
|
if not open then return end
|
||||||
|
return dev.seek(handle, whence, point)
|
||||||
|
end
|
||||||
if not mode then
|
if not mode then
|
||||||
return {
|
return {
|
||||||
close = closer,
|
close = closer,
|
||||||
|
seek = seeker,
|
||||||
read = function (len)
|
read = function (len)
|
||||||
if len == "*a" then
|
if len == "*a" then
|
||||||
local ch = ""
|
local ch = ""
|
||||||
@ -34,6 +39,7 @@ return function(dev, file, mode)
|
|||||||
else
|
else
|
||||||
return {
|
return {
|
||||||
close = closer,
|
close = closer,
|
||||||
|
seek = seeker,
|
||||||
write = function (txt)
|
write = function (txt)
|
||||||
if type(txt) ~= "string" then error("Write data must be string-bytearray") end
|
if type(txt) ~= "string" then error("Write data must be string-bytearray") end
|
||||||
local ok, b = dev.write(handle, txt)
|
local ok, b = dev.write(handle, txt)
|
||||||
|
Loading…
Reference in New Issue
Block a user