More work on guest sharing mobile site, #3402

Ylian Saint-Hilaire committed Jan 4, 2022 at 21:56 UTC a29fdcbeda9466804a0183f79952c7e1a8bba671
1 file changed +549 -290
views/sharing-mobile.handlebars
+549 -290
@@ -1,16 +1,19 @@
1 <!DOCTYPE html>
2 <html lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 + <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
5 - <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
6 + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
7 <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />
7 - <meta name="apple-mobile-web-app-capable" content="yes" />
8 <meta name="format-detection" content="telephone=no" />
9 <meta name="robots" content="noindex,nofollow">
10 <link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS" />
11 <link type="text/css" href="styles/style-sharing.css" media="screen" rel="stylesheet" title="CSS" />
12 <link type="text/css" href="styles/xterm.css" media="screen" rel="stylesheet" title="CSS" />
13 <link rel="apple-touch-icon" href="/favicon-303x303.png" />
14 + <meta name="apple-mobile-web-app-capable" content="yes">
15 + <meta name="apple-mobile-web-app-status-bar-style" content="#ffffff">
16 + <meta name="apple-mobile-web-app-title" content="{{{title}}}">
17 <script type="text/javascript" src="scripts/common-0.0.1{{min}}.js"></script>
18 <script type="text/javascript" src="scripts/amt-redir-ws-0.1.0{{{min}}}.js"></script>
19 <script type="text/javascript" src="scripts/amt-wsman-ws-0.2.0{{{min}}}.js"></script>
@@ -28,15 +31,79 @@
31 <script type="text/javascript" src="scripts/xterm-addon-fit{{{min}}}.js"></script>
32 <script keeplink=1 type="text/javascript" src="scripts/filesaver.min.js"></script>
33 <title>{{{title}}}</title>
34 + <style>
35 +
36 + .deskButton {
37 + box-shadow: 0px 0px 10px #000;
38 + border-radius:20px;
39 + position:absolute;
40 + right:10px;
41 + top:10px;
42 + cursor:pointer;
43 + background-color:#AAA;
44 + z-index:1000;
45 + }
46 +
47 + .menuButton{
48 + box-shadow: 0px 0px 10px #000;
49 + border-radius:10px;
50 + display:inline-block;
51 + width:120px;
52 + background-color:#AAA;
53 + text-align:center;
54 + padding:8px;
55 + cursor:pointer;
56 + margin:10px;
57 + z-index:1000;
58 + }
59 +
60 + #dialog {
61 + z-index:1000;
62 + background-color:#EEE;
63 + box-shadow:0px 0px 15px #666;
64 + font-family:Arial,Helvetica,sans-serif;
65 + border-radius:5px;
66 + position:fixed;
67 + top:90px;
68 + width:300px;
69 + }
70 +
71 + .night #dialog {
72 + color: black;
73 + background-color:#AAA;
74 + }
75 +
76 + </style>
77 </head>
78 <body style="overflow:hidden;background-color:black;margin:0;padding:0;border:0;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
79 <div id=p11 class="noselect" style="overflow:hidden;position:absolute;left:0;top:0;right:0;bottom:32px;display:none">
34 - <div id=deskarea0>
80 + <div id=p10dialog 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:30px;width:300px;left:30px;display:none">
81 + <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0">
82 + <div style=padding:5px>Keyboard Shortcuts Customization</div>
83 + <div style=width:100%;margin:6px></div>
84 + </div>
85 + <div style="margin-right:16px;margin-left:8px"><div id=p10dialog2 style="margin:auto;margin:3px"></div></div>
86 + <div style="padding:10px;margin-bottom:20px"><input type="button" value="OK" style="float:right;width:80px" onclick="deskCustomizeKeysEx()"></div>
87 + </div>
88 + <img id="deskkeybutton1" src="images/mobile-desk-exit.png" class="deskButton" style="top:10px;display:none" onclick="exitButton(event)" />
89 + <img id="deskkeybutton3a" src="images/mobile-desk-menu-open.png" class="deskButton" style="top:60px;display:none" onclick="toggleMenu(false)" />
90 + <img id="deskkeybutton3b" src="images/mobile-desk-menu-close.png" class="deskButton" style="top:60px;display:none" onclick="toggleMenu(true)" />
91 + <img id="deskkeybutton4a" src="images/mobile-desk-mouse-left.png" class="deskButton" style="top:110px;display:none" onclick="deskChangeMouseButton(0)" />
92 + <img id="deskkeybutton4b" src="images/mobile-desk-mouse-right.png" class="deskButton" style="top:110px;display:none" onclick="deskChangeMouseButton(1)" />
93 + <img id="deskkeybutton5a" src="images/mobile-desk-scale-out.png" class="deskButton" style="top:160px;display:none" onclick="deskChangeFullscreenZoom()" />
94 + <img id="deskkeybutton5b" src="images/mobile-desk-scale-in.png" class="deskButton" style="top:160px;display:none" onclick="deskChangeFullscreenZoom()" />
95 + <img id="deskkeybutton2a" src="images/mobile-desk-keyboard-open.png" class="deskButton" style="top:210px;display:none" onclick="toggleKeyboard()" />
96 + <img id="deskkeybutton2b" src="images/mobile-desk-keyboard-close.png" class="deskButton" style="top:210px;display:none" onclick="toggleKeyboard()" />
97 + <div style="position:absolute;top:0;left:0;z-index:200;opacity:0;width:1px;height:1px">
98 + <input id="softKeyboard" autocapitalize="off" autocomplete="off" type="text" spellcheck="false" style="z-index:200;opacity:0;width:1px;height:1px" onfocus="keyboardFocusChange()" onblur="keyboardFocusChange()" />
99 + </div>
100 + <div id="deskButtonMenu" style="display:none;position:absolute;top:10px;left:10px;right:55px;bottom:10px;z-index:1000"></div>
101 + <div id=deskarea0 style="position:absolute;top:0px;left:0px;right:0px;bottom:0px">
102 <div id=deskarea1 class="areaHead" style="line-height:24px">
103 <div class="toright2">
104 <span id="p11power"></span>&nbsp;
38 - <input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" class="mR" />
39 - <div id="desktopCustomUiButtons" style="float:left"></div>
105 + <input id="deskFullScreen" type="button" value="Full Screen" style="display:none" onkeypress="return false" onkeydown="return false" onclick="deskToggleFull(event)" class="mR" />
106 + <input id="deskActionsSettings" type="button" value="Settings..." onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" class="mR" />
107 <div id="deskRecordIcon" class='deskareaicon' title="Server is recording this session" style="display:none;background-color:red;width:12px;height:12px;border-radius:6px;margin-top:5px"></div>
108 </div>
109 <div>
@@ -48,7 +115,6 @@
115 </div>
116 </div>
117 <div id=deskarea3x style="max-height:calc(100vh - 60px);height:calc(100vh - 60px);">
51 - <div id=DeskFocus oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></div>
118 <div id=DeskParent>
119 <canvas id=Desk width=640 height=480 oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas>
120 </div>
@@ -205,62 +271,71 @@
271 <div id=dialog2 style="">
272 <div id=id_dialogOptions></div>
273 </div>
208 - <div id=dialog7 style="">
274 + <div id=dialog7 style="margin:auto;margin:3px">
275 <div id="d7meshkvm">
210 - <h4>Agent Remote Desktop</h4>
211 - <div>
212 - <div>Quality</div>
213 - <select id="d7bitmapquality" dir="rtl"></select>
214 - </div>
215 - <div>
216 - <div>Scaling</div>
217 - <select id="d7bitmapscaling" style="" dir="rtl">
218 - <option selected=selected value=1024>100%</option>
219 - <option value=896>87.5%</option>
220 - <option value=768>75%</option>
221 - <option value=640>62.5%</option>
222 - <option value=512>50%</option>
223 - <option value=384>37.5%</option>
224 - <option value=256>25%</option>
225 - <option value=128>12.5%</option>
226 - </select>
227 - </div>
228 - <div>
229 - <div>Frame rate</div>
230 - <select id="d7framelimiter" dir="rtl">
231 - <option selected=selected value=50>Fast</option>
232 - <option value=100>Medium</option>
233 - <option value=400>Slow</option>
234 - <option value=1000>Very slow</option>
235 - </select>
236 - </div>
237 - <div id="d7desktopOtherSettings">
238 - <div>Other Settings</div>
239 - <div id="d7otherset2" style="display:block">
240 - <label style="display:block"><input type="checkbox" id="d7deskSwapMouse" />Swap Mouse Buttons</label>
241 - <label style="display:block"><input type="checkbox" id="d7deskRemoteKeyMap" />Use Remote Keyboard Map</label>
242 - </div>
243 - </div>
276 + <h4 style="width:100%;border-bottom:1px solid gray">Agent Remote Desktop</h4>
277 + <table style="width:100%">
278 + <tr>
279 + <td>
280 + Quality
281 + </td>
282 + <td style="width:100px">
283 + <select id="d7bitmapquality" style="float:right;width:200px" dir="rtl"></select>
284 + </td>
285 + </tr>
286 + <tr>
287 + <td>
288 + Scaling
289 + </td>
290 + <td style="width:100px">
291 + <select id="d7bitmapscaling" style="float:right;width:200px" dir="rtl">
292 + <option selected=selected value=1024>100%</option>
293 + <option value=896>87.5%</option>
294 + <option value=768>75%</option>
295 + <option value=640>62.5%</option>
296 + <option value=512>50%</option>
297 + <option value=384>37.5%</option>
298 + <option value=256>25%</option>
299 + <option value=128>12.5%</option>
300 + </select>
301 + </td>
302 + </tr>
303 + <tr>
304 + <td>
305 + Rate
306 + </td>
307 + <td style="width:100px">
308 + <select id="d7framelimiter" style="float:right;width:200px" dir="rtl">
309 + <option selected=selected value=50>Fast</option>
310 + <option value=100>Medium</option>
311 + <option value=400>Slow</option>
312 + <option value=1000>Very slow</option>
313 + </select>
314 + </td>
315 + </tr>
316 + <tr>
317 + <td></td>
318 + <td>
319 + <label style="display:block" id="d7deskAutoLockLabel"><input type="checkbox" id="d7deskAutoLock" />Lock on Disconnect</label>
320 + </td>
321 + </tr>
322 + </table>
323 </div>
324 <div id="d7amtkvm">
246 - <h4>Intel&reg; AMT Hardware KVM</h4>
247 - <div>
248 - <div>Image Encoding</div>
249 - <select id="d7desktopmode">
250 - <option value="1">RLE8, Fastest</option>
251 - <option value="2">RLE16, Recommended</option>
252 - <option value="3">RAW8, Slow</option>
253 - <option value="4">RAW16, Very Slow</option>
254 - </select>
255 - </div>
256 - <div>
257 - <div>Other Settings</div>
258 - <div id="d7otherset" style="display:block">
259 - <label style="display:block"><input type="checkbox" id="d7showfocus" />Show Focus Tool</label>
260 - <label style="display:block"><input type="checkbox" id="d7showcursor" />Show Local Mouse Cursor</label>
261 - <label style="display:block"><input type="checkbox" id="d7localKeyMap" />Local Keyboard Map</label>
262 - </div>
263 - </div>
325 + <h4 style="width:100%;border-bottom:1px solid gray">Intel&reg; AMT Hardware KVM</h4>
326 + <table style="width:100%">
327 + <tr>
328 + <td>Encoding</td>
329 + <td style="width:100px">
330 + <select id="d7desktopmode" style="float:right;width:200px">
331 + <option value="1">RLE8, Fastest</option>
332 + <option value="2">RLE16, Recommended</option>
333 + <option value="3">RAW8, Slow</option>
334 + <option value="4">RAW16, Very Slow</option>
335 + </select>
336 + </td>
337 + </tr>
338 + </table>
339 </div>
340 </div>
341 </div>
@@ -285,6 +360,7 @@
360 var debugmode = urlargs.debug;
361 var attemptWebRTC = false;
362 var updateSessionTimer = null;
363 + var deskKeyboardShortcuts = [];
364 var StatusStrs = ["Disconnected", "Connecting...", "Setup...", "Connected", "Intel&reg; AMT Connected"];
365 var nodeName = decodeURIComponent('{{{nodeName}}}');
366 var webPageFullScreen = false;
@@ -318,10 +394,14 @@
394 var p13FilesConsoleMsgTimer = null;
395
396 function start() {
321 - window.onresize = deskAdjust;
322 - document.onkeypress = ondockeypress;
323 - document.onkeydown = ondockeydown;
324 - document.onkeyup = ondockeyup;
397 + window.onresize = center;
398 + center();
399 + document.onkeypress = ondeskkeypress;
400 + document.onkeydown = ondeskkeydown;
401 + document.onkeyup = ondeskkeyup;
402 + //document.onkeypress = ondockeypress;
403 + //document.onkeydown = ondockeydown;
404 + //document.onkeyup = ondockeyup;
405 setupDesktop();
406 setupTerminal();
407 setupFiles();
@@ -351,6 +431,13 @@
431 else if (features & 1) { go(12); } // Goto terminal
432 else if (features & 4) { go(13); } // Goto files
433 deskAdjust();
434 +
435 + // Set the user's desktop shortcut keys
436 + deskKeyboardShortcuts = [];
437 + var deskKeyboardShortcutsStr = '0x0A002E,0x100000,0x100028,0x100026,0x10004C,0x10004D,0x11004D,0x100052,0x020073,0x080057,0x020009,0x100025,0x100027'.split(',');
438 + for (var i in deskKeyboardShortcutsStr) { deskKeyboardShortcuts.push(parseInt(deskKeyboardShortcutsStr[i])); }
439 + updateDeskShortcutKeys();
440 + //updateTermShortcutKeys();
441 }
442
443 //
@@ -363,21 +450,34 @@
450 function deskAdjust() {
451 if ((xxcurrentView == 12) && (terminal != null) && (xtermfit != null)) { xtermfit.fit(); } // Terminal
452 QS('fileArea4')['height'] = 'calc(100vh - ' + (90 + Q('fileArea2').clientHeight) + 'px)'; // Files
366 - var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
367 - var deskH = Q('Desk').height, deskW = Q('Desk').width;
453
369 - // Fixed aspect ratio
370 - if ((parentH / parentW) > (deskH / deskW)) {
371 - var hNew = ((deskH * parentW) / deskW) + 'px';
372 - QS('Desk').height = hNew;
454 + if (fullscreen) {
455 + QS('Desk')['margin-top'] = null;
456 + QS('Desk')['margin-bottom'] = null;
457 + QS('deskarea3x')['padding-right'] = '55px';
458 QS('Desk').width = '100%';
374 - } else {
375 - var wNew = ((deskW * parentH) / deskH) + 'px';
459 QS('Desk').height = '100%';
377 - QS('Desk').width = wNew;
460 + var parentH = Q('p11').clientHeight, parentW = Q('p11').clientWidth;
461 + var deskH = Q('deskarea3x').clientHeight, deskW = Q('deskarea3x').clientWidth - 55;
462 + if (parentH > deskH) { QS('deskarea3x').top = ((parentH - deskH) / 2) + 'px'; } else { QS('deskarea3x').top = null; }
463 + if (parentW > deskW) { QS('deskarea3x').left = ((parentW - deskW) / 2) + 'px'; } else { QS('deskarea3x').left = null; }
464 + } else {
465 + var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
466 + var deskH = Q('Desk').height, deskW = Q('Desk').width;
467 +
468 + // Fixed aspect ratio
469 + if ((parentH / parentW) > (deskH / deskW)) {
470 + var hNew = ((deskH * parentW) / deskW) + 'px';
471 + QS('Desk').height = hNew;
472 + QS('Desk').width = '100%';
473 + } else {
474 + var wNew = ((deskW * parentH) / deskH) + 'px';
475 + QS('Desk').height = '100%';
476 + QS('Desk').width = wNew;
477 + }
478 + QS('Desk')['margin-top'] = null;
479 + QS('deskarea3x')['padding-right'] = null;
480 }
379 - QS('Desk')['margin-top'] = null;
380 - QS('DeskParent').overflow = 'hidden';
481 }
482
483 function setupDesktop() {
@@ -427,8 +527,8 @@
527 // Display this only if we have Chat & Notify permissions
528 QV('DeskSaveImageButton', (deskState == 3) && (Q('Desk')['toBlob'] != null));
529 QV('DeskControlSpan', viewOnly != 1);
430 - QV('deskActionsBtn', (browserfullscreen == false));
431 - QV('deskActionsSettings', (browserfullscreen == false));
530 + QV('deskActionsBtn', true);
531 + QV('deskActionsSettings', (deskState != 3));
532 Q('DeskControl').checked = true;
533 QS('DeskControlSpan').color = Q('DeskControl').checked ? null : 'red';
534 }
@@ -639,6 +739,8 @@
739 if ((desktop != null) && (desktop.webRtcActive == true)) { str += ", WebRTC"; }
740 //if (desktop.m.stopInput == true) { str += ', Loopback'; }
741 QH('deskstatus', str);
742 + QV('deskFullScreen', state == 3);
743 + QV('deskActionsSettings', state != 3);
744 switch (state) {
745 case 0:
746 // Stop recording
@@ -647,7 +749,6 @@
749 // Disconnect and clean up the remote desktop
750 desktop.Stop();
751 desktop = null;
650 - QV('DeskFocus', false);
752 QV('termdisplays', false);
753 QV('deskRecordIcon', false);
754 if (fullscreen == true) { deskToggleFull(); }
@@ -694,8 +795,6 @@
795
796 function showDesktopSettingsChanged() {
797 desktopsettings.encoding = d7desktopmode.value;
697 - desktopsettings.showfocus = d7showfocus.checked;
698 - desktopsettings.showmouse = d7showcursor.checked;
798 desktopsettings.quality = d7bitmapquality.value;
799 desktopsettings.scaling = d7bitmapscaling.value;
800 desktopsettings.framerate = d7framelimiter.value;
@@ -723,8 +822,6 @@
822 for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
823 QH('d7bitmapquality', r);
824 d7desktopmode.value = desktopsettings.encoding;
726 - d7showfocus.checked = desktopsettings.showfocus;
727 - d7showcursor.checked = desktopsettings.showmouse;
825 d7bitmapquality.value = 40; // Default value
826 if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
827 d7bitmapscaling.value = desktopsettings.scaling;
@@ -734,72 +831,120 @@
831 if (desktopsettings.localkeymap) { d7localKeyMap.checked = desktopsettings.localkeymap; }
832 }
833
737 - // Enter browser fullscreen
738 - function enterBrowserFullscreen(elem) {
739 - if (elem.requestFullscreen) { elem.requestFullscreen(); }
740 - else if (elem.msRequestFullscreen) { elem.msRequestFullscreen(); }
741 - else if (elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); }
742 - else if (elem.webkitRequestFullscreen) { elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); }
834 + function toggleMenu(x) {
835 + if (xxdialogMode) return;
836 + QV('deskButtonMenu', fullscreen && !x && (xxcurrentView == 11));
837 + QV('termButtonMenu', fullscreen && !x && (xxcurrentView == 12));
838 + QV('deskkeybutton3a', fullscreen && x);
839 + QV('deskkeybutton3b', fullscreen && !x);
840 }
841
745 - // Exit browser fullscreen
746 - function exitBrowserFullscreen() {
747 - if (document.exitFullscreen) { document.exitFullscreen(); }
748 - else if (document.msExitFullscreen) { document.msExitFullscreen(); }
749 - else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); }
750 - else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); }
842 + function deskChangeMouseButton(x) {
843 + if (xxdialogMode) return;
844 + if (desktop == null) return;
845 + desktop.m.SwapMouse = !desktop.m.SwapMouse;
846 + QV('deskkeybutton4a', fullscreen && (!desktop.m.SwapMouse));
847 + QV('deskkeybutton4b', fullscreen && (desktop.m.SwapMouse));
848 }
849
753 - // Return true if the browser is fullscreen. This is a delayed method that will return true/false late. Not very useful.
754 - function isBrowserFullscreen() {
755 - if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) { return false; } else { return true; }
850 + function deskChangeFullscreenZoom() {
851 + if (xxdialogMode) return;
852 + if (xxcurrentView == 11) {
853 + if (desktop == null) return;
854 + if (fullscreenzoom == 1) { fullscreenzoom = 0.5; } else { fullscreenzoom = 1; }
855 + QV('deskkeybutton5a', fullscreen && (fullscreenzoom == 1));
856 + QV('deskkeybutton5b', fullscreen && (fullscreenzoom != 1));
857 + QS('deskarea3x').width = (desktop.m.ScreenWidth * fullscreenzoom) + 'px';
858 + QS('deskarea3x').height = (desktop.m.ScreenHeight * fullscreenzoom) + 'px';
859 + deskAdjust();
860 + }
861 + if (xxcurrentView == 12) {
862 + if (terminal == null) return;
863 + xterm.setOption('fontSize', (xterm.getOption('fontSize') == 15) ? 10 : 15)
864 + }
865 }
866
867 var fullscreen = false;
759 - var browserfullscreen = false;
868 + var fullscreenzoom = 1;
869 function deskToggleFull(e) {
870 var xtermActive = !((urlargs.xterm === 0) || ((terminal != null) && (xterm == null)));
871 fullscreen = !fullscreen;
872 if (fullscreen) {
764 - QC('body').add('fulldesk');
765 - QS('deskarea3x')['height'] = '100%';
766 - QS('deskarea3x')['max-height'] = '100%';
873 + QV('deskarea1', false);
874 + QV('deskarea4', false);
875 + QV('xfooter', false);
876 + QS('p11').bottom = '0px';
877 + QS('deskarea0').overflow = 'scroll';
878 + QS('deskarea3x').width = (desktop.m.ScreenWidth * fullscreenzoom) + 'px';
879 + QS('deskarea3x').height = QS('deskarea3x')['max-height'] = (desktop.m.ScreenHeight * fullscreenzoom) + 'px';
880 + QS('deskarea3x')['padding-right'] = '55px';
881 if (xtermActive) {
882 // XTerm terminal
769 - QS('termTable')['position'] = 'absolute';
770 - QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = '0';
883 + //QS('termTable')['position'] = 'absolute';
884 + //QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = '0';
885 } else {
886 // Legacy terminal
773 - QS('termTable')['height'] = '100%';
774 - QS('termTable')['max-height'] = '100%';
775 - }
776 -
777 - // If shift is pressed, enter browser full screen.
778 - if (e.shiftKey == true) {
779 - enterBrowserFullscreen(Q('container'));
780 - browserfullscreen = true;
887 + //QS('termTable')['height'] = '100%';
888 + //QS('termTable')['max-height'] = '100%';
889 }
890 } else {
783 - QC('body').remove('fulldesk');
784 - var hide = urlargs.hide;
785 - if (footerBar == false) { hide |= 4; }
786 - var xh = (((hide & 1) ? 0 : 66) + ((hide & 2) ? 0 : 24) + ((hide & 4) ? 0 : 45) + ((hide & 8) ? 0 : 60)); // 0 to 195
787 - QS('deskarea3x')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
788 - QS('deskarea3x')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
891 + QV('deskarea1', true);
892 + QV('deskarea4', true);
893 + QV('xfooter', true);
894 + QS('p11').bottom = '32px';
895 + QS('deskarea0').overflow = null;
896 + QS('deskarea3x').width = null;
897 + QS('deskarea3x').height = QS('deskarea3x')['max-height'] = 'calc(100vh - 60px)';
898 + QS('deskarea3x')['padding-right'] = null;
899 if (xtermActive) {
900 // XTerm terminal
791 - QS('termTable')['position'] = null;
792 - QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = null;
901 + //QS('termTable')['position'] = null;
902 + //QS('termTable')['top'] = QS('termTable')['bottom'] = QS('termTable')['left'] = QS('termTable')['right'] = null;
903 } else {
904 // Legacy terminal
795 - QS('termTable')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
796 - QS('termTable')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
905 + //QS('termTable')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
906 + //QS('termTable')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
907 }
798 - if (browserfullscreen == true) { exitBrowserFullscreen(); browserfullscreen = false; }
908 }
800 - deskAdjust();
909 +
910 + inputAllowed = true; // todo
911 +
912 + // Show full screen buttons if needed
913 + QV('deskkeybutton1', fullscreen);
914 + if (xxcurrentView == 11) { // Desktop panel is being shown (11 = Desktop, 12 = Terminal)
915 + // Move shortcut key to desktop position
916 + QS('deskkeybutton2a').top = QS('deskkeybutton2b').top = '210px';
917 + // Move the zoom button to normal or top position
918 + QS('deskkeybutton5a').top = QS('deskkeybutton5b').top = (inputAllowed) ? '160px' : '60px'; // Zoom
919 + QV('deskkeybutton2a', fullscreen && inputAllowed);
920 + QV('deskkeybutton2b', false);
921 + QV('deskkeybutton3a', fullscreen && inputAllowed);
922 + QV('deskkeybutton3b', false);
923 + QV('deskkeybutton4a', fullscreen && inputAllowed && (!desktop.m.SwapMouse));
924 + QV('deskkeybutton4b', fullscreen && inputAllowed && (desktop.m.SwapMouse));
925 + QV('deskkeybutton5a', fullscreen && (fullscreenzoom == 1));
926 + QV('deskkeybutton5b', fullscreen && (fullscreenzoom != 1));
927 + }
928 + if (xxcurrentView == 12) {
929 + // Move right buttons to terminal position
930 + //QS('deskkeybutton3a').top = QS('deskkeybutton3b').top = '60px'; // Shortcuts
931 + //QS('deskkeybutton5a').top = QS('deskkeybutton5b').top = '110px'; // Zoom
932 + QS('deskkeybutton2a').top = QS('deskkeybutton2b').top = '110px'; // Keyboard
933 + QV('deskkeybutton2a', fullscreen);
934 + QV('deskkeybutton2b', false);
935 + QV('deskkeybutton3a', fullscreen);
936 + QV('deskkeybutton3b', false);
937 + QV('deskkeybutton4a', false);
938 + QV('deskkeybutton4b', false);
939 + QV('deskkeybutton5a', false);
940 + QV('deskkeybutton5a', false);
941 + //QV('deskkeybutton5a', xterm.getOption('fontSize') == 15);
942 + //QV('deskkeybutton5b', xterm.getOption('fontSize') != 15);
943 + }
944 +
945 + if (xxcurrentView == 11) { deskAdjust(); }
946 updateDesktopButtons();
802 - adjustPanels();
947 + //adjustPanels();
948 //setTimeout(adjustPanels, 10);
949 //setTimeout(function() { xtermfit.fit(); }, 10);
950 if (xterm != null) { if (xxcurrentView == 12) { xtermfit.fit(); xterm.focus(); } }
@@ -911,57 +1056,100 @@
1056 }
1057 }
1058
914 - function ondockeypress(e) {
1059 +
1060 + var gotKeyPressEvent = false;
1061 + function ondeskkeypress(e, t) {
1062 setSessionActivity();
916 - if (!xxdialogMode && desktop && isInputAllowed()) {
1063 + if (desktop && !xxdialogMode && (xxcurrentView == 11)) {
1064 + gotKeyPressEvent = true;
1065 + Q('softKeyboard').value = '';
1066 // Check what keys we are allows to send
918 - /*
919 - if (currentNode != null) {
920 - var meshrights = GetNodeRights(currentNode);
921 - var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
922 - if (inputAllowed == false) return false;
923 - var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
924 - if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
925 - }
926 - */
1067 + var inputAllowed = true; // TODO
1068 + if (inputAllowed == false) return false;
1069 return desktop.m.handleKeys(e);
1070 }
1071 + if (terminal && !xxdialogMode && (xxcurrentView == 12) (t !== 1)) {
1072 + if (e.altKey == true) { return true; }
1073 + gotKeyPressEvent = true;
1074 + Q('softKeyboard').value = '';
1075 + var k = 0;
1076 + if (e.charCode != 0) { k = e.charCode; } else if (e.keyCode != 0) { k = e.keyCode; }
1077 + if (k != 0) {
1078 + if (terminal.urlname == 'sshterminalrelay.ashx') {
1079 + // SSH
1080 + terminal.socket.send('~' + String.fromCharCode(k));
1081 + } else {
1082 + // Agent
1083 + terminal.sendText(String.fromCharCode(k));
1084 + }
1085 + }
1086 + return false;
1087 + }
1088 }
1089
931 - function ondockeydown(e) {
1090 + function ondeskkeydown(e, t) {
1091 setSessionActivity();
933 - if (!xxdialogMode && desktop && isInputAllowed()) {
1092 + if (desktop && !xxdialogMode && (xxcurrentView == 11)) {
1093 + gotKeyPressEvent = false;
1094 + Q('softKeyboard').value = '';
1095 // Check what keys we are allows to send
935 - /*
936 - if (currentNode != null) {
937 - var meshrights = GetNodeRights(currentNode);
938 - var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
939 - if (inputAllowed == false) return false;
940 - var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
941 - if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
942 - }
943 - */
1096 + var inputAllowed = true; // TODO
1097 + if (inputAllowed == false) return false;
1098 return desktop.m.handleKeyDown(e);
1099 }
1100 + if (terminal && !xxdialogMode && (xxcurrentView == 12) && (t !== 1)) {
1101 + if (e.altKey == true) { return true; }
1102 + Q('softKeyboard').value = '';
1103 + gotKeyPressEvent = false;
1104 + var k = 0;
1105 + if (e.charCode != 0) { k = e.charCode; } else if (e.keyCode != 0) { k = e.keyCode; }
1106 + if (k == 8) { terminal.sendText(String.fromCharCode(k)); } // Enter and backspace
1107 + else if (e.ctrlKey && (k >= 64) && (k <= 95)) {
1108 + // Ctrl keys
1109 + if (terminal.urlname == 'sshterminalrelay.ashx') {
1110 + // SSH
1111 + terminal.socket.send('~' + String.fromCharCode(k - 64));
1112 + } else {
1113 + // Agent
1114 + terminal.sendText(String.fromCharCode(k - 64));
1115 + }
1116 + }
1117 + }
1118 }
1119
948 - function ondockeyup(e) {
1120 + function ondeskkeyup(e, t) {
1121 setSessionActivity();
950 - if (!xxdialogMode && desktop && isInputAllowed()) {
1122 + if (desktop && !xxdialogMode && (xxcurrentView == 11)) {
1123 + var inputStr = Q('softKeyboard').value;
1124 + Q('softKeyboard').value = '';
1125 // Check what keys we are allows to send
952 - /*
953 - if (currentNode != null) {
954 - var meshrights = GetNodeRights(currentNode);
955 - var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
956 - if (inputAllowed == false) return false;
957 - var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
958 - if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
1126 + var inputAllowed = true; // TODO
1127 + if (inputAllowed == false) return false;
1128 + if ((gotKeyPressEvent == false) && (inputStr.length > 0) && desktop.m.SendKeyUnicode) {
1129 + // This is a mobile keyboard, we need to send that is in the input control.
1130 + var inputchar = inputStr[inputStr.length - 1].charCodeAt(0);
1131 + desktop.m.SendKeyUnicode(desktop.m.KeyAction.DOWN, inputchar);
1132 + desktop.m.SendKeyUnicode(desktop.m.KeyAction.UP, inputchar);
1133 + } else {
1134 + return desktop.m.handleKeyUp(e);
1135 }
960 - */
961 - return desktop.m.handleKeyUp(e);
1136 + }
1137 + if (terminal && !xxdialogMode && (xxcurrentView == 12) && (gotKeyPressEvent == false) && (t !== 1)) {
1138 + if (e.altKey == true) { return true; }
1139 + var inputStr = Q('softKeyboard').value;
1140 + Q('softKeyboard').value = '';
1141 + if (terminal.urlname == 'sshterminalrelay.ashx') {
1142 + // SSH
1143 + terminal.socket.send('~' + inputStr);
1144 + } else {
1145 + // Agent
1146 + if (inputStr) terminal.sendText(inputStr);
1147 + }
1148 + return false;
1149 }
1150 }
1151
1152 +
1153 // Remote desktop typing
1154 function showDeskType() {
1155 if (xxdialogMode || desktop == null || desktop.State != 3) return;
@@ -1043,136 +1231,6 @@
1231 desktop.m.sendcad();
1232 }
1233
1046 - /*
1047 - // Show process dialogs
1048 - function toggleDeskTools() {
1049 - if (xxdialogMode) return;
1050 - if (QS('DeskTools').display == 'none') {
1051 - QV('DeskTools', true);
1052 - Q('DeskTools').nodeid = currentNode._id;
1053 - QH('DeskToolsProcesses', '');
1054 - QH('DeskToolsServices', '');
1055 - QV('deskToolsTopTabService', false);
1056 - changeDeskToolTab(0)
1057 - refreshDeskTools(0);
1058 - refreshDeskTools(1);
1059 - } else {
1060 - QV('DeskTools', false);
1061 - }
1062 - }
1063 -
1064 - var deskToolTabSelection = 0;
1065 - function changeDeskToolTab(tabnum) {
1066 - deskToolTabSelection = tabnum;
1067 - QV('DeskToolsProcessTab', tabnum == 0);
1068 - QV('DeskToolsServiceTab', tabnum == 1);
1069 - QS('deskToolsTopTabProcess')['bottom'] = (tabnum == 0) ? '0px' : '3px';
1070 - QS('deskToolsTopTabService')['bottom'] = (tabnum == 1) ? '0px' : '3px';
1071 - QS('deskToolsTopTabProcess')['color'] = (tabnum == 0) ? 'black' : 'gray';
1072 - QS('deskToolsTopTabService')['color'] = (tabnum == 1) ? 'black' : 'gray';
1073 - }
1074 -
1075 - // Refresh all of the desktop tool panels
1076 - function refreshDeskTools(x) {
1077 - var sel = (x == null) ? deskToolTabSelection : x;
1078 - QV('DeskToolsRefreshButton', false);
1079 - setTimeout(refreshDeskToolsEx, 500);
1080 - if (sel == 0) meshserver.send({ action: 'msg', type: 'ps', nodeid: currentNode._id });
1081 - if (sel == 1) meshserver.send({ action: 'msg', type: 'services', nodeid: currentNode._id });
1082 - }
1083 - function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
1084 - var deskTools = { sort: 1, ssort: 1, msg: null, smsg: null };
1085 - function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); }
1086 - function sortService(sort) { deskTools.ssort = sort; showDeskToolsServices(deskTools.smsg); }
1087 - function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return sortProcessName(a, b); }
1088 - function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; }
1089 - function showDeskToolsProcesses(message) {
1090 - deskTools.msg = message;
1091 - if (message == null) { QH('DeskToolsProcesses', ''); return; }
1092 - if (Q('DeskTools').nodeid != message.nodeid) return;
1093 - var p = [], processes = null;
1094 - try { processes = JSON.parse(message.value); } catch (e) { }
1095 - if (processes != null) {
1096 - for (var pid in processes) { p.push({ p: parseInt(pid), c: processes[pid].cmd, d: processes[pid].cmd.toLowerCase(), u: processes[pid].user }); }
1097 - if (deskTools.sort == 0) { p.sort(sortProcessPid); } else if (deskTools.sort == 1) { p.sort(sortProcessName); }
1098 - var x = '';
1099 - for (var i in p) {
1100 - if (p[i].p != 0) {
1101 - var c = p[i].c;
1102 - if (c.length > 30) { c = '<span title="' + EscapeHtml(c) + '">' + EscapeHtml(c.substring(0, 30)) + '...</span>' } else { c = EscapeHtml(c); }
1103 - 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>';
1104 - }
1105 - }
1106 - QH('DeskToolsProcesses', x);
1107 - }
1108 - }
1109 - function showDeskToolsServices(message) {
1110 - deskTools.smsg = message;
1111 - if (message == null) { QH('DeskToolsProcesses', ''); return; }
1112 - if (Q('DeskTools').nodeid != message.nodeid) return;
1113 - QV('deskToolsTopTabService', true);
1114 - var s = [], services = null;
1115 - try { services = JSON.parse(message.value); } catch (e) { }
1116 - deskTools.services = services;
1117 - if (services != null) {
1118 - for (var i in services) {
1119 - if (services[i].status) {
1120 - // Windows
1121 - s.push({ p: capitalizeFirstLetter(services[i].status.state.toLowerCase()), d: services[i].displayName, i: i });
1122 - } else if (services[i].serviceType) {
1123 - // Linux (TODO: This the service status is not displayed, not sure start/stop/restart will work).
1124 - s.push({ p: services[i].serviceType, d: services[i].name, i: i });
1125 - }
1126 - }
1127 - if (deskTools.ssort == 0) { s.sort(sortProcessPid); } else if (deskTools.ssort == 1) { s.sort(sortProcessName); }
1128 - var x = '';
1129 - for (var i in s) {
1130 - if (s[i].p != 0) {
1131 - var c = s[i].d;
1132 - if (c.length > 30) { c = '<span title="' + c + '">' + c.substring(0, 30) + '...</span>' } else { c = EscapeHtml(c); }
1133 - 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>';
1134 - }
1135 - }
1136 - QH('DeskToolsServices', x);
1137 - }
1138 - }
1139 -
1140 - function showServiceDetailsDialog(index) {
1141 - if (xxdialogMode) return;
1142 - var service = deskTools.services[index];
1143 - if (service != null) {
1144 - var x = '';
1145 - if (service.name) { x += addHtmlValue("Name", service.name); }
1146 - if (service.displayName) { x += addHtmlValue("Display name", service.displayName); }
1147 - if (service.status) {
1148 - if (service.status.state) { x += addHtmlValue("State", capitalizeFirstLetter(service.status.state.toLowerCase())); }
1149 - if (service.status.pid) { x += addHtmlValue("PID", service.status.pid); }
1150 - var serviceTypes = [];
1151 - if (service.status.isFileSystemDriver === true) { serviceTypes.push("FileSystemDriver"); }
1152 - if (service.status.isInteractive === true) { serviceTypes.push("Interactive"); }
1153 - if (service.status.isKernelDriver === true) { serviceTypes.push("KernelDriver"); }
1154 - if (service.status.isOwnProcess === true) { serviceTypes.push("OwnProcess"); }
1155 - if (service.status.isSharedProcess === true) { serviceTypes.push("SharedProcess"); }
1156 - if (serviceTypes.length > 0) { x += addHtmlValue("Type", serviceTypes.join(', ')); }
1157 - }
1158 - 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>';
1159 - setDialogMode(2, "Service Details", 8, null, x, name);
1160 - }
1161 - }
1162 -
1163 - function showServiceDetailsDialogEx(action, index) {
1164 - setDialogMode(0);
1165 - if (action == 0) return;
1166 - var service = deskTools.services[index];
1167 - if (service != null) {
1168 - if (action == 1) { meshserver.send({ action: 'msg', type: 'serviceStart', nodeid: currentNode._id, serviceName: service.name }); }
1169 - if (action == 2) { meshserver.send({ action: 'msg', type: 'serviceStop', nodeid: currentNode._id, serviceName: service.name }); }
1170 - if (action == 3) { meshserver.send({ action: 'msg', type: 'serviceRestart', nodeid: currentNode._id, serviceName: service.name }); }
1171 - setTimeout(function () { refreshDeskTools(1) }, 1000);
1172 - }
1173 - }
1174 - */
1175 -
1234 // Toggle mouse and keyboard input
1235 function toggleKvmControl() { QS('DeskControlSpan').color = Q('DeskControl').checked ? null : 'red'; }
1236
@@ -1212,10 +1270,209 @@
1270 dblClickDetectArgs.y = e.clientY;
1271 }
1272
1215 - function dmousedown(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedown(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedown(e); } } dblClickDetect(e); }
1216 - function dmouseup(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mouseup(e); desktop.m.sendKeepAlive(); } else { desktop.m.mouseup(e); } }
1217 - function dmousemove(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousemove(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousemove(e); } } }
1218 - function dmousewheel(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { 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; }
1273 + function dmousedown(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null)) { if (fullscreen) { e.addx = Q('deskarea0').scrollLeft * (1 / fullscreenzoom); e.addy = Q('deskarea0').scrollTop * (1 / fullscreenzoom); } desktop.m.mousedown(e); } }
1274 + function dmouseup(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null)) { if (fullscreen) { e.addx = Q('deskarea0').scrollLeft * (1 / fullscreenzoom); e.addy = Q('deskarea0').scrollTop * (1 / fullscreenzoom); } desktop.m.mouseup(e); } }
1275 + function dmousemove(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null)) { if (fullscreen) { e.addx = Q('deskarea0').scrollLeft * (1 / fullscreenzoom); e.addy = Q('deskarea0').scrollTop * (1 / fullscreenzoom); } desktop.m.mousemove(e); } }
1276 + function dmousewheel(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null) && desktop.m.mousewheel) { if (fullscreen) { e.addx = Q('deskarea0').scrollLeft * (1 / fullscreenzoom); e.addy = Q('deskarea0').scrollTop * (1 / fullscreenzoom); } desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
1277 +
1278 + var keyboardShown = false;
1279 + var keyboardShownTimer = null;
1280 + var fullScreenMode = false;
1281 + function toggleKeyboard() {
1282 + if (xxdialogMode) return;
1283 + if (keyboardShownTimer != null) { clearTimeout(keyboardShownTimer); }
1284 + if (keyboardShown) { Q('softKeyboard').blur(); keyboardShown = false; } else { Q('softKeyboard').focus(); keyboardShown = true; }
1285 + QV('deskkeybutton2a', fullscreen && !keyboardShown);
1286 + QV('deskkeybutton2b', fullscreen && keyboardShown);
1287 + }
1288 +
1289 + function keyboardFocusChange() {
1290 + keyboardShownTimer = setTimeout(function () {
1291 + keyboardShownTimer = null;
1292 + keyboardShown = (Q('softKeyboard') == document.activeElement);
1293 + QV('deskkeybutton2a', fullscreen && !keyboardShown);
1294 + QV('deskkeybutton2b', fullscreen && keyboardShown);
1295 + }, 100);
1296 + }
1297 +
1298 + function exitButton() {
1299 + if (xxdialogMode) return;
1300 + QV('deskButtonMenu', false);
1301 + QV('termButtonMenu', false);
1302 + if (fullscreenzoom == 1) {
1303 + deskToggleFull();
1304 + } else {
1305 + deskChangeFullscreenZoom();
1306 + setTimeout(deskToggleFull, 10);
1307 + }
1308 + }
1309 +
1310 + function deskMenuButton(x) {
1311 + toggleMenu(true);
1312 + deskSendKeys(x);
1313 + }
1314 +
1315 +
1316 + //
1317 + // Desktop Shortcut Keys
1318 + //
1319 +
1320 + function updateDeskShortcutKeys() {
1321 + var x = ''; //'<div class="menuButton" onclick="deskMenuButton(-1)">' + "Customize" + '</div>';
1322 + for (var i in deskKeyboardShortcuts) { x += '<div class="menuButton" onclick="deskMenuButton(' + deskKeyboardShortcuts[i] + ')">' + keyShortcutTotext(deskKeyboardShortcuts[i]) + '</div>'; }
1323 + QH('deskButtonMenu', x);
1324 + }
1325 +
1326 + var keyStrings = { 8: "BackSpace", 9: "Tab", 13: "Enter", 27: "Escape", 44: "Print Screen", 45: "Insert", 46: "Del", 36: "Home", 35: "End", 33: "Page Up", 34: "Page Down", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 0: "None" }
1327 +
1328 + function keyShortcutTotext(n) {
1329 + var x = [];
1330 + if (n & 0x010000) { x.push("Shift"); }
1331 + if (n & 0x020000) { x.push("Alt"); }
1332 + if (n & 0x080000) { x.push("Ctrl"); }
1333 + if (n & 0x100000) { x.push("Win"); }
1334 + n = (n & 0xFFFF);
1335 + if ((n >= 112) && (n <= 123)) { x.push('F' + (n - 111)); } // Fx keys
1336 + else if ((n != 0) && (keyStrings[n])) { x.push(keyStrings[n]); }
1337 + else { if (n != 0) { x.push(String.fromCharCode(n)); } }
1338 + return x.join(' + ');
1339 + }
1340 +
1341 + // Customize keyboard shortcuts
1342 + function deskCustomizeKeys() {
1343 + if (xxdialogMode) return;
1344 + var x = '<div id=d2shortcuts style="width:100%;height:180px;padding:4px;overflow-y:auto;border:1px solid gray"></div><div style=width:100%;padding:5px>';
1345 + x += '<label><input id=d1kshift type=checkbox /> ' + "Shift" + '</label><label> <input id=d1kalt type=checkbox /> ' + "Alt" + '</label><label> <input id=d1kctrl type=checkbox /> ' + "Ctrl" + '</label> <input id=d1kwin type=checkbox /> ' + "Win" + '</label>';
1346 + x += ' <select id=d2keySelect>';
1347 + for (var i in keyStrings) { x += '<option value=' + i + '>' + keyStrings[i] + '</option>'; }
1348 + for (var i = 1; i <= 12; i++) { x += '<option value=' + (i + 111) + '>F' + i + '</option>'; }
1349 + for (var i = 0; i < 10; i++) { x += '<option value=' + (i + 48) + '>' + i + '</option>'; }
1350 + for (var i = 0; i < 26; i++) { x += '<option value=' + (i + 65) + '>' + String.fromCharCode(i + 65) + '</option>'; }
1351 + x += '</select> <input type=button value=' + "Add" + ' onclick=addDeskCustomizeKey() /></div>';
1352 + QH('p10dialog2', x);
1353 + xxdialogMode = 2;
1354 + QV('p10dialog', true);
1355 + deskUpdateShortcutList();
1356 + }
1357 +
1358 + function deskCustomizeKeysEx() {
1359 + QV('p10dialog', false);
1360 + xxdialogMode = 0;
1361 + //putstore('deskKeyShortcuts', deskKeyboardShortcuts.join(','));
1362 + updateDeskShortcutKeys();
1363 + }
1364 +
1365 + function deskUpdateShortcutList() {
1366 + var x = '';
1367 + for (var i in deskKeyboardShortcuts) {
1368 + var kt = keyShortcutTotext(deskKeyboardShortcuts[i]), orderButtons = '';
1369 + if (i != (deskKeyboardShortcuts.length - 1)) { orderButtons += '<img width=8 height=8 style=float:right;cursor:pointer;padding:3px src="images/c2.png" onclick=deskCustomizeKeyDown(' + deskKeyboardShortcuts[i] + ')>'; }
1370 + if (i != 0) { orderButtons += '<img width=8 height=8 style=float:right;cursor:pointer;padding:3px src="images/c3.png" onclick=deskCustomizeKeyUp(' + deskKeyboardShortcuts[i] + ')>'; }
1371 + x += '<div style="width:100%;background-color:#AAA;border-radius:4px;margin-bottom:4px;padding:4px;text-align:left;box-sizing:border-box" value=' + deskKeyboardShortcuts[i] + '>' + kt + '<img width=10 height=10 style=float:right;cursor:pointer;padding:2px;margin-left:8px src="images/trash.png" onclick=removeDeskCustomizeKey(' + deskKeyboardShortcuts[i] + ')>' + orderButtons + '</div>';
1372 + }
1373 + if (x == '') { x = '<i>' + "No keyboard shortcuts defined" + '</i>'; }
1374 + QH('d2shortcuts', x);
1375 + }
1376 +
1377 + function deskCustomizeKeyDown(k) {
1378 + var i = deskKeyboardShortcuts.indexOf(k), x = deskKeyboardShortcuts[i + 1];
1379 + deskKeyboardShortcuts[i + 1] = deskKeyboardShortcuts[i];
1380 + deskKeyboardShortcuts[i] = x;
1381 + deskUpdateShortcutList();
1382 + }
1383 +
1384 + function deskCustomizeKeyUp(k) {
1385 + var i = deskKeyboardShortcuts.indexOf(k), x = deskKeyboardShortcuts[i];
1386 + deskKeyboardShortcuts[i] = deskKeyboardShortcuts[i - 1];
1387 + deskKeyboardShortcuts[i - 1] = x;
1388 + deskUpdateShortcutList();
1389 + }
1390 +
1391 + function removeDeskCustomizeKey(k) {
1392 + var na = [];
1393 + for (var i in deskKeyboardShortcuts) { if (deskKeyboardShortcuts[i] != k) { na.push(deskKeyboardShortcuts[i]); } }
1394 + deskKeyboardShortcuts = na;
1395 + deskUpdateShortcutList();
1396 + }
1397 +
1398 + function addDeskCustomizeKey() {
1399 + var k = parseInt(Q('d2keySelect').value);
1400 + if (Q('d1kshift').checked) { k |= 0x010000; }
1401 + if (Q('d1kalt').checked) { k |= 0x020000; }
1402 + if (Q('d1kctrl').checked) { k |= 0x080000; }
1403 + if (Q('d1kwin').checked) { k |= 0x100000; }
1404 + if ((k > 0) && (deskKeyboardShortcuts.indexOf(k) == -1)) { deskKeyboardShortcuts.push(k); deskUpdateShortcutList(); }
1405 + }
1406 +
1407 + // Remote desktop special key combos for Windows
1408 + function deskSendKeys(ks) {
1409 + if (xxdialogMode || desktop == null || desktop.State != 3) return;
1410 +
1411 + // Construct the key command
1412 + if (ks == -1) { deskCustomizeKeys(); return; } // Customize
1413 + if (ks == 0x0A002E) { desktop.m.sendcad(); return; } // CTRL-ALT-DEL
1414 + //if ((desktop.contype == 1) && (ks == 0x10004C)) { desktop.sendCtrlMsg('{"action":"lock"}'); return; } // Lock desktop, WIN + L
1415 +
1416 + var flags = (ks & 0xFF0000) >> 16, key = (ks & 0xFFFF), keyArray = [], keyArray2 = [];
1417 + var amtTranslate = {
1418 + 8: 0xff08, // BackSpace
1419 + 9: 0xff09, // Tab
1420 + 13: 0xff0d, // Return or Enter
1421 + 27: 0xff1b, // Escape
1422 + 45: 0xff63, // Insert
1423 + 46: 0xffff, // Delete
1424 + 36: 0xff50, // Home
1425 + 35: 0xff57, // End
1426 + 33: 0xff55, // Page Up
1427 + 34: 0xff56, // Page Down
1428 + 37: 0xff51, // Left arrow
1429 + 38: 0xff52, // Up arrow
1430 + 39: 0xff53, // Right arrow
1431 + 40: 0xff54, // Down arrow
1432 + 112: 0xffbe, // F1
1433 + 113: 0xffbf, // F2
1434 + 114: 0xffc0, // F3
1435 + 115: 0xffc1, // F4
1436 + 116: 0xffc2, // F5
1437 + 117: 0xffc3, // F6
1438 + 118: 0xffc4, // F7
1439 + 119: 0xffc5, // F8
1440 + 120: 0xffc6, // F9
1441 + 121: 0xffc7, // F10
1442 + 122: 0xffc8, // F11
1443 + 123: 0xffc9 // F12
1444 + }
1445 +
1446 + // 0x010000 = Shift
1447 + // 0x020000 = Left-Alt
1448 + // 0x080000 = Ctrl
1449 + // 0x100000 = Window
1450 +
1451 + if (desktop.contype == 2) {
1452 + // Intel AMT
1453 + if (flags & 1) { keyArray.push([0xffe1, 1]); keyArray2.push([0xffe1, 0]); } // Shift
1454 + if (flags & 2) { keyArray.push([0xffe9, 1]); keyArray2.push([0xffe9, 0]); } // Left-alt
1455 + if (flags & 8) { keyArray.push([0xffe3, 1]); keyArray2.push([0xffe3, 0]); } // Ctrl
1456 + if (flags & 16) { keyArray.push([0xffe7, 1]); keyArray2.push([0xffe7, 0]); } // Windows key
1457 + if (amtTranslate[key]) { key = amtTranslate[key]; }
1458 + if ((key >= 65) && (key <= 90)) { key += 32; }
1459 + if (key != 0) { keyArray.push([key, 1]); keyArray2.push([key, 0]); }
1460 + keyArray2.reverse();
1461 + for (var i = 0; i < keyArray2.length; i++) { keyArray.push(keyArray2[i]); }
1462 + desktop.m.sendkey(keyArray);
1463 + } else {
1464 + // Agent desktop
1465 + if (flags & 1) { keyArray.push([desktop.m.KeyAction.DOWN, 16]); keyArray2.push([desktop.m.KeyAction.UP, 16]); } // Shift
1466 + if (flags & 2) { keyArray.push([desktop.m.KeyAction.EXDOWN, 18]); keyArray2.push([desktop.m.KeyAction.EXUP, 18]); } // Left-alt
1467 + if (flags & 8) { keyArray.push([desktop.m.KeyAction.EXDOWN, 17]); keyArray2.push([desktop.m.KeyAction.EXUP, 17]); } // Ctrl
1468 + if (flags & 16) { keyArray.push([desktop.m.KeyAction.EXDOWN, 0x5B]); keyArray2.push([desktop.m.KeyAction.EXUP, 0x5B]); } // Windows key
1469 + if (key != 0) { keyArray.push([desktop.m.KeyAction.DOWN, key]); keyArray2.push([desktop.m.KeyAction.UP, key]); }
1470 + keyArray2.reverse();
1471 + for (var i = 0; i < keyArray2.length; i++) { keyArray.push(keyArray2[i]); }
1472 + desktop.m.SendKeyMsgKC(keyArray);
1473 + }
1474 + }
1475 +
1476
1477 //
1478 // Terminal
@@ -2191,6 +2448,8 @@
2448 QH('xfooterMenu', '<tr>' + x);
2449 }
2450
2451 + function center() { if (xtermfit) xtermfit.fit(); QS('dialog').left = ((((getDocWidth() - 300) / 2)) + 'px'); deskAdjust(); }
2452 + function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
2453 function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
2454 function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
2455 function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }