mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
tty part 1
This commit is contained in:
parent
b72764963d
commit
b1e45d7627
4 changed files with 808 additions and 273 deletions
490
clite/bios.js
Normal file
490
clite/bios.js
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
(function() {
|
||||
var bios = {
|
||||
data:{
|
||||
version:'0.1',
|
||||
id:'BIOS',
|
||||
bootable:'clite/core.js',
|
||||
entry:null
|
||||
},
|
||||
core:{
|
||||
getHex:function(s) {
|
||||
if (typeof s === 'string')
|
||||
s = parseInt(s);
|
||||
if (typeof s !== 'number')
|
||||
return '0';
|
||||
return s.toString(16).toUpperCase();
|
||||
},
|
||||
writeStringVGA:function(x,y,v,fg) {
|
||||
for (var i=0; i<v.length; i++) {
|
||||
if (x+i >= 80)
|
||||
break;
|
||||
bios.video.text.io.write(x+i,y,v[i]);
|
||||
}
|
||||
if (typeof fg === 'undefined')
|
||||
return;
|
||||
for (var i=0; i<v.length; i++) {
|
||||
if (x+i >= 80)
|
||||
break;
|
||||
bios.video.text.io.writeSet(1,x+i,y,fg);
|
||||
}
|
||||
},
|
||||
expose:function(name,fn) {
|
||||
window['BIOS'+name] = function() {
|
||||
try{
|
||||
fn.apply(null,arguments);
|
||||
} catch(err) {}
|
||||
setTimeout(function() {window['BIOS'+name] = null;},10);
|
||||
}
|
||||
},
|
||||
load:{
|
||||
script:function(name,callback) {
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = name+'?d='+(new Date).getTime();
|
||||
script.onload = callback;
|
||||
head.appendChild(script);
|
||||
},
|
||||
file:function(name,callback) {
|
||||
if (window.location.protocol == 'file:') { // this is a dirty hack and I hate it, just let me open a file: path!
|
||||
clite.term.setCustom({type:'file',callback:callback});
|
||||
clite.term.writeLine('open file: '+name);
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(name+'?d='+(new Date).getTime())
|
||||
.then(function(response) {
|
||||
return response.text();
|
||||
})
|
||||
.then(function(data) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
io:{
|
||||
read:function(c) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
return bios.data.id;
|
||||
break;
|
||||
case 1:
|
||||
return bios.video.io;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
write:function(c,d) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
bios.data.id = d;
|
||||
document.title = d;
|
||||
break;
|
||||
case 1:
|
||||
bios.video.setMode(d);
|
||||
break;
|
||||
case 2:
|
||||
// writing to the keyboard handler without a callback flushes the buffer
|
||||
if (typeof d === 'undefined') {
|
||||
bios.input.keybuffer.buff = [];
|
||||
return;
|
||||
}
|
||||
bios.input.keybuffer.rcvr = d;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
},
|
||||
},
|
||||
video:{
|
||||
mode:{
|
||||
current:0,
|
||||
modes:[null],
|
||||
},
|
||||
viewport:{
|
||||
width:0,
|
||||
height:0
|
||||
},
|
||||
viewportResize:function() {
|
||||
bios.video.viewport.width = window.innerWidth;
|
||||
bios.video.viewport.height = window.innerHeight;
|
||||
if (bios.video.mode.current == 0)
|
||||
return;
|
||||
try{
|
||||
bios.video.mode.modes[bios.video.mode.current].resize();
|
||||
}catch(err) {}
|
||||
},
|
||||
init:function() {
|
||||
window.addEventListener('resize',bios.video.viewportResize);
|
||||
bios.video.viewportResize();
|
||||
bios.video.mode.modes[1] = bios.video.text;
|
||||
bios.video.mode.modes[2] = bios.video.graphic;
|
||||
bios.video.setMode(1);
|
||||
},
|
||||
io:{},
|
||||
setMode:function(m) {
|
||||
if (m < 0 || m >= bios.video.mode.modes.length)
|
||||
return false;
|
||||
if (m == bios.video.mode.current)
|
||||
return true;
|
||||
try{
|
||||
bios.video.mode.modes[bios.video.mode.current].exit();
|
||||
} catch(err) {}
|
||||
bios.video.mode.current = m;
|
||||
try{
|
||||
bios.video.mode.modes[bios.video.mode.current].init();
|
||||
} catch(err) {
|
||||
bios.video.io = null;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
input:{
|
||||
el:null,
|
||||
state:0,
|
||||
init:function() {
|
||||
bios.input.el = document.getElementById('input');
|
||||
bios.input.keyboard.init();
|
||||
bios.input.state = 1;
|
||||
},
|
||||
keybuffer:{
|
||||
rcvr:null,
|
||||
buff:[],
|
||||
input:function(key) {
|
||||
if (bios.input.state == 1) {
|
||||
try{
|
||||
bios.input.keybuffer.rcvr(key);
|
||||
return;
|
||||
} catch(err) {}
|
||||
}
|
||||
bios.input.keybuffer.buff.push(key);
|
||||
}
|
||||
}
|
||||
},
|
||||
boot:{
|
||||
setEntry:function(fn) {
|
||||
bios.data.entry = fn;
|
||||
setTimeout(bios.boot.doBoot,10);
|
||||
},
|
||||
preBoot:function() {
|
||||
bios.core.expose('entry',bios.boot.setEntry);
|
||||
bios.core.load.script(bios.data.bootable,null);
|
||||
},
|
||||
doBoot:function() {
|
||||
try{
|
||||
bios.data.entry(bios);
|
||||
}catch(err) {
|
||||
bios.core.writeStringVGA(1,7,'Error in bootable entry point',4);
|
||||
bios.core.writeStringVGA(1,8,err.message,6);
|
||||
}
|
||||
}
|
||||
},
|
||||
init:function() {
|
||||
bios.io.write(0,bios.data.id);
|
||||
bios.video.init();
|
||||
bios.core.writeStringVGA(2,0,'JS Basic Input Output System');
|
||||
var v = bios.data.version.toString();
|
||||
bios.core.writeStringVGA(78-v.length,0,v);
|
||||
for (var i=0; i<80; i++) {
|
||||
bios.video.io.writeSet(0,i,0,15);
|
||||
bios.video.io.writeSet(1,i,0,0);
|
||||
}
|
||||
bios.core.writeStringVGA(3,1,'Initialising...');
|
||||
bios.core.writeStringVGA(3,3,'Video Graphics Array:');
|
||||
bios.core.writeStringVGA(25,3,'Done',2);
|
||||
|
||||
bios.core.writeStringVGA(3,4,'Input Devices:');
|
||||
bios.input.init();
|
||||
bios.core.writeStringVGA(25,4,'Done',2);
|
||||
|
||||
bios.core.writeStringVGA(0,6,'Booting...');
|
||||
|
||||
bios.boot.preBoot();
|
||||
}
|
||||
};
|
||||
|
||||
bios.video.text = {
|
||||
data:{
|
||||
el:null,
|
||||
isinit:false,
|
||||
screen:{
|
||||
width:0,
|
||||
height:0,
|
||||
nw:0,
|
||||
nh:0,
|
||||
f:0
|
||||
}
|
||||
},
|
||||
internal:{
|
||||
getElement:function() {
|
||||
bios.video.text.data.el = document.getElementById('vga');
|
||||
if (typeof bios.video.text.data.el !== 'undefined' && bios.video.text.data.el != null)
|
||||
return bios.video.text.data.el;
|
||||
bios.video.text.data.el = document.createNode('div');
|
||||
bios.video.text.data.el.id = 'vga';
|
||||
bios.video.text.data.el.className = 'vga';
|
||||
document.body.appendChild(bios.video.text.data.el);
|
||||
return bios.video.data.text.el;
|
||||
},
|
||||
getPix:function(x,y) {
|
||||
return document.getElementById('vga-'+y+'-'+x);
|
||||
},
|
||||
dataToClass:function(d) {
|
||||
var c = 'vga-b'+d.bg+' vga-f'+d.fg;
|
||||
if (d.bk)
|
||||
c += ' vga-blink';
|
||||
return c;
|
||||
}
|
||||
},
|
||||
io:{
|
||||
write:function(x,y,v) {
|
||||
if (x < 0 || x > 79 || y < 0 || y > 24)
|
||||
return;
|
||||
var c = bios.video.text.internal.getPix(x,y);
|
||||
c.textContent = v;
|
||||
},
|
||||
setBG:function(x,y,id) {
|
||||
if (id < 0 || id > 15)
|
||||
return;
|
||||
var c = bios.video.text.internal.getPix(x,y);
|
||||
c.data.bg = bios.core.getHex(id);
|
||||
c.className = bios.video.text.internal.dataToClass(c.data);
|
||||
},
|
||||
setFG:function(x,y,id) {
|
||||
if (id < 0 || id > 15)
|
||||
return;
|
||||
var c = bios.video.text.internal.getPix(x,y);
|
||||
c.data.fg = bios.core.getHex(id);
|
||||
c.className = bios.video.text.internal.dataToClass(c.data);
|
||||
},
|
||||
setBlink:function(x,y,id) {
|
||||
if (typeof id !== 'boolean')
|
||||
return;
|
||||
var c = bios.video.text.internal.getPix(x,y);
|
||||
c.data.bk = id;
|
||||
c.className = bios.video.text.internal.dataToClass(c.data);
|
||||
},
|
||||
writeSet:function(name,x,y,id) {
|
||||
if (x < 0 || x > 79 || y < 0 || y > 24)
|
||||
return;
|
||||
switch(name) {
|
||||
case 0:
|
||||
bios.video.text.io.setBG(x,y,id);
|
||||
break;
|
||||
case 1:
|
||||
bios.video.text.io.setFG(x,y,id);
|
||||
break;
|
||||
case 2:
|
||||
bios.video.text.io.setBlink(x,y,id);
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
},
|
||||
init:function() {
|
||||
if (!bios.video.text.internal.getElement())
|
||||
return false;
|
||||
|
||||
bios.video.io = bios.video.text.io;
|
||||
|
||||
bios.video.text.data.el.innerHTML = '';
|
||||
var ypx;
|
||||
var xpx;
|
||||
var c = document.createElement('span');
|
||||
c.textContent = 'W';
|
||||
bios.video.text.data.el.appendChild(c);
|
||||
ypx = c.offsetHeight;
|
||||
xpx = c.offsetWidth;
|
||||
bios.video.text.data.el.innerHTML = '';
|
||||
bios.video.text.data.el.style.width = (xpx*80)+'px';
|
||||
bios.video.text.data.el.style.height = (ypx*25)+'px';
|
||||
bios.video.text.data.el.style.position = 'relative';
|
||||
for (var y=0; y<25; y++) {
|
||||
for (var x=0; x<80; x++) {
|
||||
var c = document.createElement('div');
|
||||
c.className = 'vga-b0 vga-fF';
|
||||
c.style.position = 'absolute';
|
||||
c.style.top = (y*ypx)+'px';
|
||||
c.style.left = (x*xpx)+'px';
|
||||
c.style.width = xpx+'px';
|
||||
c.style.height = ypx+'px';
|
||||
c.data = {bg:'0',fg:'F',bk:false};
|
||||
c.id = 'vga-'+y+'-'+x;
|
||||
bios.video.text.data.el.appendChild(c);
|
||||
}
|
||||
}
|
||||
bios.video.text.resize();
|
||||
bios.video.text.data.isinit = true;
|
||||
return bios.video.text.data.isinit;
|
||||
},
|
||||
exit:function() {
|
||||
if (!bios.video.text.internal.getElement())
|
||||
return;
|
||||
bios.video.text.data.el.innerHTML = '';
|
||||
},
|
||||
resize:function() {
|
||||
var w = bios.video.viewport.width;
|
||||
var h = bios.video.viewport.height;
|
||||
|
||||
if (h/1.42 > w) {
|
||||
h = w/1.42;
|
||||
}else{
|
||||
w = h*1.42;
|
||||
}
|
||||
|
||||
bios.video.text.data.screen.height = parseInt(h);
|
||||
bios.video.text.data.screen.width = parseInt(w);
|
||||
bios.video.text.data.screen.nh = parseInt(h/25);
|
||||
bios.video.text.data.screen.nw = parseInt(w/80);
|
||||
bios.video.text.data.screen.f = parseInt(bios.video.text.data.screen.nh/1.2);
|
||||
|
||||
var e = bios.video.text.internal.getElement();
|
||||
e.style.width = bios.video.text.data.screen.width+'px';
|
||||
e.style.height = bios.video.text.data.screen.height+'px';
|
||||
for (var y=0; y<25; y++) {
|
||||
for (var x=0; x<80; x++) {
|
||||
var c = bios.video.text.internal.getPix(x,y);
|
||||
c.style.top = (y*bios.video.text.data.screen.nh)+'px';
|
||||
c.style.left = (x*bios.video.text.data.screen.nw)+'px';
|
||||
c.style.width = bios.video.text.data.screen.nw+'px';
|
||||
c.style.height = bios.video.text.data.screen.nh+'px';
|
||||
c.style.fontSize = bios.video.text.data.screen.f+'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bios.video.graphic = {
|
||||
init:function() {
|
||||
},
|
||||
exit:function() {
|
||||
}
|
||||
};
|
||||
|
||||
bios.input.keyboard = {
|
||||
data:{
|
||||
el:null
|
||||
},
|
||||
internal:{
|
||||
rawDown:function(e) {
|
||||
if (e.isComposing)
|
||||
return;
|
||||
var k = {
|
||||
down:true,
|
||||
code:0,
|
||||
char:0,
|
||||
lchr:0
|
||||
};
|
||||
if (e.key.length == 1) {
|
||||
k.char = e.key;
|
||||
k.lchr = e.key.toLowerCase();
|
||||
k.code = k.lchr.charCodeAt(0);
|
||||
}else{
|
||||
bios.input.keyboard.internal.getKeyData(e.key,k);
|
||||
}
|
||||
if (k.code == 0)
|
||||
return false;
|
||||
bios.input.keybuffer.input(k);
|
||||
return false;
|
||||
},
|
||||
rawUp:function(e) {
|
||||
if (e.isComposing)
|
||||
return;
|
||||
var k = {
|
||||
down:false,
|
||||
code:0,
|
||||
char:0,
|
||||
lchr:0
|
||||
};
|
||||
if (e.key.length == 1) {
|
||||
k.char = e.key;
|
||||
k.lchr = e.key.toLowerCase();
|
||||
k.code = k.lchr.charCodeAt(0);
|
||||
}else{
|
||||
bios.input.keyboard.internal.getKeyData(e.key,k);
|
||||
}
|
||||
if (k.code == 0)
|
||||
return false;
|
||||
e.target.value = '';
|
||||
bios.input.keybuffer.input(k);
|
||||
return false;
|
||||
},
|
||||
resetFocus:function(e) {
|
||||
setTimeout(function() {
|
||||
try{
|
||||
document.getElementById('kbd').focus();
|
||||
} catch(err) {}
|
||||
},10);
|
||||
return false;
|
||||
},
|
||||
getKeyData:function(key,k) {
|
||||
// arrow keys are assigned the ascii device control 1/2/3/4 code
|
||||
// this will be changed by the tty
|
||||
switch (key) {
|
||||
case "Down":
|
||||
case "ArrowDown":
|
||||
k.code = 17;
|
||||
break;
|
||||
case "Up":
|
||||
case "ArrowUp":
|
||||
k.code = 18;
|
||||
break;
|
||||
case "Left":
|
||||
case "ArrowLeft":
|
||||
k.code = 19;
|
||||
break;
|
||||
case "Right":
|
||||
case "ArrowRight":
|
||||
k.code = 20;
|
||||
break;
|
||||
case "Enter":
|
||||
k.char = String.fromCharCode(10);
|
||||
k.lchr = k.char;
|
||||
k.code = 10;
|
||||
break;
|
||||
case "Esc":
|
||||
case "Escape":
|
||||
k.code = 27;
|
||||
break;
|
||||
case "Shift":
|
||||
k.code = 15;
|
||||
break;
|
||||
case "Tab":
|
||||
k.char = String.fromCharCode(9);
|
||||
k.lchr = k.char;
|
||||
k.code = 9;
|
||||
break;
|
||||
case "Delete":
|
||||
k.char = String.fromCharCode(127);
|
||||
k.lchr = k.char;
|
||||
k.code = 127;
|
||||
break;
|
||||
default:
|
||||
k.code = key;
|
||||
}
|
||||
}
|
||||
},
|
||||
getElement:function() {
|
||||
bios.input.keyboard.data.el = document.getElementById('kbd');
|
||||
if (typeof bios.input.keyboard.data.el === 'undefined' || bios.input.keyboard.data.el == null) {
|
||||
bios.input.keyboard.data.el = document.createElement('textarea');
|
||||
bios.input.keyboard.data.el.id = 'kbd';
|
||||
bios.input.keyboard.data.el.className = 'kbd';
|
||||
bios.input.keyboard.data.el.style.zIndex = '100';
|
||||
bios.input.keyboard.data.el.style.display = 'block';
|
||||
}
|
||||
bios.input.keyboard.data.el.addEventListener('keydown',bios.input.keyboard.internal.rawDown);
|
||||
bios.input.keyboard.data.el.addEventListener('keyup',bios.input.keyboard.internal.rawUp);
|
||||
bios.input.keyboard.data.el.addEventListener('focusout',bios.input.keyboard.internal.resetFocus);
|
||||
return bios.input.keyboard.data.el;
|
||||
},
|
||||
init:function() {
|
||||
var el = bios.input.keyboard.getElement();
|
||||
bios.input.el.appendChild(el);
|
||||
bios.input.keyboard.internal.resetFocus();
|
||||
}
|
||||
};
|
||||
|
||||
bios.core.expose('init',bios.init);
|
||||
})();
|
||||
|
|
@ -1,18 +1,7 @@
|
|||
html,body {margin:0; padding:0; overflow:hidden; width:100%; height:100%; max-height:100%; background-color:#000000; color:#FFFFFF; font-family:monospace; font-size:14px; line-height:20px;}
|
||||
body {display:flex; flex-direction:column;}
|
||||
|
||||
div, header, section, article, p, form, h1 {display:block; margin:0; padding:0;}
|
||||
header {padding:10px;}
|
||||
header h1 {line-height:40px; font-size:30px;}
|
||||
section {}
|
||||
section.content {position:relative; overflow:hidden; width:100%; height:100%;}
|
||||
section.content div#terminal {width:100%; min-width: 500px; max-width:1000px; min-height:100px; height:100%; font-size:14px; line-height:20px; margin:0 auto; overflow:hidden; overflow-y:auto; scrollbar-width:none;}
|
||||
section.content div#termalt {width:100%; min-width: 500px; max-width:1000px; min-height:100px; height:100%; font-size:14px; line-height:20px; margin:0 auto; overflow:hidden; overflow-y:auto; scrollbar-width:none; z-index:99; background:#000000;}
|
||||
section.content article {unicode-bidi: embed; white-space: pre-wrap;}
|
||||
section.content form {display:flex;}
|
||||
section.content form label, section.content form input, section.content form input:focus {display:block; border:none; margin:0; padding:0; font-family:monospace; font-size:14px; line-height:20px; background-color:#000000; color:#FFFFFF; outline:none;}
|
||||
section.content form input, section.content form input:focus {flex-grow:100;}
|
||||
html,body {margin:0; padding:0; overflow:auto; width:100%; height:100%; background-color:black; color:white; font-family:monospace; font-size:14px;}
|
||||
body {display:grid; align-items:center;}
|
||||
|
||||
div {display:block; margin:0; padding:0;}
|
||||
div.vga {margin:auto; z-index:10; background-color:#000000;}
|
||||
div.io {position:absolute; top:0px; left:0px; width:100px; height:100px; z-index:3;}
|
||||
div.ioblank {position:absolute; top:0px; left:0px; width:100px; height:100px; z-index:9; background-color:black;}
|
||||
|
|
|
|||
572
clite/core.js
572
clite/core.js
|
|
@ -2,7 +2,8 @@ var clite = {
|
|||
state:{
|
||||
version:'0.4.0',
|
||||
isinit:false,
|
||||
runlevel:1
|
||||
runlevel:1,
|
||||
bios:null,
|
||||
},
|
||||
includes:{
|
||||
// a list of program/command files to load
|
||||
|
|
@ -51,8 +52,8 @@ var clite = {
|
|||
},
|
||||
file:function(name,callback) {
|
||||
if (window.location.protocol == 'file:') { // this is a dirty hack and I hate it, just let me open a file: path!
|
||||
clite.term.setCustom({type:'file',callback:callback});
|
||||
clite.term.writeLine('open file: '+name);
|
||||
//clite.term.setCustom({type:'file',callback:callback});
|
||||
//clite.term.writeLine('open file: '+name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -92,19 +93,34 @@ var clite = {
|
|||
l('clite/core.js',function() {setTimeout('clite.init();',500)});
|
||||
},10);
|
||||
},
|
||||
shutdown:function() {
|
||||
clite.log.write('The system is shutting down');
|
||||
setTimeout(function() {
|
||||
var s = Array.from(document.getElementsByTagName('src'));
|
||||
s.forEach(function(el) {
|
||||
el.parentNode.removeChild(el);
|
||||
});
|
||||
clite.term.ttyctrl('hide');
|
||||
delete clite;
|
||||
clite = null;
|
||||
},10);
|
||||
},
|
||||
hostname:function() {
|
||||
if (window.location.protocol != 'file:')
|
||||
return window.location.hostname;
|
||||
return 'localhost';
|
||||
}
|
||||
},
|
||||
init:function() {
|
||||
if (this.state.isinit)
|
||||
init:function(bios) {
|
||||
if (clite.state.isinit)
|
||||
return;
|
||||
this.state.isinit = true;
|
||||
clite.state.isinit = true;
|
||||
|
||||
this.core.execSafeAsync(function() {
|
||||
clite.term.clear();
|
||||
clite.state.bios = bios;
|
||||
clite.state.bios.io.write(0,'CLIte '+clite.state.version);
|
||||
|
||||
clite.core.execSafeAsync(function() {
|
||||
clite.console.init();
|
||||
var vfsapi = null;
|
||||
|
||||
function defaultDevices() {
|
||||
|
|
@ -187,15 +203,7 @@ var clite = {
|
|||
case 0:
|
||||
clite.state.runlevel = rli;
|
||||
n.data.content.data = 0;
|
||||
setTimeout(function() {
|
||||
var s = Array.from(document.getElementsByTagName('src'));
|
||||
s.forEach(function(el) {
|
||||
el.parentNode.removeChild(el);
|
||||
});
|
||||
clite.term.ttyctrl('hide');
|
||||
delete clite;
|
||||
clite = null;
|
||||
},10);
|
||||
clite.core.shutdown();
|
||||
break;
|
||||
case 1: // essentially the booting runlevel
|
||||
clite.state.runlevel = rli;
|
||||
|
|
@ -228,8 +236,8 @@ var clite = {
|
|||
return false;
|
||||
}
|
||||
n.data.content = {
|
||||
read:null,
|
||||
write:null
|
||||
read:clite.console.read,
|
||||
write:clite.console.write
|
||||
};
|
||||
n.perms = 'crw-rw-rw-';
|
||||
n.data.isdev = true;
|
||||
|
|
@ -243,35 +251,9 @@ var clite = {
|
|||
return false;
|
||||
}
|
||||
n.data.content = {
|
||||
receive:{
|
||||
callback:null,
|
||||
buffer:[],
|
||||
input:function(str) {
|
||||
if (n.data.content.receive.callback != null) {
|
||||
var fn = n.data.content.receive.callback;
|
||||
clite.core.execSafeAsync(function() {
|
||||
fn(str);
|
||||
});
|
||||
n.data.content.receive.callback = null;
|
||||
return;
|
||||
}
|
||||
n.data.content.receive.buffer.push(str);
|
||||
}
|
||||
},
|
||||
read:function(cb) {
|
||||
if (n.data.content.receive.buffer.length > 0) {
|
||||
var str = n.data.content.receive.buffer.shift();
|
||||
cb(str);
|
||||
return true;
|
||||
}
|
||||
n.data.content.receive.callback = cb;
|
||||
clite.term.genForm();
|
||||
clite.term.data.field.focus();
|
||||
return true;
|
||||
},
|
||||
write:clite.term.writeLine
|
||||
read:null,
|
||||
write:null
|
||||
};
|
||||
clite.term.data.handler = n.data.content.receive.input;
|
||||
n.perms = 'crw-rw-rw-';
|
||||
n.data.isdev = true;
|
||||
n.data.istty = true;
|
||||
|
|
@ -449,6 +431,8 @@ cat /etc/greeting
|
|||
clite.log.write('Setting up VFS');
|
||||
clite.vfs.init();
|
||||
vfsapi = clite.vfs.getApi();
|
||||
clite.log.write('Setting up TTY');
|
||||
clite.tty.init(vfsapi);
|
||||
clite.log.init(vfsapi);
|
||||
clite.log.write('Mounting wfs on /');
|
||||
// mount core (root) filesystem using data/filesys.txt
|
||||
|
|
@ -659,6 +643,7 @@ clite.proc = {
|
|||
gid:0, // the group id this process is running as
|
||||
gpid:mapCPID(cpid), // the group pid (parent process id) of this process
|
||||
pid:data.nextid++, // the pid (process id) of this process
|
||||
ctty:0, // the id of the controlling tty for this process
|
||||
func:fn, // the function this process executes
|
||||
waits:[] // array of wait() calls pending for this process on exit
|
||||
});
|
||||
|
|
@ -666,6 +651,7 @@ clite.proc = {
|
|||
if (parent) {
|
||||
proc.uid = parent.uid;
|
||||
proc.gid = parent.gid;
|
||||
proc.ctty = parent.ctty;
|
||||
}
|
||||
data.procs.push(proc);
|
||||
vfsapi.mkFile(0,'/proc/'+proc.pid);
|
||||
|
|
@ -767,12 +753,19 @@ clite.proc = {
|
|||
return 0;
|
||||
return proc.gid;
|
||||
}
|
||||
clite.proc.getTTY = function(pid) {
|
||||
var proc = getProc(pid);
|
||||
if (!proc)
|
||||
return -1;
|
||||
return proc.ctty;
|
||||
}
|
||||
clite.proc.setLogin = function(pid,uid) {
|
||||
var proc = getProc(pid);
|
||||
if (!proc)
|
||||
return false;
|
||||
proc.uid = uid;
|
||||
proc.gid = clite.user.getGID(uid);
|
||||
return true;
|
||||
}
|
||||
clite.proc.init = null;
|
||||
return true;
|
||||
|
|
@ -787,6 +780,8 @@ clite.proc = {
|
|||
addGroup:function() {return false;},
|
||||
getUID:function(pid) {return 0;},
|
||||
getGID:function(pid) {return 0;},
|
||||
getTTY:function(pid) {return 0;},
|
||||
setLogin:function(pid,uid) {return false;}
|
||||
};
|
||||
|
||||
clite.user = {
|
||||
|
|
@ -923,14 +918,7 @@ clite.user = {
|
|||
return 0;
|
||||
return udata.gid;
|
||||
}
|
||||
function setLogin(uid) {
|
||||
var udata = getUser(uid);
|
||||
if (!udata)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
clite.user.genGuest = function() {
|
||||
clite.term.clear();
|
||||
vfsapi.mkDir(0,'/usr/home/guest');
|
||||
var n = vfsapi.getNode(0,'/usr/home/guest');
|
||||
if (n) {
|
||||
|
|
@ -942,17 +930,15 @@ clite.user = {
|
|||
|
||||
vfsapi.mkFile(1,'/usr/home/guest/.shrc');
|
||||
n = vfsapi.getNode(1,'/usr/home/guest/.shrc');
|
||||
if (n) {
|
||||
n.perms = '-rwx------';
|
||||
n.uid = 1;
|
||||
n.gid = 1;
|
||||
n.data.content = `
|
||||
if (!n)
|
||||
return;
|
||||
n.perms = '-rwx------';
|
||||
n.uid = 1;
|
||||
n.gid = 1;
|
||||
n.data.content = `
|
||||
#!/bin/sh
|
||||
cat -l /usr/share/introduction
|
||||
`;
|
||||
}
|
||||
|
||||
setLogin(1);
|
||||
}
|
||||
clite.user.getEnv = function(uid) {
|
||||
var udata = getUser(uid);
|
||||
|
|
@ -1224,7 +1210,12 @@ clite.io = {
|
|||
if (fd.node.data.istty) {
|
||||
try{
|
||||
if (typeof cb === 'function') {
|
||||
fd.node.data.content.read(cb);
|
||||
if (fd.node.data.content.read.length == 2) {
|
||||
var ctty = clite.proc.getTTY(pid);
|
||||
fd.node.data.content.read(ctty,cb);
|
||||
}else{
|
||||
fd.node.data.content.read(cb);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch(err) {}
|
||||
|
|
@ -1254,7 +1245,12 @@ clite.io = {
|
|||
if (fd.node.data.istty) {
|
||||
try{
|
||||
if (typeof cb === 'function') {
|
||||
fd.node.data.content.read(cb);
|
||||
if (fd.node.data.content.read.length == 2) {
|
||||
var ctty = clite.proc.getTTY(pid);
|
||||
fd.node.data.content.read(ctty,cb);
|
||||
}else{
|
||||
fd.node.data.content.read(cb);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch(err) {}
|
||||
|
|
@ -1308,6 +1304,12 @@ clite.io = {
|
|||
if (typeof fd.node.data.content != 'string') {
|
||||
fd.node.time.modify = clite.time.sec();
|
||||
try{
|
||||
if (fd.node.data.content.write.length == 2) {
|
||||
var ctty = clite.proc.getTTY(pid);
|
||||
fd.node.data.content.write(ctty,cb);
|
||||
}else{
|
||||
fd.node.data.content.write(cb);
|
||||
}
|
||||
return fd.node.data.content.write(data);
|
||||
} catch(err) {
|
||||
return false;
|
||||
|
|
@ -2138,7 +2140,7 @@ clite.log = {
|
|||
clite.log.write = function(txt) {
|
||||
if (clite.state.runlevel != 3) {
|
||||
try {
|
||||
clite.term.writeLine(txt);
|
||||
clite.console.write(txt+'\n');
|
||||
} catch(e) {}
|
||||
}
|
||||
var n = vfsapi.getNode(0,'/var/logs');
|
||||
|
|
@ -2154,215 +2156,267 @@ clite.log = {
|
|||
write:function(txt) {
|
||||
clite.log.logs.push(txt);
|
||||
try {
|
||||
clite.term.writeLine(txt);
|
||||
clite.console.write(txt+'\n');
|
||||
} catch(e) {}
|
||||
console.log(txt);
|
||||
}
|
||||
};
|
||||
|
||||
clite.term = {
|
||||
clite.tty = {
|
||||
data:{
|
||||
type:'text',
|
||||
show:false,
|
||||
isalt:false,
|
||||
form:null,
|
||||
field:null,
|
||||
handler:null,
|
||||
prompt:'',
|
||||
buff:'',
|
||||
alt:{
|
||||
israwOut:false,
|
||||
israwIn:false,
|
||||
echo:true,
|
||||
lines:0,
|
||||
cols:0
|
||||
active:null,
|
||||
activeID:-1,
|
||||
ttys:[]
|
||||
},
|
||||
internal:{
|
||||
genTTY:function() {return null;},
|
||||
write:function(id,ch) {
|
||||
var cc = ch.charCodeAt(0);
|
||||
var updateLine = false;
|
||||
var updateAll = false;
|
||||
var updateX = clite.tty.data.ttys[id].x;
|
||||
var updateY = clite.tty.data.ttys[id].y;
|
||||
|
||||
switch (cc) {
|
||||
case 10: //LF
|
||||
clite.tty.data.ttys[id].y++;
|
||||
break;
|
||||
case 13: //CR
|
||||
clite.tty.data.ttys[id].x = 0;
|
||||
updateLine = true;
|
||||
break;
|
||||
default:
|
||||
clite.tty.data.ttys[id].data[updateY][updateX].ch = ch;
|
||||
clite.tty.data.ttys[id].x++;
|
||||
}
|
||||
|
||||
if (clite.tty.data.ttys[id].x > 79) {
|
||||
clite.tty.data.ttys[id].y++;
|
||||
clite.tty.data.ttys[id].x = 0;
|
||||
}
|
||||
// theoretically this should be fine, in practice it may not
|
||||
if (clite.tty.data.ttys[id].y > 24) {
|
||||
var l = clite.tty.data.ttys[id].data.shift()
|
||||
for (var i=0; i<80; i++) {
|
||||
l[i].ch = ' ';
|
||||
l[i].fg = clite.tty.data.ttys[id].fg;
|
||||
l[i].bg = clite.tty.data.ttys[id].bg;
|
||||
}
|
||||
clite.tty.data.ttys[id].y = 24;
|
||||
clite.tty.data.ttys[id].data.push(l);
|
||||
updateAll = true;
|
||||
}
|
||||
|
||||
if (clite.tty.data.activeID != id)
|
||||
return;
|
||||
|
||||
if (updateAll) {
|
||||
clite.console.drawBuff(clite.tty.data.ttys[id].data);
|
||||
}else if (updateLine) {
|
||||
clite.console.drawLine(updateY,clite.tty.data.ttys[id].data[updateY]);
|
||||
}else{
|
||||
clite.console.drawAt(updateX,updateY,clite.tty.data.ttys[id].data[updateY][updateX]);
|
||||
}
|
||||
}
|
||||
},
|
||||
events:{
|
||||
keydown:function(e) {
|
||||
if (e.key == 'Tab') {
|
||||
clite.term.events.refocus();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
keyup:function(e) {
|
||||
if (clite.term.data.isalt && clite.term.data.alt.israwIn) {
|
||||
if (clite.term.data.handler != null) {
|
||||
if (e.key == 'Tab') {
|
||||
clite.term.data.handler('\t');
|
||||
}else{
|
||||
clite.term.data.handler(e.key);
|
||||
}
|
||||
}
|
||||
if (!clite.term.data.alt.echo) {
|
||||
e.target.value = '';
|
||||
clite.term.data.buff = '';
|
||||
return false;
|
||||
}
|
||||
}else if (e.key.length > 1 && e.key != 'Spacebar' && clite.term.data.handler != null) {
|
||||
if (e.key == 'Enter') {
|
||||
clite.term.data.buff = '';
|
||||
clite.term.data.handler(e.target.value);
|
||||
return false;
|
||||
}else{
|
||||
clite.term.data.handler('\1'+e.key);
|
||||
init:function(vfsapi) {
|
||||
clite.tty.internal.genTTY = function() {
|
||||
var l = [];
|
||||
for (var y=0; y<25; y++) {
|
||||
l[y] = [];
|
||||
for (var x=0; x<80; x++) {
|
||||
l[y].push({bg:0,fg:15,bk:false,ch:' '});
|
||||
}
|
||||
}
|
||||
clite.term.data.buff = e.target.value;
|
||||
return false;
|
||||
},
|
||||
refocus:function(e) {
|
||||
clite.core.execSafeAsync(function() {
|
||||
try{
|
||||
clite.term.data.field.focus()
|
||||
} catch(err) {
|
||||
clite.term.genForm();
|
||||
}
|
||||
});
|
||||
var id = clite.tty.data.ttys.length;
|
||||
var t = {id:id,x:0,y:0,fg:15,bg:0,data:l};
|
||||
clite.tty.data.ttys.push(t);
|
||||
|
||||
|
||||
vfsapi.mkFile(0,'/dev/tty'+id);
|
||||
let n = vfsapi.getNode(0,'/dev/tty'+id);
|
||||
if (!n) {
|
||||
clite.log.write('tty creation failure (/dev/tty'+id+')');
|
||||
return null;
|
||||
}
|
||||
n.data.content = {
|
||||
read:null,
|
||||
write:null
|
||||
};
|
||||
n.perms = 'crw-rw-rw-';
|
||||
n.data.isdev = true;
|
||||
n.data.istty = true;
|
||||
|
||||
clite.tty.data.ttys.push(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
clite.tty.internal.genTTY();
|
||||
},
|
||||
input:function(key) {
|
||||
},
|
||||
read:function(id,cb) {
|
||||
},
|
||||
write:function(id,str) {
|
||||
if (id<0 || id>=clite.tty.data.ttys.length)
|
||||
return;
|
||||
|
||||
for (var i=0; i<str.length; i++) {
|
||||
var ch = str[i];
|
||||
var cc = ch.charCodeAt(0);
|
||||
// TODO: escape/control sequences
|
||||
if (cc < 32 || cc > 126) {
|
||||
switch (cc) {
|
||||
case 10: // NL/LF to CR+LF
|
||||
clite.tty.internal.write(id,String.fromCharCode(13));
|
||||
clite.tty.internal.write(id,String.fromCharCode(10));
|
||||
break;
|
||||
default:
|
||||
clite.tty.internal.write(id,'^');
|
||||
}
|
||||
}else{
|
||||
clite.tty.internal.write(id,ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
clite.console = {
|
||||
data:{
|
||||
vgaio:null,
|
||||
state:0,
|
||||
size:[80,25],
|
||||
cursor:[0,0,0,0]
|
||||
},
|
||||
init:function() {
|
||||
// set graphics to text mode, and get the VGA api
|
||||
clite.state.bios.io.write(1,1);
|
||||
clite.console.data.vgaio = clite.state.bios.io.read(1);
|
||||
// set a keyboard handler, then flush the buffer
|
||||
clite.state.bios.io.write(2,clite.tty.input);
|
||||
clite.state.bios.io.write(2);
|
||||
clite.console.data.state = 1;
|
||||
clite.console.clear();
|
||||
},
|
||||
clear:function() {
|
||||
if (clite.term.data.isalt) {
|
||||
document.getElementById('termalt').innerHTML = '';
|
||||
return;
|
||||
}
|
||||
document.getElementById('terminal').innerHTML = '';
|
||||
},
|
||||
writeLine:function(txt) {
|
||||
if (clite.term.data.isalt) {
|
||||
var t = document.getElementById('termalt');
|
||||
if (!t)
|
||||
t = clite.term.genAlt();
|
||||
if (clite.term.data.alt.israwOut) {
|
||||
t.innerHTML += txt;
|
||||
if (clite.term.data.show)
|
||||
clite.term.genForm();
|
||||
return;
|
||||
}
|
||||
var a = document.createElement('article');
|
||||
a.innerHTML = clite.lib.htmlEncode(txt);
|
||||
t.appendChild(a);
|
||||
if (clite.term.data.show)
|
||||
clite.term.genForm();
|
||||
return;
|
||||
}
|
||||
var a = document.createElement('article');
|
||||
a.innerHTML = clite.lib.htmlEncode(txt);
|
||||
var t = document.getElementById('terminal');
|
||||
if (!t)
|
||||
return;
|
||||
t.appendChild(a);
|
||||
if (clite.term.data.show)
|
||||
clite.term.genForm();
|
||||
t.scrollTop = t.scrollHeight;
|
||||
},
|
||||
genAlt:function() {
|
||||
var t = document.getElementById('termalt');
|
||||
if (!t) {
|
||||
t = document.createElement('div');
|
||||
t.id = 'termalt';
|
||||
}
|
||||
|
||||
var term = document.getElementById('terminal');
|
||||
var p = term.parentNode;
|
||||
|
||||
t.style.width = term.offsetWidth+'px';
|
||||
if (p.offsetHeight > term.offsetHeight) {
|
||||
t.style.minHeight = p.offsetHeight+'px';
|
||||
}else{
|
||||
t.style.minHeight = term.offsetHeight+'px';
|
||||
}
|
||||
t.style.position = 'absolute';
|
||||
t.style.top = term.offsetTop+'px';
|
||||
t.style.left = term.offsetLeft+'px';
|
||||
p.appendChild(t);
|
||||
|
||||
// some calculations to help with putting content in
|
||||
var s = document.createElement('span');
|
||||
s.innerText = 'W';
|
||||
t.appendChild(s);
|
||||
// 20 should not be hardcoded
|
||||
clite.term.data.alt.lines = parseInt((t.offsetHeight/20)-1);
|
||||
// TODO: shouldn't need the 0.8 thing, but urgh
|
||||
clite.term.data.alt.cols = parseInt((t.offsetWidth/s.offsetWidth)*0.8);
|
||||
t.removeChild(s);
|
||||
|
||||
clite.term.data.buff = '';
|
||||
|
||||
return t;
|
||||
},
|
||||
genForm:function() {
|
||||
var f = document.getElementById('form');
|
||||
if (!clite.term.data.show) {
|
||||
if (f)
|
||||
f.parentNode.removeChild(f);
|
||||
return;
|
||||
}
|
||||
if (!f)
|
||||
f = document.createElement('form');
|
||||
f.id = 'form';
|
||||
f.innerHTML = '';
|
||||
if (!clite.term.data.isalt) {
|
||||
var l = document.createElement('label');
|
||||
l.innerHTML = clite.lib.htmlEncode(clite.term.data.prompt);
|
||||
f.appendChild(l);
|
||||
}
|
||||
var i = document.createElement('input');
|
||||
i.type = clite.term.getType();
|
||||
i.value = clite.term.data.buff;
|
||||
f.appendChild(i);
|
||||
clite.term.data.form = f;
|
||||
clite.term.data.field = i;
|
||||
if (clite.term.data.isalt) {
|
||||
var t = document.getElementById('termalt');
|
||||
if (!t)
|
||||
t = clite.term.genAlt();
|
||||
t.appendChild(f);
|
||||
}else{
|
||||
var t = document.getElementById('terminal');
|
||||
if (!t)
|
||||
return;
|
||||
t.appendChild(f);
|
||||
}
|
||||
i.onkeydown = clite.term.events.keydown;
|
||||
i.onkeyup = clite.term.events.keyup;
|
||||
i.onfocusout = clite.term.events.refocus;
|
||||
i.onblur = clite.term.events.refocus;
|
||||
if (i.type == 'file') { // this is only needed due to dirty hacks to read in a file: path
|
||||
i.onchange = function(e) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
var cb = clite.term.data.type.callback;
|
||||
clite.term.setPass(false);
|
||||
clite.term.writeLine('loaded');
|
||||
cb(reader.result);
|
||||
};
|
||||
reader.onerror = function() {
|
||||
var cb = clite.term.data.type.callback;
|
||||
clite.term.setPass(false);
|
||||
clite.term.writeLine('load failed');
|
||||
cb(null);
|
||||
};
|
||||
reader.readAsText(e.target.files[0]);
|
||||
if (clite.console.data.state == 1) {
|
||||
for (var y=0; y<25; y++) {
|
||||
for (var x=0; x<80; x++) {
|
||||
clite.console.data.vgaio.write(x,y,' ');
|
||||
clite.console.data.vgaio.writeSet(0,x,y,0);
|
||||
clite.console.data.vgaio.writeSet(1,x,y,15);
|
||||
clite.console.data.vgaio.writeSet(2,x,y,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
f.onsubmit = function() {return false;};
|
||||
clite.term.events.refocus();
|
||||
},
|
||||
setPass:function(is) {
|
||||
clite.term.data.type = (!!is) ? 'password' : 'text';
|
||||
drawBuff:function(buff) {
|
||||
if (clite.console.data.state == 1) {
|
||||
for (var y=0; y<25; y++) {
|
||||
for (var x=0; x<80; x++) {
|
||||
unix.vga.io.write(x,y,buff[y][x].ch);
|
||||
unix.vga.io.writeSet(0,x,y,buff[y][x].bg);
|
||||
unix.vga.io.writeSet(1,x,y,buff[y][x].fg);
|
||||
unix.vga.io.writeSet(2,x,y,buff[y][x].bk);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
setCustom:function(type) {
|
||||
clite.term.data.type = type;
|
||||
drawLine:function(y,buff) {
|
||||
if (clite.console.data.state == 1) {
|
||||
for (var x=0; x<80; x++) {
|
||||
unix.vga.io.write(x,y,buff[x].ch);
|
||||
unix.vga.io.writeSet(0,x,y,buff[x].bg);
|
||||
unix.vga.io.writeSet(1,x,y,buff[x].fg);
|
||||
unix.vga.io.writeSet(2,x,y,buff[x].bk);
|
||||
}
|
||||
}
|
||||
},
|
||||
getType:function() {
|
||||
if (typeof clite.term.data.type == 'string')
|
||||
return clite.term.data.type;
|
||||
if (typeof clite.term.data.type == 'object' && typeof clite.term.data.type.type == 'string')
|
||||
return clite.term.data.type.type;
|
||||
return 'text';
|
||||
drawAt:function(x,y,data) {
|
||||
if (clite.console.data.state == 1) {
|
||||
if (x<0 || x>79 || y<0 || y>24)
|
||||
return;
|
||||
clite.console.data.vgaio.write(x,y,data.ch);
|
||||
clite.console.data.vgaio.writeSet(0,x,y,data.bg);
|
||||
clite.console.data.vgaio.writeSet(1,x,y,data.fg);
|
||||
clite.console.data.vgaio.writeSet(2,x,y,data.bk);
|
||||
}
|
||||
},
|
||||
moveCursor:function() {
|
||||
if (
|
||||
clite.console.data.cursor[0] == clite.console.data.cursor[2]
|
||||
&& clite.console.data.cursor[1] == clite.console.data.cursor[3]
|
||||
)
|
||||
return;
|
||||
clite.console.data.vgaio.writeSet(2,clite.console.data.cursor[0],clite.console.data.cursor[1],false);
|
||||
clite.console.data.cursor[0] = clite.console.data.cursor[2];
|
||||
clite.console.data.cursor[1] = clite.console.data.cursor[3];
|
||||
clite.console.data.vgaio.writeSet(2,clite.console.data.cursor[0],clite.console.data.cursor[1],true);
|
||||
},
|
||||
setCursor:function(x,y) {
|
||||
clite.console.data.cursor[2] = x;
|
||||
clite.console.data.cursor[3] = y;
|
||||
clite.console.moveCursor();
|
||||
},
|
||||
read:function() {
|
||||
},
|
||||
write:function(str) {
|
||||
var d = {
|
||||
ch:'',
|
||||
bg:0,
|
||||
fg:15,
|
||||
bk:false
|
||||
};
|
||||
clite.console.moveCursor();
|
||||
var x = clite.console.data.cursor[0];
|
||||
var y = clite.console.data.cursor[1];
|
||||
for (var i=0; i<str.length; i++) {
|
||||
if (str[i] == '\n') {
|
||||
x = 0;
|
||||
y++;
|
||||
continue;
|
||||
}
|
||||
if (x >= 80) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
d.ch = str[i];
|
||||
clite.console.drawAt(x,y,d);
|
||||
x++;
|
||||
}
|
||||
clite.console.setCursor(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
clite.term = {
|
||||
//events:{
|
||||
//keyup:function(e) {
|
||||
//if (clite.term.data.isalt && clite.term.data.alt.israwIn) {
|
||||
//if (clite.term.data.handler != null) {
|
||||
//if (e.key == 'Tab') {
|
||||
//clite.term.data.handler('\t');
|
||||
//}else{
|
||||
//clite.term.data.handler(e.key);
|
||||
//}
|
||||
//}
|
||||
//if (!clite.term.data.alt.echo) {
|
||||
//e.target.value = '';
|
||||
//clite.term.data.buff = '';
|
||||
//return false;
|
||||
//}
|
||||
//}else if (e.key.length > 1 && e.key != 'Spacebar' && clite.term.data.handler != null) {
|
||||
//if (e.key == 'Enter') {
|
||||
//clite.term.data.buff = '';
|
||||
//clite.term.data.handler(e.target.value);
|
||||
//return false;
|
||||
//}else{
|
||||
//clite.term.data.handler('\1'+e.key);
|
||||
//}
|
||||
//}
|
||||
//clite.term.data.buff = e.target.value;
|
||||
//return false;
|
||||
//},
|
||||
//},
|
||||
ttyctrl:function(fn,v) {
|
||||
switch (fn) {
|
||||
case 'iget': // returns the current input string - bypassing tty read
|
||||
|
|
@ -2398,7 +2452,7 @@ clite.term = {
|
|||
break;
|
||||
case 'show': // turns on input
|
||||
clite.term.data.show = true;
|
||||
clite.term.genForm();
|
||||
//clite.term.genForm();
|
||||
break;
|
||||
case 'alt': // switch to the alternate frame buffer
|
||||
if (typeof v === 'boolean') {
|
||||
|
|
@ -2409,9 +2463,9 @@ clite.term = {
|
|||
if (t)
|
||||
t.parentNode.removeChild(t);
|
||||
}else{
|
||||
clite.term.genAlt();
|
||||
//clite.term.genAlt();
|
||||
}
|
||||
clite.term.genForm();
|
||||
//clite.term.genForm();
|
||||
return clite.term.data.isalt;
|
||||
break;
|
||||
case 'rawout':
|
||||
|
|
@ -2586,3 +2640,5 @@ clite.lib = {
|
|||
clite.proc.exit(pid);
|
||||
}
|
||||
}
|
||||
|
||||
window.BIOSentry(clite.init);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@
|
|||
<div class="input" id="input"></div>
|
||||
<div class="output" id="output"></div>
|
||||
</div>
|
||||
<script type="text/javascript">bios.power.off();</script>
|
||||
<script type="text/javascript">window.BIOSinit();</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in a new issue