All the fixes, and app-klogo

This commit is contained in:
20kdc 2018-03-28 22:15:09 +01:00
parent c2b373f261
commit 8e0c74c41b
12 changed files with 380 additions and 61 deletions

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"
}, },

Binary file not shown.

View File

@ -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
View 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

View File

@ -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)

View File

@ -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

View File

@ -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)