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

some boring stuff, like better multimonitor & keyboard support

This commit is contained in:
20kdc 2018-03-22 02:33:52 +00:00
parent 53db9fd2cb
commit 87932ab26c
10 changed files with 418 additions and 83 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
# leaving in preSH.tar.gz for anyone who's interested # leaving in preSH.tar.gz for anyone who's interested
# in how NOT to do compression # in how NOT to do compression
code.tar
work.tar work.tar
work work
work/ work/

View File

@ -2,24 +2,30 @@
-- No warranty is provided, implied or otherwise. -- No warranty is provided, implied or otherwise.
-- 'neolithic': Text Editor -- 'neolithic': Text Editor
-- This was textedit (femto) from KittenOS brought kicking and screaming into the NEO world -- This was textedit (femto) from KittenOS 'ported' to NEO.
-- It also has fixes for bugs involving wide text, and runs faster due to the chars -> lines change. -- It also has fixes for bugs involving wide text, and runs faster due to the chars -> lines change.
-- needs translation??? figure out how to do translation in the new system NICELY local mapping, _ = unicode.keymap("ASQCVDJK")
local mappingFinal = {}
for i = 1, #mapping do
mappingFinal[i] = unicode.sub(mapping, i, i)
end
local lines = { local lines = {
"Neolithic: Text Editor", "Neolithic: Text Editor",
"^A, ^S, ^Q: Load, Save, New", "Keymap " .. unicode.getKeymap() .. ", to correct, type",
"^C, ^V, ^D: Copy, Paste, Delete Line", "\"A Cruel Jump's Kinesis: DVSQuest\"",
"Then, restart the text editor.",
"^" .. mappingFinal[1] .. ", ^" .. mappingFinal[2] .. ", ^" .. mappingFinal[3] .. ": Load, Save, New",
"^" .. mappingFinal[4] .. ", ^" .. mappingFinal[5] .. ", ^" .. mappingFinal[6] .. ": Copy, Paste, Delete Line",
-- These two are meant to replace similar functionality in GNU Nano -- These two are meant to replace similar functionality in GNU Nano
-- (which I consider the best console text editor out there - Neolithic is an *imitation* and a poor one at that), -- (which I consider the best console text editor out there - Neolithic is an *imitation* and a poor one at that),
-- except fixing a UI flaw by instead making J responsible for resetting the append flag, -- except fixing a UI flaw by instead making J responsible for resetting the append flag,
-- so the user can more or less arbitrarily mash together lines -- so the user can more or less arbitrarily mash together lines
"^J: Reset 'append' flag for Cut Lines", "^" .. mappingFinal[7] .. ": Reset 'append' flag for Cut Lines",
"^K: Cut Line(s)", "^" .. mappingFinal[8] .. ": Cut Line(s)",
"^<arrows>: Resize Win", "^<arrows>: Resize Win",
"'^' is Control.", "'^' is Control.",
"Wide text can be pasted in,", "Wide text & clipboard supported.",
" using your 'actual' clipboard.",
" ", " ",
} }

View File

@ -172,12 +172,13 @@ local function updateRegion(monitorId, x, y, w, h, surfaceSpanCache)
end end
local function updateStatus() local function updateStatus()
statusLine = "Λ-¶: menu, ◣-Λ-C: Session hardkill" statusLine = "Λ-¶: menu (launch 'pass' to logout)"
if surfaces[1] then if surfaces[1] then
if #monitors > 1 then if #monitors > 1 then
statusLine = "Λ-: move, Λ-Z: switch, Λ-X: swMonitor" -- 123456789X123456789X123456789X123456789X123456789X
statusLine = "Λ-+: move, Λ-Z: switch, Λ-X: swMonitor, Λ-C: close"
else else
statusLine = "Λ-: move, Λ-Z: switch" statusLine = "Λ-+: move, Λ-Z: switch, Λ-C: close"
end end
end end
statusLine = unicode.safeTextFormat(statusLine) statusLine = unicode.safeTextFormat(statusLine)
@ -370,12 +371,13 @@ everestProvider(function (pkg, pid, sendSig)
end end
local m = 0 local m = 0
if renderingAllowed() then m = 1 end if renderingAllowed() then m = 1 end
if surfaces[1] then m = surfaces[1][1] end
local surf = {m, 1, 1, w, h} local surf = {m, 1, 1, w, h}
local focusState = false local focusState = false
local llid = lid local llid = lid
lid = lid + 1 lid = lid + 1
local specialDragHandler local specialDragHandler
surf[6] = function (ev, a, b, c) surf[6] = function (ev, a, b, c, d, e)
-- Must forward surface events -- Must forward surface events
if ev == "focus" then if ev == "focus" then
focusState = a focusState = a
@ -401,6 +403,13 @@ everestProvider(function (pkg, pid, sendSig)
end end
b = b - 1 b = b - 1
end end
if ev == "scroll" then
b = b - 1
end
if ev == "drop" then
specialDragHandler = nil
b = b - 1
end
if ev == "line" then if ev == "line" then
if a == 1 then if a == 1 then
local lw = surf[4] local lw = surf[4]
@ -426,7 +435,7 @@ everestProvider(function (pkg, pid, sendSig)
handleSpan(surf, surf[4], a, " ", 0, 0) handleSpan(surf, surf[4], a, " ", 0, 0)
a = a - 1 a = a - 1
end end
sendSig(llid, ev, a, b, c) sendSig(llid, ev, a, b, c, d, e)
end end
local osrf = surfaces[1] local osrf = surfaces[1]
table.insert(surfaces, 1, surf) table.insert(surfaces, 1, surf)
@ -580,19 +589,20 @@ while true do
for k, v in ipairs(monitors) do for k, v in ipairs(monitors) do
if v[2] == s[2] then if v[2] == s[2] then
local x, y = math.floor(s[3]), math.floor(s[4]) local x, y = math.floor(s[3]), math.floor(s[4])
local ix, iy = s[3] - x, s[4] - y
local sid, lx, ly = surfaceAt(k, x, y) local sid, lx, ly = surfaceAt(k, x, y)
if sid then if sid then
local os = surfaces[1] local os = surfaces[1]
local ns = table.remove(surfaces, sid) local ns = table.remove(surfaces, sid)
table.insert(surfaces, 1, ns) table.insert(surfaces, 1, ns)
changeFocus(os) changeFocus(os)
ns[6]("touch", lx, ly) ns[6]("touch", lx, ly, ix, iy, s[5])
end end
break break
end end
end end
end end
if s[1] == "h.drag" then if s[1] == "h.drag" or s[1] == "h.drop" or s[1] == "h.scroll" then
-- Pass to focus surface, even if out of bounds -- Pass to focus surface, even if out of bounds
local focus = surfaces[1] local focus = surfaces[1]
if focus then if focus then
@ -600,7 +610,9 @@ while true do
if v[2] == s[2] then if v[2] == s[2] then
if k == focus[1] then if k == focus[1] then
local x, y = (math.floor(s[3]) - focus[2]) + 1, (math.floor(s[4]) - focus[3]) + 1 local x, y = (math.floor(s[3]) - focus[2]) + 1, (math.floor(s[4]) - focus[3]) + 1
focus[6]("drag", x, y) local ix, iy = s[3] - math.floor(s[3]), s[4] - math.floor(s[4])
-- Ok, so let's see...
focus[6](s[1]:sub(3), x, y, ix, iy, s[5])
end end
break break
end end

View File

@ -3,9 +3,10 @@
-- s-donkonit : config, shutdown, screens -- s-donkonit : config, shutdown, screens
-- Doesn't matter what calls this service, because there's a mutex here.
local donkonitSPProvider = neo.requireAccess("r.neo.sys.manage", "creating NEO core APIs") -- Restrict to s- local donkonitSPProvider = neo.requireAccess("r.neo.sys.manage", "creating NEO core APIs") -- Restrict to s-
-- Doesn't matter what calls this service, because there's a mutex here.
local donkonitRDProvider = neo.requireAccess("r.neo.sys.screens", "creating NEO core APIs") local donkonitRDProvider = neo.requireAccess("r.neo.sys.screens", "creating NEO core APIs")
local glacierDCProvider = neo.requireAccess("r.neo.sys.randr", "creating NEO core APIs")
local computer = neo.requireAccess("k.computer", "shutting down") local computer = neo.requireAccess("k.computer", "shutting down")
local fs = neo.requireAccess("c.filesystem", "settings I/O") local fs = neo.requireAccess("c.filesystem", "settings I/O")
@ -21,6 +22,7 @@ end
-- keys are pids -- keys are pids
local targs = {} -- settings notify targs local targs = {} -- settings notify targs
local targsDC = {} -- displaycontrol settings notify targs
local targsSD = {} -- shutdown notify targs local targsSD = {} -- shutdown notify targs
local targsST = {} -- saving throws local targsST = {} -- saving throws
@ -70,9 +72,9 @@ local function saveSettings()
st.close() st.close()
end end
-- Monitor management stuff -- [i] = screenProxy
local monitorPool = {} local monitorPool = {}
-- {gpu, claimedLoseCallback} -- [screenAddr] = {gpu, claimedLoseCallback}
local monitorClaims = {} local monitorClaims = {}
local function announceFreeMonitor(address, except) local function announceFreeMonitor(address, except)
@ -97,17 +99,38 @@ local function getGPU(monitor)
return bestG return bestG
end end
local function sRattle(name, val)
for _, v in pairs(targs) do
v("set_setting", name, val)
end
if name:sub(1, 4) == "scr." then
for k, v in pairs(targsDC) do
if not targs[k] then
v("set_setting", name, val)
end
end
end
end
-- Settings integration w/ monitors
local function getMonitorSettings(a)
local w = tonumber(settings["scr.w." .. a]) or 80
local h = tonumber(settings["scr.h." .. a]) or 25
local d = tonumber(settings["scr.d." .. a]) or 8
w, h, d = math.floor(w), math.floor(h), math.floor(d)
return w, h, d
end
local function setupMonitor(gpu, monitor) local function setupMonitor(gpu, monitor)
local maxW, maxH = gpu.maxResolution() local maxW, maxH = gpu.maxResolution()
local maxD = gpu.maxDepth() local maxD = gpu.maxDepth()
local w = tonumber(settings["scr.w." .. monitor.address]) or 80 local w, h, d = getMonitorSettings(monitor.address)
local h = tonumber(settings["scr.h." .. monitor.address]) or 25
local d = tonumber(settings["scr.d." .. monitor.address]) or 8
w, h, d = math.floor(w), math.floor(h), math.floor(d)
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)
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.h." .. monitor.address, tostring(h))
sRattle("scr.d." .. monitor.address, tostring(d))
gpu.setResolution(w, h) gpu.setResolution(w, h)
gpu.setDepth(d) gpu.setDepth(d)
pcall(saveSettings) pcall(saveSettings)
@ -132,18 +155,17 @@ donkonitSPProvider(function (pkg, pid, sendSig)
local val = nil local val = nil
if name == "password" then val = "" end if name == "password" then val = "" end
settings[name] = val settings[name] = val
for _, v in pairs(targs) do sRattle(name, val)
v("set_setting", name, val)
end
pcall(saveSettings) pcall(saveSettings)
end, end,
setSetting = function (name, val) setSetting = function (name, val)
if type(name) ~= "string" then error("Setting name must be string") end if type(name) ~= "string" then error("Setting name must be string") end
if type(val) ~= "string" then error("Setting value must be string") end if type(val) ~= "string" then error("Setting value must be string") end
settings[name] = val settings[name] = val
for _, v in pairs(targs) do -- NOTE: Either a monitor is under application control,
v("set_setting", name, val) -- or it's not under any control.
end -- Monitor settings are applied on the transition to control.
sRattle(name, val)
pcall(saveSettings) pcall(saveSettings)
--saveSettings() --saveSettings()
end, end,
@ -249,10 +271,11 @@ loadSettings()
local function rescanDevs() local function rescanDevs()
monitorPool = {} monitorPool = {}
local hasGPU = gpus.list()() local hasGPU = gpus.list()()
for k, v in pairs(monitorClaims) do
v[2](true)
end
monitorClaims = {}
for m in screens.list() do for m in screens.list() do
if monitorClaims[m.address] then
monitorClaims[m.address][2](true)
end
table.insert(monitorPool, m) table.insert(monitorPool, m)
if hasGPU then if hasGPU then
announceFreeMonitor(m.address) announceFreeMonitor(m.address)
@ -265,6 +288,45 @@ rescanDevs()
saveSettings() saveSettings()
-- -- -- --
glacierDCProvider(function (pkg, pid, sendSig)
targsDC[pid] = sendSig
return {
getKnownMonitors = function ()
local tbl = {}
-- yes, this should work fine so long as GMS is the *last* one #luaquirks
for k, v in ipairs(monitorPool) do
tbl[k] = {v.address, false, getMonitorSettings(v.address)}
end
for k, v in pairs(monitorClaims) do
table.insert(tbl, {k, true, getMonitorSettings(v.address)})
end
end,
changeMonitorSetup = function (ma, w, h, d)
neo.ensureType(ma, "string")
neo.ensureType(w, "number")
neo.ensureType(h, "number")
neo.ensureType(d, "number")
w = math.floor(w)
h = math.floor(h)
d = math.floor(d)
if w < 1 then error("Invalid width") end
if h < 1 then error("Invalid height") end
if d < 1 then error("Invalid depth") end
w, h, d = tostring(w), tostring(h), tostring(d)
settings["scr.w." .. ma] = w
settings["scr.h." .. ma] = h
settings["scr.d." .. ma] = d
sRattle("scr.w." .. ma, w)
sRattle("scr.h." .. ma, h)
sRattle("scr.d." .. ma, d)
pcall(saveSettings)
end,
forceRescan = rescanDevs
}
end)
-- main loop
while true do while true do
local s = {coroutine.yield()} local s = {coroutine.yield()}
if s[1] == "k.timer" then if s[1] == "k.timer" then
@ -272,13 +334,19 @@ while true do
shutdownFin(shutdownMode) shutdownFin(shutdownMode)
end end
if s[1] == "h.component_added" then if s[1] == "h.component_added" then
rescanDevs() -- Before doing anything, is it worth it?
if s[3] == "gpu" or s[3] == "screen" then
rescanDevs()
end
end end
if s[1] == "h.component_removed" then if s[1] == "h.component_removed" then
rescanDevs() if s[3] == "gpu" or s[3] == "screen" then
rescanDevs()
end
end end
if s[1] == "k.procdie" then if s[1] == "k.procdie" then
targs[s[3]] = nil targs[s[3]] = nil
targsDC[s[3]] = nil
targsSD[s[3]] = nil targsSD[s[3]] = nil
if targsST[s[3]] then if targsST[s[3]] then
if s[4] then if s[4] then

View File

@ -276,11 +276,28 @@ end
local function initializeSystem() local function initializeSystem()
-- System has just booted, bristol is in charge -- System has just booted, bristol is in charge
-- Firstly, initialize hardware to something sensible since we don't know scrcfg -- Firstly, since we don't know scrcfg, let's work out something sensible.
gpu = neo.requestAccess("c.gpu").list()() -- Note that we should try to keep going with this if there's no reason to do otherwise.
if gpu then local gpuAc = neo.requestAccess("c.gpu")
screen = neo.requestAccess("c.screen").list()() local screenAc = neo.requestAccess("c.screen")
if not screen then gpu = nil end -- time to setup gpu/screen variables!
if gpuAc and screenAc then
local scrBestWHD = 0
for s in screenAc.list() do
for g in gpuAc.list() do
g.bind(s.address)
local w, h = g.maxResolution()
local whd = w * h * g.maxDepth()
if whd > scrBestWHD then
screen = s
gpu = g
scrBestWHD = whd
end
end
if screen then
break
end
end
end end
if gpu then if gpu then
screen = screen.address screen = screen.address

View File

@ -2,11 +2,7 @@
-- This is released into the public domain. -- This is released into the public domain.
-- No warranty is provided, implied or otherwise. -- No warranty is provided, implied or otherwise.
-- NOTE: If it's not "local", it's because k.root ought to access it. -- NOTE: local is considered unnecessary in kernel since 21 March
-- List of things that apply:
-- primaryDisk, timers, libraries, processes, accesses, wrapMeta,
-- distEvent, baseProcEnv, loadLibraryInner, retrieveAccess,
-- start
-- Debugging option, turns process errors into actual errors (!) -- Debugging option, turns process errors into actual errors (!)
local criticalFailure = false local criticalFailure = false
@ -14,9 +10,9 @@ local criticalFailure = false
local readBufSize = 2048 local readBufSize = 2048
-- A function used for logging, usable by programs. -- A function used for logging, usable by programs.
local emergencyFunction = function () end
-- Comment this out if you don't want programs to have -- Comment this out if you don't want programs to have
-- access to ocemu's logger. -- access to ocemu's logger.
local emergencyFunction = function () end
local ocemu = component.list("ocemu", true)() local ocemu = component.list("ocemu", true)()
if ocemu then if ocemu then
ocemu = component.proxy(ocemu) ocemu = component.proxy(ocemu)
@ -77,7 +73,13 @@ function unicode.undoSafeTextFormat(s)
for i = 1, unicode.len(s) do for i = 1, unicode.len(s) do
if not ignoreNext then if not ignoreNext then
local ch = unicode.sub(s, i, i) local ch = unicode.sub(s, i, i)
ignoreNext = unicode.charWidth(ch) ~= 1 if unicode.charWidth(ch) ~= 1 then
if unicode.sub(s, i + 1, i + 1) ~= " " then
ch = " "
else
ignoreNext = true
end
end
res = res .. ch res = res .. ch
else else
ignoreNext = false ignoreNext = false
@ -86,6 +88,168 @@ function unicode.undoSafeTextFormat(s)
return res return res
end end
-- Yes, this is what I used the freed up SR space for.
-- Think of this as my apology for refusing translation support on NEO.
keymaps = {
-- 'synth' keymap
["unknown"] = {
},
["??-qwerty"] = {
{16, "QWERTYUIOP"},
{16, "qwertyuiop"},
{30, "ASDFGHJKL"},
{30, "asdfghjkl"},
{44, "ZXCVBNM"},
{44, "zxcvbnm"},
},
["??-qwertz"] = {
{16, "QWERTZUIOP"},
{16, "qwertzuiop"},
{30, "ASDFGHJKL"},
{30, "asdfghjkl"},
{44, "YXCVBNM"},
{44, "yxcvbnm"},
},
["??-dvorak"] = {
{19, "PYFGCRL"},
{19, "pyfgcrl"},
{30, "AOEUIDHTN"},
{30, "aoeuidhtn"},
{45, "QJKXBM"},
{45, "qjkxbm"},
},
["??-dvorak-full"] = {
{16, "\"<>PYFGCRL"},
{16, "',.pyfgcrl"},
{30, "AOEUIDHTN"},
{30, "aoeuidhtn"},
{44, ":QJKXBM"},
{44, ";qjkxbm"},
},
["cz-qwertz"] = {
{2, "+ěščřžýáíé="}, -- The last letter is a *compose key*. #WTF
{2, "1234567890%"},
{15, "\tQWERTZUIOP/("},
{15, "\tqwertzuiopú)"},
{30, "ASDFGHJKL\"!'"},
{30, "asdfghjklů§"},
{44, "YXCVBNM?:_"},
{44, "yxcvbnm,.-"},
},
["de-qwertz"] = {
{2, "1234567890ß"}, -- another one?
{2, "!\"§$%&/()=?"},
{15, "\tQWERTZUIOPÜ*"},
{15, "\tqwertzuiopü+"},
{30, "ASDFGHJKLÖÄ"},
{30, "asdfghjklÖÄ"},
{44, "YXCVBNM;:_"},
{44, "yxcvbnm,.-"},
},
["uk-qwerty"] = {
{41, "`"}, {41, "¬"},
{2, "1234567890-="},
{2, "!\"£$%^&*()_+"},
{15, "\tQWERTYUIOP{}"},
{15, "\tqwertyuiop[]"},
{30, "ASDFGHJKL:@"},
{30, "asdfghjkl;'"},
{44, "ZXCVBNM<>?"},
{44, "zxcvbnm,./"},
},
["us-qwerty"] = {
{41, "`"}, {41, "~"},
{2, "1234567890-="},
{2, "!@#$%^&*()_+"},
{15, "\tQWERTYUIOP{}\r"},
{15, "\tqwertyuiop[]\r"},
{30, "ASDFGHJKL\"|"},
{30, "asdfghjkl'\\"},
{44, "ZXCVBNM<>?"},
{44, "zxcvbnm,./"},
}
}
local unknownKeymapContains = {}
currentKeymap = "unknown"
-- Not really part of this package, but...
unicode.getKeymap = function ()
return currentKeymap
end
-- raw info functions, they return nil if they don't know
-- Due to a fantastic oversight, unicode.byte or such doesn't exist in OCEmu,
-- so things are managed via "Ch" internally.
unicode.getKCByCh = function (ch, km)
for _, v in ipairs(keymaps[km]) do
local spanLen = unicode.len(v[2])
for i = 1, spanLen do
if unicode.sub(v[2], i, i) == ch then
return v[1] + i - 1
end
end
end
end
unicode.getChByKC = function (kc, km)
for _, v in ipairs(keymaps[km]) do
local spanLen = unicode.len(v[2])
if kc >= v[1] and kc < v[1] + spanLen then
return unicode.sub(v[2], kc + 1 - v[1], kc + 1 - v[1])
end
end
end
local function keymapDetect(ka, kc)
if ka == 0 then return end
if kc == 0 then return end
-- simple algorithm, does the job
-- emergencyFunction("KD: " .. unicode.char(signal[3]) .. " " .. signal[4])
ka = unicode.char(ka)
if unknownKeymapContains[ka] ~= kc then
unknownKeymapContains[ka] = kc
table.insert(keymaps["unknown"], {kc, ka})
else
return
end
-- 25% of used keys must be known to pass
local bestRatio = 0.25
local bestName = "unknown"
for k, _ in pairs(keymaps) do
if k ~= "unknown" then
local count = 0
local total = 0
for kCh, kc in pairs(unknownKeymapContains) do
if unicode.getKCByCh(kCh, k) == kc then
count = count + 1
end
total = total + 1
end
local r = count / math.max(1, total)
if r > bestRatio then
bestRatio = r
bestName = k
end
end
end
if currentKeymap ~= bestName then emergencyFunction("Switching to Keymap " .. bestName) end
currentKeymap = bestName
end
-- rtext, codes (codes can end up nil)
-- rtext is text's letters switched over
-- (for code that will still use the same keycodes,
-- but wants to display correct text)
-- codes is the keycodes mapped based on the letters
unicode.keymap = function (text)
local km = unicode.getKeymap()
local rtext = ""
local codes = {}
for i = 1, unicode.len(text) do
local ch = unicode.sub(text, i, i)
local okc = unicode.getKCByCh(ch, "uk-qwerty") or 0
rtext = rtext .. (unicode.getChByKC(okc, currentKeymap) or unicode.getChByKC(okc, "unknown") or ch)
codes[i] = unicode.getKCByCh(ch, currentKeymap) or unicode.getKCByCh(ch, "unknown")
end
return rtext, codes
end
local function loadfile(s, e) local function loadfile(s, e)
local h = primaryDisk.open(s) local h = primaryDisk.open(s)
if h then if h then
@ -308,6 +472,7 @@ function baseProcEnv()
totalIdleTime = function () return idleTime end, totalIdleTime = function () return idleTime end,
ensurePath = ensurePath, ensurePath = ensurePath,
ensurePathComponent = ensurePathComponent, ensurePathComponent = ensurePathComponent,
ensureType = ensureType
} }
} }
end end
@ -631,6 +796,9 @@ while true do
if dist < 0.05 then dist = 0.05 end if dist < 0.05 then dist = 0.05 end
end end
local signal = {computer.pullSignal(dist)} local signal = {computer.pullSignal(dist)}
if signal[1] == "key_down" then
keymapDetect(signal[3], signal[4])
end
idleTime = idleTime + (computer.uptime() - now) idleTime = idleTime + (computer.uptime() - now)
if signal[1] then if signal[1] then
distEvent(nil, "h." .. signal[1], select(2, table.unpack(signal))) distEvent(nil, "h." .. signal[1], select(2, table.unpack(signal)))

View File

@ -216,6 +216,45 @@ return function (event, neo)
end end
end end
rotateSelIndex() rotateSelIndex()
local function moveIndex(vertical, negative)
if not controls[selIndex] then return end
local currentMA, currentOA = controls[selIndex].y, controls[selIndex].x
local currentMAX = controls[selIndex].y + controls[selIndex].h - 1
if vertical then
currentMA, currentOA = controls[selIndex].x, controls[selIndex].y
currentMAX = controls[selIndex].x + controls[selIndex].w - 1
end
local bestOA = 9001
local bestSI = selIndex
if negative then
bestOA = -9000
end
for k, v in ipairs(controls) do
if (k ~= selIndex) and v.selectable then
local ma, oa = v.y, v.x
local max = v.y + v.h - 1
if vertical then
ma, oa = v.x, v.y
max = v.x + v.w - 1
end
if (ma >= currentMA and ma <= currentMAX) or (max >= currentMA and max <= currentMAX)
or (currentMA >= ma and currentMA <= max) or (currentMAX >= ma and currentMAX <= max) then
if negative then
if (oa < currentOA) and (oa > bestOA) then
bestOA = oa
bestSI = k
end
else
if (oa > currentOA) and (oa < bestOA) then
bestOA = oa
bestSI = k
end
end
end
end
end
selIndex = bestSI
end
local function doLine(window, a) local function doLine(window, a)
window.span(1, a, (" "):rep(w), bg, fg) window.span(1, a, (" "):rep(w), bg, fg)
@ -237,7 +276,17 @@ return function (event, neo)
end end
end end
return function (window, ev, a, b, c) local function moveIndexAU(window, vertical, negative)
local c1 = controls[selIndex]
moveIndex(vertical, negative)
local c2 = controls[selIndex]
local cache = {}
if c1 then doZone(window, c1, cache) end
if c2 then doZone(window, c2, cache) end
end
return function (window, ev, a, b, c, d, e)
-- X,Y,Xi,Yi,B
if ev == "touch" then if ev == "touch" then
local found = nil local found = nil
for k, v in ipairs(controls) do for k, v in ipairs(controls) do
@ -263,20 +312,35 @@ return function (event, neo)
if c2 then if c2 then
doZone(window, c2, cache) doZone(window, c2, cache)
if c2.touch then if c2.touch then
c2.touch(window, function () doZone(window, c2) end, (a - c2.x) + 1, (b - c2.y) + 1) c2.touch(window, function () doZone(window, c2) end, (a - c2.x) + 1, (b - c2.y) + 1, c, d, e)
end end
end end
end end
end -- X,Y,Xi,Yi,B (or D for scroll)
if ev == "drag" then elseif ev == "drag" or ev == "drop" or ev == "scroll" then
if controls[selIndex] then if controls[selIndex] then
if controls[selIndex].drag then if controls[selIndex][ev] then
controls[selIndex].drag(window, function () doZone(window, controls[selIndex]) end, (a - controls[selIndex].x) + 1, (b - controls[selIndex].y) + 1) controls[selIndex][ev](window, function () doZone(window, controls[selIndex]) end, (a - controls[selIndex].x) + 1, (b - controls[selIndex].y) + 1, c, d, e)
end end
end end
end elseif ev == "key" then
if ev == "key" then if b == 203 then
if a == 9 then if c then
moveIndexAU(window, false, true)
end
elseif b == 205 then
if c then
moveIndexAU(window, false, false)
end
elseif b == 200 then
if c then
moveIndexAU(window, true, true)
end
elseif b == 208 then
if c then
moveIndexAU(window, true, false)
end
elseif a == 9 then
if c then if c then
local c1 = controls[selIndex] local c1 = controls[selIndex]
rotateSelIndex() rotateSelIndex()
@ -285,18 +349,14 @@ return 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
else elseif controls[selIndex] then
if controls[selIndex] then if controls[selIndex].key then
if controls[selIndex].key then controls[selIndex].key(window, function () doZone(window, controls[selIndex]) end, a, b, c)
controls[selIndex].key(window, function () doZone(window, controls[selIndex]) end, a, b, c)
end
end end
end end
end elseif ev == "line" then
if ev == "line" then
doLine(window, a) doLine(window, a)
end elseif ev == "close" then
if ev == "close" then
closing(window) closing(window)
end end
end, doZone end, doZone

