You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tabVMConsoleRDP.html 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <!--
  2. VM Console tab
  3. Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com)
  4. $Id: tabVMConsoleRDP.html 595 2015-04-17 09:50:36Z imoore76 $
  5. -->
  6. <div id='vboxTabVMUnavailable' style='display: none' class='translate'>Virtual machine is not running or is not configured to accept RDP connections.</div>
  7. <div id='vboxRDPFormContainer' style='padding-top: 8px; display: none'>
  8. <form name="vboxRDPForm" id="vboxRDPForm">
  9. <div class='vboxInvisible' id='vboxRDPConnParams'>
  10. <span id='vboxConsoleLoginInfo'>
  11. <span class='translate'>User name</span>: <input class='vboxRDPSet' type=text size=20 name=logonUsername value="">
  12. <span class='translate'>Password</span>: <input class='vboxRDPSet' type=password size=20 name=logonPassword value="">
  13. </span>
  14. <span class='translate'>Requested desktop size</span>:
  15. <select id='vboxRDPSize' name='vboxRDPSizeSelect'>
  16. <option value='800x600'>800x600</option>
  17. <option value='1024x768'>1024x768</option>
  18. <option value='1280x1024'>1280x1024</option>
  19. </select>
  20. </div>
  21. <p>
  22. <input name=connectionButton type=button value="Connect" onclick="vboxRDPConnect();" />
  23. <input type='text' id='vboxConsoleAddr' name='serverAddress' class='vboxRDPSet' value='' />
  24. <!-- and hardcore web dev guys across the world frown ... //-->
  25. &nbsp; &nbsp; &nbsp;
  26. <input name=cadButton id='vboxConsoleCADButton' style='display: none' type=button value="Ctrl-Alt-Del" onClick="vboxRDPsendCAD()" />
  27. <input id='vboxVRDPDetachBtn' style='display: none' name='detach' type='button' value='Detach' onClick="vboxRDPDetach();" />
  28. <span id='vboxRDPStatus'></span>
  29. </p>
  30. </form>
  31. </div>
  32. <div id="FlashRDPContainer" style='width: 100%;'>
  33. <div id="FlashRDP" style='width: 100%;'></div>
  34. </div>
  35. <script type="text/javascript">
  36. var vboxRDPFlashLoaded = false;
  37. var vboxConsoleDetached = (vboxConsoleDetached || false);
  38. var vboxRDPFlashListenersAdded = false;
  39. $('#vboxRDPForm').on('submit',function(e){
  40. e.stopPropagation();
  41. e.preventDefault();
  42. return false;
  43. });
  44. // Custom resolutions
  45. if($("#vboxPane").data('vboxConfig').consoleResolutions) {
  46. var res = $("#vboxPane").data('vboxConfig').consoleResolutions;
  47. // first one must be valid
  48. if(res[0].split('x').length == 2) {
  49. document.vboxRDPForm.vboxRDPSizeSelect.options.length = 0;
  50. $(document.vboxRDPForm.vboxRDPSizeSelect).children().remove();
  51. for(var i = 0; i < res.length; i++) {
  52. document.vboxRDPForm.vboxRDPSizeSelect.options[i] = new Option(res[i],res[i]);
  53. }
  54. }
  55. }
  56. // Translations
  57. $('#vboxTabVMConsole').find(".translate").html(function(i,h){return trans(h,'VBoxConsoleWgt');}).removeClass('translate');
  58. $(document.vboxRDPForm.connectionButton).val(trans('Connect','VBoxConsoleWgt'));
  59. $(document.vboxRDPForm.cadButton).val(trans("Send Ctrl-Alt-Del",'VBoxConsoleWgt'));
  60. $(document.vboxRDPForm.vboxVRDPDetachBtn).val(trans("Detach",'VBoxConsoleWgt'));
  61. $("#vboxRDPStatus").html(trans("Loading ...",'UIVMDesktop'));
  62. if(vboxConsoleDetached) window.status = $("#vboxRDPStatus").text();
  63. // Disable / enable tab on selection list changes
  64. $('#vboxPane').on('vmSelectionListChanged', function(){
  65. var vm = vboxChooser.getSingleSelected();
  66. // Initially disable tab
  67. $('#vboxTabVMConsole').parent().trigger('disableTab', ['vboxTabVMConsole']);
  68. if(!vm || !vboxVMStates.isRunning(vm)) {
  69. $('#vboxRDPFormContainer').css({'display':'none'});
  70. $('#FlashRDPContainer').css({'visibility':'hidden'});
  71. $('#vboxTabVMUnavailable').css({'display':'none'});
  72. } else {
  73. // VM is running, get runtime data
  74. $.when(vboxVMDataMediator.getVMDataCombined(vm.id)).done(function(info) {
  75. if(info.VRDEServerInfo && info.VRDEServerInfo.port > 0 && info.VRDEServer.VRDEExtPack.indexOf("VNC") == -1) {
  76. $('#vboxRDPFormContainer').css({'display':''});
  77. $('#FlashRDPContainer').css({'visibility':'visible'});
  78. $('#vboxTabVMUnavailable').css({'display':'none'});
  79. $('#vboxTabVMConsole').parent().trigger('enableTab', ['vboxTabVMConsole']);
  80. }
  81. });
  82. }
  83. // Update on console info change
  84. }).on('vboxOnVRDEServerInfoChanged',function(e,eventData) {
  85. // Shorthand
  86. var vmid = eventData.machineId;
  87. var VRDEServerInfo = eventData.enrichmentData;
  88. var selVM = vboxChooser.getSingleSelected();
  89. var enabled = (selVM && selVM.id == vmid && vboxVMStates.isRunning(selVM) && VRDEServerInfo && VRDEServerInfo.port > 0);
  90. if(enabled) {
  91. $.when(vboxVMDataMediator.getVMDataCombined(vmid)).done(function(info) {
  92. enabled = (info.VRDEServerInfo && info.VRDEServerInfo.port > 0 && info.VRDEServer.VRDEExtPack.indexOf("VNC") == -1);
  93. if(enabled) {
  94. $('#vboxTabVMConsole').parent().trigger('enableTab', ['vboxTabVMConsole']);
  95. $('#vboxRDPFormContainer').css({'display':''});
  96. $('#FlashRDPContainer').css({'visibility':'visible'});
  97. $('#vboxTabVMUnavailable').css({'display':'none'});
  98. var chost = vboxGetVRDEHost(selVM);
  99. chost+=':'+VRDEServerInfo.port;
  100. if($(document.vboxRDPForm.serverAddress).val() != chost) {
  101. // console host changed
  102. vboxRDPDisconnect();
  103. }
  104. $(document.vboxRDPForm.serverAddress).val(chost);
  105. } else {
  106. $('#vboxTabVMConsole').parent().trigger('disableTab', ['vboxTabVMConsole']);
  107. }
  108. });
  109. } else {
  110. $('#vboxTabVMConsole').parent().trigger('disableTab', ['vboxTabVMConsole']);
  111. }
  112. // Update tab on machine state change
  113. }).on('vboxOnMachineStateChanged', function(e, eventData){
  114. var selVMId = vboxChooser.getSingleSelectedId();
  115. var enabled = (selVMId == eventData.machineId && vboxVMStates.isRunning({'state':eventData.state}));
  116. $('#vboxTabVMConsole').parent().trigger('disableTab', ['vboxTabVMConsole']);
  117. if(enabled) {
  118. // VM is running, get runtime data
  119. $.when(vboxVMDataMediator.getVMRuntimeData(eventData.machineId)).done(function(vm) {
  120. if(vm.VRDEServerInfo && vm.VRDEServerInfo.port > 0) {
  121. $('#vboxTabVMConsole').parent().trigger('enableTab', ['vboxTabVMConsole']);
  122. $('#vboxRDPFormContainer').css({'display':''});
  123. $('#FlashRDPContainer').css({'visibility':'visible'});
  124. $('#vboxTabVMUnavailable').css({'display':'none'});
  125. }
  126. });
  127. }
  128. // Clean up local data storage when a machine is unregistered
  129. }).on('vboxMachineRegistered', function(e, eventData) {
  130. if(!eventData.registered) {
  131. vboxSetLocalDataItem('vbox'+eventData.machineId+'ConsoleSize','',true);
  132. vboxSetLocalDataItem('vbox'+eventData.machineId+'ConsoleConnected','',true);
  133. }
  134. });
  135. /*
  136. * Populate console info values when this tab is shown
  137. */
  138. $('#vboxTabVMConsole').on('show',function(){
  139. var vm = vboxChooser.getSingleSelected();
  140. if(!vm || !vboxVMStates.isRunning(vm)) {
  141. $('#vboxRDPFormContainer').css({'display':'none'});
  142. $('#FlashRDPContainer').css({'visibility':'hidden'});
  143. $('#vboxTabVMUnavailable').css({'display':''});
  144. return;
  145. }
  146. $('#vboxConsoleLoginInfo').hide();
  147. /* Load runtime data. This will tell us if the VRDE server is actually active */
  148. /* And details. This will give us info about the VRDEServer configuration */
  149. $.when(vboxVMDataMediator.getVMRuntimeData(vm.id),vboxVMDataMediator.getVMDetails(vm.id))
  150. .done(function(runtimeData, detailsData) {
  151. /* Not active */
  152. if(!(runtimeData.VRDEServerInfo && runtimeData.VRDEServerInfo.port > 0)) {
  153. $('#vboxTabVMUnavailable').css({'display':''});
  154. $('#vboxTabVMConsole').parent().trigger('disableTab',['vboxTabVMConsole']);
  155. return;
  156. }
  157. // Hide login form if authtype is not set
  158. if(detailsData.VRDEServer.authType != 'Null') {
  159. $('#vboxConsoleLoginInfo').show();
  160. }
  161. $('#vboxConsoleLoginInfo').data('vboxVRDPauthType',detailsData.VRDEServer.authType);
  162. /* Active */
  163. $('#vboxRDPFormContainer').css({'display':''});
  164. $('#FlashRDPContainer').css({'visibility':'visible'});
  165. $('#vboxTabVMUnavailable').css({'display':'none'});
  166. vboxRDPDisconnect();
  167. $("#vboxRDPStatus").html('');
  168. if(vboxConsoleDetached) window.status = $("#vboxRDPStatus").text();
  169. var chost = vboxGetVRDEHost(detailsData);
  170. chost+=':'+runtimeData.VRDEServerInfo.port;
  171. $(document.vboxRDPForm.serverAddress).val(chost);
  172. // Set default console size for this VM?
  173. var cs = vboxGetLocalDataItem('vbox'+detailsData.id+'ConsoleSize');
  174. if(cs) {
  175. $(document.vboxRDPForm.vboxRDPSizeSelect).children('[value='+cs+']').first().prop('selected',true);
  176. }
  177. $('#vboxRDPFormContainer').css({'display':''});
  178. vboxRDPLoad();
  179. });
  180. });
  181. function vboxRDPLoad() {
  182. var flashvars = {};
  183. var params = {};
  184. params.wmode="opaque";
  185. params.menu="false";
  186. params.bgcolor="#e9e9e9";
  187. params.quality="low";
  188. params.allowScriptAccess="always";
  189. params.flashId="FlashRDP";
  190. var attributes = {};
  191. swfobject.embedSWF("rdpweb/RDPClientUI.swf", "FlashRDP", "100", "100", "9.0.0","", flashvars, params, attributes);
  192. var ua = swfobject.ua;
  193. // No flash installed
  194. if(!ua || ua.pv[0] == '0') {
  195. $('#vboxRDPFormContainer').css('display','none');
  196. $("#FlashRDP").css('width','100%').html("The Adobe Flash plugin is not installed.");
  197. }
  198. }
  199. function vboxRDPgetFlashProperty(name) {
  200. var flash = RDPWebClient.getFlashById("FlashRDP");
  201. try {
  202. return flash.getProperty(name);
  203. } catch (e) {
  204. return '';
  205. }
  206. }
  207. /*
  208. * RDP client event handlers.
  209. * They will be called when the flash movie is ready and some event occurs.
  210. * Note: the function name must be the "flash_id" + "event name".
  211. */
  212. function RDPWebEventLoaded(flashid) {
  213. vboxRDPFlashLoaded = true;
  214. $("#vboxRDPStatus").html(trans("Version",'UIVMDesktop') + ": " + vboxRDPgetFlashProperty("version"));
  215. if(vboxConsoleDetached) window.status = $("#vboxRDPStatus").text();
  216. var flash = RDPWebClient.getFlashById("FlashRDP");
  217. // Apply keyboard layout
  218. flash.setProperty("keyboardLayout", ($('#vboxPane').data('vboxConfig').consoleKeyboardLayout == 'DE' ? 'de' : 'en'));
  219. // Only do this once
  220. if(!vboxRDPFlashListenersAdded) {
  221. if (window.addEventListener) {
  222. window.addEventListener("contextmenu", function(event) { return RDPWebClient._MozillaContextMenu(event); }, true);
  223. window.addEventListener("mousedown", function(event) { return RDPWebClient._MozillaMouse(event, true); }, true);
  224. window.addEventListener("mouseup", function(event) { return RDPWebClient._MozillaMouse(event, false); }, true);
  225. flash.addEventListener("mouseout", function(event) { return RDPWebClient._MozillaMouseOut(event); }, true);
  226. } else {
  227. document.oncontextmenu = function() { return RDPWebClient._IEContextMenu(); };
  228. flash.parentNode.onmousedown = function() { return RDPWebClient._IEMouse(true); };
  229. flash.parentNode.onmouseup = function() { return RDPWebClient._IEMouse(false); };
  230. flash.onmouseout=function() {return RDPWebClient._IEMouseOut(); };
  231. }
  232. vboxRDPFlashListenersAdded = true;
  233. }
  234. // Connect if "detached"
  235. if(vboxConsoleDetached) {
  236. $('#vboxTabVMUnavailable').css({'display':'none'});
  237. $('#vboxRDPFormContainer').css({'display':'none'});
  238. $('#vboxRDPSize').val($(window.opener.document.getElementById('vboxRDPSize')).val());
  239. $('#vboxRDPFormContainer').find(".vboxRDPSet").each(function(){
  240. $(this).val(window.opener.document.forms['vboxRDPForm'][$(this).attr('name')].value);
  241. });
  242. $(window).on('resize',function(){
  243. var flash = RDPWebClient.getFlashById("FlashRDP");
  244. var wh = [ $(window).width()-2, $(window).height()-2 ];
  245. $(flash).css({'height':wh[1]+'px','width':wh[0]+'px'});
  246. $('#FlashRDP').css({'height':wh[1]+'px','width':wh[0]+'px'});
  247. flash.setProperty("displayWidth", wh[0]);
  248. flash.setProperty("displayHeight", wh[1]);
  249. $(flash).css({'display':'none'});
  250. $(flash).css({'display':'block'});
  251. });
  252. vboxRDPConnect();
  253. } else {
  254. $('#vboxRDPConnParams').show();
  255. $('#vboxRDPFormContainer').css('display','');
  256. // Did not explicitly disconnect from this VM and has no auth settings so reconnect
  257. if(vboxGetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleConnected') == 'true' && $('#vboxConsoleLoginInfo').data('vboxVRDPauthType') == 'Null') {
  258. document.vboxRDPForm.connectionButton.click();
  259. }
  260. }
  261. }
  262. function RDPWebEventConnected(flashId) {
  263. $("#vboxRDPStatus").data('vmConnected',true);
  264. $("#vboxRDPStatus").html(trans("Connected to %1",'VBoxConsoleWgt').replace('%1',$(document.vboxRDPForm.serverAddress).val()));
  265. if(vboxConsoleDetached) window.status = $("#vboxRDPStatus").text();
  266. $('#vboxConsoleCADButton').show();
  267. $('#vboxVRDPDetachBtn').show();
  268. }
  269. function RDPWebEventServerRedirect(flashId) {
  270. $("#vboxRDPStatus").html(trans("Redirection by %1",'VBoxConsoleWgt').replace('%1',vboxRDPgetFlashProperty("serverAddress")));
  271. if(vboxConsoleDetached) window.status = $("#vboxRDPStatus").text();
  272. }
  273. function RDPWebEventDisconnected(flashId) {
  274. $("#vboxRDPStatus").data('vmConnected',false);
  275. $('#vboxRDPConnParams').show();
  276. $('#vboxVRDPDetachBtn').hide();
  277. /* RDP connection has been lost */
  278. $("#vboxRDPStatus").html(trans("Disconnect reason",'VBoxConsoleWgt')+":\n" + vboxRDPgetFlashProperty("lastError"));
  279. if(vboxConsoleDetached) {
  280. alert($("#vboxRDPStatus").text());
  281. window.close();
  282. }
  283. document.vboxRDPForm.connectionButton.value = trans("Connect",'VBoxConsoleWgt');
  284. document.vboxRDPForm.connectionButton.onclick=function() {
  285. vboxSetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleSize',$('#vboxRDPSize').val(),true);
  286. vboxSetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleConnected','true',true);
  287. return vboxRDPConnect();
  288. };
  289. $('#vboxConsoleAddr').css('display','');
  290. $('#vboxConsoleCADButton').hide();
  291. $('#vboxRDPFormContainer').css({'display':''});
  292. }
  293. function vboxRDPConnect() {
  294. vboxSetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleSize',$('#vboxRDPSize').val(), true);
  295. if (!vboxRDPFlashLoaded) return false;
  296. var flash = RDPWebClient.getFlashById("FlashRDP");
  297. if (!flash) return;
  298. $('#vboxRDPConnParams').hide();
  299. document.vboxRDPForm.connectionButton.value = trans("Disconnect",'VBoxConsoleWgt');
  300. document.vboxRDPForm.connectionButton.onclick=function(){
  301. vboxSetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleConnected');
  302. return vboxRDPDisconnect();
  303. };
  304. $('#vboxConsoleAddr').css('display','none');
  305. $('#FlashRDPContainer').css({'visibility':'visible'});
  306. var flash = RDPWebClient.getFlashById("FlashRDP");
  307. var wh = null;
  308. if(vboxConsoleDetached) {
  309. wh = [ $(document).width()-2, $(document).height()-2 ];
  310. } else {
  311. wh = $('#vboxRDPSize').val().split('x');
  312. }
  313. $(flash).css({'height':wh[1]+'px','width':wh[0]+'px'});
  314. flash.setProperty("displayWidth", wh[0]);
  315. flash.setProperty("displayHeight", wh[1]);
  316. /* Setup the client parameters. */
  317. $('#vboxRDPFormContainer').find(".vboxRDPSet").each(function(){
  318. flash.setProperty($(this).attr('name'),$(this).val());
  319. });
  320. $("#vboxRDPStatus").html(trans("Connecting to %1",'VBoxConsoleWgt').replace('%1',$(document.vboxRDPForm.serverAddress).val()) + "...");
  321. if(vboxConsoleDetached) window.status = $("#vboxRDPStatus").html();
  322. /* Establish the connection. */
  323. flash.connect();
  324. }
  325. function vboxRDPDisconnect() {
  326. var flash = RDPWebClient.getFlashById("FlashRDP");
  327. if (flash) try { flash.disconnect(); } catch (err) {};
  328. /* Restore the "Connect" form. And resize flash*/
  329. document.vboxRDPForm.connectionButton.value = trans("Connect",'VBoxConsoleWgt');
  330. document.vboxRDPForm.connectionButton.onclick=function() {
  331. vboxSetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleConnected','true',true);
  332. vboxSetLocalDataItem('vbox'+vboxChooser.getSingleSelectedId()+'ConsoleSize',$('#vboxRDPSize').val(),true);
  333. vboxRDPConnect();this.blur();
  334. };
  335. $('#vboxConsoleCADButton').hide();
  336. $(flash).css({'height':'100px','width':'100px'});
  337. $('#vboxConsoleAddr').css('display','');
  338. }
  339. function vboxRDPsendCAD() {
  340. var flash = RDPWebClient.getFlashById("FlashRDP");
  341. if (flash) flash.keyboardSendCAD();
  342. }
  343. function vboxRDPDetach() {
  344. vboxRDPDisconnect();
  345. var vmname = vboxChooser.getSingleSelected().name;
  346. var wh = $('#vboxRDPSize').val().split('x');
  347. var newwin = window.open('about:blank','vboxConsoleDetachedWin'+vmname.replace(/[^a-zA-Z0-9]/g,'_'),'toolbar=0,menubar=0,location=0,directories=0,status=true,resize=true,width='+(parseInt(wh[0])+20)+',height='+(parseInt(wh[1])+20)+'');
  348. newwin.document.open();
  349. newwin.document.write('<html><head><title>'+vmname + ' - ' + trans('Console','UIVMDesktop')+'</title></head><body style="margin: 0px; border: 0px; padding: 0px; overflow: hidden;"><div style="margin: 0px; border: 0px; padding: 0px" id="vboxPane"><img src="images/spinner.gif" /></div></body></html>');
  350. newwin.document.close();
  351. newwin.trans = function(t) { return t; };
  352. var newHead = newwin.document.getElementsByTagName('HEAD')[0];
  353. var headTags = document.getElementsByTagName('HEAD')[0].getElementsByTagName('SCRIPT');
  354. for(var i = 0; i < headTags.length; i++) {
  355. // Ignore runtime scripts
  356. if(!$(headTags[i]).attr('src')) continue;
  357. var script = newwin.document.createElement('script');
  358. script.setAttribute('type','text/javascript');
  359. script.setAttribute('src',$(headTags[i]).attr('src'));
  360. newHead.appendChild(script);
  361. }
  362. // Load self
  363. var script = newwin.document.createElement('script');
  364. script.setAttribute('type','text/javascript');
  365. script.text = "var vboxConsoleDetached = true;\
  366. function vboxConsoleCheckLoad() {\
  367. if(vboxLoader && jQuery) vboxConsoleDetachedOnload();\
  368. else setTimeout(\"vboxConsoleCheckLoad()\",1000);\
  369. }\
  370. function vboxConsoleDetachedOnload(){\
  371. l = new vboxLoader();\
  372. l.add('getConfig',function(d){$('#vboxPane').data('vboxConfig',d.responseData);});\
  373. l.addFile('panes/tabVMConsoleRDP.html',function(d){$('#vboxPane').children().remove();$('#vboxPane').append(d);$('#vboxTabVMConsole').css('display','');vboxRDPLoad();});\
  374. l.run();};\
  375. setTimeout(\"vboxConsoleCheckLoad()\",1000);";
  376. newHead.appendChild(script);
  377. }
  378. </script>
  379. <iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
  380. this frame prevents back forward cache in Safari
  381. </iframe>