1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-26 04:18:05 +11:00

Compare commits

...

8 Commits

Author SHA1 Message Date
20kdc
fab88f137c svc-virtudev: virtual devices for KittenOS NEO 2020-03-28 00:32:16 +00:00
20kdc
7680aa7579 Apparently I missed a few details of the packaging stuff for setup 2020-03-27 22:35:00 +00:00
20kdc
429de87a61 Add missing secpolicy version bump (oops) 2019-01-02 15:28:59 +00:00
20kdc
7307eb30a4 Consider 'tablet' component & tablet_use safe in secpolicy, fix incorrect documentation on k.computer 2019-01-02 15:28:01 +00:00
20kdc
0d9583fcff r8: Yet another release for a single feature request
This isn't getting pushed until AmandaC's tested it.
I'm not sure this is such a good idea, anyway ; if it's for load/save
 workflow improvements, wouldn't it be better to have a file access method
 that allows for file re-opening?
That said, there's a limit to *that* before you just have to say,
 "Just use /data/".
2018-12-24 21:11:59 +00:00
20kdc
375995c2d3 r7: Fix the read-only-FS filemanager bug AmandaC found
This should fix everything
2018-12-11 16:40:30 +00:00
20kdc
efae7716da Merge branch 'repository' (for rwhateverwe'reon) 2018-12-11 15:26:23 +00:00
20kdc
27bd71f9e4 (Probably) fix sys-init self-destructing if no monitors around 2018-11-09 23:19:27 +00:00
21 changed files with 344 additions and 93 deletions

View File

@ -3,7 +3,7 @@
return { return {
["neo"] = { ["neo"] = {
desc = "KittenOS NEO Kernel & Base Libs", desc = "KittenOS NEO Kernel & Base Libs",
v = 5, v = 8,
deps = { deps = {
}, },
dirs = { dirs = {
@ -26,7 +26,7 @@ return {
}, },
["neo-init"] = { ["neo-init"] = {
desc = "KittenOS NEO / sys-init (startup)", desc = "KittenOS NEO / sys-init (startup)",
v = 6, v = 7,
deps = { deps = {
"neo", "neo",
"neo-icecap", "neo-icecap",
@ -67,7 +67,7 @@ return {
}, },
["neo-icecap"] = { ["neo-icecap"] = {
desc = "KittenOS NEO / Icecap", desc = "KittenOS NEO / Icecap",
v = 3, v = 8,
deps = { deps = {
"neo" "neo"
}, },
@ -84,7 +84,7 @@ return {
}, },
["neo-secpolicy"] = { ["neo-secpolicy"] = {
desc = "KittenOS NEO / Secpolicy", desc = "KittenOS NEO / Secpolicy",
v = 2, v = 8,
deps = { deps = {
}, },
dirs = { dirs = {
@ -125,7 +125,7 @@ return {
}, },
["neo-logo"] = { ["neo-logo"] = {
desc = "KittenOS NEO Logo (data)", desc = "KittenOS NEO Logo (data)",
v = 6, v = 8,
deps = { deps = {
}, },
dirs = { dirs = {

View File

@ -24,7 +24,7 @@ return {
}, },
["neo-docs"] = { ["neo-docs"] = {
desc = "KittenOS NEO system documentation", desc = "KittenOS NEO system documentation",
v = 5, v = 8,
deps = { deps = {
"zzz-license-pd" "zzz-license-pd"
}, },
@ -251,6 +251,24 @@ return {
"docs/repoauthors/app-slaunch" "docs/repoauthors/app-slaunch"
}, },
}, },
["svc-virtudev"] = {
desc = "a clone of vcomponent",
v = 0,
deps = {
"neo",
"zzz-license-pd"
},
dirs = {
"apps",
"docs",
"docs/repoauthors"
},
files = {
"apps/svc-virtudev.lua",
"apps/app-vdrslamp.lua",
"docs/repoauthors/svc-virtudev"
},
},
-- libraries -- libraries
["lib-knbs"] = { ["lib-knbs"] = {
desc = "NBS reader/writer library", desc = "NBS reader/writer library",

View File

@ -109,17 +109,20 @@ donkonitDFProvider(function (pkg, pid, sendSig)
end end
end end
return { return {
showFileDialogAsync = function (forWrite) showFileDialogAsync = function (forWrite, defName)
if not rawequal(forWrite, nil) then if not rawequal(forWrite, nil) then
require("sys-filewrap").ensureMode(forWrite) require("sys-filewrap").ensureMode(forWrite)
end end
if not rawequal(defName, nil) then
defName = tostring(defName)
end
-- Not hooked into the event API, so can't safely interfere -- Not hooked into the event API, so can't safely interfere
-- Thus, this is async and uses a return event. -- Thus, this is async and uses a return event.
local tag = {} local tag = {}
neo.scheduleTimer(0) neo.scheduleTimer(0)
table.insert(todo, function () table.insert(todo, function ()
-- sys-filedialog is yet another "library to control memory usage". -- sys-filedialog is yet another "library to control memory usage".
local closer = require("sys-filedialog")(event, nexus, function (res) openHandles[tag] = nil sendSig("filedialog", tag, res) end, neo.requireAccess("c.filesystem", "file managers"), pkg, forWrite) local closer = require("sys-filedialog")(event, nexus, function (res) openHandles[tag] = nil sendSig("filedialog", tag, res) end, neo.requireAccess("c.filesystem", "file managers"), pkg, forWrite, defName)
openHandles[tag] = closer openHandles[tag] = closer
end) end)
return tag return tag

View File

@ -65,6 +65,17 @@ local function basicDraw(bg)
return gpu return gpu
end end
local function consoleEventHandler(ev)
if ev[1] == "h._kosneo_syslog" then
local text = ""
for i = 3, #ev do
if i ~= 3 then text = text .. " " end
text = text .. tostring(ev[i])
end
table.insert(console, text)
end
end
-- Attempts to get an NSS monitor with a priority list of screens -- Attempts to get an NSS monitor with a priority list of screens
local function retrieveNssMonitor(...) local function retrieveNssMonitor(...)
local spc = {...} local spc = {...}
@ -133,17 +144,6 @@ local function retrieveNssMonitor(...)
end end
end end
local function consoleEventHandler(ev)
if ev[1] == "h._kosneo_syslog" then
local text = ""
for i = 3, #ev do
if i ~= 3 then text = text .. " " end
text = text .. tostring(ev[i])
end
table.insert(console, text)
end
end
local function sleep(t) local function sleep(t)
neo.scheduleTimer(os.uptime() + t) neo.scheduleTimer(os.uptime() + t)
while true do while true do

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -25,7 +25,7 @@ newNeoux = function (event, neo)
end end
end) end)
local neoux = {} local neoux = {}
neoux.fileDialog = function (forWrite, callback) neoux.fileDialog = function (forWrite, callback, dfn)
local sync = false local sync = false
local rtt = nil local rtt = nil
if not callback then if not callback then
@ -35,7 +35,7 @@ newNeoux = function (event, neo)
rtt = rt rtt = rt
end end
end end
local tag = neo.requireAccess("x.neo.pub.base", "filedialog").showFileDialogAsync(forWrite) local tag = neo.requireAccess("x.neo.pub.base", "filedialog").showFileDialogAsync(forWrite, dfn)
local f local f
f = function (_, fd, tg, re) f = function (_, fd, tg, re)
if fd == "filedialog" then if fd == "filedialog" then

View File

@ -2,7 +2,7 @@
-- No warranty is provided, implied or otherwise. -- No warranty is provided, implied or otherwise.
-- just don't bother with proper indent here -- just don't bother with proper indent here
return function (event, nexus, retFunc, fs, pkg, mode) return function (event, nexus, retFunc, fs, pkg, mode, defName)
local fmt = require("fmttext") local fmt = require("fmttext")
local class = "manage" local class = "manage"
@ -141,7 +141,7 @@ end
nexus.create(w, h, class .. " " .. pkg, function (w, ev, a, b, c) nexus.create(w, h, class .. " " .. pkg, function (w, ev, a, b, c)
if not wnd then if not wnd then
wnd = w wnd = w
prepareNode(require("sys-filevfs")(fs, mode)) prepareNode(require("sys-filevfs")(fs, mode, defName))
end end
if ev == "key" then if ev == "key" then
key2(a, b, c) key2(a, b, c)

View File

@ -16,12 +16,12 @@ end
local getFsNode, getRoot local getFsNode, getRoot
local setupCopyNode local setupCopyNode
function setupCopyNode(parent, myRoot, op, complete, impliedName) function setupCopyNode(parent, myRoot, op, complete)
local function handleResult(aRes, res) local function handleResult(aRes, res)
if aRes then if aRes then
return complete(res, true) return complete(res, true)
else else
return nil, setupCopyNode(parent, res, op, complete, impliedName) return nil, setupCopyNode(parent, res, op, complete)
end end
end end
return { return {
@ -32,11 +32,6 @@ function setupCopyNode(parent, myRoot, op, complete, impliedName)
complete(nil, false) complete(nil, false)
return false, parent return false, parent
end}) end})
if impliedName and myRoot.unknownAvailable then
table.insert(l, {"Implied: " .. impliedName, function ()
return handleResult(myRoot.selectUnknown(impliedName))
end})
end
for _, v in ipairs(myRoot.list()) do for _, v in ipairs(myRoot.list()) do
table.insert(l, {v[1], function () table.insert(l, {v[1], function ()
return handleResult(v[2]()) return handleResult(v[2]())
@ -54,7 +49,7 @@ local function setupCopyVirtualEnvironment(fs, parent, fwrap, impliedName)
if not fwrap then if not fwrap then
return false, dialog("Could not open source", parent) return false, dialog("Could not open source", parent)
end end
local myRoot = getRoot(fs, true) local myRoot = getRoot(fs, true, impliedName)
-- Setup wrapping node -- Setup wrapping node
return setupCopyNode(parent, myRoot, "Copy", function (fwrap2, intent) return setupCopyNode(parent, myRoot, "Copy", function (fwrap2, intent)
if not fwrap2 then if not fwrap2 then
@ -72,14 +67,22 @@ local function setupCopyVirtualEnvironment(fs, parent, fwrap, impliedName)
fwrap.close() fwrap.close()
fwrap2.close() fwrap2.close()
return false, dialog("Completed copy.", parent) return false, dialog("Completed copy.", parent)
end, impliedName) end)
end end
function getFsNode(fs, parent, fsc, path, mode) function getFsNode(fs, parent, fsc, path, mode, impliedName)
local va = fsc.address:sub(1, 4) local va = fsc.address:sub(1, 4)
local fscrw = not fsc.isReadOnly() local fscrw = not fsc.isReadOnly()
local dir = path:sub(#path, #path) == "/" local dir = path:sub(#path, #path) == "/"
local confirmedDel = false local confirmedDel = false
local t local t
local function selectUnknown(text)
-- Relies on text being nil if used in leaf node
local rt, re = require("sys-filewrap").create(fsc, path .. (text or ""), mode)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return true, rt
end
t = { t = {
name = ((dir and "DIR: ") or "FILE: ") .. va .. path, name = ((dir and "DIR: ") or "FILE: ") .. va .. path,
list = function () list = function ()
@ -94,7 +97,7 @@ function getFsNode(fs, parent, fsc, path, mode)
if fsc.isDirectory(fp) then if fsc.isDirectory(fp) then
nm = "D: " .. v nm = "D: " .. v
end end
n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode) end} n[k + 1] = {nm, function () return nil, getFsNode(fs, t, fsc, fp, mode, impliedName) end}
end end
end end
if fscrw then if fscrw then
@ -114,31 +117,6 @@ function getFsNode(fs, parent, fsc, path, mode)
end end
} }
end}) end})
else
if mode ~= nil then
local tx = "Open"
if mode == true then
tx = "Save"
elseif mode == "append" then
tx = "Append"
end
if fscrw or mode == false then
table.insert(n, {tx, function ()
local rt, re = require("sys-filewrap").create(fsc, path, mode)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return true, rt
end})
end
end
table.insert(n, {"Copy", function ()
local rt, re = require("sys-filewrap").create(fsc, path, false)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
end})
end end
if path ~= "/" then if path ~= "/" then
local delText = "Delete" local delText = "Delete"
@ -172,20 +150,38 @@ function getFsNode(fs, parent, fsc, path, mode)
end}) end})
end end
end end
if not dir then
table.insert(n, {"Copy", function ()
local rt, re = require("sys-filewrap").create(fsc, path, false)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return nil, setupCopyVirtualEnvironment(fs, parent, rt, path:match("[^/]*$") or "")
end})
if (fscrw or mode == false) and (mode ~= nil) then
local tx = "Open"
if mode == true then
tx = "Save (Overwrite)"
elseif mode == "append" then
tx = "Append"
end
if fscrw or mode == false then
table.insert(n, {tx, selectUnknown})
end
end
elseif impliedName then
table.insert(n, {"Implied: " .. impliedName, function ()
return selectUnknown(impliedName)
end})
end
return n return n
end, end,
unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw), unknownAvailable = dir and (mode ~= nil) and ((mode == false) or fscrw),
selectUnknown = function (text) selectUnknown = selectUnknown
local rt, re = require("sys-filewrap").create(fsc, path .. text, mode)
if not rt then
return false, dialog("Open Error: " .. tostring(re), parent)
end
return true, rt
end
} }
return t return t
end end
function getRoot(fs, mode) function getRoot(fs, mode, defName)
local t local t
t = { t = {
name = "DRVS:", name = "DRVS:",
@ -209,7 +205,7 @@ function getRoot(fs, mode)
id = "RW " .. amount .. "% " .. mb .. "M " .. id id = "RW " .. amount .. "% " .. mb .. "M " .. id
end end
table.insert(l, {fsi.address:sub(1, 4) .. " " .. id, function () table.insert(l, {fsi.address:sub(1, 4) .. " " .. id, function ()
return nil, getFsNode(fs, t, fsi, "/", mode) return nil, getFsNode(fs, t, fsi, "/", mode, defName)
end}) end})
end end
return l return l

View File

@ -22,7 +22,7 @@ local function actualPolicy(pkg, pid, perm, matchesSvc)
return "allow" return "allow"
end end
-- These signals are harmless, though they identify HW (as does everything in OC...) -- These signals are harmless, though they identify HW (as does everything in OC...)
if perm == "s.h.component_added" or perm == "s.h.component_removed" then if perm == "s.h.component_added" or perm == "s.h.component_removed" or perm == "s.h.tablet_use" or perm == "c.tablet" then
return "allow" return "allow"
end end
if matchesSvc("r.", pkg, perm) then if matchesSvc("r.", pkg, perm) then

View File

@ -34,8 +34,12 @@ while blk ~= "" do
break break
end end
local pm = p - 1 local pm = p - 1
bestData = string.char(128 + lm, math.floor(pm / 256), pm % 256) local thirdByte = pm % 256
bestRes = pfx -- anti ']'-corruption helper
if thirdByte ~= 93 then
bestData = string.char(128 + lm, math.floor(pm / 256), thirdByte)
bestRes = pfx
end
end end
-- ok, encode! -- ok, encode!
io.write(bestData) io.write(bestData)

View File

@ -6,9 +6,5 @@
cp ocemu.cfg.default ocemu.cfg && rm -rf c1-sda c1-sdb cp ocemu.cfg.default ocemu.cfg && rm -rf c1-sda c1-sdb
mkdir c1-sda c1-sdb mkdir c1-sda c1-sdb
echo -n c1-sda > c1-eeprom/data.bin echo -n c1-sda > c1-eeprom/data.bin
cd ..
cp -r code/* laboratory/c1-sdb/ ./update.sh
cp -r repository/* laboratory/c1-sdb/
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/code-claw.lua > /dev/null
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/repo-claw.lua >> /dev/null
cp -r laboratory/c1-sdb/* laboratory/c1-sda/

11
laboratory/update.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
# This is released into the public domain.
# No warranty is provided, implied or otherwise.
cd ..
cp -r code/* laboratory/c1-sdb/
cp -r repository/* laboratory/c1-sdb/
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/code-claw.lua > /dev/null
lua claw/clawconv.lua laboratory/c1-sdb/data/app-claw/ < claw/repo-claw.lua >> /dev/null
cp -r laboratory/c1-sdb/* laboratory/c1-sda/

View File

@ -5,8 +5,11 @@
# Package repository using supplied inst.lua (use inst-gold.lua for repository branch) # Package repository using supplied inst.lua (use inst-gold.lua for repository branch)
stat repobuild/data/app-claw && rm -rf repobuild # this is a guard check to avoid removing repobuild if it's blatantly
mkdir repobuild # not the actual repobuild directory (this is an rm -rf after all)
stat repobuild/data/app-claw 1>/dev/null 2>/dev/null && rm -rf repobuild
mkdir -p repobuild
cp -r code/* repobuild/ cp -r code/* repobuild/
cp -r repository/* repobuild/ cp -r repository/* repobuild/
cp $1 repobuild/ cp $1 repobuild/

View File

@ -4,6 +4,7 @@
# No warranty is provided, implied or otherwise. # No warranty is provided, implied or otherwise.
rm code/data/app-claw/* rm code/data/app-claw/*
mkdir -p code/data/app-claw
lua claw/clawconv.lua code/data/app-claw/ < claw/code-claw.lua > /dev/null lua claw/clawconv.lua code/data/app-claw/ < claw/code-claw.lua > /dev/null
rm code.tar rm code.tar
# Hey, look behind you, there's nothing to see here. # Hey, look behind you, there's nothing to see here.

View File

@ -0,0 +1,49 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- svc-vdrslamp.lua : Virtual Redstone Lamp
-- Authors: 20kdc
local vdev = neo.requireAccess("x.svc.virtudev", "lamp dev")
local evr = neo.requireAccess("x.neo.pub.window", "the lamp")
local wnd = evr(12, 6)
local bLine = (" "):rep(12)
local function blank()
return 0
end
local total = 0
vdev.install({
type = "redstone",
address = "vdrslamp-" .. neo.pid,
slot = 0,
getWakeThreshold = blank,
setWakeThreshold = blank,
getInput = blank,
getOutput = function (i)
return total
end,
setOutput = function (i, v)
total = v
wnd.setSize(12, 6)
end
})
while true do
local e = {coroutine.yield()}
if e[1] == "x.neo.pub.window" then
if e[3] == "close" then
-- the ignorance of unregistration is deliberate
-- a working impl. will properly recover
return
elseif e[3] == "line" then
local bg = 0xFFFFFF
if total == 0 then bg = 0 end
wnd.span(1, e[4], bLine, bg, bg)
end
end
end

View File

@ -0,0 +1,156 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- svc-virtudev.lua : Virtual Device interface
-- Authors: 20kdc
local ic = neo.requireAccess("x.neo.pub.base", "to lock x.svc.virtudev")
-- this is a pretty powerful permission, and PROBABLY EXPLOITABLE
ic.lockPerm("x.svc.virtudev")
local r = neo.requireAccess("r.svc.virtudev", "api endpoint")
local root = neo.requireAccess("k.root", "the ability to modify the component API")
local proxies = {}
local types = {}
local function uninstall(k)
proxies[k] = nil
types[k] = nil
root.computer.pushSignal("component_removed", k, types[k])
end
local users = {}
local userCount = 0
r(function (pkg, pid, sendSig)
local userAddresses = {}
users[pid] = userAddresses
userCount = userCount + 1
return {
install = function (proxy)
local proxyAddress = proxy.address
local proxyType = proxy.type
assert(type(proxyAddress) == "string")
assert(type(proxyType) == "string")
assert(not proxies[proxyAddress], "proxy address in use: " .. proxyAddress)
proxies[proxyAddress] = proxy
types[proxyAddress] = proxyType
userAddresses[proxyAddress] = true
root.computer.pushSignal("component_added", proxyAddress, proxyType)
return function (a, ...)
root.computer.pushSignal(a, proxyAddress, ...)
end
end,
uninstall = function (k)
if userAddresses[k] then
uninstall(k)
userAddresses[k] = nil
end
end
}
end)
local componentProxyRaw = root.component.proxy
local componentTypeRaw = root.component.type
local componentMethodsRaw = root.component.methods
local componentFieldsRaw = root.component.fields
local componentDocRaw = root.component.doc
local componentInvokeRaw = root.component.invoke
local componentListRaw = root.component.list
root.component.proxy = function (address)
if proxies[address] then
return proxies[address]
end
return componentProxyRaw(address)
end
root.component.type = function (address)
if types[address] then
return types[address]
end
return componentTypeRaw(address)
end
local function methodsFieldsHandler(address, methods)
if proxies[address] then
local mt = {}
for k, v in pairs(proxies[address]) do
if (type(v) == "function") == methods then
mt[k] = true
end
end
return mt
end
if methods then
return componentMethodsRaw(address)
else
return componentFieldsRaw(address)
end
end
root.component.methods = function (address) return methodsFieldsHandler(address, true) end
root.component.fields = function (address) return methodsFieldsHandler(address, false) end
root.component.doc = function (address, method)
if proxies[address] then
return tostring(proxies[address][method])
end
return componentDocRaw(address, method)
end
root.component.invoke = function (address, method, ...)
if proxies[address] then
return proxies[address][method](...)
end
return componentInvokeRaw(address, method, ...)
end
root.component.list = function (f, e)
local iter = componentListRaw(f, e)
local ended = false
local others = {}
for k, v in pairs(types) do
if (f == v) or ((not e) and v:find(f, 1, true)) then
table.insert(others, {k, v})
end
end
return function ()
if not ended then
local a, t = iter()
if not a then
ended = true
else
return a, t
end
end
-- at end of that, so what about others
local ent = table.remove(others, 1)
if ent then
return table.unpack(ent)
end
end
end
while true do
local e1, e2, e3 = coroutine.yield()
if e1 == "k.procdie" then
if users[e3] then
for k, _ in pairs(users[e3]) do
uninstall(k)
end
users[e3] = nil
userCount = userCount - 1
if userCount == 0 then
break
end
end
end
end
root.component.proxy = componentProxyRaw
root.component.type = componentTypeRaw
root.component.methods = componentMethodsRaw
root.component.fields = componentFieldsRaw
root.component.doc = componentDocRaw
root.component.invoke = componentInvokeRaw
root.component.list = componentListRaw

View File

@ -53,9 +53,9 @@ Here, "*" means that everything after
program to start up. program to start up.
"k.computer": The "computer" table, "k.computer": The "computer" table,
with wrapMeta applied, with wrapMeta applied.
pullSignal removed, The security check may be aliased to
and also pushSignal. the "k.root" permission in future.
"k.kill": function (pid) to kill any "k.kill": function (pid) to kill any
process on the system. process on the system.

View File

@ -0,0 +1,3 @@
repository/apps/svc-virtudev.lua: 20kdc, Public Domain
repository/apps/app-vdrslamp.lua: 20kdc, Public Domain

View File

@ -15,10 +15,12 @@ The mode you give to it can be one of
true: Write "wb" true: Write "wb"
"append": Append "ab" "append": Append "ab"
May have some readability May have some readability
propertiues - just in properties - just in
case, I've added 'read', case, I've added 'read',
but don't get your hopes but don't get your hopes
up... up...
"access": Like read, but can be
re-opened for write.
It returns two things - a table, that It returns two things - a table, that
being the file object, and the being the file object, and the
@ -37,7 +39,9 @@ The possible functions are:
[aw] write(data): Writes to the [aw] write(data): Writes to the
file. file.
[arw] read(data): Reads from the [arw] read(data): Reads from the
file. file. data is the byte count.
However, "*a" is valid here.
Other string-based options are not.
NOTE: Some of these may not actually NOTE: Some of these may not actually
work. They're just there as more or work. They're just there as more or

View File

@ -33,16 +33,19 @@ The most reliable reference on the
Main functions: Main functions:
fileDialog(mode[, callback]): neoux.fileDialog(mode, [callback],
[dfn]):
Creates a file dialog, returning a Creates a file dialog, returning a
file wrapper (see ul-fwrap) on file wrapper (see ul-fwrap) on
success, or nil on failure. success, or nil on failure.
If a callback is given, then nil is If callback isn't nil, then nil is
always returned immediately, and always returned immediately, and
the callback is called when the the callback is called with the
dialog has shown. result when the dialog is closed.
mode is the mode used for the file, mode is the mode used for the file,
so see ul-fwrap for values. so see ul-fwrap for values.
dfn is, if not nil, the default
'implied' filename (as with Copy).
neoux.create(w, h, title, callback): neoux.create(w, h, title, callback):
Creates a window, Creates a window,

View File

@ -57,11 +57,15 @@ Paths for the IO parts of this API
the standard KittenOS NEO path the standard KittenOS NEO path
safety rules in the kernel. safety rules in the kernel.
showFileDialogAsync(mode): Shows a showFileDialogAsync(mode, dfn):
filedialog with a given filemode, Shows a filedialog with a given
or nil for "none". Returns a new, filemode, or nil for "none".
empty table as a "tag", and emits a Returns a new, empty table as a
"filedialog" event on completion. "tag", and emits a "filedialog"
event on completion.
dfn meanwhile adds an 'Implied'
button for reasonable default file
names.
myApi: A string such as "svc.abc" myApi: A string such as "svc.abc"
for the program svc-abc, used for for the program svc-abc, used for