/*****************************************************************************/
/*
vkb_lkish.js
A DCLinabox virtual keyboard that has looks reminiscent of an LK2/3/4/5
keyboard and provides key behaviours in a mostly faithful emulation.
Please overlook the utter lack of sophistication in the implementation.
Still, it seems to work and fits into DCLinabox feel, form and function.
VERSION LOG
-----------
31-JAN-2020 MGD initial
*/
/*****************************************************************************/
var vkbid;
var vkbAltLocked = false;
var vkbCapsLocked = false;
var vkbCtrlLocked = false;
var vkbOptLocked = false;
var vkbAlt1 = 0;
var vkbCtrl1 = 0;
var vkbOnce1 = 0;
var vkbShift1 = 0;
var vkbKeyActive = 'lightCyan';
var vkbKeyInActive = 'ghostWhite';
setTimeout('vkbBuild',50);
function vkbBuild ()
{
/******************/
/* build keyboard */
/******************/
vkbid = document.getElementById("vtvkb");
var html = '
';
html += '';
/******************/
/* unshifted keys */
/******************/
/* 7 bit CSI ("[") works for both 7 and 8 bit terminals */
var func = 'F1 | ';
func += 'F2 | ';
func += 'F3 | ';
func += 'F4 | ';
func += 'F5 | ';
func += ' | ';
func += 'F6 | ';
func += 'F7 | ';
func += 'F8 | ';
func += 'F9 | ';
func += 'F10 | ';
func += ' | ';
func += 'F11 | ';
func += 'F12 | ';
func += 'F13 | ';
func += 'F14 | ';
func += ' | ';
func += 'Hlp | ';
func += 'Do | ';
func += ' | ';
func += 'F17 | ';
func += 'F18 | ';
func += 'F19 | ';
func += 'F20 | ';
func += ' ';
func += ' | ';
html += func;
html += '';
html += 'Esc | ';
html += '` | ';
html += '1 | ';
html += '2 | ';
html += '3 | ';
html += '4 | ';
html += '5 | ';
html += '6 | ';
html += '7 | ';
html += '8 | ';
html += '9 | ';
html += '0 | ';
html += '- | ';
html += '= | ';
html += 'Del | ';
html += ' | ';
var find = 'Fnd | ';
find += 'Ins | ';
find += 'Rem | ';
find += ' | ';
find += 'PF1 | ';
find += 'PF2 | ';
find += 'PF3 | ';
find += 'PF4 | ';
find += ' ';
html += find;
html += '';
if (vkbTheDetachedChild)
html += '↖ | ';
else
html += '↖ | ';
html += 'Tab | ';
html += 'q | ';
html += 'w | ';
html += 'e | ';
html += 'r | ';
html += 't | ';
html += 'y | ';
html += 'u | ';
html += 'i | ';
html += 'o | ';
html += 'p | ';
html += '[ | ';
html += '] | ';
html += 'Ret urn | ';
html += ' | ';
var slct = 'Sel | ';
slct += 'Prv | ';
slct += 'Nxt | ';
slct += ' | ';
slct += '7 | ';
slct += '8 | ';
slct += '9 | ';
slct += '- | ';
slct += ' ';
html += slct;
html += '';
html += '⧉ | ';
html += '…Caps | ';
html += 'a | ';
html += 's | ';
html += 'd | ';
html += 'f | ';
html += 'g | ';
html += 'h | ';
html += 'j | ';
html += 'k | ';
html += 'l | ';
html += '; | ';
html += '\' | ';
html += '\\ | ';
var four = ' | ';
four += '4 | ';
four += '5 | ';
four += '6 | ';
four += ', | ';
four += ' ';
html += four;
html += '';
html += ' | ';
html += 'Shift | ';
html += '< | ';
html += 'z | ';
html += 'x | ';
html += 'c | ';
html += 'v | ';
html += 'b | ';
html += 'n | ';
html += 'm | ';
html += ', | ';
html += '. | ';
html += '/ | ';
html += '…Shift | ';
var uarr = ' | ';
uarr += ' | ';
uarr += '↑ | ';
uarr += ' | ';
uarr += ' | ';
uarr += '1 | ';
uarr += '2 | ';
uarr += '3 | ';
uarr += 'Ent er | ';
uarr += ' ';
html += uarr;
var ctrl = '';
ctrl += 'Ctrl | ';
ctrl += 'Alt | ';
ctrl += ' | ';
ctrl += '…Alt | ';
ctrl += '…Ctrl | ';
ctrl += ' | ';
ctrl += '← | ';
ctrl += '↓ | ';
ctrl += '→ | ';
ctrl += ' | ';
ctrl += '0 | ';
ctrl += '. | ';
html += ctrl;
html += ' ';
/****************/
/* shifted keys */
/****************/
html += '';
html += func;
html += ' ';
html += 'Esc | ';
html += '~ | ';
html += '! | ';
html += '@ | ';
html += '# | ';
html += '$ | ';
html += '% | ';
html += '^ | ';
html += '& | ';
html += '* | ';
html += '( | ';
html += ') | ';
html += '_ | ';
html += '+ | ';
html += 'Del | ';
html += ' | ';
html += find;
html += ' ';
if (vkbTheDetachedChild)
html += '↖ | ';
else
html += '↖ | ';
html += 'Tab | ';
html += 'Q | ';
html += 'W | ';
html += 'E | ';
html += 'R | ';
html += 'T | ';
html += 'Y | ';
html += 'U | ';
html += 'I | ';
html += 'O | ';
html += 'P | ';
html += '{ | ';
html += '} | ';
html += 'Ret urn | ';
html += ' | ';
html += slct;
html += ' ';
html += '⧉ | ';
html += '…Caps | ';
html += 'A | ';
html += 'S | ';
html += 'D | ';
html += 'F | ';
html += 'G | ';
html += 'H | ';
html += 'J | ';
html += 'K | ';
html += 'L | ';
html += ': | ';
html += '\" | ';
html += '| | ';
html += four;
html += ' ';
html += ' | ';
html += 'Shift | ';
html += '> | ';
html += 'Z | ';
html += 'X | ';
html += 'C | ';
html += 'V | ';
html += 'B | ';
html += 'N | ';
html += 'M | ';
html += ', | ';
html += '. | ';
html += '? | ';
html += '…Shift | ';
html += uarr;
html += ctrl;
html += ' ';
html += ' | |
';
vkbid.innerHTML = html;
/**********************/
/* end build keyboard */
/**********************/
setTimeout (vkbLogo, 50);
}
/* populate the "logo space" above the cursor keys */
function vkbLogo ()
{
// avoid "unreachable code after return statement"
if (true) return;
var logo = document.getElementsByName('vkblogo');
logo[0].style.font = logo[1].style.font = 'normal normal 160% Brush Script MT';
logo[0].style.textAlign = logo[1].style.textAlign = 'center';
logo[0].style.letterSpacing = logo[1].style.letterSpacing = '+1px';
logo[0].style.lineHeight = logo[1].style.lineHeight = '1em';
logo[0].style.overflow = logo[1].style.overflow = 'visible';
logo[0].innerHTML = logo[1].innerHTML = 'field test!';
}
/* a key has been pressed */
function vkbpress (code)
{
if (code)
{
if (Array.isArray(code))
{
/* sequence of ASCII codes (e.g. 27 91 2 9 126 for Do key) */
for (var idx = 0; idx < code.length; idx++)
vkbcode(code[idx]);
}
else
{
/* simple ASCII code from keypress */
if (vkbCapsLocked || vkbCtrlLocked)
if (code >= 97 && code <= 122)
code = code - 32;
if (vkbAltLocked) code = code + 128;
if (vkbCtrlLocked) code = code & 0x3f;
vkbcode(code);
}
/* if one-shot keypress modifier */
if (vkbShift1) vkbUnShift();
if (vkbCtrl1) vkbCtrlPress(1);
if (vkbAlt1) vkbAltPress(1);
if (vkbOnce1) vkbOncePress();
}
}
/* send the ASCII code to the terminal */
function vkbcode (code)
{
/* provide code to the terminal */
if (vkbTheDetachedChild)
window.opener.dataTx(String.fromCharCode(code));
else
dataTx(String.fromCharCode(code));
// console.log(code);
}
/* shift key has been pressed */
function vkbShift (count)
{
vkbShift1 = count;
document.getElementById("vkbtable1").style.display = 'none';
document.getElementById("vkbtable2").style.display = 'table';
if (vkbShift1)
{
var name = document.getElementsByName('vkbshift1');
name[1].style.backgroundColor = vkbKeyActive;
}
else
{
var name = document.getElementsByName('vkbshift0');
name[1].style.backgroundColor = vkbKeyActive;
}
}
/* shift key has been un-pressed physically or by one-shot */
function vkbUnShift ()
{
vkbShift1 = 0;
document.getElementById("vkbtable1").style.display = 'table';
document.getElementById("vkbtable2").style.display = 'none';
var name = document.getElementsByName('vkbshift1');
name[0].style.backgroundColor = name[1].style.backgroundColor = vkbKeyInActive;
var name = document.getElementsByName('vkbshift0');
name[0].style.backgroundColor = name[1].style.backgroundColor = vkbKeyInActive;
}
/* caps-lock key has been pressed or un-pressed physically or by one-shot */
function vkbCapsPress ()
{
var active;
if (!vkbCapsLocked)
{
vkbCapsLocked = true;
active = vkbKeyActive;
}
else
{
vkbCapsLocked = false;
active = vkbKeyInActive;
}
var name = document.getElementsByName('vkbcaps');
name[0].style.backgroundColor = name[1].style.backgroundColor = active;
}
/* control key has been pressed or un-pressed physically or by one-shot */
function vkbCtrlPress (count)
{
var active;
if (!vkbCtrlLocked)
{
vkbCtrlLocked = true;
vkbCtrl1 = count;
active = vkbKeyActive;
}
else
{
vkbCtrlLocked = false;
active = vkbKeyInActive;
}
if (vkbCtrl1)
var name = document.getElementsByName('vkbctrl1');
else
var name = document.getElementsByName('vkbctrl0');
name[0].style.backgroundColor = name[1].style.backgroundColor = active;
if (!vkbCtrlLocked) vkbCtrl1 = 0;
}
/* alternate key has been pressed or un-pressed physically or by one-shot */
function vkbAltPress (count)
{
var active;
if (!vkbAltLocked)
{
vkbAltLocked = true;
vkbAlt1 = count;
active = vkbKeyActive;
}
else
{
vkbAltLocked = false;
active = vkbKeyInActive;
}
if (vkbAlt1)
var name = document.getElementsByName('vkbalt1');
else
var name = document.getElementsByName('vkbalt0');
name[0].style.backgroundColor = name[1].style.backgroundColor = active;
if (!vkbAltLocked) vkbAlt1 = 0;
}
/* one-shot key has been pressed or un-pressed physically or by one-shot */
function vkbOncePress ()
{
var active;
if (!vkbOnce1)
{
vkbOnce1 = 1;
active = vkbKeyActive;
}
else
{
if (vkbTheDetachedChild)
{
/* detached keyboard */
window.opener.thisDCLinabox.focusCursor();
var parent = window.open('', 'vkbDCLinabox');
parent.focus();
}
else
{
/* attached keyboard */
document.getElementById("input").focus();
thisDCLinabox.focusCursor();
}
vkbOnce1 = 0;
active = 'inherit';
}
var name = document.getElementsByName('vkbonce');
name[0].style.backgroundColor = name[1].style.backgroundColor = active;
}
/************/
/* detached */
/************/
var vkbDetachChild;
/* the "detach keyboard" key has been pressed */
function vkbDetach ()
{
if (vkbTheDetachedChild) return;
if (vkbDetachChild && !vkbDetachChild.closed)
{
virtualKeyboardClick (this);
vkbDetachChild.window.focus();
return;
}
window.addEventListener('unload',vkbDetachUnload);
window.name = 'vkbDCLinabox';
var specs = 'toolbar=0,location=0,directories=0,status=0,menubar=0,' +
'scrollbars=0,resizable=0,copyhistory=0,width=850,height=250';
var locn = window.location;
var url = locn.protocol + '//' + locn.host + '/dclinabox/-/vkb_lkish.html';
vkbDetachChild = window.open(url, "vkbDetachWindow", specs);
virtualKeyboardClick (this);
vkbDetachChild.window.focus();
}
/* close the virtual keyboard as the terminal session window is close */
function vkbDetachUnload ()
{
if (vkbDetachChild && !vkbDetachChild.closed) vkbDetachChild.close();
}
var vkbTheDetachedChild = false;
/* the detached window HTML onload= event */
function vkbDetached ()
{
vkbTheDetachedChild = true;
var target = document.getElementById("vtvkb");
vkbBuild();
setTimeout (vkbDetachedAdjust, 50);
}
function vkbDetachedAdjust ()
{
document.body.style.fontSize = window.opener.DCLinaboxFontSize + 'px';
var target = document.getElementById("vtvkb");
target.style.display = 'block';
target.style.border = 'none';
target.style.width = 'auto';
target = document.getElementById("vkbtable");
target.style.margin = 0;
target.style.padding = 0;
target.style.width = 'auto';
target = document.getElementById("vkbtable1");
target.style.width = 'auto';
target.style.lineHeight = '1.6em';
target.style.fontSize = '100%';
target = document.getElementById("vkbtable2");
target.style.width = 'auto';
target.style.lineHeight = '1.6em';
target.style.fontSize = '100%';
setTimeout (vkbDetachedResize, 50);
}
var vkbDetachWidth = 0;
var vkbDetachHeight = 0;
var vkbDetachLast = 0;
/* keep the child (detached keyboard) window an appropriate size */
function vkbDetachedResize ()
{
var date = new Date();
var secs = date.getTime() / 1000;
if (secs == vkbDetachLast) return;
vkbDetachLast = secs;
if (!(vkbDetachWidth && vkbDetachHeight))
{
var vkbtable = document.getElementById("vkbtable");
var vkbtable1 = document.getElementById("vkbtable1");
var width = vkbtable1.offsetWidth;
width += window.outerWidth - window.innerWidth;
var height = vkbtable1.offsetHeight;
height += window.outerHeight - window.innerHeight;
vkbDetachWidth = width + 28;
vkbDetachHeight = height + 28;
}
window.resizeTo(vkbDetachWidth, vkbDetachHeight);
}
/*****************************************************************************/