More mobile site improvements, MeshCmd fix
Ylian Saint-Hilaire committed
Jun 6, 2018 at 16:52 UTC
b87eeee0f065a5caf6256bd10b645b2fd3d146cc
4 files changed
+471
-51
agents/meshcmd.js
+21
-17
@@ -1305,8 +1305,10 @@ function removeItemFromArray(array, element) {
1305
// Run MeshCmd, but before we do, we need to see if what type of service we are going to be
1306
var serviceName = null;
1307
var serviceOpSpecified = 0;
1308
+var serviceInstall = 0;
1309
1310
for (var i in process.argv) {
1311
+ if (process.argv[i].toLowerCase() == 'install') { serviceInstall = 1 } else if (process.argv[i].toLowerCase() == 'uninstall') { serviceInstall = -1 }
1312
if ((process.argv[i].toLowerCase() == 'microlms') || (process.argv[i].toLowerCase() == 'amtlms') || (process.argv[i].toLowerCase() == 'lms')) { serviceName = 'MicroLMS'; break; }
1313
if ((process.argv[i].toLowerCase() == 'meshcommander') || (process.argv[i].toLowerCase() == 'commander')) { serviceName = 'MeshCommander'; break; }
1314
}
@@ -1323,22 +1325,24 @@ if (serviceName == null) {
1325
else { serviceName = 'not_a_service'; }
1326
}
1327
1326
-var serviceHost = require('serviceHost');
1327
-var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
1328
-
1329
-// Called when the background service is started.
1330
-meshcmdService.on('serviceStart', function onStart() {
1331
- console.setDestination(console.Destinations.DISABLED); // Disable console.log().
1332
- if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } //
1333
- else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); }
1334
- else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); }
1335
-});
1336
-
1337
-// Called when the background service is stopping
1338
-meshcmdService.on('serviceStop', function onStop() { console.log('Stopping service'); process.exit(); }); // The console.log() is for debugging, will be ignored unless "console.setDestination()" is set.
1339
-
1340
-// Called when the executable is not running as a service, run normally.
1341
-meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } });
1342
-meshcmdService.run();
1328
+if (serviceInstall == 0) {
1329
+ run(process.argv);
1330
+} else {
1331
+ var serviceHost = require('serviceHost');
1332
+ var meshcmdService = new serviceHost({ name: serviceName, startType: 'AUTO_START' });
1333
+
1334
+ // Called when the background service is started.
1335
+ meshcmdService.on('serviceStart', function onStart() {
1336
+ console.setDestination(console.Destinations.DISABLED); // Disable console.log().
1337
+ if (process.execPath.includes('MicroLMS')) { run([process.execPath, 'microlms']); } //
1338
+ else if (process.execPath.includes('MeshCommander')) { run([process.execPath, 'meshcommander']); }
1339
+ else { console.log('Aborting Service Start, because unknown binary: ' + process.execPath); process.exit(1); }
1340
+ });
1341
1342
+ // Called when the background service is stopping
1343
+ meshcmdService.on('serviceStop', function onStop() { console.log('Stopping service'); process.exit(); }); // The console.log() is for debugging, will be ignored unless "console.setDestination()" is set.
1344
1345
+ // Called when the executable is not running as a service, run normally.
1346
+ meshcmdService.on('normalStart', function onNormalStart() { try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); } });
1347
+ meshcmdService.run();
1348
+}
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.1.8-a",
3
+ "version": "0.1.8-b",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
views/default-mobile.handlebars
+448
-33
@@ -8,23 +8,20 @@
8
<meta name="format-detection" content="telephone=no" />
9
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
10
<script type="text/javascript" src="scripts/meshcentral.js"></script>
11
+ <script type="text/javascript" src="scripts/agent-redir-ws-0.1.0.js"></script>
12
+ <script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
13
+ <script type="text/javascript" src="scripts/amt-0.2.0.js"></script>
14
+ <script type="text/javascript" src="scripts/amt-redir-ws-0.1.0.js"></script>
15
+ <script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
16
+ <script type="text/javascript" src="scripts/zlib.js"></script>
17
+ <script type="text/javascript" src="scripts/zlib-inflate.js"></script>
18
+ <script type="text/javascript" src="scripts/zlib-adler32.js"></script>
19
+ <script type="text/javascript" src="scripts/zlib-crc32.js"></script>
20
<title>MeshCentral - Login</title>
21
<style>
13
- a {
14
- color: #036;
15
- text-decoration: underline;
16
- }
17
-
18
- #footer a {
19
- color: #fff;
20
- text-decoration: underline;
21
- }
22
-
23
- #footer a:hover {
24
- color: #fff;
25
- text-decoration: none;
26
- }
27
-
22
+ a { color: #036; text-decoration: underline }
23
+ #footer a { color: #fff; text-decoration: underline }
24
+ #footer a:hover { color: #fff; text-decoration: none }
25
.i1 {background:url(../images/icons50.png) 0px 0px;height:50px;width:50px;border:none;}
26
.i2 {background:url(../images/icons50.png) -50px 0px;height:50px;width:50px;border:none;}
27
.i3 {background:url(../images/icons50.png) -100px 0px;height:50px;width:50px;border:none;}
@@ -148,11 +145,64 @@
145
</td>
146
</tr>
147
</table>
151
- <div style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%">
148
+ <div id=p10general style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%">
149
<div id=p10html style="margin-left:8px;margin-right:8px"></div>
150
<div id=p10html2></div>
151
<div id=p10html3></div>
152
</div>
153
+ <div id=p10desktop style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%;display:none">
154
+ <div id=deskarea1>
155
+ <div style="padding-top:2px;padding-bottom:2px;background:#C0C0C0">
156
+ <div style="float:right;text-align:right">
157
+ <span id="p14power"></span>
158
+ </div>
159
+ <div style="margin-left:3px">
160
+ <input type=button id=connectbutton1 value="Connect" onclick=connectDesktop(event,1) onkeypress="return false" onkeydown="return false" disabled="disabled">
161
+ <input type=button id=connectbutton1h value="HW Connect" onclick=connectDesktop(event,2) onkeypress="return false" onkeydown="return false" disabled="disabled">
162
+ <input type=button id=disconnectbutton1 value="Disconnect" onclick=connectDesktop(event,0) onkeypress="return false" onkeydown="return false">
163
+ <span id="deskstatus">Disconnected</span>
164
+ </div>
165
+ </div>
166
+ </div>
167
+ <div id=deskarea2>
168
+ <div>
169
+ <div style=background-color:gray><div id=progressbar style=height:2px;width:0%;background-color:red></div></div>
170
+ </div>
171
+ </div>
172
+ <div id=deskarea3 style="height:calc(100% - 56px)">
173
+ <div id=deskarea3x style="background:black;text-align:center;height:100%;position:relative">
174
+ <div id=DeskParent style="height:100%">
175
+ <canvas id=Desk width=640 height=200 style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas>
176
+ </div>
177
+ <div id=DeskTools style="position:absolute;width:400px;height:100%;background-color:gray;top:0;right:0;border-left:2px solid lightgray;display:none">
178
+ <a id=DeskToolsRefreshButton style="float:right;padding:3px;cursor:pointer" onclick="refreshDeskTools()">Refresh</a>
179
+ <div id=DeskToolsBar style="position:absolute;padding:3px;border-radius: 3px 3px 0px 0px;top:5px;left:4px;bottom:26px;background-color:lightgray;cursor:pointer">Processes</div>
180
+ <div style="position:absolute;top:26px;left:4px;right:4px;bottom:4px;background-color:lightgray;text-align:left">
181
+ <div style="border-bottom:1px solid darkgray;padding:3px"><a style=width:50px;padding-right:5px;float:left;cursor:pointer title="Sort by process id" onclick=sortProcess(0)>PID</a><a style=cursor:pointer title="Sort by name" onclick=sortProcess(1)>Name</a></div>
182
+ <div id="DeskToolsProcesses" style="overflow-y:scroll;position:absolute;top:24px;bottom:0px;width:100%"></div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+ </div>
187
+ <div id=deskarea4>
188
+ <div style=padding-top:2px;padding-bottom:2px;background:#C0C0C0>
189
+ <div style=float:right;text-align:right>
190
+ <select id=termdisplays style=display:none onchange=deskSetDisplay(event) onclick=deskGetDisplayNumbers(event)></select>
191
+ <input id=DeskToastButton type=button value=Toast title="Display a notification message on the remote computer" onkeypress="return false" onkeydown="return false" onclick="deviceToastFunction()">
192
+ <!--<input id=DeskToolsButton type=button value=Tools title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()"> -->
193
+ </div>
194
+ <div>
195
+ <input id="deskActionsBtn" type=button style="margin-left:3px" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value=Actions onclick=deviceActionFunction() />
196
+ <input type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()">
197
+ <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="display:none">
198
+ <input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()">
199
+ </div>
200
+ </div>
201
+ </div>
202
+ </div>
203
+ <div id=p10files style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%;display:none">
204
+
205
+ </div>
206
</div>
207
<div id=p20 style=display:none;position:absolute;bottom:0;top:0;width:100%>
208
<table cellspacing=0 style="margin:0;padding:0;border-spacing:0;border:0;">
@@ -178,12 +228,7 @@
228
</div>
229
</div>
230
<div id=footer style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
181
- <table cellpadding=0 cellspacing=6 style=width:100%>
182
- <tr>
183
- <td style=text-align:left;color:white>{{{footer}}}</td>
184
- <td style=text-align:right>{{{rootCertLink}}} <a href=terms>Terms & Privacy</a></td>
185
- </tr>
186
- </table>
231
+ <table id=footerMenu cellpadding=0 cellspacing=0 style="height:32px;width:100%;color:white;cursor:pointer;table-layout:fixed"></table>
232
</div>
233
</div>
234
<div id=dialog style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:90px;width:300px;display:none">
@@ -221,6 +266,11 @@
266
var serverinfo = null;
267
var users = null;
268
var nodeShortIdent = 0;
269
+ var serverPublicNamePort = "{{{serverDnsName}}}:{{{serverPublicPort}}}";
270
+ var debugmode = false;
271
+ var features = {{{features}}};
272
+ var attemptWebRTC = ((features & 128) != 0);
273
+ var StatusStrs = ['Disconnected', 'Connecting...', 'Setup...', 'Connected', 'Intel® AMT Connected'];
274
275
function startup() {
276
if ((features & 32) == 0) {
@@ -240,6 +290,11 @@
290
meshserver.onStateChanged = onStateChanged;
291
meshserver.onMessage = onMessage;
292
meshserver.Start();
293
+
294
+ // Load desktop settings
295
+ var t = localStorage.getItem('desktopsettings');
296
+ if (t != null) { desktopsettings = JSON.parse(t); }
297
+ applyDesktopSettings();
298
}
299
300
function onStateChanged(server, state) {
@@ -555,12 +610,18 @@
610
function goStack() {
611
if (backStack.length == 0) { go(2); return; }
612
var id = backStack[backStack.length - 1], idtype = id.split('/')[0];
558
- if (idtype == 'node') { gotoDevice(id); }
613
+ if (idtype == 'node') { setupDeviceMenu(0); gotoDevice(id); }
614
if (idtype == 'mesh') { gotoMesh(id); }
615
if (idtype == 'account') { go(3); }
616
if (idtype == 'devices') { go(2); }
617
}
618
619
+ function updateFooterMenu(options) {
620
+ var x = '', count = 0;
621
+ if (options != null) { for (var i in options) { x += '<td style="cursor:pointer' + (count == 0?'':';border-left:solid 1px white') + '" onclick="' + options[i].f + '">' + options[i].n; count++; } }
622
+ QH('footerMenu', '<tr>' + x);
623
+ }
624
+
625
//
626
// MY ACCOUNT
627
//
@@ -688,6 +749,7 @@
749
750
function gotoMesh(meshid) {
751
currentMesh = meshes[meshid];
752
+ if (currentMesh == null) { goBack(); }
753
p20updateMesh();
754
go(20);
755
}
@@ -904,6 +966,7 @@
966
return mesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights;
967
}
968
969
+ var currentDevicePanel = 0;
970
var currentNode;
971
var powerTimelineNode = null;
972
var powerTimelineReq = null;
@@ -911,7 +974,10 @@
974
var powerTimeline = null;
975
function getCurrentNode() { return currentNode; };
976
function gotoDevice(nodeid, panel, refresh) {
914
- var node = getNodeFromId(nodeid), mesh = meshes[node.meshid];
977
+ var node = getNodeFromId(nodeid);
978
+ if (node == null) { goBack(); }
979
+ var mesh = meshes[node.meshid];
980
+ if (mesh == null) { goBack(); }
981
var meshrights = mesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights;
982
if (!currentNode || currentNode._id != node._id || refresh == true) {
983
currentNode = node;
@@ -921,14 +987,6 @@
987
if (nname.length == 0) { nname = '<i>None</i>'; }
988
if ((meshrights & 4) != 0) { nname = '<span onclick=showEditNodeValueDialog(0) style=cursor:pointer>' + nname + '</span>'; }
989
QH('p10deviceName', nname);
924
- /*
925
- QH('p11deviceName', nname);
926
- QH('p12deviceName', nname);
927
- QH('p13deviceName', nname);
928
- QH('p14deviceName', nname);
929
- QH('p15deviceName', nname);
930
- QH('p16deviceName', nname);
931
- */
990
991
// Node attributes
992
var x = '<table style=width:100%>';
@@ -979,7 +1037,7 @@
1037
else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>Unknown Version & State</i>'; }
1038
else {
1039
str += provisioningStates[node.intelamt.state];
982
- if (node.intelamt.flags) { if (node.intelamt.flags & 2) { str += ' <span title="Intel AMT is activated in Client Control Mode">CCM</span>'; } else if (node.intelamt.flags & 4) { str += ' <span title="Intel AMT is activated in Admin Control Mode">ACM</span>'; } }
1040
+ if (node.intelamt.flags) { if (node.intelamt.flags & 2) { str = ' <span title="Intel AMT is activated in Client Control Mode">CCM</span>'; } else if (node.intelamt.flags & 4) { str = ' <span title="Intel AMT is activated in Admin Control Mode">ACM</span>'; } }
1041
str += (', v' + node.intelamt.ver);
1042
}
1043
@@ -1060,8 +1118,33 @@
1118
// Request the power timeline
1119
if ((powerTimelineNode != currentNode._id) && (powerTimelineReq != currentNode._id)) { QH('p10html2', ''); powerTimelineReq = currentNode._id; meshserver.send({ action: 'powertimeline', nodeid: currentNode._id }); }
1120
}
1121
+ setupDesktop(); // Always refresh the desktop, even if we are on the same device, we need to do some canvas switching.
1122
if (!panel) panel = 10;
1123
go(panel);
1124
+
1125
+ // Update the footer menu
1126
+ setupDeviceMenu();
1127
+ }
1128
+
1129
+ function deviceToastFunction() {
1130
+ if (xxdialogMode) return;
1131
+ setDialogMode(2, "Device Toast", 3, deviceToastFunctionEx, '<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>');
1132
+ }
1133
+
1134
+ function deviceToastFunctionEx() {
1135
+ meshserver.send({ action: 'toast', nodeids: [ currentNode._id ], title: 'MeshCentral', msg: Q('d2devToast').value });
1136
+ }
1137
+
1138
+ function setupDeviceMenu(op) {
1139
+ if (op != null) { currentDevicePanel = op; }
1140
+ QV('p10general', currentDevicePanel == 0);
1141
+ QV('p10desktop', currentDevicePanel == 1);
1142
+ QV('p10files', currentDevicePanel == 2);
1143
+ var menus = [];
1144
+ if (currentDevicePanel != 0) { menus.push( { n:'General', f:'setupDeviceMenu(0)' } ); }
1145
+ if (currentDevicePanel != 1) { menus.push( { n:'Desktop', f:'setupDeviceMenu(1)' } ); }
1146
+ if (currentDevicePanel != 2) { menus.push( { n:'Files', f:'setupDeviceMenu(2)' } ); }
1147
+ updateFooterMenu(menus);
1148
}
1149
1150
function deviceActionFunction() {
@@ -1255,6 +1338,337 @@
1338
if ((e != null) && (x == true) && (e.keyCode == 13)) { dialogclose(1); }
1339
}
1340
1341
+ //
1342
+ // DESKTOP
1343
+ //
1344
+
1345
+ var desktop;
1346
+ var desktopNode;
1347
+ var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 50 };
1348
+ function setupDesktop() {
1349
+ // Setup the remote desktop
1350
+ if ((desktopNode != currentNode) && (desktop != null)) { desktop.Stop(); delete desktop; desktopNode = null; desktop = null; }
1351
+
1352
+ // If the device desktop is already connected in multi-desktop, use that.
1353
+ if ((desktopNode != currentNode) || (desktop == null)) {
1354
+ // Device is not already connected, just setup a blank canvas
1355
+ QH('DeskParent', '<canvas id=Desk width=640 height=200 style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');
1356
+ desktopNode = currentNode;
1357
+ // Setup the mouse wheel
1358
+ Q('Desk').addEventListener('DOMMouseScroll', function (e) { return dmousewheel(e); });
1359
+ Q('Desk').addEventListener('mousewheel', function (e) { return dmousewheel(e); });
1360
+ }
1361
+ desktopNode = currentNode;
1362
+ updateDesktopButtons();
1363
+
1364
+ // On some browsers like IE, we can't save screen shots. Hide the scheenshot/capture buttons.
1365
+ if (!Q('Desk')['toBlob']) { QV('deskSaveBtn', false); }
1366
+ }
1367
+
1368
+ // Show and enable the right buttons
1369
+ function updateDesktopButtons() {
1370
+ var mesh = meshes[currentNode.meshid];
1371
+ var deskState = 0;
1372
+ if (desktop != null) { deskState = desktop.State; }
1373
+
1374
+ // Show the right buttons
1375
+ QV('disconnectbutton1', (deskState != 0));
1376
+ QV('connectbutton1', (deskState == 0) && (mesh.mtype == 2));
1377
+ QV('connectbutton1h', (deskState == 0) && ((currentNode.intelamt != null) && (mesh.mtype == 1 || currentNode.intelamt.state == 2) && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))));
1378
+
1379
+ // Show the right settings
1380
+ QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))) && ((deskState == 0) || (desktop.contype == 2)));
1381
+ QV('d7meshkvm', (mesh.mtype == 2) && ((deskState == false) || (desktop.contype == 1)));
1382
+
1383
+ // Enable buttons
1384
+ var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop
1385
+ QE('connectbutton1', online);
1386
+ var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal
1387
+ QE('connectbutton1h', hwonline);
1388
+ //QE('deskSaveBtn', deskState == 3);
1389
+ QE('DeskCAD', deskState == 3);
1390
+ QE('DeskWD', deskState == 3);
1391
+ QE('deskkeys', deskState == 3);
1392
+ QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5));
1393
+ QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5));
1394
+ QE('DeskToolsButton', online);
1395
+ QV('DeskToastButton', (currentNode.agent) && (currentNode.agent.id < 5));
1396
+ QE('DeskToastButton', online);
1397
+ if (online == false) QV('DeskTools', false);
1398
+ }
1399
+
1400
+ function connectDesktop(e, contype) {
1401
+ if (desktop == null) {
1402
+ desktopNode = currentNode;
1403
+ if (contype == 2) {
1404
+ // Setup the Intel AMT remote desktop
1405
+ if ((desktopNode.intelamt.user == null) || (desktopNode.intelamt.user == '')) { editDeviceAmtSettings(desktopNode._id, connectDesktop); return; }
1406
+ desktop = CreateAmtRedirect(CreateAmtRemoteDesktop('Desk'));
1407
+ desktop.debugmode = debugmode;
1408
+ desktop.onStateChanged = onDesktopStateChange;
1409
+ desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
1410
+ desktop.m.useZRLE = (desktopsettings.encoding < 3);
1411
+ desktop.m.showmouse = desktopsettings.showmouse;
1412
+ desktop.m.onScreenSizeChange = deskAdjust;
1413
+ desktop.Start(desktopNode._id, 16994, '*', '*', 0);
1414
+ desktop.contype = 2;
1415
+ } else {
1416
+ // Setup the Mesh Agent remote desktop
1417
+ desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort);
1418
+ desktop.debugmode = debugmode;
1419
+ desktop.m.debugmode = debugmode;
1420
+ desktop.attemptWebRTC = attemptWebRTC;
1421
+ desktop.onStateChanged = onDesktopStateChange;
1422
+ desktop.m.CompressionLevel = desktopsettings.quality; // Number from 1 to 100. 50 or less is best.
1423
+ desktop.m.ScalingLevel = desktopsettings.scaling;
1424
+ desktop.m.FrameRateTimer = desktopsettings.framerate;
1425
+ desktop.m.onDisplayinfo = deskDisplayInfo;
1426
+ desktop.m.onScreenSizeChange = deskAdjust;
1427
+ desktop.Start(desktopNode._id);
1428
+ desktop.contype = 1;
1429
+ }
1430
+ } else {
1431
+ // Disconnect and clean up the remote desktop
1432
+ desktop.Stop();
1433
+ delete desktop;
1434
+ desktopNode = desktop = null;
1435
+ }
1436
+ }
1437
+
1438
+ function onDesktopStateChange(xdesktop, state) {
1439
+ var xstate = state;
1440
+ if ((xstate == 3) && (xdesktop.contype == 2)) { xstate++; }
1441
+ var str = StatusStrs[xstate];
1442
+ if ((desktop != null) && (desktop.webRtcActive == true)) { str += ', WebRTC'; }
1443
+ //if (desktop.m.stopInput == true) { str += ', Loopback'; }
1444
+ QH('deskstatus', str);
1445
+ switch (state) {
1446
+ case 0:
1447
+ // Disconnect and clean up the remote desktop
1448
+ desktop.Stop();
1449
+ delete desktop;
1450
+ desktopNode = desktop = null;
1451
+ QV('termdisplays', false);
1452
+ if (fullscreen == true) { deskToggleFull(); }
1453
+ break;
1454
+ case 2:
1455
+ break;
1456
+ }
1457
+ updateDesktopButtons();
1458
+ deskAdjust();
1459
+ setTimeout(deskAdjust, 50);
1460
+ }
1461
+
1462
+ function showDesktopSettings() {
1463
+ if (xxdialogMode) return;
1464
+ applyDesktopSettings();
1465
+ updateDesktopButtons();
1466
+ setDialogMode(7, "Remote Desktop Settings", 3, showDesktopSettingsChanged);
1467
+ }
1468
+
1469
+ function showDesktopSettingsChanged() {
1470
+ desktopsettings.encoding = d7desktopmode.value;
1471
+ desktopsettings.showfocus = d7showfocus.checked;
1472
+ desktopsettings.showmouse = d7showcursor.checked;
1473
+ desktopsettings.quality = d7bitmapquality.value;
1474
+ desktopsettings.scaling = d7bitmapscaling.value;
1475
+ desktopsettings.framerate = d7framelimiter.value;
1476
+ localStorage.setItem('desktopsettings', JSON.stringify(desktopsettings));
1477
+ applyDesktopSettings();
1478
+ if (desktop) {
1479
+ if (desktop.contype == 1) {
1480
+ if (desktop.State != 0) { desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate); }
1481
+ }
1482
+ if (desktop.contype == 2) {
1483
+ if (desktop.State != 0) { desktop.Stop(); setTimeout(function () { connectDesktop(null, 2); }, 50); }
1484
+ }
1485
+ }
1486
+ }
1487
+
1488
+ function applyDesktopSettings() {
1489
+ /*
1490
+ var r = '', ops = (features & 512)?[90,70,50,40,30,20,10,5,1]:[50,40,30,20,10,5,1];
1491
+ for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
1492
+ QH('d7bitmapquality', r);
1493
+ d7desktopmode.value = desktopsettings.encoding;
1494
+ d7showfocus.checked = desktopsettings.showfocus;
1495
+ d7showcursor.checked = desktopsettings.showmouse;
1496
+ d7bitmapquality.value = 40; // Default value
1497
+ if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
1498
+ d7bitmapscaling.value = desktopsettings.scaling;
1499
+ if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; }
1500
+ */
1501
+ }
1502
+
1503
+ var fullscreen = false;
1504
+ /*
1505
+ function deskToggleFull() {
1506
+ fullscreen = !fullscreen;
1507
+ QV('mastheadx', !fullscreen);
1508
+ QV('masthead', !fullscreen);
1509
+ QV('topbar', !fullscreen);
1510
+ QV('p11deviceNameHeader', !fullscreen);
1511
+ QV('footer', !fullscreen);
1512
+ QV('column_l_bottomgap', !fullscreen);
1513
+ QV('idx_deskFullBtn2', fullscreen);
1514
+ QV('deskFullBtn', !fullscreen);
1515
+ if (fullscreen) {
1516
+ QS('container').width = '100%';
1517
+ QS('container')['border-right'] = '0';
1518
+ QS('container')['border-left'] = '0';
1519
+ QS('column_l').padding = '0';
1520
+ QS('column_l').width = '100%';
1521
+ } else {
1522
+ QS('container').width = '960px';
1523
+ QS('container')['border-right'] = '1px solid #b7b7b7';
1524
+ QS('container')['border-left'] = '1px solid #b7b7b7';
1525
+ QS('column_l').padding = '0 15px';
1526
+ QS('column_l').width = '930px';
1527
+ toggleFullScreen();
1528
+ }
1529
+ deskAdjust();
1530
+ }
1531
+ */
1532
+
1533
+ function deskAdjust() {
1534
+ var x = (Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - (Q('deskarea1').clientHeight + Q('deskarea2').clientHeight + Q('Desk').clientHeight + Q('deskarea4').clientHeight + 2)) / 2;
1535
+ if (fullscreen) {
1536
+ document.documentElement.style.overflow = 'hidden';
1537
+ //QS('deskarea3x').height = null;
1538
+ if (x < 0) {
1539
+ var mh = (Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - (Q('deskarea1').clientHeight + Q('deskarea2').clientHeight + Q('deskarea4').clientHeight));
1540
+ var mw = 9999;
1541
+ if (desktop) { mw = (desktop.m.width / desktop.m.height) * mh; }
1542
+ QS('Desk')['max-height'] = mh + 'px';
1543
+ QS('Desk')['max-width'] = mw + 'px';
1544
+ x = 0;
1545
+ } else {
1546
+ QS('Desk')['max-height'] = null;
1547
+ QS('Desk')['max-width'] = null;
1548
+ }
1549
+ QS('Desk')['margin-top'] = x + 'px';
1550
+ QS('Desk')['margin-bottom'] = x + 'px';
1551
+ } else {
1552
+ document.documentElement.style.overflow = 'auto';
1553
+ //QS('deskarea3x').height = (desktop)?'40px':'400px';
1554
+ QS('Desk')['max-height'] = null;
1555
+ QS('Desk')['max-width'] = null;
1556
+ QS('Desk')['margin-top'] = '0';
1557
+ QS('Desk')['margin-bottom'] = '0';
1558
+ }
1559
+ }
1560
+
1561
+ // Remote desktop special key combos for Windows
1562
+ function deskSendKeys() {
1563
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
1564
+ var ks = Q('deskkeys').value;
1565
+ if (ks == 0) { // WIN+Down arrow
1566
+ if (desktop.contype == 2) {
1567
+ 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
1568
+ } else {
1569
+ 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
1570
+ }
1571
+ } else if (ks == 1) { // WIN+Up arrow
1572
+ if (desktop.contype == 2) {
1573
+ 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
1574
+ } else {
1575
+ 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
1576
+ }
1577
+ } else if (ks == 2) { // WIN+L arrow
1578
+ if (desktop.contype == 2) {
1579
+ desktop.m.sendkey([[0xffe7,1],[0x6c,1],[0x6c,0],[0xffe7,0]]); // Intel AMT: Meta-left down, 'l' press, 'l' release, Meta-left release
1580
+ } else {
1581
+ 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
1582
+ }
1583
+ } else if (ks == 3) { // WIN+M arrow
1584
+ if (desktop.contype == 2) {
1585
+ desktop.m.sendkey([[0xffe7,1],[0x6d,1],[0x6d,0],[0xffe7,0]]); // Intel AMT: Meta-left down, 'm' press, 'm' release, Meta-left release
1586
+ } else {
1587
+ 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
1588
+ }
1589
+ } else if (ks == 4) { // Shift+WIN+M arrow
1590
+ if (desktop.contype == 2) {
1591
+ 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
1592
+ } else {
1593
+ 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
1594
+ }
1595
+ }
1596
+ }
1597
+
1598
+ // Send CTRL-ALT-DEL
1599
+ function sendCAD() {
1600
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
1601
+ desktop.m.sendcad();
1602
+ }
1603
+
1604
+ // Show process dialogs
1605
+ function toggleDeskTools() {
1606
+ if (xxdialogMode) return;
1607
+ if (QS('DeskTools').display == 'none') {
1608
+ QV('DeskTools', true);
1609
+ Q('DeskTools').nodeid = currentNode._id;
1610
+ refreshDeskTools();
1611
+ } else {
1612
+ QV('DeskTools', false);
1613
+ }
1614
+ }
1615
+
1616
+ // Refresh all of the desktop tool panels
1617
+ function refreshDeskTools() {
1618
+ QV('DeskToolsRefreshButton', false);
1619
+ setTimeout(refreshDeskToolsEx, 500);
1620
+ meshserver.send({ action: 'msg', type:'ps', nodeid: currentNode._id });
1621
+ }
1622
+ function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
1623
+ var deskTools = { sort: 1, msg: null };
1624
+ function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); }
1625
+ function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return 0; }
1626
+ function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; }
1627
+ function showDeskToolsProcesses(message) {
1628
+ deskTools.msg = message;
1629
+ if (message == null) { QH('DeskToolsProcesses', ''); return; }
1630
+ if (Q('DeskTools').nodeid != message.nodeid) return;
1631
+ var p = [], processes = null;
1632
+ try { processes = JSON.parse(message.value); } catch (e) { }
1633
+ console.log(processes);
1634
+ if (processes != null) {
1635
+ for (var pid in processes) { p.push( { p:parseInt(pid), c:processes[pid].cmd, d:processes[pid].cmd.toLowerCase(), u: processes[pid].user } ); }
1636
+ if (deskTools.sort == 0) { p.sort(sortProcessPid); } else if (deskTools.sort == 1) { p.sort(sortProcessName); }
1637
+ var x = '';
1638
+ for (var i in p) { if (p[i].p != 0) { x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + p[i].p + '</div><a style=float:right;padding-right:5px;cursor:pointer title="Stop process" onclick=stopProcess(' + p[i].p + ',"' + p[i].c + '")><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u?p[i].u:'') + '</div><div>' + p[i].c + '</div></div>'; } }
1639
+ QH('DeskToolsProcesses', x);
1640
+ }
1641
+ }
1642
+
1643
+ // Save the desktop image to file
1644
+ function deskSaveImage() {
1645
+ if (xxdialogMode || desktop == null || desktop.State != 3) return;
1646
+ var d = new Date(), n = 'Desktop-' + currentNode.name + '-' + d.getFullYear() + "-" + ("0" + (d.getMonth() + 1)).slice(-2) + "-" + ("0" + d.getDate()).slice(-2) + "-" + ("0" + d.getHours()).slice(-2) + "-" + ("0" + d.getMinutes()).slice(-2);
1647
+ Q("Desk")['toBlob'](function (blob) { saveAs(blob, n + ".jpg"); });
1648
+ }
1649
+
1650
+ function deskDisplayInfo(sender, info, selDisplay, selItem) {
1651
+ var txt = Q('termdisplays').value;
1652
+ if (info.length > 0) { var options = ''; for (var x in info) { options += '<option' + ((txt == info[x])?' selected':'') + '>' + info[x] + '</option>'; } QH('termdisplays', options); }
1653
+ QV('termdisplays', info.length > 0);
1654
+ }
1655
+
1656
+ function deskGetDisplayNumbers(e) { desktop.m.GetDisplayNumbers(); }
1657
+
1658
+ function deskSetDisplay(e) {
1659
+ var display = 0, txt = Q('termdisplays').value;
1660
+ if (txt == "All Displays") display = 65535; else display = parseInt(txt.substring(8));
1661
+ desktop.m.SetDisplay(display);
1662
+ }
1663
+
1664
+ function dmousedown(e) { if (!xxdialogMode && desktop != null) desktop.m.mousedown(e) }
1665
+ function dmouseup(e) { if (!xxdialogMode && desktop != null) desktop.m.mouseup(e) }
1666
+ function dmousemove(e) { if (!xxdialogMode && desktop != null) desktop.m.mousemove(e) }
1667
+ function dmousewheel(e) { if (!xxdialogMode && desktop != null && desktop.m.mousewheel) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
1668
+ function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
1669
+ function stopProcess(id, name) { setDialogMode(2, "Process Control", 3, stopProcessEx, 'Stop process #' + id + ' "' + name + '"?', id); }
1670
+ function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type:'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
1671
+
1672
//
1673
// MY MESHS
1674
//
@@ -1450,6 +1864,7 @@
1864
var xxcurrentView = -1;
1865
function go(x) {
1866
if (xxdialogMode || xxcurrentView == x) return;
1867
+ updateFooterMenu();
1868
setDialogMode(0);
1869
// Edit this line when adding a new screen
1870
for (var i = 0; i < 32; i++) { QV('p' + i, i == x); }
views/default.handlebars
+1
@@ -3475,6 +3475,7 @@
3475
}
3476
3477
function showDesktopSettings() {
3478
+ if (xxdialogMode) return;
3479
applyDesktopSettings();
3480
updateDesktopButtons();
3481
setDialogMode(7, "Remote Desktop Settings", 3, showDesktopSettingsChanged);