View File

@ -2,24 +2,27 @@
-- No warranty is provided, implied or otherwise. XX -- No warranty is provided, implied or otherwise. XX
local sector = io.write -- XX local sector = io.write -- XX
-- BUNDIVIDE reference implementation for integration XX -- BUNDIVIDE reference implementation for integration XX
local Cs,Cbu,Cb,Cw,Cp,Ci,CP,CB,CD={},128,"",128,"" local Cs,Cbu,Cb,Cw,Cp,Ct,Ci,CP,CB,CD={},128,"",128,"",""
CP=function(d,b,i) CP=function(d,b)
i=1 Ct=Ct..d
while i<=#d do while#Ct>2 do
b=d:byte(i) b=Ct:byte()
i=i+1 Ct=Ct:sub(2)
if b==127 then if b==127then
b=d:byte(i) b=Ct:byte()
i=i+1 Ct=Ct:sub(2)
if b==127 then if b==127then
b=d:byte(i)+254 b=Ct:byte()+254
i=i+1 if b>255then
b=b-256
end
Ct=Ct:sub(2)
else else
b=b+127 b=b+127
end end
end end
Cp=Cp..string.char(b) Cp=Cp..string.char(b)
if #Cp==512 then if #Cp==512then
sector(Cp) sector(Cp)
Cp="" Cp=""
end end
@ -63,4 +66,4 @@ CD(io.read("*a")) -- XX
--local Ch=D.open("init-bdivide.lua","rb")-- --local Ch=D.open("init-bdivide.lua","rb")--
--dieCB=function()D.close(Ch)D.remove("init-bdivide.lua")end-- --dieCB=function()D.close(Ch)D.remove("init-bdivide.lua")end--
--while true do local t=D.read(Ch, 64)if not t then break end CD(t)end-- --while true do local t=D.read(Ch, 64)if not t then break end CD(t)end--
CD("\x00\x00")CP(Cs[Cw]) CD("\x00\x00")CP(Cs[Cw] .. "\x00\x00")

View File

@ -52,7 +52,7 @@ local function tA(s)
else else
tFN = s:sub(1, 100):gsub("\x00", "") tFN = s:sub(1, 100):gsub("\x00", "")
local sz = convoct(s:sub(125, 135)) local sz = convoct(s:sub(125, 135))
if tFN:sub(1, 5) ~= "work/" then if tFN:sub(1, 5) ~= "code/" then
tW = math.ceil(sz / 512) tW = math.ceil(sz / 512)
else else
tFN = tFN:sub(6) tFN = tFN:sub(6)

View File

@ -3,7 +3,7 @@
# This is released into the public domain. # This is released into the public domain.
# No warranty is provided, implied or otherwise. # No warranty is provided, implied or otherwise.
echo "WARNING: This will rm -rf the 'work' folder." rm code.tar
# safety measure: unless we are likely in the right folder, DO NOT CONTINUE # Hey, look behind you, there's nothing to see here.
git status && stat imitclaw.lua code/apps/sys-init.lua && rm -rf work work.tar # ... ok, are they seriously all named "Mann"?
lua imitclaw.lua && tar -cf work.tar work tar --owner=gray:0 --group=mann:0 -cf code.tar code