1112 lines
68 KiB
Handlebars
1112 lines
68 KiB
Handlebars
<!DOCTYPE html>
|
|
<html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
|
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="format-detection" content="telephone=no" />
|
|
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS" />
|
|
<script type="text/javascript" src="scripts/common-0.0.1{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-redir-ws-0.1.0{{{min}}}.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-wsman-ws-0.2.0{{{min}}}.js"></script>
|
|
<script type="text/javascript" src="scripts/agent-redir-ws-0.1.1{{{min}}}.js"></script>
|
|
<script type="text/javascript" src="scripts/agent-redir-rtc-0.1.0{{{min}}}.js"></script>
|
|
<script type="text/javascript" src="scripts/agent-desktop-0.0.2{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-desktop-0.0.2{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-terminal-0.0.2{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib-inflate{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib-adler32{{min}}.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib-crc32{{min}}.js"></script>
|
|
<script keeplink=1 type="text/javascript" src="scripts/filesaver.min.js"></script>
|
|
<title>{{{title}}}</title>
|
|
</head>
|
|
<body style="overflow:hidden;background-color:black">
|
|
<div id=p11 class="noselect" style="overflow:hidden">
|
|
<div id=deskarea0>
|
|
<div id=deskarea1 class="areaHead">
|
|
<div class="toright2">
|
|
<span id="p11power"></span>
|
|
<div class='deskareaicon' title="Toggle View Mode" onclick="toggleAspectRatio(1)">⇲</div>
|
|
<div class='deskareaicon' title="Rotate Left" onclick="drotate(-1)">↺</div>
|
|
<div class='deskareaicon' title="Rotate Right" onclick="drotate(1)">↻</div>
|
|
<input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" class="mR" />
|
|
<div id="desktopCustomUiButtons" style="float:left"></div>
|
|
</div>
|
|
<div>
|
|
<div id="idx_deskFullBtn2" onclick=deskToggleFull(event)> ✖</div>
|
|
<input type="button" id="autoconnectbutton1" value="AutoConnect" onclick=autoConnectDesktop(event) onkeypress="return false" onkeydown="return false" style="display:none" />
|
|
<span id=connectbutton1span><input type=button id=connectbutton1 cmenu="deskConnectButton" value="Connect" onclick=connectDesktop(event,3) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
|
|
<span id=connectbutton1hspan> <input type=button id=connectbutton1h value="HW Connect" title="Connect using Intel AMT hardware KVM" onclick=connectDesktop(event,2) onkeypress="return false" onkeydown="return false" disabled="disabled" /></span>
|
|
<span id=disconnectbutton1span> <input type=button id=disconnectbutton1 value="Disconnect" onclick=connectDesktop(event,0) onkeypress="return false" onkeydown="return false" /></span>
|
|
<span id="deskstatus">Disconnected</span><span id="deskmetadata"></span>
|
|
</div>
|
|
</div>
|
|
<div id=deskarea3x style="max-height:calc(100vh - 52px);height:calc(100vh - 52px);">
|
|
<div id=DeskFocus oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></div>
|
|
<div id=DeskParent>
|
|
<canvas id=Desk width=640 height=480 oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas>
|
|
</div>
|
|
<div id=p11DeskConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=clearConsoleMsg()></div>
|
|
</div>
|
|
<div id=deskarea4 class="areaFoot">
|
|
<div class="toright2">
|
|
<span id="DeskLatency" title="Desktop Session Latency"></span>
|
|
<span id="DeskTimer" style="display:none" title="Session time"></span>
|
|
<select id=termdisplays style="display:none" onchange=deskSetDisplay(event) onkeypress="return false" onkeydown="return false"></select>
|
|
<span id=DeskSaveImageButton title="Save a screenshot of the remote desktop"><img src='images/icon-camera.png' onclick=deskSaveImage() height=16 width=16 style=padding-top:2px /></span>
|
|
</div>
|
|
<div>
|
|
<select id="deskkeys">
|
|
<option value=10>Ctrl+Alt+Del</option>
|
|
<option value=5>Win</option>
|
|
<option value=0>Win+Down</option>
|
|
<option value=1>Win+Up</option>
|
|
<option value=2>Win+L</option>
|
|
<option value=3>Win+M</option>
|
|
<option value=4>Shift+Win+M</option>
|
|
<option value=6>Win+R</option>
|
|
<option value=7>Alt-F4</option>
|
|
<option value=8>Ctrl-W</option>
|
|
<option value=9>Alt-Tab</option>
|
|
<option value=11>Win+Left</option>
|
|
<option value=12>Win+Right</option>
|
|
</select>
|
|
<input id="DeskWD" type=button value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()" />
|
|
<input id="DeskClip" style="" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()" />
|
|
<input id="DeskType" style="" type="button" value="Type" onkeypress="return false" onkeydown="return false" onclick="showDeskType()" />
|
|
<label><span id="DeskControlSpan" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()" />Input</span></label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id=dialog class="noselect" style="display:none">
|
|
<div id=dialogHeader>
|
|
<div tabindex=0 id=id_dialogclose onclick=setDialogMode() onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
|
|
<div id=id_dialogtitle></div>
|
|
</div>
|
|
<div id=dialogBody>
|
|
<div id=dialog1>
|
|
<div id=id_dialogMessage style=""></div>
|
|
</div>
|
|
<div id=dialog2 style="">
|
|
<div id=id_dialogOptions></div>
|
|
</div>
|
|
<div id=dialog7 style="">
|
|
<div id="d7meshkvm">
|
|
<h4>Agent Remote Desktop</h4>
|
|
<div>
|
|
<div>Quality</div>
|
|
<select id="d7bitmapquality" dir="rtl"></select>
|
|
</div>
|
|
<div>
|
|
<div>Scaling</div>
|
|
<select id="d7bitmapscaling" style="" dir="rtl">
|
|
<option selected=selected value=1024>100%</option>
|
|
<option value=896>87.5%</option>
|
|
<option value=768>75%</option>
|
|
<option value=640>62.5%</option>
|
|
<option value=512>50%</option>
|
|
<option value=384>37.5%</option>
|
|
<option value=256>25%</option>
|
|
<option value=128>12.5%</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<div>Frame rate</div>
|
|
<select id="d7framelimiter" dir="rtl">
|
|
<option selected=selected value=50>Fast</option>
|
|
<option value=100>Medium</option>
|
|
<option value=400>Slow</option>
|
|
<option value=1000>Very slow</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div id="d7amtkvm">
|
|
<h4>Intel® AMT Hardware KVM</h4>
|
|
<div>
|
|
<div>Image Encoding</div>
|
|
<select id="d7desktopmode">
|
|
<option value="1">RLE8, Fastest</option>
|
|
<option value="2">RLE16, Recommended</option>
|
|
<option value="3">RAW8, Slow</option>
|
|
<option value="4">RAW16, Very Slow</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<div>Other Settings</div>
|
|
<div id="d7otherset" style="display:block">
|
|
<label style="display:block"><input type="checkbox" id="d7showfocus" />Show Focus Tool</label>
|
|
<label style="display:block"><input type="checkbox" id="d7showcursor" />Show Local Mouse Cursor</label>
|
|
<label style="display:block"><input type="checkbox" id="d7localKeyMap" />Local Keyboard Map</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="idx_dlgButtonBar">
|
|
<input id="idx_dlgCancelButton" type="button" value="Cancel" style="" onclick="dialogclose(0)">
|
|
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
|
<div><input id="idx_dlgDeleteButton" type="button" value="Delete" style="display:none" onclick="dialogclose(2)"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
var sessionActivity = null;
|
|
var desktop = null;
|
|
var agentPresent = true;
|
|
var intelAmtPresent = false;
|
|
var deskAspectRatio = 0;
|
|
var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 100, localkeymap: false };
|
|
var p11DeskConsoleMsgTimer = null;
|
|
var serverPublicNamePort = '{{{serverDnsName}}}:{{{serverPublicPort}}}';
|
|
var domain = '{{{domain}}}';
|
|
var domainUrl = '{{{domainurl}}}';
|
|
var authCookie = '{{{authCookie}}}';
|
|
var urlargs = parseUriArgs();
|
|
var debugmode = urlargs.debug;
|
|
var attemptWebRTC = false;
|
|
var updateSessionTimer = null;
|
|
var StatusStrs = ["Disconnected", "Connecting...", "Setup...", "Connected", "Intel® AMT Connected"];
|
|
var webPageFullScreen = false;
|
|
var expire = '{{{expire}}}';
|
|
if (expire != '') { QH('p11power', format("Expires at {0}", printTime(new Date(parseInt(expire))))) }
|
|
|
|
function start() {
|
|
window.onresize = deskAdjust;
|
|
setupDesktop();
|
|
}
|
|
|
|
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
|
|
|
// Toggle the web page to full screen
|
|
function toggleAspectRatio(toggle) {
|
|
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
|
|
deskAdjust();
|
|
}
|
|
|
|
function deskAdjust() {
|
|
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
|
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
|
|
|
if (deskAspectRatio == 2) {
|
|
// Scale mode
|
|
QS('Desk')['margin-top'] = null;
|
|
QS('Desk').height = '100%';
|
|
QS('Desk').width = '100%';
|
|
QS('DeskParent').overflow = 'hidden';
|
|
} else if (deskAspectRatio == 1) {
|
|
// Zoomed mode
|
|
QS('Desk')['margin-top'] = '0px';
|
|
//QS('Desk')['margin-left'] = '0px';
|
|
QS('Desk').height = deskH + 'px';
|
|
QS('Desk').width = deskW + 'px';
|
|
QS('DeskParent').overflow = 'scroll';
|
|
} else {
|
|
// Fixed aspect ratio
|
|
if ((parentH / parentW) > (deskH / deskW)) {
|
|
var hNew = ((deskH * parentW) / deskW) + 'px';
|
|
//if (webPageFullScreen || fullscreen) {
|
|
//QS('deskarea3x').height = null;
|
|
//} else {
|
|
// QS('deskarea3x').height = hNew;
|
|
//QS('deskarea3x').height = null;
|
|
//}
|
|
QS('Desk').height = hNew;
|
|
QS('Desk').width = '100%';
|
|
} else {
|
|
var wNew = ((deskW * parentH) / deskH) + 'px';
|
|
//if (webPageFullScreen || fullscreen) {
|
|
//QS('Desk').height = null;
|
|
//} else {
|
|
QS('Desk').height = '100%';
|
|
//}
|
|
QS('Desk').width = wNew;
|
|
}
|
|
QS('Desk')['margin-top'] = null;
|
|
QS('DeskParent').overflow = 'hidden';
|
|
}
|
|
}
|
|
|
|
//
|
|
// DESKTOP
|
|
//
|
|
|
|
function setupDesktop() {
|
|
// Setup the remote desktop
|
|
if (desktop != null) { desktop.Stop(); desktop = null; }
|
|
|
|
// If the device desktop is already connected in multi-desktop, use that.
|
|
if (desktop == null) {
|
|
// Device is not already connected, just setup a blank canvas
|
|
QH('DeskParent', '<canvas id=Desk oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');
|
|
|
|
// Setup the mouse wheel
|
|
Q('Desk').addEventListener('DOMMouseScroll', function (e) { return dmousewheel(e); });
|
|
Q('Desk').addEventListener('mousewheel', function (e) { return dmousewheel(e); });
|
|
}
|
|
updateDesktopButtons();
|
|
deskAdjust();
|
|
updateMetadata(desktop, 'deskmetadata');
|
|
}
|
|
|
|
// Show and enable the right buttons
|
|
function updateDesktopButtons() {
|
|
var deskState = 0;
|
|
if (desktop != null) { deskState = desktop.State; }
|
|
|
|
// Show the right buttons
|
|
QV('disconnectbutton1span', (deskState != 0));
|
|
QV('connectbutton1span', (deskState == 0) && (agentPresent));
|
|
QV('connectbutton1hspan', (deskState == 0) && (intelAmtPresent));
|
|
|
|
// Show the right settings
|
|
QV('d7meshkvm', agentPresent && ((deskState == 0) || (desktop.contype == 1)));
|
|
QV('d7amtkvm', intelAmtPresent && ((deskState == 0) || (desktop.contype == 2)));
|
|
|
|
// Enable buttons
|
|
var inputAllowed = true; // TODO
|
|
QE('connectbutton1', agentPresent);
|
|
QE('connectbutton1h', intelAmtPresent);
|
|
//QV('DeskClip', agentPresent && ((desktop == null) || (desktop.contype != 2))); // Clipboard not supported on macOS
|
|
QV('DeskClip', false); // Clipboard not supported on this page
|
|
QE('DeskClip', deskState == 3);
|
|
QE('DeskType', deskState == 3);
|
|
QV('DeskWD', inputAllowed);
|
|
QE('DeskWD', deskState == 3);
|
|
QV('deskkeys', inputAllowed);
|
|
QE('deskkeys', deskState == 3);
|
|
|
|
// Display this only if we have Chat & Notify permissions
|
|
QV('DeskSaveImageButton', (deskState == 3) && (Q('Desk')['toBlob'] != null));
|
|
QV('DeskControlSpan', inputAllowed)
|
|
QV('deskActionsBtn', (browserfullscreen == false));
|
|
QV('deskActionsSettings', (browserfullscreen == false));
|
|
Q('DeskControl').checked = true;
|
|
QS('DeskControlSpan').color = Q('DeskControl').checked ? null : 'red';
|
|
}
|
|
|
|
// Debug
|
|
var autoConnectDesktopTimer = null;
|
|
function autoConnectDesktop(e) { if (autoConnectDesktopTimer == null) { autoConnectDesktopTimer = setInterval(function () { connectDesktop(null, 1) }, 1000); } else { clearInterval(autoConnectDesktopTimer); autoConnectDesktopTimer = null; } }
|
|
|
|
// Used to translate incoming agent console messages
|
|
var agentConsoleMessages = ['', "Waiting for user to grant access...", "Denied", "Failed to start remote terminal session, {0} ({1})", "Timeout", "Received invalid network data"];
|
|
function formatAgentConsoleMessage(msg, msgid, msgargs) {
|
|
var r;
|
|
if (msgargs == null) { msgargs = []; }
|
|
while (msgargs.length < 3) { msgargs.push(''); } // We need to call the format function in a way that works with older browsers and minifier, can't use apply() or ...
|
|
if (msgid && (msgid < agentConsoleMessages.length)) { r = EscapeHtml(format(agentConsoleMessages[msgid], (msgargs[0]), (msgargs[1]), (msgargs[2]))); } else { r = EscapeHtml(msg); }
|
|
return r.split('\n').join('<br />') + '<br /><br />';
|
|
}
|
|
|
|
function connectDesktop(e, contype, tsid, consent) {
|
|
if (xxdialogMode) return;
|
|
if ((e != null) && (e.shiftKey != false) && (contype == 3)) { contype = 1; } // If the shift key is not pressed, don't try to ask for session list.
|
|
QV('p11DeskSessionSelector', false);
|
|
p11clearConsoleMsg();
|
|
if (desktop == null) {
|
|
if (contype == 2) {
|
|
// Setup the Intel AMT remote desktop
|
|
//if ((desktopNode.intelamt.user == null) || (desktopNode.intelamt.user == '')) { editDeviceAmtSettings(desktopNode._id, connectDesktop, 2); return; }
|
|
desktop = CreateAmtRedirect(CreateAmtRemoteDesktop('Desk'), authCookie);
|
|
desktop.debugmode = debugmode;
|
|
desktop.onStateChanged = onDesktopStateChange;
|
|
desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
|
|
desktop.m.useZRLE = (desktopsettings.encoding < 3);
|
|
desktop.m.localKeyMap = desktopsettings.localkeymap;
|
|
desktop.m.showmouse = desktopsettings.showmouse;
|
|
desktop.m.onScreenSizeChange = deskAdjust;
|
|
desktop.m.onKvmData = function (x) {
|
|
//console.log('onKvmData (' + x.length + '): ' + x);
|
|
// Send the presense probe only once if needed.
|
|
if (x.length == 0) { if (!desktop.m._sentPresence) { desktop.m._sentPresence = true; desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 })); } return; }
|
|
var data = null;
|
|
try { data = JSON.parse(x); } catch (e) { }
|
|
if ((data != null) && (data.action != null)) {
|
|
if (data.action == 'restart') {
|
|
// Clear WebRTC channel
|
|
webRtcDesktopReset();
|
|
desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 }));
|
|
} else if ((data.action == 'present') && (webRtcDesktop == null)) {
|
|
// Setup WebRTC channel
|
|
webRtcDesktop = { platform: data.platform };
|
|
var configuration = null; //{ "iceServers": [ { 'urls': 'stun:stun.services.mozilla.com' }, { 'urls': 'stun:stun.l.google.com:19302' } ] };
|
|
if (typeof RTCPeerConnection !== 'undefined') { webRtcDesktop.webrtc = new RTCPeerConnection(configuration); }
|
|
else if (typeof webkitRTCPeerConnection !== 'undefined') { webRtcDesktop.webrtc = new webkitRTCPeerConnection(configuration); }
|
|
|
|
webRtcDesktop.webchannel = webRtcDesktop.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
|
|
webRtcDesktop.webchannel.onopen = function () {
|
|
// Switch to software KVM
|
|
//if (urlvars && urlvars['kvmdatatrace']) { console.log('WebRTC Data Channel Open'); }
|
|
console.log('WebRTC Data Channel Open');
|
|
Q('deskstatus').textContent = StatusStrs[desktop.State] + ", Soft-KVM";
|
|
desktop.m.hold(true);
|
|
webRtcDesktop.webRtcActive = true;
|
|
webRtcDesktop.softdesktop = CreateKvmDataChannel(webRtcDesktop.webchannel, CreateAgentRemoteDesktop('Desk', Q('id_mainarea')), desktop.m);
|
|
webRtcDesktop.softdesktop.m.setRotation(desktop.m.rotation);
|
|
webRtcDesktop.softdesktop.m.onScreenSizeChange = deskAdjust;
|
|
if (desktopsettings.quality) { webRtcDesktop.softdesktop.m.CompressionLevel = desktopsettings.quality; } // Number from 1 to 100. 50 or less is best.
|
|
if (desktopsettings.scaling) { webRtcDesktop.softdesktop.m.ScalingLevel = desktopsettings.scaling; }
|
|
webRtcDesktop.softdesktop.Start();
|
|
|
|
// Check if we can get remote file access
|
|
// ###BEGIN###{DesktopInbandFiles}
|
|
/*
|
|
QV('go24', true); // Files
|
|
downloadFile = null;
|
|
p24files = webRtcDesktop.softdesktop;
|
|
p24targetpath = '';
|
|
webRtcDesktop.softdesktop.onControlMsg = onFilesControlData;
|
|
webRtcDesktop.softdesktop.sendCtrlMsg(JSON.stringify({ action: 'ls', reqid: 1, path: '' })); // Ask for the root folder
|
|
*/
|
|
// ###END###{DesktopInbandFiles}
|
|
}
|
|
webRtcDesktop.webchannel.onclose = function (event) {
|
|
//if (urlvars['kvmdatatrace']) { console.log('WebRTC Data Channel Closed'); }
|
|
console.log('WebRTC Data Channel Closed');
|
|
webRtcDesktopReset();
|
|
}
|
|
webRtcDesktop.webrtc.onicecandidate = function (e) {
|
|
if (e.candidate == null) {
|
|
desktop.m.sendKvmData(JSON.stringify({ action: 'offer', ver: 1, sdp: webRtcDesktop.webrtcoffer.sdp }));
|
|
} else {
|
|
webRtcDesktop.webrtcoffer.sdp += ('a=' + e.candidate.candidate + '\r\n'); // New candidate, add it to the SDP
|
|
}
|
|
}
|
|
webRtcDesktop.webrtc.oniceconnectionstatechange = function () {
|
|
if ((webRtcDesktop != null) && (webRtcDesktop.webrtc != null) && ((webRtcDesktop.webrtc.iceConnectionState == 'disconnected') || (webRtcDesktop.webrtc.iceConnectionState == 'failed'))) { /*console.log('WebRTC ICE Failed');*/ webRtcDesktopReset(); }
|
|
}
|
|
webRtcDesktop.webrtc.createOffer(function (offer) {
|
|
// Got the offer
|
|
webRtcDesktop.webrtcoffer = offer;
|
|
webRtcDesktop.webrtc.setLocalDescription(offer, function () { }, webRtcDesktopReset);
|
|
}, webRtcDesktopReset, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
|
|
} else if ((data.action == 'answer') && (webRtcDesktop != null)) {
|
|
// Complete the WebRTC channel
|
|
webRtcDesktop.webrtc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: data.sdp }), function () { }, webRtcDesktopReset);
|
|
}
|
|
}
|
|
};
|
|
desktop.Start(null, 16994, '*', '*', 0);
|
|
desktop.contype = 2;
|
|
} else if ((contype == null) || (contype == 1) || (contype == 3)) {
|
|
// Setup the Mesh Agent remote desktop
|
|
var meshserver = null;
|
|
desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie, null, domainUrl);
|
|
desktop.m.mouseCursorActive(true);
|
|
desktop.debugmode = debugmode;
|
|
desktop.m.debugmode = debugmode;
|
|
desktop.attemptWebRTC = attemptWebRTC;
|
|
desktop.options = {};
|
|
if (tsid != null) { desktop.options.tsid = tsid; }
|
|
if (consent != null) { desktop.options.consent = consent; }
|
|
desktop.onStateChanged = onDesktopStateChange;
|
|
desktop.onConsoleMessageChange = function () {
|
|
if (desktop.consoleMessage) {
|
|
Q('p11DeskConsoleMsg').innerHTML += formatAgentConsoleMessage(desktop.consoleMessage, desktop.consoleMessageId, desktop.consoleMessageArgs);
|
|
QV('p11DeskConsoleMsg', true);
|
|
if (p11DeskConsoleMsgTimer != null) { clearTimeout(p11DeskConsoleMsgTimer); }
|
|
if (desktop.consoleMessageTimeout) { p11DeskConsoleMsgTimer = setTimeout(p11clearConsoleMsg, desktop.consoleMessageTimeout * 1000); }
|
|
} else {
|
|
p11clearConsoleMsg();
|
|
}
|
|
}
|
|
desktop.onMetadataChange = function (metadata) { updateMetadata(desktop, 'deskmetadata'); }
|
|
desktop.m.CompressionLevel = desktopsettings.quality; // Number from 1 to 100. 50 or less is best.
|
|
desktop.m.ScalingLevel = desktopsettings.scaling;
|
|
if (desktopsettings.framerate) { desktop.m.FrameRateTimer = desktopsettings.framerate; }
|
|
desktop.m.onDisplayinfo = deskDisplayInfo;
|
|
desktop.m.onScreenSizeChange = deskAdjust;
|
|
desktop.Start(null);
|
|
desktop.latency.callback = function (ms) { console.log('latency', ms); updateSessionTime(); };
|
|
desktop.contype = 1;
|
|
}
|
|
} else {
|
|
// Disconnect and clean up the remote desktop
|
|
desktop.Stop();
|
|
webRtcDesktopReset();
|
|
desktop = null;
|
|
//if (pluginHandler != null) { pluginHandler.callHook('onDesktopDisconnect'); }
|
|
}
|
|
}
|
|
|
|
function updateMetadata(conn, elementid) {
|
|
var str = '', viewerCount = 0;
|
|
if (conn && (conn.State == 3)) {
|
|
if (conn.metadata && conn.metadata.users) { for (var i in conn.metadata.users) { viewerCount += conn.metadata.users[i]; } }
|
|
if (viewerCount > 1) { str = '<span onclick=showSessionMetadata(1) style=cursor:pointer>' + format(", {0} watching", viewerCount) + '</span>'; }
|
|
}
|
|
QH('deskmetadata', str);
|
|
if ((conn == desktop) && (xxdialogTag == ('sessionMetadata1'))) { showSessionMetadata(1); }
|
|
}
|
|
|
|
function showSessionMetadata(cid) {
|
|
if (xxdialogMode && (xxdialogTag != ('sessionMetadata' + cid))) return;
|
|
if (xxdialogMode) { setDialogMode(0); }
|
|
var conn = null;
|
|
if (cid == 1) { conn = desktop; }
|
|
if (conn && conn.metadata) {
|
|
var x = '';
|
|
if (conn.metadata.startTime) { x += addHtmlValue4("Start Time", printDateTime(new Date(conn.metadata.startTime))); }
|
|
if (conn.metadata.users) {
|
|
for (var i in conn.metadata.users) {
|
|
var val = (conn.metadata.users[i] == 1) ? "1 connection" : format("{0} connections", conn.metadata.users[i]);
|
|
var username = i.split('/')[2];
|
|
if ((users != null) && (users[i] != null)) { username = users[i].name; }
|
|
x += addHtmlValue4(format("User \"{0}\"", username), val);
|
|
}
|
|
}
|
|
setDialogMode(2, "Session Information", 1, null, x, 'sessionMetadata' + cid);
|
|
}
|
|
}
|
|
|
|
function p11clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); QV('p11DeskConsoleMsg', false); if (p11DeskConsoleMsgTimer) { clearTimeout(p11DeskConsoleMsgTimer); p11DeskConsoleMsgTimer = null; } }
|
|
|
|
var webRtcDesktop = null;
|
|
function webRtcDesktopReset() {
|
|
if (webRtcDesktop == null) return;
|
|
if (webRtcDesktop.softdesktop != null) { webRtcDesktop.softdesktop.Stop(); webRtcDesktop.softdesktop = null; }
|
|
if (webRtcDesktop.webchannel != null) { try { webRtcDesktop.webchannel.close(); } catch (e) { } webRtcDesktop.webchannel = null; }
|
|
if (webRtcDesktop.webrtc != null) { try { webRtcDesktop.webrtc.close(); } catch (e) { } webRtcDesktop.webrtc = null; }
|
|
webRtcDesktop = null;
|
|
// Switch back to hardware KVM
|
|
if (desktop && desktop.m) {
|
|
desktop.m.hold(false);
|
|
Q('deskstatus').textContent = StatusStrs[desktop.State];
|
|
}
|
|
// ###BEGIN###{DesktopInbandFiles}
|
|
/*
|
|
p24files = null;
|
|
p24downloadFileCancel() // If any downloads are in process, cancel them.
|
|
p24uploadFileCancel(); // If any uploads are in process, cancel them.
|
|
QV('go24', false); // Files
|
|
if (currentView == 24) { go(14); }
|
|
*/
|
|
// ###END###{DesktopInbandFiles}
|
|
}
|
|
|
|
function onDesktopStateChange(xdesktop, state) {
|
|
var xstate = state;
|
|
if ((xstate == 3) && (xdesktop.contype == 2)) { xstate++; }
|
|
var str = StatusStrs[xstate];
|
|
if ((desktop != null) && (desktop.webRtcActive == true)) { str += ", WebRTC"; }
|
|
//if (desktop.m.stopInput == true) { str += ', Loopback'; }
|
|
QH('deskstatus', str);
|
|
switch (state) {
|
|
case 0:
|
|
// Stop recording
|
|
if (desktop.m.recordedData != null) { deskRecordSession(); }
|
|
|
|
// Disconnect and clean up the remote desktop
|
|
desktop.Stop();
|
|
desktop = null;
|
|
QV('DeskFocus', false);
|
|
QV('termdisplays', false);
|
|
QV('deskRecordIcon', false);
|
|
if (fullscreen == true) { deskToggleFull(); }
|
|
webRtcDesktopReset();
|
|
deskPreferedStickyDisplay = 0;
|
|
break;
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
if (desktop && (desktop.serverIsRecording == true)) { QV('deskRecordIcon', true); }
|
|
desktop.startTime = new Date();
|
|
if (updateSessionTimer == null) { updateSessionTimer = setInterval(updateSessionTime, 1000); }
|
|
break;
|
|
default:
|
|
//console.log('Unknown onDesktopStateChange state', state);
|
|
break;
|
|
}
|
|
updateDesktopButtons();
|
|
deskAdjust();
|
|
setTimeout(deskAdjust, 50);
|
|
updateMetadata(desktop, 'deskmetadata');
|
|
}
|
|
|
|
function updateSessionTime() {
|
|
// Desktop
|
|
var latencyStr = '', seconds = 0;
|
|
if (desktop && desktop.startTime) {
|
|
if (desktop.latency && (desktop.latency.current >= 0)) { latencyStr = format('{0} ms, ', desktop.latency.current); }
|
|
seconds = Math.floor((new Date() - desktop.startTime) / 1000);
|
|
QH('DeskTimer', latencyStr + zeroPad(Math.floor(seconds / 3600), 2) + ':' + zeroPad((Math.floor(seconds / 60) % 60), 2) + ':' + zeroPad((seconds % 60), 2));
|
|
} else {
|
|
QH('DeskTimer', '');
|
|
}
|
|
|
|
if (desktop == null) { clearInterval(updateSessionTimer); updateSessionTimer = null; }
|
|
}
|
|
|
|
function showDesktopSettings() {
|
|
if (xxdialogMode) return;
|
|
applyDesktopSettings();
|
|
updateDesktopButtons();
|
|
setDialogMode(7, "Remote Desktop Settings", 3, showDesktopSettingsChanged);
|
|
}
|
|
|
|
function showDesktopSettingsChanged() {
|
|
desktopsettings.encoding = d7desktopmode.value;
|
|
desktopsettings.showfocus = d7showfocus.checked;
|
|
desktopsettings.showmouse = d7showcursor.checked;
|
|
desktopsettings.quality = d7bitmapquality.value;
|
|
desktopsettings.scaling = d7bitmapscaling.value;
|
|
desktopsettings.framerate = d7framelimiter.value;
|
|
desktopsettings.localkeymap = d7localKeyMap.checked;
|
|
localStorage.setItem('desktopsettings', JSON.stringify(desktopsettings));
|
|
applyDesktopSettings();
|
|
if (desktop) {
|
|
if (desktop.contype == 1) {
|
|
if (desktop.State != 0) {
|
|
desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate);
|
|
}
|
|
}
|
|
if (desktop.contype == 2) {
|
|
if (desktop.State != 0) { desktop.Stop(); setTimeout(function () { connectDesktop(null, 2); }, 50); }
|
|
}
|
|
}
|
|
}
|
|
|
|
function applyDesktopSettings() {
|
|
var r = '', ops = [60, 50, 40, 30, 20, 10, 5, 1];
|
|
for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
|
|
QH('d7bitmapquality', r);
|
|
d7desktopmode.value = desktopsettings.encoding;
|
|
d7showfocus.checked = desktopsettings.showfocus;
|
|
d7showcursor.checked = desktopsettings.showmouse;
|
|
d7bitmapquality.value = 40; // Default value
|
|
if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
|
|
d7bitmapscaling.value = desktopsettings.scaling;
|
|
if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; } else { d7framelimiter.value = 100; }
|
|
if (desktopsettings.localkeymap) { d7localKeyMap.checked = desktopsettings.localkeymap; }
|
|
}
|
|
|
|
// Enter browser fullscreen
|
|
function enterBrowserFullscreen(elem) {
|
|
if (elem.requestFullscreen) { elem.requestFullscreen(); }
|
|
else if (elem.msRequestFullscreen) { elem.msRequestFullscreen(); }
|
|
else if (elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); }
|
|
else if (elem.webkitRequestFullscreen) { elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); }
|
|
}
|
|
|
|
// Exit browser fullscreen
|
|
function exitBrowserFullscreen() {
|
|
if (document.exitFullscreen) { document.exitFullscreen(); }
|
|
else if (document.msExitFullscreen) { document.msExitFullscreen(); }
|
|
else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); }
|
|
else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); }
|
|
}
|
|
|
|
// Return true if the browser is fullscreen. This is a delayed method that will return true/false late. Not very useful.
|
|
function isBrowserFullscreen() {
|
|
if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { return false; } else { return true; }
|
|
}
|
|
|
|
var fullscreen = false;
|
|
var browserfullscreen = false;
|
|
function deskToggleFull(e) {
|
|
var xtermActive = !((urlargs.xterm === 0) || ((terminal != null) && (xterm == null)));
|
|
fullscreen = !fullscreen;
|
|
if (fullscreen) {
|
|
QC('body').add('fulldesk');
|
|
QS('deskarea3x')['height'] = '100%';
|
|
QS('deskarea3x')['max-height'] = '100%';
|
|
if (xtermActive) {
|
|
// XTerm terminal
|
|
QS('termTable')['position'] = 'absolute';
|
|
QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = '0';
|
|
} else {
|
|
// Legacy terminal
|
|
QS('termTable')['height'] = '100%';
|
|
QS('termTable')['max-height'] = '100%';
|
|
}
|
|
|
|
// If shift is pressed, enter browser full screen.
|
|
if (e.shiftKey == true) {
|
|
enterBrowserFullscreen(Q('container'));
|
|
browserfullscreen = true;
|
|
}
|
|
} else {
|
|
QC('body').remove('fulldesk');
|
|
var hide = urlargs.hide;
|
|
if (footerBar == false) { hide |= 4; }
|
|
var xh = (((hide & 1) ? 0 : 66) + ((hide & 2) ? 0 : 24) + ((hide & 4) ? 0 : 45) + ((hide & 8) ? 0 : 60)); // 0 to 195
|
|
QS('deskarea3x')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
|
|
QS('deskarea3x')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
|
|
if (xtermActive) {
|
|
// XTerm terminal
|
|
QS('termTable')['position'] = null;
|
|
QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = null;
|
|
} else {
|
|
// Legacy terminal
|
|
QS('termTable')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
|
|
QS('termTable')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
|
|
}
|
|
if (browserfullscreen == true) { exitBrowserFullscreen(); browserfullscreen = false; }
|
|
}
|
|
deskAdjust();
|
|
updateDesktopButtons();
|
|
adjustPanels();
|
|
//setTimeout(adjustPanels, 10);
|
|
//setTimeout(function() { xtermfit.fit(); }, 10);
|
|
if (xterm != null) { if (xxcurrentView == 12) { xtermfit.fit(); xterm.focus(); } }
|
|
}
|
|
|
|
function deskAdjust() {
|
|
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
|
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
|
|
|
if (deskAspectRatio == 2) {
|
|
// Scale mode
|
|
QS('Desk')['margin-top'] = null;
|
|
QS('Desk').height = '100%';
|
|
QS('Desk').width = '100%';
|
|
//QS('deskarea3x').height = null;
|
|
QS('DeskParent').overflow = 'hidden';
|
|
} else if (deskAspectRatio == 1) {
|
|
// Zoomed mode
|
|
QS('Desk')['margin-top'] = '0px';
|
|
QS('Desk').height = deskH + 'px';
|
|
QS('Desk').width = deskW + 'px';
|
|
QS('DeskParent').overflow = 'scroll';
|
|
} else {
|
|
// Fixed aspect ratio
|
|
if ((parentH / parentW) > (deskH / deskW)) {
|
|
var hNew = ((deskH * parentW) / deskW) + 'px';
|
|
//if (webPageFullScreen || fullscreen) {
|
|
//QS('deskarea3x').height = null;
|
|
//} else {
|
|
// QS('deskarea3x').height = hNew;
|
|
//QS('deskarea3x').height = null;
|
|
//}
|
|
QS('Desk').height = hNew;
|
|
QS('Desk').width = '100%';
|
|
} else {
|
|
var wNew = ((deskW * parentH) / deskH) + 'px';
|
|
if (webPageFullScreen || fullscreen) {
|
|
QS('Desk').height = null;
|
|
} else {
|
|
QS('Desk').height = '100%';
|
|
}
|
|
QS('Desk').width = wNew;
|
|
}
|
|
QS('Desk')['margin-top'] = null;
|
|
QS('DeskParent').overflow = 'hidden';
|
|
}
|
|
}
|
|
|
|
function mdeskAdjust(mod, sw, sh, cv) {
|
|
if (!mod || !sw || !sh || !cv) return;
|
|
|
|
// Check if we are in single desktop mode
|
|
if (cv.id == 'Desk') { deskAdjust(); return; }
|
|
|
|
// Figure out and adjust the size to fill the width of the div
|
|
var vsize = [{ x: 180, y: 101 }, { x: 302, y: 169 }, { x: 454, y: 255 }][Q('sizeselect').selectedIndex];
|
|
var realw = vsize.x + 2, tw = Q('xdevices').clientWidth - 30, xw = Math.floor(tw / realw);
|
|
xw = realw + Math.floor((tw - (xw * realw)) / xw);
|
|
vsize.y = vsize.y * (xw / vsize.x);
|
|
vsize.x = xw;
|
|
var mh = vsize.y, mw = vsize.x;
|
|
if (mod.State != 0) { mh = vsize.y; mw = (sw / sh) * vsize.y; }
|
|
QS(cv.id)['max-height'] = mh + 'px';
|
|
QS(cv.id)['max-width'] = mw + 'px';
|
|
QS(cv.id)['margin-top'] = '0';
|
|
QS(cv.id)['margin-bottom'] = '0';
|
|
}
|
|
|
|
// Remote desktop special key combos for Windows
|
|
function deskSendKeys() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
var ks = Q('deskkeys').value;
|
|
if (ks == 0) { // WIN+Down arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xff54, 1], [0xff54, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Down arrow press, Down arrow release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 40], [desktop.m.KeyAction.UP, 40], [desktop.m.KeyAction.EXUP, 0x5B]]); // Agent: L-Winkey press, Down arrow press, Down arrow release, L-Winkey release
|
|
}
|
|
} else if (ks == 1) { // WIN+Up arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xff52, 1], [0xff52, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Up arrow press, Up arrow release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 38], [desktop.m.KeyAction.UP, 38], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, Up arrow press, Up arrow release, L-Winkey release
|
|
}
|
|
} else if (ks == 2) { // WIN+L arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0x6c, 1], [0x6c, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'l' press, 'l' release, Meta-left release
|
|
} else {
|
|
desktop.sendCtrlMsg('{"action":"lock"}');
|
|
//desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,76],[desktop.m.KeyAction.UP,76],[desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, 'L' press, 'L' release, L-Winkey release
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXDOWN, 0x5B);
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.DOWN, 76);
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.UP, 76);
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXUP, 0x5B);
|
|
}
|
|
} else if (ks == 3) { // WIN+M arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0x6d, 1], [0x6d, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'm' press, 'm' release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 77], [desktop.m.KeyAction.UP, 77], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, 'M' press, 'M' release, L-Winkey release
|
|
}
|
|
} else if (ks == 4) { // Shift+WIN+M arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe1, 1], [0xffe7, 1], [0x6d, 1], [0x6d, 0], [0xffe7, 0], [0xffe1, 0]]); // Intel AMT: Shift-left down, Meta-left down, 'm' press, 'm' release, Meta-left release, Shift-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN, 16], [desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 77], [desktop.m.KeyAction.UP, 77], [desktop.m.KeyAction.EXUP, 0x5B], [desktop.m.KeyAction.UP, 16]]); // MeshAgent: L-shift press, L-Winkey press, 'M' press, 'M' release, L-Winkey release, L-shift release
|
|
}
|
|
} else if (ks == 5) { // WIN
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xffe7, 0]]); // Intel AMT: Meta-left down, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, L-Winkey release
|
|
}
|
|
} else if (ks == 6) { // WIN+R
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0x72, 1], [0x72, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'r' press, 'r' release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 82], [desktop.m.KeyAction.UP, 82], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, 'R' press, 'R' release, L-Winkey release
|
|
}
|
|
} else if (ks == 7) { // ALT-F4
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe9, 1], [0xffc1, 1], [0xffc1, 0], [0xffe9, 0]]); // Intel AMT: Alt down, 'F4' press, 'F4' release, Alt release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 18], [desktop.m.KeyAction.DOWN, 115], [desktop.m.KeyAction.UP, 115], [desktop.m.KeyAction.EXUP, 18]]); // MeshAgent: Alt press, 'F4' press, 'F4' release, Alt release
|
|
}
|
|
} else if (ks == 8) { // CTRL-W
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe3, 1], [0x77, 1], [0x77, 0], [0xffe3, 0]]); // Intel AMT: Ctrl down, 'w' press, 'w' release, Ctrl release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 17], [desktop.m.KeyAction.DOWN, 87], [desktop.m.KeyAction.UP, 87], [desktop.m.KeyAction.EXUP, 17]]); // MeshAgent: Ctrl press, 'W' press, 'W' release, Ctrl release
|
|
}
|
|
} else if (ks == 9) { // ALT-TAB
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe9, 1], [0xff09, 1], [0xff09, 0], [0xffe9, 0]]); // Intel AMT: Alt down, 'TAB' press, 'TAB' release, Alt release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 18], [desktop.m.KeyAction.DOWN, 9], [desktop.m.KeyAction.UP, 9], [desktop.m.KeyAction.EXUP, 18]]); // MeshAgent: Alt press, 'TAB' press, 'TAB' release, Alt release
|
|
}
|
|
} else if (ks == 10) { // CTRL-ALT-DEL
|
|
desktop.m.sendcad();
|
|
} else if (ks == 11) { // WIN-LEFT
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xff51, 1], [0xff51, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Left arrow press, Left arrow release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 37], [desktop.m.KeyAction.UP, 37], [desktop.m.KeyAction.EXUP, 0x5B]]);
|
|
}
|
|
} else if (ks == 12) { // WIN-RIGHT
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xff53, 1], [0xff53, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Right arrow press, Right arrow release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 39], [desktop.m.KeyAction.UP, 39], [desktop.m.KeyAction.EXUP, 0x5B]]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remote desktop typing
|
|
function showDeskType() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
Q('DeskType').blur();
|
|
var x = '<div>' + "Enter text and click OK to remotely type it using a US english keyboard. Make sure to place the remote cursor at the correct position before proceeding." + '<div>';
|
|
x += '<textarea id=d2typeText style="margin-top:5px;width:100%;height:184px;resize:none" maxlength=2000></textarea>';
|
|
setDialogMode(2, "Remote Keyboard Entry", 3, showDeskTypeEx, x);
|
|
Q('d2typeText').focus();
|
|
}
|
|
|
|
var AmtDeskTypeTimer = null;
|
|
var AmtDeskTypeContent = null;
|
|
var DeskTypeTranslate = { 39: 222, 42: 106, 43: 107, 44: 188, 45: 189, 46: 190, 47: 191, 59: 186, 61: 187, 91: 219, 92: 220, 93: 221, 96: 192, 191: 111 };
|
|
var DeskTypeShiftTranslate = { 33: 49, 34: 222, 35: 51, 36: 52, 37: 53, 38: 55, 40: 57, 41: 48, 58: 186, 60: 188, 62: 190, 63: 191, 64: 50, 94: 54, 95: 189, 106: 56, 107: 187, 123: 219, 124: 220, 125: 221, 126: 192 };
|
|
function showDeskTypeEx() {
|
|
var txt = Q('d2typeText').value, ltxt = Q('d2typeText').value.toUpperCase(), x = [], shift = false;
|
|
if (desktop.contype == 2) {
|
|
// Intel AMT
|
|
for (var i in txt) { var a = txt.charCodeAt(i); x.push([a, 1], [a, 0]); }
|
|
AmtDeskTypeContent = x;
|
|
AmtDeskTypeTimer = setInterval(function () {
|
|
var key = AmtDeskTypeContent.shift();
|
|
if (desktop) { desktop.m.sendkey(key[0], key[1]); }
|
|
if ((desktop == null) || (AmtDeskTypeContent.length == 0)) { clearInterval(AmtDeskTypeTimer); AmtDeskTypeContent = null; }
|
|
}, 10);
|
|
} else {
|
|
// MeshAgent
|
|
for (var i in txt) {
|
|
var a = txt.charCodeAt(i), b = ltxt.charCodeAt(i);
|
|
if (((a >= 65) && (a <= 90)) || ((a >= 97) && (a <= 122))) {
|
|
if ((a == b) && (shift == false)) { x.push([desktop.m.KeyAction.DOWN, 16]); shift = true; } // LShift down
|
|
if ((a != b) && (shift == true)) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // LShift up
|
|
} else if ((a >= 48) && (a <= 57)) {
|
|
if (shift == true) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // Shift up
|
|
} else if (DeskTypeTranslate[a]) {
|
|
if (shift == true) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // Shift up
|
|
b = DeskTypeTranslate[a];
|
|
} else if (DeskTypeShiftTranslate[a]) {
|
|
if (shift == false) { x.push([desktop.m.KeyAction.DOWN, 16]); shift = true; } // LShift down
|
|
b = DeskTypeShiftTranslate[a];
|
|
}
|
|
x.push([desktop.m.KeyAction.DOWN, b], [desktop.m.KeyAction.UP, b]);
|
|
}
|
|
if (shift == true) { x.push([desktop.m.KeyAction.UP, 16]); shift = false; } // Shift up
|
|
desktop.m.SendKeyMsgKC(x);
|
|
}
|
|
}
|
|
|
|
/*
|
|
// Show clipboard dialog
|
|
function showDeskClip() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
Q('DeskClip').blur();
|
|
var x = '';
|
|
x += '<input id=dlgClipGet type=button value="Get Clipboard" style=width:120px onclick=showDeskClipGet()>';
|
|
x += '<input id=dlgClipSet type=button value="Set Clipboard" style=width:120px onclick=showDeskClipSet()>';
|
|
x += '<div id=dlgClipStatus style="display:inline-block;margin-left:8px" ></div>';
|
|
x += '<textarea id=d2clipText style="width:100%;height:184px;resize:none" maxlength=65535></textarea>';
|
|
x += '<input type=button value="Close" style=width:80px;float:right onclick=dialogclose(0)><div style=height:26px;margin-top:3px><span id=linuxClipWarn style=display:none>' + "Remote clipboard is valid for 60 seconds." + '</span> </div><div></div>';
|
|
setDialogMode(2, "Remote Clipboard", 8, null, x, 'clipboard');
|
|
Q('d2clipText').focus();
|
|
}
|
|
|
|
function showDeskClipGet() {
|
|
if (desktop == null || desktop.State != 3) return;
|
|
meshserver.send({ action: 'msg', type: 'getclip', nodeid: currentNode._id });
|
|
}
|
|
|
|
function showDeskClipSet() {
|
|
if (desktop == null || desktop.State != 3) return;
|
|
meshserver.send({ action: 'msg', type: 'setclip', nodeid: currentNode._id, data: Q('d2clipText').value });
|
|
//QV('linuxClipWarn', currentNode && currentNode.agent && (currentNode.agent.id > 4) && (currentNode.agent.id != 21) && (currentNode.agent.id != 22));
|
|
}
|
|
*/
|
|
|
|
// Send CTRL-ALT-DEL
|
|
function sendCAD() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
desktop.m.sendcad();
|
|
}
|
|
|
|
/*
|
|
// Show process dialogs
|
|
function toggleDeskTools() {
|
|
if (xxdialogMode) return;
|
|
if (QS('DeskTools').display == 'none') {
|
|
QV('DeskTools', true);
|
|
Q('DeskTools').nodeid = currentNode._id;
|
|
QH('DeskToolsProcesses', '');
|
|
QH('DeskToolsServices', '');
|
|
QV('deskToolsTopTabService', false);
|
|
changeDeskToolTab(0)
|
|
refreshDeskTools(0);
|
|
refreshDeskTools(1);
|
|
} else {
|
|
QV('DeskTools', false);
|
|
}
|
|
}
|
|
|
|
var deskToolTabSelection = 0;
|
|
function changeDeskToolTab(tabnum) {
|
|
deskToolTabSelection = tabnum;
|
|
QV('DeskToolsProcessTab', tabnum == 0);
|
|
QV('DeskToolsServiceTab', tabnum == 1);
|
|
QS('deskToolsTopTabProcess')['bottom'] = (tabnum == 0) ? '0px' : '3px';
|
|
QS('deskToolsTopTabService')['bottom'] = (tabnum == 1) ? '0px' : '3px';
|
|
QS('deskToolsTopTabProcess')['color'] = (tabnum == 0) ? 'black' : 'gray';
|
|
QS('deskToolsTopTabService')['color'] = (tabnum == 1) ? 'black' : 'gray';
|
|
}
|
|
|
|
// Refresh all of the desktop tool panels
|
|
function refreshDeskTools(x) {
|
|
var sel = (x == null) ? deskToolTabSelection : x;
|
|
QV('DeskToolsRefreshButton', false);
|
|
setTimeout(refreshDeskToolsEx, 500);
|
|
if (sel == 0) meshserver.send({ action: 'msg', type: 'ps', nodeid: currentNode._id });
|
|
if (sel == 1) meshserver.send({ action: 'msg', type: 'services', nodeid: currentNode._id });
|
|
}
|
|
function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
|
|
var deskTools = { sort: 1, ssort: 1, msg: null, smsg: null };
|
|
function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); }
|
|
function sortService(sort) { deskTools.ssort = sort; showDeskToolsServices(deskTools.smsg); }
|
|
function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return sortProcessName(a, b); }
|
|
function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; }
|
|
function showDeskToolsProcesses(message) {
|
|
deskTools.msg = message;
|
|
if (message == null) { QH('DeskToolsProcesses', ''); return; }
|
|
if (Q('DeskTools').nodeid != message.nodeid) return;
|
|
var p = [], processes = null;
|
|
try { processes = JSON.parse(message.value); } catch (e) { }
|
|
if (processes != null) {
|
|
for (var pid in processes) { p.push({ p: parseInt(pid), c: processes[pid].cmd, d: processes[pid].cmd.toLowerCase(), u: processes[pid].user }); }
|
|
if (deskTools.sort == 0) { p.sort(sortProcessPid); } else if (deskTools.sort == 1) { p.sort(sortProcessName); }
|
|
var x = '';
|
|
for (var i in p) {
|
|
if (p[i].p != 0) {
|
|
var c = p[i].c;
|
|
if (c.length > 30) { c = '<span title="' + EscapeHtml(c) + '">' + EscapeHtml(c.substring(0, 30)) + '...</span>' } else { c = EscapeHtml(c); }
|
|
x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + EscapeHtml(p[i].p) + '</div><a href=# style=float:right;padding-right:5px;cursor:pointer title="' + "Stop process" + '" onclick=\'return stopProcess(' + EscapeHtml(p[i].p) + ',"' + EscapeHtml(p[i].c) + '")\'><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u ? EscapeHtml(p[i].u) : '') + '</div><div>' + c + '</div></div>';
|
|
}
|
|
}
|
|
QH('DeskToolsProcesses', x);
|
|
}
|
|
}
|
|
function showDeskToolsServices(message) {
|
|
deskTools.smsg = message;
|
|
if (message == null) { QH('DeskToolsProcesses', ''); return; }
|
|
if (Q('DeskTools').nodeid != message.nodeid) return;
|
|
QV('deskToolsTopTabService', true);
|
|
var s = [], services = null;
|
|
try { services = JSON.parse(message.value); } catch (e) { }
|
|
deskTools.services = services;
|
|
if (services != null) {
|
|
for (var i in services) {
|
|
if (services[i].status) {
|
|
// Windows
|
|
s.push({ p: capitalizeFirstLetter(services[i].status.state.toLowerCase()), d: services[i].displayName, i: i });
|
|
} else if (services[i].serviceType) {
|
|
// Linux (TODO: This the service status is not displayed, not sure start/stop/restart will work).
|
|
s.push({ p: services[i].serviceType, d: services[i].name, i: i });
|
|
}
|
|
}
|
|
if (deskTools.ssort == 0) { s.sort(sortProcessPid); } else if (deskTools.ssort == 1) { s.sort(sortProcessName); }
|
|
var x = '';
|
|
for (var i in s) {
|
|
if (s[i].p != 0) {
|
|
var c = s[i].d;
|
|
if (c.length > 30) { c = '<span title="' + c + '">' + c.substring(0, 30) + '...</span>' } else { c = EscapeHtml(c); }
|
|
x += '<div onclick=showServiceDetailsDialog(' + s[i].i + ') class=deskToolsBar><div style=width:70px;float:left;padding-right:5px>' + EscapeHtml(s[i].p) + '</div><div>' + c + '</div></div>';
|
|
}
|
|
}
|
|
QH('DeskToolsServices', x);
|
|
}
|
|
}
|
|
|
|
function showServiceDetailsDialog(index) {
|
|
if (xxdialogMode) return;
|
|
var service = deskTools.services[index];
|
|
if (service != null) {
|
|
var x = '';
|
|
if (service.name) { x += addHtmlValue("Name", service.name); }
|
|
if (service.displayName) { x += addHtmlValue("Display name", service.displayName); }
|
|
if (service.status) {
|
|
if (service.status.state) { x += addHtmlValue("State", capitalizeFirstLetter(service.status.state.toLowerCase())); }
|
|
if (service.status.pid) { x += addHtmlValue("PID", service.status.pid); }
|
|
var serviceTypes = [];
|
|
if (service.status.isFileSystemDriver === true) { serviceTypes.push("FileSystemDriver"); }
|
|
if (service.status.isInteractive === true) { serviceTypes.push("Interactive"); }
|
|
if (service.status.isKernelDriver === true) { serviceTypes.push("KernelDriver"); }
|
|
if (service.status.isOwnProcess === true) { serviceTypes.push("OwnProcess"); }
|
|
if (service.status.isSharedProcess === true) { serviceTypes.push("SharedProcess"); }
|
|
if (serviceTypes.length > 0) { x += addHtmlValue("Type", serviceTypes.join(', ')); }
|
|
}
|
|
x += '<br/><div style=float:right;margin-bottom:12px><input type=button value="' + "Close" + '" onclick=showServiceDetailsDialogEx(0,' + index + ')></div><div style=margin-bottom:12px><input type=button value="' + "Start" + '" onclick=showServiceDetailsDialogEx(1,' + index + ')><input type=button value="' + "Stop" + '" onclick=showServiceDetailsDialogEx(2,' + index + ')><input type=button value="' + "Restart" + '" onclick=showServiceDetailsDialogEx(3,' + index + ')></div>';
|
|
setDialogMode(2, "Service Details", 8, null, x, name);
|
|
}
|
|
}
|
|
|
|
function showServiceDetailsDialogEx(action, index) {
|
|
setDialogMode(0);
|
|
if (action == 0) return;
|
|
var service = deskTools.services[index];
|
|
if (service != null) {
|
|
if (action == 1) { meshserver.send({ action: 'msg', type: 'serviceStart', nodeid: currentNode._id, serviceName: service.name }); }
|
|
if (action == 2) { meshserver.send({ action: 'msg', type: 'serviceStop', nodeid: currentNode._id, serviceName: service.name }); }
|
|
if (action == 3) { meshserver.send({ action: 'msg', type: 'serviceRestart', nodeid: currentNode._id, serviceName: service.name }); }
|
|
setTimeout(function () { refreshDeskTools(1) }, 1000);
|
|
}
|
|
}
|
|
*/
|
|
|
|
// Toggle mouse and keyboard input
|
|
function toggleKvmControl() { QS('DeskControlSpan').color = Q('DeskControl').checked ? null : 'red'; }
|
|
|
|
// Save the desktop image to file
|
|
function deskSaveImage() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
var d = new Date(), n = "Desktop" + '-' + d.getFullYear() + '-' + ('0' + (d.getMonth() + 1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + '-' + ('0' + d.getHours()).slice(-2) + '-' + ('0' + d.getMinutes()).slice(-2);
|
|
Q('Desk')['toBlob'](function (blob) { saveAs(blob, n + '.png'); });
|
|
}
|
|
|
|
function deskDisplayInfo(sender, displays, selDisplay) {
|
|
var displayCount = 0, displaySelector = '';
|
|
for (var i in displays) {
|
|
displayCount++;
|
|
displaySelector += '<option' + ((selDisplay == i) ? ' selected' : '') + ' value=' + i + '>' + displays[i] + '</option>';
|
|
if ((deskPreferedStickyDisplay == i) && (selDisplay != deskPreferedStickyDisplay)) { desktop.m.SetDisplay(i); }
|
|
deskPreferedStickyDisplay = -1;
|
|
}
|
|
QH('termdisplays', displaySelector);
|
|
QV('termdisplays', displayCount > 1);
|
|
}
|
|
|
|
function deskGetDisplayNumbers(e) { desktop.m.GetDisplayNumbers(); }
|
|
var deskPreferedStickyDisplay = -1;
|
|
function deskSetDisplay(e) { desktop.m.SetDisplay(deskPreferedStickyDisplay = parseInt(Q('termdisplays').value)); Q('termdisplays').blur(); }
|
|
|
|
// Double click detection. This is important for macOS.
|
|
var dblClickDetectArgs = { t: 0, x: 0, y: 0 };
|
|
function dblClickDetect(e) {
|
|
if (e.buttons != 1) return;
|
|
var t = Date.now();
|
|
if (((t - dblClickDetectArgs.t) < 250) && (Math.abs(e.clientX - dblClickDetectArgs.x) < 2) && (Math.abs(e.clientY - dblClickDetectArgs.y) < 2)) {
|
|
if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedblclick(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedblclick(e); } }
|
|
}
|
|
dblClickDetectArgs.t = t;
|
|
dblClickDetectArgs.x = e.clientX;
|
|
dblClickDetectArgs.y = e.clientY;
|
|
}
|
|
|
|
function dmousedown(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedown(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedown(e); } } dblClickDetect(e); }
|
|
function dmouseup(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mouseup(e); desktop.m.sendKeepAlive(); } else { desktop.m.mouseup(e); } }
|
|
function dmousemove(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousemove(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousemove(e); } } }
|
|
function dmousewheel(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousewheel(e); desktop.m.sendKeepAlive(); } else { if (desktop.m.mousewheel) { desktop.m.mousewheel(e); } } haltEvent(e); return true; } return false; }
|
|
function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
|
|
function stopProcess(id, name) { setDialogMode(2, "Process Control", 3, stopProcessEx, format("Stop process #{0} \"{1}\"?", id, name), id); return false; }
|
|
function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type: 'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
|
|
|
|
//
|
|
// POPUP DIALOG
|
|
//
|
|
|
|
// null = Hidden, 1 = Generic Message
|
|
var xxdialogMode;
|
|
var xxdialogFunc;
|
|
var xxdialogButtons;
|
|
var xxdialogTag;
|
|
var xxcurrentView = -1;
|
|
|
|
// Display a dialog box
|
|
// Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
|
|
function setDialogMode(x, y, b, f, c, tag) {
|
|
xxdialogMode = x;
|
|
xxdialogFunc = f;
|
|
xxdialogButtons = b;
|
|
xxdialogTag = tag;
|
|
QE('idx_dlgOkButton', true);
|
|
QV('idx_dlgOkButton', b & 1);
|
|
QV('idx_dlgCancelButton', b & 2);
|
|
QV('id_dialogclose', (b & 2) || (b & 8));
|
|
QV('idx_dlgDeleteButton', b & 4);
|
|
QV('idx_dlgButtonBar', b & 7);
|
|
if (y) QH('id_dialogtitle', y);
|
|
for (var i = 1; i < 8; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
|
|
QV('dialog', x);
|
|
if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
|
|
}
|
|
|
|
function dialogclose(x) {
|
|
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
|
|
setDialogMode();
|
|
if (((b & 8) || x) && f) f(x, t);
|
|
}
|
|
|
|
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
|
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
|
|
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
|
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
|
|
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
|
|
function setSessionActivity() { sessionActivity = Date.now(); /*QH('idleTimeoutNotify', '');*/ }
|
|
function printDate(d) { return d.toLocaleDateString(urlargs.locale); }
|
|
function printTime(d) { return d.toLocaleTimeString(urlargs.locale); }
|
|
function printDateTime(d) { return d.toLocaleString(urlargs.locale); }
|
|
|
|
start();
|
|
</script>
|
|
</body>
|
|
</html> |