Added template website
This commit is contained in:
parent
a96c97bc3c
commit
956cb20820
4 changed files with 1965 additions and 0 deletions
27
web/index.html
Normal file
27
web/index.html
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>JSLinux</title>
|
||||
<link href="style.css" type="text/css" rel="stylesheet"/>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="term_wrap">
|
||||
<div id="term_container">
|
||||
</div>
|
||||
<div>
|
||||
<textarea id="term_paste" cols="10" rows="1" autocorrect="off">Paste Here</textarea>
|
||||
<label>
|
||||
<img title="Upload files" src="images/upload-icon.png"><input type="file" id="files" multiple onchange="on_update_files(this.files)">
|
||||
</label>
|
||||
<progress id="net_progress">
|
||||
</progress>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="term.js"></script>
|
||||
<script type="text/javascript" src="jslinux.js"></script>
|
||||
<div id="copyright">© 2017-2019 Fabrice Bellard</div>
|
||||
</body>
|
||||
</html>
|
||||
646
web/jslinux.js
Normal file
646
web/jslinux.js
Normal file
|
|
@ -0,0 +1,646 @@
|
|||
/*
|
||||
* JS Linux main
|
||||
*
|
||||
* Copyright (c) 2017 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
var term, console_write1;
|
||||
var graphic_display, display_key_event, display_mouse_event;
|
||||
var net_state, net_write_packet, net_set_carrier;
|
||||
var display_wheel_event;
|
||||
var fs_import_file;
|
||||
var Module = {};
|
||||
var downloading_timer_pending = false;
|
||||
var downloading_timer;
|
||||
|
||||
function on_update_file(f)
|
||||
{
|
||||
var f, reader;
|
||||
reader = new FileReader();
|
||||
reader.onload = function (ev) {
|
||||
var buf, buf_addr, buf_len;
|
||||
buf = new Uint8Array(reader.result);
|
||||
buf_len = buf.length;
|
||||
buf_addr = _malloc(buf_len);
|
||||
HEAPU8.set(buf, buf_addr);
|
||||
/* the buffer is freed by the function */
|
||||
fs_import_file(f.name, buf_addr, buf_len);
|
||||
};
|
||||
reader.readAsArrayBuffer(f);
|
||||
}
|
||||
|
||||
function on_update_files(files)
|
||||
{
|
||||
var i, n;
|
||||
n = files.length;
|
||||
for(i = 0; i < n; i++) {
|
||||
on_update_file(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function term_handler(str)
|
||||
{
|
||||
var i;
|
||||
for(i = 0; i < str.length; i++) {
|
||||
console_write1(str.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
function downloading_timer_cb()
|
||||
{
|
||||
var el = document.getElementById("net_progress");
|
||||
el.style.visibility = "hidden";
|
||||
downloading_timer_pending = false;
|
||||
}
|
||||
|
||||
function update_downloading(flag)
|
||||
{
|
||||
var el;
|
||||
if (flag) {
|
||||
if (downloading_timer_pending) {
|
||||
clearTimeout(downloading_timer);
|
||||
downloading_timer_pending = false;
|
||||
} else {
|
||||
el = document.getElementById("net_progress");
|
||||
el.style.visibility = "visible";
|
||||
}
|
||||
} else {
|
||||
downloading_timer_pending = true;
|
||||
downloading_timer = setTimeout(downloading_timer_cb, 500);
|
||||
}
|
||||
}
|
||||
|
||||
function get_params()
|
||||
{
|
||||
var url, query_str, p, tab, i, params, tab2;
|
||||
query_str = window.location.href;
|
||||
p = query_str.indexOf("?");
|
||||
if (p < 0)
|
||||
return {};
|
||||
query_str = query_str.substr(p + 1);
|
||||
tab = query_str.split("&");
|
||||
params = {};
|
||||
for(i = 0; i < tab.length; i++) {
|
||||
tab2 = tab[i].split("=");
|
||||
params[decodeURIComponent(tab2[0])] = decodeURIComponent(tab2[1]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function get_absolute_url(fname)
|
||||
{
|
||||
var path, p;
|
||||
|
||||
if (fname.indexOf(":") >= 0)
|
||||
return fname;
|
||||
path = window.location.pathname;
|
||||
p = path.lastIndexOf("/");
|
||||
if (p < 0)
|
||||
return fname;
|
||||
return window.location.origin + path.slice(0, p + 1) + fname;
|
||||
}
|
||||
|
||||
function GraphicDisplay(parent_el, width, height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.canvas_el = document.createElement("canvas");
|
||||
this.canvas_el.width = width; /* logical width */
|
||||
this.canvas_el.height = height; /* logical width */
|
||||
/* displayed size */
|
||||
this.canvas_el.style.width = width + "px";
|
||||
this.canvas_el.style.height = height + "px";
|
||||
this.canvas_el.style.cursor = "none";
|
||||
|
||||
parent_el.appendChild(this.canvas_el);
|
||||
|
||||
this.ctx = this.canvas_el.getContext("2d");
|
||||
/* clear the display */
|
||||
this.ctx.fillStyle = "#000000";
|
||||
this.ctx.fillRect(0, 0, width, height);
|
||||
|
||||
this.image = this.ctx.createImageData(width, height);
|
||||
|
||||
this.key_pressed = new Uint8Array(128);
|
||||
|
||||
document.addEventListener("keydown",
|
||||
this.keyDownHandler.bind(this), false);
|
||||
document.addEventListener("keyup",
|
||||
this.keyUpHandler.bind(this), false);
|
||||
document.addEventListener("blur",
|
||||
this.blurHandler.bind(this), false);
|
||||
|
||||
this.canvas_el.onmousedown = this.mouseMoveHandler.bind(this);
|
||||
this.canvas_el.onmouseup = this.mouseMoveHandler.bind(this);
|
||||
this.canvas_el.onmousemove = this.mouseMoveHandler.bind(this);
|
||||
this.canvas_el.oncontextmenu = this.onContextMenuHandler.bind(this);
|
||||
this.canvas_el.onwheel = this.wheelHandler.bind(this);
|
||||
}
|
||||
|
||||
GraphicDisplay.code_to_input_map = {
|
||||
"Escape": 0x01,
|
||||
"Digit1": 0x02,
|
||||
"Digit2": 0x03,
|
||||
"Digit3": 0x04,
|
||||
"Digit4": 0x05,
|
||||
"Digit5": 0x06,
|
||||
"Digit6": 0x07,
|
||||
"Digit7": 0x08,
|
||||
"Digit8": 0x09,
|
||||
"Digit9": 0x0a,
|
||||
"Digit0": 0x0b,
|
||||
"Minus": 0x0c,
|
||||
"Equal": 0x0d,
|
||||
"Backspace": 0x0e,
|
||||
"Tab": 0x0f,
|
||||
"KeyQ": 0x10,
|
||||
"KeyW": 0x11,
|
||||
"KeyE": 0x12,
|
||||
"KeyR": 0x13,
|
||||
"KeyT": 0x14,
|
||||
"KeyY": 0x15,
|
||||
"KeyU": 0x16,
|
||||
"KeyI": 0x17,
|
||||
"KeyO": 0x18,
|
||||
"KeyP": 0x19,
|
||||
"BracketLeft": 0x1a,
|
||||
"BracketRight": 0x1b,
|
||||
"Enter": 0x1c,
|
||||
"ControlLeft": 0x1d,
|
||||
"KeyA": 0x1e,
|
||||
"KeyS": 0x1f,
|
||||
"KeyD": 0x20,
|
||||
"KeyF": 0x21,
|
||||
"KeyG": 0x22,
|
||||
"KeyH": 0x23,
|
||||
"KeyJ": 0x24,
|
||||
"KeyK": 0x25,
|
||||
"KeyL": 0x26,
|
||||
"Semicolon": 0x27,
|
||||
"Quote": 0x28,
|
||||
"Backquote": 0x29,
|
||||
"ShiftLeft": 0x2a,
|
||||
"Backslash": 0x2b,
|
||||
"KeyZ": 0x2c,
|
||||
"KeyX": 0x2d,
|
||||
"KeyC": 0x2e,
|
||||
"KeyV": 0x2f,
|
||||
"KeyB": 0x30,
|
||||
"KeyN": 0x31,
|
||||
"KeyM": 0x32,
|
||||
"Comma": 0x33,
|
||||
"Period": 0x34,
|
||||
"Slash": 0x35,
|
||||
"ShiftRight": 0x36,
|
||||
"NumpadMultiply": 0x37,
|
||||
"AltLeft": 0x38,
|
||||
"Space": 0x39,
|
||||
"CapsLock": 0x3a,
|
||||
"F1": 0x3b,
|
||||
"F2": 0x3c,
|
||||
"F3": 0x3d,
|
||||
"F4": 0x3e,
|
||||
"F5": 0x3f,
|
||||
"F6": 0x40,
|
||||
"F7": 0x41,
|
||||
"F8": 0x42,
|
||||
"F9": 0x43,
|
||||
"F10": 0x44,
|
||||
"NumLock": 0x45,
|
||||
"ScrollLock": 0x46,
|
||||
"Numpad7": 0x47,
|
||||
"Numpad8": 0x48,
|
||||
"Numpad9": 0x49,
|
||||
"NumpadSubtract": 0x4a,
|
||||
"Numpad4": 0x4b,
|
||||
"Numpad5": 0x4c,
|
||||
"Numpad6": 0x4d,
|
||||
"NumpadAdd": 0x4e,
|
||||
"Numpad1": 0x4f,
|
||||
"Numpad2": 0x50,
|
||||
"Numpad3": 0x51,
|
||||
"Numpad0": 0x52,
|
||||
"NumpadDecimal": 0x53,
|
||||
"IntlBackslash": 0x56,
|
||||
"F11": 0x57,
|
||||
"F12": 0x58,
|
||||
|
||||
"NumpadEnter": 96,
|
||||
"ControlRight": 97,
|
||||
"NumpadDivide": 98,
|
||||
"AltRight": 100,
|
||||
"Home": 102,
|
||||
"ArrowUp": 103,
|
||||
"PageUp": 104,
|
||||
"ArrowLeft": 105,
|
||||
"ArrowRight": 106,
|
||||
"End": 107,
|
||||
"ArrowDown": 108,
|
||||
"PageDown": 109,
|
||||
"Insert": 110,
|
||||
"Delete": 111,
|
||||
"OSLeft": 125,
|
||||
"OSRight": 126,
|
||||
"ContextMenu": 127,
|
||||
};
|
||||
|
||||
GraphicDisplay.key_code_to_input_map = new Uint8Array([
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x0E, 0x0F, 0, 0, 0, 0x1C, 0, 0,
|
||||
0x2A, 0x1D, 0x38, 0, 0x3A, 0, 0, 0, /* 0x10 */
|
||||
0, 0, 0, 0x01, 0, 0, 0, 0,
|
||||
0x39, 104, 109, 107, 102, 105, 103, 106, /* 0x20 */
|
||||
0x50, 0, 0, 0, 0, 0x52, 0x53, 0,
|
||||
0x0B, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, /* 0x30 */
|
||||
0x09, 0x0A, 0, 0x27, 0, 0x0D, 0, 0,
|
||||
0, 0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, /* 0x40 */
|
||||
0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18,
|
||||
0x19, 0x10, 0x13, 0x1F, 0x14, 0x16, 0x2F, 0x11, /* 0x50 */
|
||||
0x2D, 0x15, 0x2C, 125, 126, 127, 0, 0,
|
||||
0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47, /* 0x60 */
|
||||
0x48, 0x49, 0x37, 0x4e, 0, 0x4a, 0x53, 98,
|
||||
0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, /* 0x70 */
|
||||
0x43, 0x44, 0x57, 0x58, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x45, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
|
||||
0, 0, 0, 0, 0, 0x0C, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
|
||||
0, 0, 0x27, 0x0D, 0x33, 0x0C, 0x34, 0x35,
|
||||
0x29, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
|
||||
0, 0, 0, 0x1A, 0x2B, 0x1B, 0x28, 0,
|
||||
125, 100, 0, 0, 0, 0, 0, 0, /* 0xe0 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
]);
|
||||
|
||||
GraphicDisplay.prototype.keyHandler = function keyHandler(ev, isDown)
|
||||
{
|
||||
var code, input_key_code;
|
||||
|
||||
/* At least avoid exiting the navigator if Ctrl-Q or Ctrl-W are
|
||||
* pressed */
|
||||
if (ev.ctrlKey) {
|
||||
window.onbeforeunload = function() {
|
||||
window.onbeforeunload = null;
|
||||
return "CTRL-W or Ctrl-Q cannot be sent to the emulator.";
|
||||
};
|
||||
} else {
|
||||
window.onbeforeunload = null;
|
||||
}
|
||||
|
||||
if (typeof ev.code != "undefined") {
|
||||
code = ev.code;
|
||||
input_key_code = GraphicDisplay.code_to_input_map[code];
|
||||
if (typeof input_key_code != "undefined") {
|
||||
// console.log("code=" + code + " isDown=" + isDown + " input_key_code=" + input_key_code);
|
||||
this.key_pressed[input_key_code] = isDown;
|
||||
display_key_event(isDown, input_key_code);
|
||||
|
||||
if (ev.stopPropagation)
|
||||
ev.stopPropagation();
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* fallback using keyCodes. Works only with an US keyboard */
|
||||
code = ev.keyCode;
|
||||
if (code < 256) {
|
||||
input_key_code = GraphicDisplay.key_code_to_input_map[code];
|
||||
// console.log("keyCode=" + code + " isDown=" + isDown + " input_key_code=" + input_key_code);
|
||||
if (input_key_code) {
|
||||
this.key_pressed[input_key_code] = isDown;
|
||||
display_key_event(isDown, input_key_code);
|
||||
|
||||
if (ev.stopPropagation)
|
||||
ev.stopPropagation();
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GraphicDisplay.prototype.keyDownHandler = function keyDownHandler(ev)
|
||||
{
|
||||
return this.keyHandler(ev, 1);
|
||||
}
|
||||
|
||||
GraphicDisplay.prototype.keyUpHandler = function keyUpHandler(ev)
|
||||
{
|
||||
return this.keyHandler(ev, 0);
|
||||
}
|
||||
|
||||
GraphicDisplay.prototype.blurHandler = function blurHandler(ev, isDown)
|
||||
{
|
||||
var i, n, key_pressed;
|
||||
/* allow unloading the page */
|
||||
window.onbeforeunload = null;
|
||||
/* release all keys */
|
||||
key_pressed = this.key_pressed;
|
||||
for(i = 0; i < key_pressed.length; i++) {
|
||||
if (key_pressed[i]) {
|
||||
display_key_event(0, i);
|
||||
key_pressed[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphicDisplay.prototype.mouseMoveHandler = function (ev)
|
||||
{
|
||||
var x, y, rect, buttons;
|
||||
rect = this.canvas_el.getBoundingClientRect();
|
||||
x = ev.clientX - rect.left;
|
||||
y = ev.clientY - rect.top;
|
||||
buttons = ev.buttons & 7;
|
||||
// console.log("mouse: x=" + x + " y=" + y + " buttons=" + buttons);
|
||||
display_mouse_event(x, y, buttons);
|
||||
if (ev.stopPropagation)
|
||||
ev.stopPropagation();
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
GraphicDisplay.prototype.wheelHandler = function (ev)
|
||||
{
|
||||
if (ev.deltaY < 0) {
|
||||
display_wheel_event(1);
|
||||
} else if (ev.deltaY > 0) {
|
||||
display_wheel_event(-1);
|
||||
}
|
||||
if (ev.stopPropagation)
|
||||
ev.stopPropagation();
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
/* disable contextual menu */
|
||||
GraphicDisplay.prototype.onContextMenuHandler = function (ev)
|
||||
{
|
||||
if (ev.stopPropagation)
|
||||
ev.stopPropagation();
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Network support */
|
||||
|
||||
function Ethernet(url)
|
||||
{
|
||||
try {
|
||||
this.socket = new WebSocket(url);
|
||||
} catch(err) {
|
||||
this.socket = null;
|
||||
console.log("Could not open websocket url=" + url);
|
||||
return;
|
||||
}
|
||||
this.socket.binaryType = 'arraybuffer';
|
||||
this.socket.onmessage = this.messageHandler.bind(this);
|
||||
this.socket.onclose = this.closeHandler.bind(this);
|
||||
this.socket.onopen = this.openHandler.bind(this);
|
||||
this.socket.onerror = this.errorHandler.bind(this);
|
||||
}
|
||||
|
||||
Ethernet.prototype.openHandler = function(e)
|
||||
{
|
||||
net_set_carrier(1);
|
||||
}
|
||||
|
||||
Ethernet.prototype.closeHandler = function(e)
|
||||
{
|
||||
net_set_carrier(0);
|
||||
}
|
||||
|
||||
Ethernet.prototype.errorHandler = function(e)
|
||||
{
|
||||
console.log("Websocket error=" + e);
|
||||
}
|
||||
|
||||
Ethernet.prototype.messageHandler = function(e)
|
||||
{
|
||||
var str, buf_len, buf_addr, buf;
|
||||
if (e.data instanceof ArrayBuffer) {
|
||||
buf_len = e.data.byteLength;
|
||||
buf = new Uint8Array(e.data);
|
||||
buf_addr = _malloc(buf_len);
|
||||
HEAPU8.set(buf, buf_addr);
|
||||
net_write_packet(buf_addr, buf_len);
|
||||
_free(buf_addr);
|
||||
} else {
|
||||
str = e.data.toString();
|
||||
if (str.substring(0, 5) == "ping:") {
|
||||
try {
|
||||
this.socket.send('pong:' + str.substring(5));
|
||||
} catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ethernet.prototype.recv_packet = function(buf)
|
||||
{
|
||||
if (this.socket) {
|
||||
try {
|
||||
this.socket.send(buf);
|
||||
} catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function start_vm(user, pwd)
|
||||
{
|
||||
var url, mem_size, cpu, params, vm_url, cmdline, cols, rows, guest_url;
|
||||
var font_size, graphic_enable, width, height, net_url, alloc_size;
|
||||
var drive_url, vm_file;
|
||||
|
||||
function loadScript(src, f) {
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
var script = document.createElement("script");
|
||||
script.src = src;
|
||||
var done = false;
|
||||
script.onload = script.onreadystatechange = function() {
|
||||
// attach to both events for cross browser finish detection:
|
||||
if ( !done && (!this.readyState ||
|
||||
this.readyState == "loaded" || this.readyState == "complete") ) {
|
||||
done = true;
|
||||
if (f) {
|
||||
f();
|
||||
}
|
||||
script.onload = script.onreadystatechange = null;
|
||||
head.removeChild(script);
|
||||
}
|
||||
};
|
||||
head.appendChild(script);
|
||||
}
|
||||
|
||||
function start()
|
||||
{
|
||||
/* C functions called from javascript */
|
||||
console_write1 = Module.cwrap('console_queue_char', null, ['number']);
|
||||
fs_import_file = Module.cwrap('fs_import_file', null, ['string', 'number', 'number']);
|
||||
display_key_event = Module.cwrap('display_key_event', null, ['number', 'number']);
|
||||
display_mouse_event = Module.cwrap('display_mouse_event', null, ['number', 'number', 'number']);
|
||||
display_wheel_event = Module.cwrap('display_wheel_event', null, ['number']);
|
||||
net_write_packet = Module.cwrap('net_write_packet', null, ['number', 'number']);
|
||||
net_set_carrier = Module.cwrap('net_set_carrier', null, ['number']);
|
||||
|
||||
net_state = null;
|
||||
if (net_url != "") {
|
||||
net_state = new Ethernet(net_url);
|
||||
}
|
||||
|
||||
Module.ccall("vm_start", null, ["string", "number", "string", "string", "number", "number", "number", "string"], [url, mem_size, cmdline, pwd, width, height, (net_state != null) | 0, drive_url]);
|
||||
pwd = null;
|
||||
}
|
||||
|
||||
/* read the parameters */
|
||||
|
||||
params = get_params();
|
||||
cpu = params["cpu"] || "riscv64";
|
||||
url = params["url"];
|
||||
if (!url) {
|
||||
if (cpu == "x86")
|
||||
url = "root-x86.cfg";
|
||||
else
|
||||
url = "root-riscv64.cfg";
|
||||
}
|
||||
url = get_absolute_url(url);
|
||||
mem_size = (params["mem"] | 0) || 128; /* in mb */
|
||||
cmdline = params["cmdline"] || "";
|
||||
cols = (params["cols"] | 0) || 80;
|
||||
rows = (params["rows"] | 0) || 30;
|
||||
font_size = (params["font_size"] | 0) || 15;
|
||||
guest_url = params["guest_url"] || "";
|
||||
width = (params["w"] | 0) || 1024;
|
||||
height = (params["h"] | 0) || 640;
|
||||
graphic_enable = params["graphic"] | 0;
|
||||
net_url = params["net_url"] || ""; /* empty string means no network */
|
||||
if (typeof net_url == "undefined")
|
||||
net_url = "wss://relay.widgetry.org/";
|
||||
drive_url = params["drive_url"] || "";
|
||||
|
||||
if (user) {
|
||||
cmdline += " LOGIN_USER=" + user;
|
||||
} else if (guest_url) {
|
||||
cmdline += " GUEST_URL=" + guest_url;
|
||||
}
|
||||
|
||||
if (graphic_enable) {
|
||||
graphic_display = new GraphicDisplay(document.getElementById("term_container"), width, height);
|
||||
} else {
|
||||
width = 0;
|
||||
height = 0;
|
||||
/* start the terminal */
|
||||
term = new Term(cols, rows, term_handler, 10000);
|
||||
term.open(document.getElementById("term_container"),
|
||||
document.getElementById("term_paste"));
|
||||
term.term_el.style.fontSize = font_size + "px";
|
||||
term.write("Loading...\r\n");
|
||||
}
|
||||
|
||||
// console.log("cpu=" + cpu + " url=" + url + " mem=" + mem_size);
|
||||
|
||||
switch(cpu) {
|
||||
case "x86":
|
||||
vm_file = "x86emu";
|
||||
break;
|
||||
case "riscv64":
|
||||
case "riscv":
|
||||
vm_file = "riscvemu64";
|
||||
break;
|
||||
case "riscv32":
|
||||
vm_file = "riscvemu32";
|
||||
break;
|
||||
default:
|
||||
term.writeln("Unknown cpu=" + cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof WebAssembly === "object") {
|
||||
/* wasm support : the memory grows automatically */
|
||||
vm_url = vm_file + "-wasm.js";
|
||||
} else {
|
||||
/* set the total memory */
|
||||
alloc_size = mem_size;
|
||||
if (cpu == "x86")
|
||||
alloc_size += 16;
|
||||
if (graphic_enable) {
|
||||
/* frame buffer memory */
|
||||
alloc_size += (width * height * 4 + 1048576 - 1) >> 20;
|
||||
}
|
||||
alloc_size += 32; /* extra space (XXX: reduce it ?) */
|
||||
alloc_size = (alloc_size + 15) & -16; /* align to 16 MB */
|
||||
Module.TOTAL_MEMORY = alloc_size << 20;
|
||||
vm_url = vm_file + ".js";
|
||||
}
|
||||
Module.preRun = start;
|
||||
|
||||
loadScript(vm_url, null);
|
||||
}
|
||||
|
||||
function on_login()
|
||||
{
|
||||
var login_wrap_el = document.getElementById("wrap");
|
||||
var term_wrap_el = document.getElementById("term_wrap");
|
||||
var form = document.getElementById("form");
|
||||
var status = document.getElementById("status");
|
||||
var user = form.user.value;
|
||||
var pwd = form.password.value;
|
||||
|
||||
if (user.length <= 1) {
|
||||
status.innerHTML = "User name must be provided";
|
||||
return false;
|
||||
}
|
||||
|
||||
login_wrap_el.style.display = "none";
|
||||
term_wrap_el.style.display = "block";
|
||||
form.password.value = "";
|
||||
form.user.value = "";
|
||||
|
||||
start_vm(user, pwd);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
(function() {
|
||||
var login, params;
|
||||
|
||||
params = get_params();
|
||||
login = params["login"] || 0;
|
||||
if (login) {
|
||||
var login_wrap_el = document.getElementById("wrap");
|
||||
login_wrap_el.style.display = "block";
|
||||
} else {
|
||||
var term_wrap_el = document.getElementById("term_wrap");
|
||||
term_wrap_el.style.display = "block";
|
||||
start_vm(null, null);
|
||||
}
|
||||
})();
|
||||
41
web/style.css
Normal file
41
web/style.css
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
.term {
|
||||
font-family: courier,fixed,swiss,monospace,sans-serif;
|
||||
font-size: 15px;
|
||||
color: #f0f0f0;
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.term_content a {
|
||||
color: #ffff00;
|
||||
}
|
||||
|
||||
.term_cursor {
|
||||
color: #000000;
|
||||
background: #00ff00;
|
||||
}
|
||||
|
||||
.term_scrollbar { background: transparent url(images/bg-scrollbar-track-y.png) no-repeat 0 0; position: relative; background-position: 0 0; float: right; width: 15px; height: 100%; }
|
||||
.term_track { background: transparent url(images/bg-scrollbar-trackend-y.png) no-repeat 0 100%; height: 100%; width:13px; position: relative; padding: 0 1px; }
|
||||
.term_thumb { background: transparent url(images/bg-scrollbar-thumb-y.png) no-repeat 50% 100%; height: 20px; width: 25px; cursor: pointer; overflow: hidden; position: absolute; top: 0; left: -5px; }
|
||||
.term_thumb .term_end { background: transparent url(images/bg-scrollbar-thumb-y.png) no-repeat 50% 0; overflow: hidden; height: 5px; width: 25px; }
|
||||
.noSelect { user-select: none; -o-user-select: none; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; }
|
||||
#term_paste {
|
||||
border: 1px solid;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
/* file import */
|
||||
#files {
|
||||
visibility: hidden;
|
||||
width:1px;
|
||||
height:1px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
bordex: 0px;
|
||||
}
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
1251
web/term.js
Normal file
1251
web/term.js
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue