1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-25 15:45:23 +00:00

fix console password & sendkey & css fixes & add scale vb

This commit is contained in:
catborise 2020-06-24 12:39:32 +03:00
parent 48f9ba6d73
commit 4f8a1fd50d
9 changed files with 767 additions and 886 deletions

View file

@ -1,6 +1,7 @@
{% load staticfiles %} {% load staticfiles %}
{% load i18n %} {% load i18n %}
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="shortcut icon" href="{% static "favicon.ico" %}"> <link rel="shortcut icon" href="{% static "favicon.ico" %}">
@ -9,19 +10,13 @@
<link href="{% static "css/webvirtcloud.css" %}" rel="stylesheet"> <link href="{% static "css/webvirtcloud.css" %}" rel="stylesheet">
<style> <style>
body {
margin: 0;
padding: 0;
background-color: #313131;
}
#main_container { #main_container {
padding: 0; padding: 0;
width: 100%; width: 100%;
max-width: none; max-width: none;
height: 100%; height: 100%;
background-color:#494949; background-color: #494949;
border-bottom-right-radius: 800px 600px; border-bottom-right-radius: 850px 600px;
} }
@ -32,102 +27,90 @@
margin-right: auto; margin-right: auto;
display: block; display: block;
} }
#status {
z-index: 10000;
width: 80%;
position: absolute;
top: 5px;
left: 10%;
text-align: center;
}
</style> </style>
{% block head %}{% endblock %} {% block head %}{% endblock %}
</head> </head>
<body> <body>
<div id='main_container' class="container"> <div id='main_container' class="container">
<nav class="navbar navbar-expand-md navbar-dark bg-primary" arial-label="console navbar"> <nav class="navbar navbar-expand-md navbar-dark bg-primary" arial-label="console navbar">
<div class="container"> <div class="container">
<a class="navbar-brand">{{ instance.name }}</a> <a class="navbar-brand">{{ instance.name }}</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target=".navbar-collapse" aria-expanded="false" aria-label="Toggle navigation"> <button type="button" class="navbar-toggler" data-toggle="collapse" data-target=".navbar-collapse"
<span class="navbar-toggler-icon"></span> aria-expanded="false" aria-label="Toggle navigation">
</button> <span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse"> <div class="collapse navbar-collapse">
<ul class="navbar-nav mr-auto mt-2 mt-md-0"> <ul class="navbar-nav mr-auto mt-2 mt-md-0">
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" role="button"
data-toggle="dropdown" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
role="button" {% trans "Send key(s)" %}
id="dropdownMenuLink" </a>
data-toggle="dropdown" <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
aria-haspopup="true" <a class="dropdown-item" id="ctrlaltdel" href='#'>Ctrl+Alt+Del</a>
aria-expanded="false"> <div class="dropdown-divider"></div>
{% trans "Send key(s)" %} <a class="dropdown-item" id="ctrlaltf1" href='#'>Ctrl+Alt+F1</a>
</a> <a class="dropdown-item" id="ctrlaltf2" href='#'>Ctrl+Alt+F2</a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <a class="dropdown-item" id="ctrlaltf3" href='#'>Ctrl+Alt+F3</a>
<a class="dropdown-item" id="ctrlaltdel" href='#'>Ctrl+Alt+Del</a> <a class="dropdown-item" id="ctrlaltf4" href='#'>Ctrl+Alt+F4</a>
<div class="dropdown-divider"></div> <a class="dropdown-item" id="ctrlaltf5" href='#'>Ctrl+Alt+F5</a>
<a class="dropdown-item" id="ctrlaltf1" href='#'>Ctrl+Alt+F1</a> <a class="dropdown-item" id="ctrlaltf6" href='#'>Ctrl+Alt+F6</a>
<a class="dropdown-item" id="ctrlaltf2" href='#'>Ctrl+Alt+F2</a> <a class="dropdown-item" id="ctrlaltf7" href='#'>Ctrl+Alt+F7</a>
<a class="dropdown-item" id="ctrlaltf3" href='#'>Ctrl+Alt+F3</a> <a class="dropdown-item" id="ctrlaltf8" href='#'>Ctrl+Alt+F8</a>
<a class="dropdown-item" id="ctrlaltf4" href='#'>Ctrl+Alt+F4</a> <a class="dropdown-item" id="ctrlaltf9" href='#'>Ctrl+Alt+F9</a>
<a class="dropdown-item" id="ctrlaltf5" href='#'>Ctrl+Alt+F5</a> <a class="dropdown-item" id="ctrlaltf10" href='#'>Ctrl+Alt+F10</a>
<a class="dropdown-item" id="ctrlaltf6" href='#'>Ctrl+Alt+F6</a> <a class="dropdown-item" id="ctrlaltf11" href='#'>Ctrl+Alt+F11</a>
<a class="dropdown-item" id="ctrlaltf7" href='#'>Ctrl+Alt+F7</a> <a class="dropdown-item" id="ctrlaltf12" href='#'>Ctrl+Alt+F12</a>
<a class="dropdown-item" id="ctrlaltf8" href='#'>Ctrl+Alt+F8</a> </div>
<a class="dropdown-item" id="ctrlaltf9" href='#'>Ctrl+Alt+F9</a> </li>
<a class="dropdown-item" id="ctrlaltf10" href='#'>Ctrl+Alt+F10</a> <li class="nav-item" id="fullscreen_button">
<a class="dropdown-item" id="ctrlaltf11" href='#'>Ctrl+Alt+F11</a> <a class="nav-link" href='#'>{% trans "Fullscreen" %}</a>
<a class="dropdown-item" id="ctrlaltf12" href='#'>Ctrl+Alt+F12</a> </li>
{% block navbarmenu %}{% endblock %}
</ul>
</div> </div>
</li> </div>
<li class="nav-item" id="fullscreen_button"> </nav>
<a class="nav-link" href='#'>{% trans "Fullscreen" %}</a> {% block content %}{% endblock %}
</li> </div>
{% block navbarmenu %}{% endblock %} <script src="{% static "js/jquery.js" %}"></script>
</ul> <script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
</div>
</nav>
{% block content %}{% endblock %} <script>
</div> function log_message(msg, type) {
<script src="{% static "js/jquery.js" %}"></script> var exist = $('#status').is('div');
<script src="{% static "js/bootstrap.bundle.min.js" %}"></script> status_div = $('<div id="status" class="alert alert-' + type + ' role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + msg + '</div>');
if (exist) {
<script> $('#status').remove();
function log_message(msg,type) { $('body').prepend(status_div);
var exist=$('#status').is('div'); }
status_div=$('<div id="status" class="alert alert-'+type+' role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>'+msg+'</div>'); else {
if (exist) { status_div.hide();
$('#status').remove(); $('body').prepend(status_div);
$('body').prepend(status_div); status_div.fadeIn(200);
}
if (type != 'danger') {
status_div.delay(3000).fadeOut(200);
}
} }
else {
status_div.hide();
$('body').prepend(status_div);
status_div.fadeIn(200);
}
if (type!='danger') {
status_div.delay(3000).fadeOut(200);
}
}
function log_error(msg) { function log_error(msg) {
log_message(msg,'danger'); log_message(msg, 'danger');
} }
function log_info(msg) { function log_info(msg) {
log_message(msg,'info'); log_message(msg, 'info');
} }
{% if console_error %} {% if console_error %}
log_error('{{ console_error|escapejs }}'); log_error('{{ console_error|escapejs }}');
{% endif %} {% endif %}
</script> </script>
{% block foot %}{% endblock %} {% block foot %}{% endblock %}
</body> </body>
</html> </html>

View file

@ -27,138 +27,116 @@
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<title>WebVirtCloud - Spice Client - Full</title> <title>WebVirtCloud - Spice Client - Full</title>
<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" /> <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
<!-- ES2015/ES6 modules polyfill --> <!-- ES2015/ES6 modules polyfill -->
<script type="module"> <script type="module">
window._spice_has_module_support = true; window._spice_has_module_support = true;
</script> </script>
<script> <script>
window.addEventListener("load", function() { window.addEventListener("load", function () {
if (window._spice_has_module_support) return; if (window._spice_has_module_support) return;
var loader = document.createElement("script"); var loader = document.createElement("script");
loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}'; loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
document.head.appendChild(loader); document.head.appendChild(loader);
}); });
</script> </script>
<script type="module" crossorigin="anonymous"> <script type="module" crossorigin="anonymous">
import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}'; import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
var host = null, port = null; var host = null, port = null;
var sc; var sc;
function spice_error(e) { function spice_error(e) {
disconnect();
}
function connect() {
var host, port, password, scheme = "ws://", uri;
host = document.getElementById("host").value;
port = document.getElementById("port").value;
password = document.getElementById("password").value;
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (sc) {
sc.stop();
}
uri = scheme + host + ":" + port;
document.getElementById('connectButton').innerHTML = "Stop";
document.getElementById('connectButton').onclick = disconnect;
try {
sc = new SpiceHtml5.SpiceMainConn({
uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected
});
}
catch (e) {
alert(e.toString());
disconnect(); disconnect();
} }
}
function connect() { function disconnect() {
var host, port, password, scheme = "ws://", uri; console.log(">> disconnect");
if (sc) {
host = document.getElementById("host").value; sc.stop();
port = document.getElementById("port").value; }
password = document.getElementById("password").value; document.getElementById('connectButton').innerHTML = "Start";
document.getElementById('connectButton').onclick = connect;
if ((!host) || (!port)) { if (window.File && window.FileReader && window.FileList && window.Blob) {
console.log("must set host and port"); var spice_xfer_area = document.getElementById('spice-xfer-area');
return; if (spice_xfer_area != null) {
document.getElementById('spice-area').removeChild(spice_xfer_area);
} }
document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
}
console.log("<< disconnect");
}
if (sc) { function agent_connected(sc) {
sc.stop(); window.addEventListener('resize', SpiceHtml5.handle_resize);
} window.spice_connection = this;
uri = scheme + host + ":" + port; SpiceHtml5.resize_helper(this);
document.getElementById('connectButton').innerHTML = "Stop"; if (window.File && window.FileReader && window.FileList && window.Blob) {
document.getElementById('connectButton').onclick = disconnect; var spice_xfer_area = document.createElement("div");
spice_xfer_area.setAttribute('id', 'spice-xfer-area');
document.getElementById('spice-area').appendChild(spice_xfer_area);
document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
}
else {
console.log("File API is not supported");
}
}
try { function toggle_console() {
sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div", var checkbox = document.getElementById('show_console');
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected }); var m = document.getElementById('message-div');
}
catch (e) { if (checkbox.checked) {
alert(e.toString()); m.style.display = 'block';
disconnect(); }
} else {
m.style.display = 'none';
} }
function disconnect() { window.addEventListener('resize', SpiceHtml5.handle_resize);
console.log(">> disconnect"); if (sc) {
if (sc) { SpiceHtml5.resize_helper(sc);
sc.stop();
}
document.getElementById('connectButton').innerHTML = "Start";
document.getElementById('connectButton').onclick = connect;
if (window.File && window.FileReader && window.FileList && window.Blob) {
var spice_xfer_area = document.getElementById('spice-xfer-area');
if (spice_xfer_area != null) {
document.getElementById('spice-area').removeChild(spice_xfer_area);
}
document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
}
console.log("<< disconnect");
}
function agent_connected(sc) {
window.addEventListener('resize', SpiceHtml5.handle_resize);
window.spice_connection = this;
SpiceHtml5.resize_helper(this);
if (window.File && window.FileReader && window.FileList && window.Blob) {
var spice_xfer_area = document.createElement("div");
spice_xfer_area.setAttribute('id', 'spice-xfer-area');
document.getElementById('spice-area').appendChild(spice_xfer_area);
document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
}
else {
console.log("File API is not supported");
}
}
function toggle_console() {
var checkbox = document.getElementById('show_console');
var m = document.getElementById('message-div');
if (checkbox.checked) {
m.style.display = 'block';
}
else {
m.style.display = 'none';
}
window.addEventListener('resize', SpiceHtml5.handle_resize);
if (sc) {
SpiceHtml5.resize_helper(sc);
}
}
/* SPICE port event listeners
window.addEventListener('spice-port-data', function(event) {
// Here we convert data to text, but really we can obtain binary data also
var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
});
window.addEventListener('spice-port-event', function(event) {
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
});
*/
function fullscreen() {
var screen=document.getElementById('spice-screen');
if(screen.requestFullscreen) {
screen.requestFullscreen();
} else if(screen.mozRequestFullScreen) {
screen.mozRequestFullScreen();
} else if(screen.webkitRequestFullscreen) {
screen.webkitRequestFullscreen();
} else if(screen.msRequestFullscreen) {
screen.msRequestFullscreen();
} }
} }
/* SPICE port event listeners /* SPICE port event listeners
@ -168,24 +146,53 @@
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text); DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
}); });
window.addEventListener('spice-port-event', function(event) {
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
});
*/
function fullscreen() {
var screen = document.getElementById('spice-screen');
if (screen.requestFullscreen) {
screen.requestFullscreen();
} else if (screen.mozRequestFullScreen) {
screen.mozRequestFullScreen();
} else if (screen.webkitRequestFullscreen) {
screen.webkitRequestFullscreen();
} else if (screen.msRequestFullscreen) {
screen.msRequestFullscreen();
}
}
function sendctrlaltfn(f) {
SpiceHtml5.sendCtrlAltFN(sc, f);
return false;
}
/* SPICE port event listeners
window.addEventListener('spice-port-data', function(event) {
// Here we convert data to text, but really we can obtain binary data also
var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
});
window.addEventListener('spice-port-event', function(event) { window.addEventListener('spice-port-event', function(event) {
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent); DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
}); });
*/ */
document.getElementById("fullscreen_button").addEventListener('click', fullscreen); document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltdel').addEventListener('click', function(){sendCtrlAltDel(sc);}); document.getElementById('ctrlaltdel').addEventListener('click', function () { sendCtrlAltDel(sc); });
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);}); document.getElementById('ctrlaltf1').addEventListener('click', function () { sendctrlaltfn(0) });
document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);}); document.getElementById('ctrlaltf2').addEventListener('click', function () { sendctrlaltfn(1) });
document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);}); document.getElementById('ctrlaltf3').addEventListener('click', function () { sendctrlaltfn(2) });
document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);}); document.getElementById('ctrlaltf4').addEventListener('click', function () { sendctrlaltfn(3) });
document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);}); document.getElementById('ctrlaltf5').addEventListener('click', function () { sendctrlaltfn(4) });
document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);}); document.getElementById('ctrlaltf6').addEventListener('click', function () { sendctrlaltfn(5) });
document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);}); document.getElementById('ctrlaltf7').addEventListener('click', function () { sendctrlaltfn(6) });
document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);}); document.getElementById('ctrlaltf8').addEventListener('click', function () { sendctrlaltfn(7) });
document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);}); document.getElementById('ctrlaltf9').addEventListener('click', function () { sendctrlaltfn(8) });
document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);}); document.getElementById('ctrlaltf10').addEventListener('click', function () { sendctrlaltfn(9) });
document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);}); document.getElementById('ctrlaltf11').addEventListener('click', function () { sendctrlaltfn(10) });
document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);}); document.getElementById('ctrlaltf12').addEventListener('click', function () { sendctrlaltfn(11) });
document.getElementById('connectButton').onclick = connect; document.getElementById('connectButton').onclick = connect;
document.getElementById('show_console').onchange = toggle_console; document.getElementById('show_console').onchange = toggle_console;
@ -193,24 +200,26 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div id="login"> <div id="login">
<span class="logo">SPICE</span> <span class="logo">SPICE</span>
<label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost --> <label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
<label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'> <label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'>
<label for="password">{% trans 'Password' %}:</label> <input type='password' id='password' value='{{ console_passwd }}'> <label for="password">{% trans 'Password' %}:</label> <input type='password' id='password'
<label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1" onchange="toggle_console()" checked> value='{{ console_passwd }}'>
<button id="connectButton">{% trans 'Start' %}</button> <label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1"
</div> onchange="toggle_console()" checked>
<button id="connectButton">{% trans 'Start' %}</button>
</div>
<div id="spice-area"> <div id="spice-area">
<div id="spice-screen" class="spice-screen"></div> <div id="spice-screen" class="spice-screen"></div>
</div> </div>
<div id="message-div" class="spice-message"></div> <div id="message-div" class="spice-message"></div>
<div id="debug-div"> <div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here --> <!-- If DUMPXXX is turned on, dumped images will go here -->
</div> </div>
{% endblock %} {% endblock %}

View file

@ -27,198 +27,205 @@
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<title>WebVirtCloud - Spice - Lite</title> <title>WebVirtCloud - Spice - Lite</title>
<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" /> <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
<!-- ES2015/ES6 modules polyfill --> <!-- ES2015/ES6 modules polyfill -->
<script type="module"> <script type="module">
window._spice_has_module_support = true; window._spice_has_module_support = true;
</script> </script>
<script> <script>
window.addEventListener("load", function() { window.addEventListener("load", function () {
if (window._spice_has_module_support) return; if (window._spice_has_module_support) return;
var loader = document.createElement("script"); var loader = document.createElement("script");
loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}'; loader.src = '{% static "thirdparty/browser-es-module-loader/dist/browser-es-module-loader.js" %}';
document.head.appendChild(loader); document.head.appendChild(loader);
}); });
</script> </script>
<script type="module" crossorigin="anonymous"> <script type="module" crossorigin="anonymous">
import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}'; import * as SpiceHtml5 from '{% static "js/spice-html5/main.js" %}';
var host = null, port = null; var host = null, port = null;
var sc; var sc;
function spice_set_cookie(name, value, days) { function spice_set_cookie(name, value, days) {
var date, expires; var date, expires;
date = new Date(); date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000)); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString(); expires = "; expires=" + date.toGMTString();
document.cookie = name + "=" + value + expires + "; path=/"; document.cookie = name + "=" + value + expires + "; path=/";
}; };
function spice_query_var(name, defvalue) { function spice_query_var(name, defvalue) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search); var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue; return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue;
}
function spice_error(e) {
disconnect();
if (e !== undefined && e.message === "Permission denied.") {
var pass = prompt("Password");
connect(pass);
}
}
function connect(password) {
var host, port, scheme = "ws://", uri;
// By default, use the host and port of server that served this file
// host = spice_query_var('host', window.location.hostname);
host = '{{ ws_host| safe }}';
// Note that using the web server port only makes sense
// if your web server has a reverse proxy to relay the WebSocket
// traffic to the correct destination port.
var default_port = window.location.port;
if (!default_port) {
if (window.location.protocol == 'http:') {
default_port = 80;
}
else if (window.location.protocol == 'https:') {
default_port = 443;
}
}
//port = spice_query_var('port', default_port);
port = '{{ ws_port| safe }}';
if (window.location.protocol == 'https:') {
scheme = "wss://";
} }
function spice_error(e) { // If a token variable is passed in, set the parameter in a cookie.
// This is used by nova-spiceproxy.
var token = spice_query_var('token', null);
if (token) {
spice_set_cookie('token', token, 1)
}
if (password === undefined) {
password = spice_query_var('password', '');
password = '{{ console_passwd | safe }}';
}
if (password === 'None') password = '';
var path = spice_query_var('path', 'websockify');
if ((!host) || (!port)) {
console.log(_("must specify host and port in URL"));
return;
}
if (sc) {
sc.stop();
}
uri = scheme + host + ":" + port;
if (path) {
uri += path[0] == '/' ? path : ('/' + path);
}
try {
sc = new SpiceHtml5.SpiceMainConn({
uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected
});
}
catch (e) {
alert(e.toString());
disconnect(); disconnect();
if (e !== undefined && e.message === "Permission denied.") {
var pass = prompt("Password");
connect(pass);
}
} }
function connect(password) { }
var host, port, scheme = "ws://", uri;
// By default, use the host and port of server that served this file
// host = spice_query_var('host', window.location.hostname);
host = '{{ ws_host| safe }}';
// Note that using the web server port only makes sense
// if your web server has a reverse proxy to relay the WebSocket
// traffic to the correct destination port.
var default_port = window.location.port;
if (!default_port) {
if (window.location.protocol == 'http:') {
default_port = 80;
}
else if (window.location.protocol == 'https:') {
default_port = 443;
}
}
//port = spice_query_var('port', default_port);
port = '{{ ws_port| safe }}';
if (window.location.protocol == 'https:') {
scheme = "wss://";
}
// If a token variable is passed in, set the parameter in a cookie.
// This is used by nova-spiceproxy.
var token = spice_query_var('token', null);
if (token) {
spice_set_cookie('token', token, 1)
}
if (password === undefined) {
password = spice_query_var('password', '');
password = '{{ console_passwd | safe }}';
}
if (password === 'None') password = '';
var path = spice_query_var('path', 'websockify');
if ((!host) || (!port)) {
console.log(_("must specify host and port in URL"));
return;
}
if (sc) {
sc.stop();
}
uri = scheme + host + ":" + port;
if (path) {
uri += path[0] == '/' ? path : ('/' + path);
}
try {
sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
}
catch (e) {
alert(e.toString());
disconnect();
}
function disconnect() {
console.log(">> disconnect");
if (sc) {
sc.stop();
} }
if (window.File && window.FileReader && window.FileList && window.Blob) {
function disconnect() { var spice_xfer_area = document.getElementById('spice-xfer-area');
console.log(">> disconnect"); if (spice_xfer_area != null) {
if (sc) { document.getElementById('spice-area').removeChild(spice_xfer_area);
sc.stop();
} }
if (window.File && window.FileReader && window.FileList && window.Blob) { document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
var spice_xfer_area = document.getElementById('spice-xfer-area'); document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
if (spice_xfer_area != null) {
document.getElementById('spice-area').removeChild(spice_xfer_area);
}
document.getElementById('spice-area').removeEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', SpiceHtml5.handle_file_drop, false);
}
console.log("<< disconnect");
} }
console.log("<< disconnect");
}
function agent_connected(sc) { function agent_connected(sc) {
window.addEventListener('resize', SpiceHtml5.handle_resize); window.addEventListener('resize', SpiceHtml5.handle_resize);
window.spice_connection = this; window.spice_connection = this;
SpiceHtml5.resize_helper(this); SpiceHtml5.resize_helper(this);
if (window.File && window.FileReader && window.FileList && window.Blob) { if (window.File && window.FileReader && window.FileList && window.Blob) {
var spice_xfer_area = document.createElement("div"); var spice_xfer_area = document.createElement("div");
spice_xfer_area.setAttribute('id', 'spice-xfer-area'); spice_xfer_area.setAttribute('id', 'spice-xfer-area');
document.getElementById('spice-area').appendChild(spice_xfer_area); document.getElementById('spice-area').appendChild(spice_xfer_area);
document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false); document.getElementById('spice-area').addEventListener('dragover', SpiceHtml5.handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false); document.getElementById('spice-area').addEventListener('drop', SpiceHtml5.handle_file_drop, false);
}
else {
console.log("File API is not supported");
}
} }
else {
function fullscreen() { console.log("File API is not supported");
var screen=document.getElementById('spice-screen');
if(screen.requestFullscreen) {
screen.requestFullscreen();
} else if(screen.mozRequestFullScreen) {
screen.mozRequestFullScreen();
} else if(screen.webkitRequestFullscreen) {
screen.webkitRequestFullscreen();
} else if(screen.msRequestFullscreen) {
screen.msRequestFullscreen();
}
} }
}
/* SPICE port event listeners function fullscreen() {
window.addEventListener('spice-port-data', function(event) { var screen = document.getElementById('spice-screen');
// Here we convert data to text, but really we can obtain binary data also if (screen.requestFullscreen) {
var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data)); screen.requestFullscreen();
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text); } else if (screen.mozRequestFullScreen) {
}); screen.mozRequestFullScreen();
} else if (screen.webkitRequestFullscreen) {
screen.webkitRequestFullscreen();
} else if (screen.msRequestFullscreen) {
screen.msRequestFullscreen();
}
}
window.addEventListener('spice-port-event', function(event) { function sendctrlaltfn(f) {
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent); SpiceHtml5.sendCtrlAltFN(sc, f);
}); return false;
*/ }
document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltdel').addEventListener('click', function(){sendCtrlAltDel(sc);}); /* SPICE port event listeners
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);}); window.addEventListener('spice-port-data', function(event) {
document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);}); // Here we convert data to text, but really we can obtain binary data also
document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);}); var msg_text = arraybuffer_to_str(new Uint8Array(event.detail.data));
document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);}); DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'message text:', msg_text);
document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);}); });
document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);});
document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);}); window.addEventListener('spice-port-event', function(event) {
document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);}); DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);}); });
document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);}); */
document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);}); document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);}); document.getElementById('ctrlaltdel').addEventListener('click', function () { sendCtrlAltDel(sc); });
connect(undefined); document.getElementById('ctrlaltf1').addEventListener('click', function () { sendctrlaltfn(0) });
</script> document.getElementById('ctrlaltf2').addEventListener('click', function () { sendctrlaltfn(1) });
document.getElementById('ctrlaltf3').addEventListener('click', function () { sendctrlaltfn(2) });
document.getElementById('ctrlaltf4').addEventListener('click', function () { sendctrlaltfn(3) });
document.getElementById('ctrlaltf5').addEventListener('click', function () { sendctrlaltfn(4) });
document.getElementById('ctrlaltf6').addEventListener('click', function () { sendctrlaltfn(5) });
document.getElementById('ctrlaltf7').addEventListener('click', function () { sendctrlaltfn(6) });
document.getElementById('ctrlaltf8').addEventListener('click', function () { sendctrlaltfn(7) });
document.getElementById('ctrlaltf9').addEventListener('click', function () { sendctrlaltfn(8) });
document.getElementById('ctrlaltf10').addEventListener('click', function () { sendctrlaltfn(9) });
document.getElementById('ctrlaltf11').addEventListener('click', function () { sendctrlaltfn(10) });
document.getElementById('ctrlaltf12').addEventListener('click', function () { sendctrlaltfn(11) });
connect(undefined);
</script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div id="spice-area"> <div id="spice-area">
<div id="spice-screen" class="spice-screen"></div> <div id="spice-screen" class="spice-screen"></div>
</div> </div>
<div id="message-div" class="spice-message"></div> <div id="message-div" class="spice-message"></div>
<div id="debug-div"> <div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here --> <!-- If DUMPXXX is turned on, dumped images will go here -->
</div> </div>
{% endblock %} {% endblock %}

View file

@ -3,306 +3,228 @@
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<!--
<!--
noVNC example: lightweight example using minimal UI and features noVNC example: lightweight example using minimal UI and features
Copyright (C) 2012 Joel Martin This is a self-contained file which doesn't import WebUtil or external CSS.
Copyright (C) 2017 Samuel Mannehed for Cendio AB Copyright (C) 2019 The noVNC Authors
noVNC is licensed under the MPL 2.0 (see LICENSE.txt) noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
This file is licensed under the 2-Clause BSD license (see LICENSE.txt). This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
Connect parameters are provided in query string: Connect parameters are provided in query string:
http://example.com/?host=HOST&port=PORT&encrypt=1 http://example.com/?host=HOST&port=PORT&scale=true
or the fragment: -->
http://example.com/#host=HOST&port=PORT&encrypt=1 <title>WebVirtCloud - noVNC - Lite</title>
-->
<title>WebVirtCloud - noVNC - Lite</title>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame <!-- Always force latest IE rendering engine (even in intranet) &
Remove this if you use the .htaccess --> Chrome Frame. Remove this if you use the .htaccess -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Icons (see Makefile for what the sizes are for) --> <!-- Stylesheets -->
<link rel="icon" sizes="16x16" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-16x16.png" %}"> <link rel="stylesheet" href='{% static "js/novnc/app/styles/lite.css" %}'>
<link rel="icon" sizes="24x24" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-24x24.png" %}">
<link rel="icon" sizes="32x32" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-32x32.png" %}">
<link rel="icon" sizes="48x48" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-48x48.png" %}">
<link rel="icon" sizes="60x60" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-60x60.png" %}">
<link rel="icon" sizes="64x64" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-64x64.png" %}">
<link rel="icon" sizes="72x72" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-72x72.png" %}">
<link rel="icon" sizes="76x76" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-76x76.png" %}">
<link rel="icon" sizes="96x96" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-96x96.png" %}">
<link rel="icon" sizes="120x120" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-120x120.png" %}">
<link rel="icon" sizes="144x144" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-144x144.png" %}">
<link rel="icon" sizes="152x152" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-152x152.png" %}">
<link rel="icon" sizes="192x192" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-192x192.png" %}">
<!-- Firefox currently mishandles SVG, see #1419039
<link rel="icon" sizes="any" type="image/svg+xml" href="{% static "js/novnc/app/images/icons/novnc-icon.svg" %}">
-->
<!-- Repeated last so that legacy handling will pick this -->
<link rel="icon" sizes="16x16" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-16x16.png" %}">
<!-- Apple iOS Safari settings --> <!-- Promise polyfill for IE11 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <script src="{% static 'js/novnc/vendor/promise.js' %}"></script>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<!-- Home Screen Icons (favourites and bookmarks use the normal icons) -->
<link rel="apple-touch-icon" sizes="60x60" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-60x60.png" %}">
<link rel="apple-touch-icon" sizes="76x76" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-76x76.png" %}">
<link rel="apple-touch-icon" sizes="120x120" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-120x120.png" %}">
<link rel="apple-touch-icon" sizes="152x152" type="image/png" href="{% static "js/novnc/app/images/icons/novnc-152x152.png" %}">
<!-- Stylesheets --> <!-- ES2015/ES6 modules polyfill -->
<link rel="stylesheet" href="{% static "js/novnc/app/styles/lite.css" %}"> <script nomodule
src="{% static 'js/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js' %}"></script>
<!-- <!-- actual script modules -->
<script type='text/javascript' <script type="module" crossorigin="anonymous">
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script> // RFB holds the API to connect and communicate with a VNC server
--> import RFB from '{% static "js/novnc/core/rfb.js" %}';
<!-- promise polyfills promises for IE11 --> let rfb;
<script src="{% static "js/novnc/vendor/promise.js" %}"></script> let desktopName;
<!-- ES2015/ES6 modules polyfill -->
<script type="module"> window._noVNC_has_module_support = true;</script>
<script>
window.addEventListener("load", function() {
if (window._noVNC_has_module_support) return;
var loader = document.createElement("script");
loader.src = "{% static "js/novnc/vendor/browser-es-module-loader/dist/browser-es-module-loader.js" %}";
document.head.appendChild(loader);
});
</script>
<!-- actual script modules --> // When this function is called we have
<script type="module" crossorigin="anonymous"> // successfully connected to a server
// Load supporting scripts function connectedToServer(e) {
import * as WebUtil from '{% static "js/novnc/app/webutil.js" %}'; status("Connected to " + desktopName);
import RFB from '{% static "js/novnc/core/rfb.js" %}'; }
var rfb; // This function is called when we are disconnected
var desktopName; function disconnectedFromServer(e) {
if (e.detail.clean) {
function updateDesktopName(e) { status("Disconnected");
desktopName = e.detail.name; } else {
status("Something went wrong, connection is closed");
} }
function credentials(e) { }
var html;
var form = document.createElement('form'); // When this function is called, the server requires
form.innerHTML = '<label></label>'; // credentials to authenticate
form.innerHTML += '<input type=password size=10 id="password_input">'; function credentialsAreRequired(e) {
form.onsubmit = setPassword; const password = prompt("Password Required:");
rfb.sendCredentials({ password: password });
}
// bypass status() because it sets text content // When this function is called we have received
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_warn"); // a desktop name from the server
document.getElementById('noVNC_status').innerHTML = ''; function updateDesktopName(e) {
document.getElementById('noVNC_status').appendChild(form); desktopName = e.detail.name;
document.getElementById('noVNC_status').querySelector('label').textContent = 'Password Required: '; }
}
function setPassword() { // Since most operating systems will catch Ctrl+Alt+Del
rfb.sendCredentials({ password: document.getElementById('password_input').value }); // before they get a chance to be intercepted by the browser,
return false; // we provide a way to emulate this key sequence.
} function sendCtrlAltDel() {
function fullscreen() { rfb.sendCtrlAltDel();
if (document.fullscreenElement || // alternative standard method return false;
document.mozFullScreenElement || // currently working methods }
document.webkitFullscreenElement ||
document.msFullscreenElement) { function fullscreen() {
if (document.exitFullscreen) { if (document.fullscreenElement || // alternative standard method
document.exitFullscreen(); document.mozFullScreenElement || // currently working methods
} else if (document.mozCancelFullScreen) { document.webkitFullscreenElement ||
document.mozCancelFullScreen(); document.msFullscreenElement) {
} else if (document.webkitExitFullscreen) { if (document.exitFullscreen) {
document.webkitExitFullscreen(); document.exitFullscreen();
} else if (document.msExitFullscreen) { } else if (document.mozCancelFullScreen) {
document.msExitFullscreen(); document.mozCancelFullScreen();
} } else if (document.webkitExitFullscreen) {
} else { document.webkitExitFullscreen();
if (document.documentElement.requestFullscreen) { } else if (document.msExitFullscreen) {
document.documentElement.requestFullscreen(); document.msExitFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
} else if (document.body.msRequestFullscreen) {
document.body.msRequestFullscreen();
}
} }
return false; } else {
} if (document.documentElement.requestFullscreen) {
function sendCtrlAltFN(f) { document.documentElement.requestFullscreen();
rfb.sendCtrlAltFN(f); } else if (document.documentElement.mozRequestFullScreen) {
return false; document.documentElement.mozRequestFullScreen();
} } else if (document.documentElement.webkitRequestFullscreen) {
function sendCtrlAltDel() { document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
rfb.sendCtrlAltDel(); } else if (document.body.msRequestFullscreen) {
return false; document.body.msRequestFullscreen();
}
function machineShutdown() {
rfb.machineShutdown();
return false;
}
function machineReboot() {
rfb.machineReboot();
return false;
}
function machineReset() {
rfb.machineReset();
return false;
}
function status(text, level) {
switch (level) {
case 'normal':
case 'warn':
case 'error':
break;
default:
level = "warn";
}
document.getElementById('noVNC_status_bar').className = "noVNC_status_" + level;
document.getElementById('noVNC_status').textContent = text;
}
function connected(e) {
document.getElementById('sendCtrlAltDelButton').disabled = false;
if (WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:"))) {
status("Connected (encrypted) to " + desktopName, "normal");
} else {
status("Connected (unencrypted) to " + desktopName, "normal");
} }
} }
return false;
}
function sendCtrlAltFN(f) {
rfb.sendCtrlAltFN(f);
return false;
}
function machineShutdown() {
rfb.machineShutdown();
return false;
}
function machineReboot() {
rfb.machineReboot();
return false;
}
function machineReset() {
rfb.machineReset();
return false;
}
function disconnected(e) { // Show a status text in the top bar
document.getElementById('sendCtrlAltDelButton').disabled = true; function status(text) {
updatePowerButtons(); document.getElementById('noVNC_status').textContent = text;
if (e.detail.clean) { }
status("Disconnected", "normal");
} else { // This function extracts the value of one variable from the
status("Something went wrong, connection is closed", "error"); // query string. If the variable isn't defined in the URL
} // it returns the default value instead.
function readQueryVariable(name, defaultValue) {
// A URL with a query parameter can look like this:
// https://www.example.com?myqueryparam=myvalue
//
// Note that we use location.href instead of location.search
// because Firefox < 53 has a bug w.r.t location.search
const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
match = document.location.href.match(re);
if (match) {
// We have to decode the URL since want the cleartext value
return decodeURIComponent(match[1]);
} }
function updatePowerButtons() { return defaultValue;
var powerbuttons; }
powerbuttons = document.getElementById('noVNC_power_buttons');
if (rfb.capabilities.power) {
powerbuttons.className= "noVNC_shown";
} else {
powerbuttons.className = "noVNC_hidden";
}
}
document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel; document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
document.getElementById('machineShutdownButton').onclick = machineShutdown; document.getElementById('machineShutdownButton').onclick = machineShutdown;
document.getElementById('machineRebootButton').onclick = machineReboot; document.getElementById('machineRebootButton').onclick = machineReboot;
document.getElementById('machineResetButton').onclick = machineReset; document.getElementById('machineResetButton').onclick = machineReset;
document.getElementById('fullscreen_button').onclick = fullscreen; document.getElementById('fullscreen_button').onclick = fullscreen;
document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel); document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);}); document.getElementById('ctrlaltf1').addEventListener('click', function () { sendCtrlAltFN(0); });
document.getElementById('ctrlaltf2').addEventListener('click', function(){sendCtrlAltFN(1);}); document.getElementById('ctrlaltf2').addEventListener('click', function () { sendCtrlAltFN(1); });
document.getElementById('ctrlaltf3').addEventListener('click', function(){sendCtrlAltFN(2);}); document.getElementById('ctrlaltf3').addEventListener('click', function () { sendCtrlAltFN(2); });
document.getElementById('ctrlaltf4').addEventListener('click', function(){sendCtrlAltFN(3);}); document.getElementById('ctrlaltf4').addEventListener('click', function () { sendCtrlAltFN(3); });
document.getElementById('ctrlaltf5').addEventListener('click', function(){sendCtrlAltFN(4);}); document.getElementById('ctrlaltf5').addEventListener('click', function () { sendCtrlAltFN(4); });
document.getElementById('ctrlaltf6').addEventListener('click', function(){sendCtrlAltFN(5);}); document.getElementById('ctrlaltf6').addEventListener('click', function () { sendCtrlAltFN(5); });
document.getElementById('ctrlaltf7').addEventListener('click', function(){sendCtrlAltFN(6);}); document.getElementById('ctrlaltf7').addEventListener('click', function () { sendCtrlAltFN(6); });
document.getElementById('ctrlaltf8').addEventListener('click', function(){sendCtrlAltFN(7);}); document.getElementById('ctrlaltf8').addEventListener('click', function () { sendCtrlAltFN(7); });
document.getElementById('ctrlaltf9').addEventListener('click', function(){sendCtrlAltFN(8);}); document.getElementById('ctrlaltf9').addEventListener('click', function () { sendCtrlAltFN(8); });
document.getElementById('ctrlaltf10').addEventListener('click', function(){sendCtrlAltFN(9);}); document.getElementById('ctrlaltf10').addEventListener('click', function () { sendCtrlAltFN(9); });
document.getElementById('ctrlaltf11').addEventListener('click', function(){sendCtrlAltFN(10);}); document.getElementById('ctrlaltf11').addEventListener('click', function () { sendCtrlAltFN(10); });
document.getElementById('ctrlaltf12').addEventListener('click', function(){sendCtrlAltFN(11);}); document.getElementById('ctrlaltf12').addEventListener('click', function () { sendCtrlAltFN(11); });
WebUtil.init_logging(WebUtil.getConfigVar('logging', 'warn')); // Read parameters specified in the URL query string
document.title = WebUtil.getConfigVar('title', 'noVNC'); // By default, use the host and port of server that served this file
// By default, use the host and port of server that served this file const host = readQueryVariable('host', '{{ ws_host }}');
//var host = WebUtil.getConfigVar('host', window.location.hostname); let port = readQueryVariable('port', '{{ ws_port }}');
//var port = WebUtil.getConfigVar('port', window.location.port); const password = readQueryVariable('password');
var host = '{{ ws_host }}'; const path = readQueryVariable('path', 'websockify');
var port = '{{ ws_port }}';
// if port == 80 (or 443) then it won't be present and should be
// set manually
if (!port) {
if (window.location.protocol.substring(0,5) == 'https') {
port = 443;
}
else if (window.location.protocol.substring(0,4) == 'http') {
port = 80;
}
}
//var password = WebUtil.getConfigVar('password', ''); // | | | | | |
var password = '{{ console_passwd }}'; // | | | Connect | | |
// v v v v v v
var path = WebUtil.getConfigVar('path', 'websockify'); status("Connecting");
// If a token variable is passed in, set the parameter in a cookie. // Build the websocket URL used to connect
// This is used by nova-novncproxy. let url;
var token = WebUtil.getConfigVar('token', null); if (window.location.protocol === "https:") {
if (token) { url = 'wss';
// if token is already present in the path we should use it } else {
path = WebUtil.injectParamIfMissing(path, "token", token); url = 'ws';
}
url += '://' + host;
if (port) {
url += ':' + port;
}
url += '/' + path;
WebUtil.createCookie('token', token, 1) // Creating a new RFB object will start a new connection
} rfb = new RFB(document.getElementById('noVNC_container'), url,
{ credentials: { password: password } });
(function() { // Add listeners to important events from the RFB module
rfb.addEventListener("connect", connectedToServer);
rfb.addEventListener("disconnect", disconnectedFromServer);
rfb.addEventListener("credentialsrequired", credentialsAreRequired);
rfb.addEventListener("desktopname", updateDesktopName);
rfb.addEventListener("capabilities", function () { updatePowerButtons(); });
status("Connecting", "normal"); // Set parameters that can be changed on an active connection
rfb.viewOnly = readQueryVariable('view_only', {{ view_only }});
rfb.scaleViewport = readQueryVariable('scale', {{ scale }});
rfb.resizeSession = readQueryVariable('resize', {{ resize_session }});
rfb.clipViewport = readQueryVariable('clip_viewport', {{ clip_viewport }});
if ((!host) || (!port)) { </script>
status('Must specify host and port in URL', 'error');
}
var url;
if (WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:"))) {
url = 'wss';
} else {
url = 'ws';
}
url += '://' + host;
if(port) {
url += ':' + port;
}
url += '/' + path;
//rfb = new RFB(document.body, url,
// { repeaterID: WebUtil.getConfigVar('repeaterID', ''),
// shared: WebUtil.getConfigVar('shared', true),
// credentials: { password: password } });
rfb = new RFB(document.getElementById('noVNC_container'), url,
{ repeaterID: WebUtil.getConfigVar('repeaterID', ''),
shared: WebUtil.getConfigVar('shared', true),
credentials: { password: password } });
rfb.viewOnly = WebUtil.getConfigVar('view_only', false);
rfb.addEventListener("connect", connected);
rfb.addEventListener("disconnect", disconnected);
rfb.addEventListener("capabilities", function () { updatePowerButtons(); });
rfb.addEventListener("credentialsrequired", credentials);
rfb.addEventListener("desktopname", updateDesktopName);
rfb.scaleViewport = WebUtil.getConfigVar('scale', false);
rfb.resizeSession = WebUtil.getConfigVar('resize', false);
})();
</script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div id="noVNC_status_bar"> <div id="noVNC_status_bar">
<div id="noVNC_left_dummy_elem"></div> <div id="noVNC_left_dummy_elem"></div>
<div id="noVNC_status">{% trans 'Loading' %}</div> <div id="noVNC_status">{% trans 'Loading' %}</div>
<div id="noVNC_buttons"> <div id="noVNC_buttons">
<input type="button" value="Send CtrlAltDel" id="sendCtrlAltDelButton" class="noVNC_shown"> <input type="button" value="Send CtrlAltDel" id="sendCtrlAltDelButton" class="noVNC_shown">
<span id="noVNC_power_buttons" class="noVNC_hidden"> <span id="noVNC_power_buttons" class="noVNC_hidden">
<input type=button value="Shutdown" id="machineShutdownButton"> <input type="button" value="Shutdown" id="machineShutdownButton">
<input type=button value="Reboot" id="machineRebootButton"> <input type="button" value="Reboot" id="machineRebootButton">
<input type=button value="Reset" id="machineResetButton"> <input type="button" value="Reset" id="machineResetButton">
</span> </span>
</div>
</div> </div>
<div id='noVNC_container'></div> </div>
<div id="noVNC_container">
<!-- This is where the remote screen will appear -->
</div>
{% endblock %} {% endblock %}

View file

@ -16,6 +16,10 @@ def console(request):
if request.method == 'GET': if request.method == 'GET':
token = request.GET.get('token', '') token = request.GET.get('token', '')
view_type = request.GET.get('view', 'lite') view_type = request.GET.get('view', 'lite')
view_only = request.GET.get('view_only', 0)
scale = request.GET.get('scale', 0)
resize_session = request.GET.get('resize_session', 0)
clip_viewport = request.GET.get('clip_viewport', 0)
try: try:
temptoken = token.split('-', 1) temptoken = token.split('-', 1)

View file

@ -10,7 +10,7 @@ body {
margin:0; margin:0;
background-color:#313131; background-color:#313131;
border-bottom-right-radius: 800px 600px; border-bottom-right-radius: 800px 600px;
height:100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }

View file

@ -38,8 +38,7 @@ var Meta_state = -1;
** SpiceInputsConn ** SpiceInputsConn
** Drive the Spice Inputs channel (e.g. mouse + keyboard) ** Drive the Spice Inputs channel (e.g. mouse + keyboard)
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
function SpiceInputsConn() function SpiceInputsConn() {
{
SpiceConn.apply(this, arguments); SpiceConn.apply(this, arguments);
this.mousex = undefined; this.mousex = undefined;
@ -49,26 +48,22 @@ function SpiceInputsConn()
} }
SpiceInputsConn.prototype = Object.create(SpiceConn.prototype); SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
SpiceInputsConn.prototype.process_channel_message = function(msg) SpiceInputsConn.prototype.process_channel_message = function (msg) {
{ if (msg.type == Constants.SPICE_MSG_INPUTS_INIT) {
if (msg.type == Constants.SPICE_MSG_INPUTS_INIT)
{
var inputs_init = new Messages.SpiceMsgInputsInit(msg.data); var inputs_init = new Messages.SpiceMsgInputsInit(msg.data);
this.keyboard_modifiers = inputs_init.keyboard_modifiers; this.keyboard_modifiers = inputs_init.keyboard_modifiers;
DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers); DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers);
// FIXME - We don't do anything with the keyboard modifiers... // FIXME - We don't do anything with the keyboard modifiers...
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_INPUTS_KEY_MODIFIERS) if (msg.type == Constants.SPICE_MSG_INPUTS_KEY_MODIFIERS) {
{
var key = new Messages.SpiceMsgInputsKeyModifiers(msg.data); var key = new Messages.SpiceMsgInputsKeyModifiers(msg.data);
this.keyboard_modifiers = key.keyboard_modifiers; this.keyboard_modifiers = key.keyboard_modifiers;
DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers); DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers);
// FIXME - We don't do anything with the keyboard modifiers... // FIXME - We don't do anything with the keyboard modifiers...
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_INPUTS_MOUSE_MOTION_ACK) if (msg.type == Constants.SPICE_MSG_INPUTS_MOUSE_MOTION_ACK) {
{
DEBUG > 1 && console.log("mouse motion ack"); DEBUG > 1 && console.log("mouse motion ack");
this.waiting_for_ack -= Constants.SPICE_INPUT_MOTION_ACK_BUNCH; this.waiting_for_ack -= Constants.SPICE_INPUT_MOTION_ACK_BUNCH;
return true; return true;
@ -78,35 +73,28 @@ SpiceInputsConn.prototype.process_channel_message = function(msg)
function handle_mousemove(e) function handle_mousemove(e) {
{
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
var move; var move;
if (this.sc.mouse_mode == Constants.SPICE_MOUSE_MODE_CLIENT) if (this.sc.mouse_mode == Constants.SPICE_MOUSE_MODE_CLIENT) {
{
move = new Messages.SpiceMsgcMousePosition(this.sc, e) move = new Messages.SpiceMsgcMousePosition(this.sc, e)
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_POSITION, move); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
} }
else else {
{
move = new Messages.SpiceMsgcMouseMotion(this.sc, e) move = new Messages.SpiceMsgcMouseMotion(this.sc, e)
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_MOTION, move); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
} }
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready") {
{ if (this.sc.inputs.waiting_for_ack < (2 * Constants.SPICE_INPUT_MOTION_ACK_BUNCH)) {
if (this.sc.inputs.waiting_for_ack < (2 * Constants.SPICE_INPUT_MOTION_ACK_BUNCH))
{
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
this.sc.inputs.waiting_for_ack++; this.sc.inputs.waiting_for_ack++;
} }
else else {
{
DEBUG > 0 && this.sc.log_info("Discarding mouse motion"); DEBUG > 0 && this.sc.log_info("Discarding mouse motion");
} }
} }
if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor) if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor) {
{
this.sc.cursor.spice_simulated_cursor.style.display = 'block'; this.sc.cursor.spice_simulated_cursor.style.display = 'block';
this.sc.cursor.spice_simulated_cursor.style.left = e.pageX - this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px'; this.sc.cursor.spice_simulated_cursor.style.left = e.pageX - this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px';
this.sc.cursor.spice_simulated_cursor.style.top = e.pageY - this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px'; this.sc.cursor.spice_simulated_cursor.style.top = e.pageY - this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px';
@ -115,8 +103,7 @@ function handle_mousemove(e)
} }
function handle_mousedown(e) function handle_mousedown(e) {
{
var press = new Messages.SpiceMsgcMousePress(this.sc, e) var press = new Messages.SpiceMsgcMousePress(this.sc, e)
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
@ -126,14 +113,12 @@ function handle_mousedown(e)
e.preventDefault(); e.preventDefault();
} }
function handle_contextmenu(e) function handle_contextmenu(e) {
{
e.preventDefault(); e.preventDefault();
return false; return false;
} }
function handle_mouseup(e) function handle_mouseup(e) {
{
var release = new Messages.SpiceMsgcMouseRelease(this.sc, e) var release = new Messages.SpiceMsgcMouseRelease(this.sc, e)
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_RELEASE, release); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
@ -143,8 +128,7 @@ function handle_mouseup(e)
e.preventDefault(); e.preventDefault();
} }
function handle_mousewheel(e) function handle_mousewheel(e) {
{
var press = new Messages.SpiceMsgcMousePress; var press = new Messages.SpiceMsgcMousePress;
var release = new Messages.SpiceMsgcMouseRelease; var release = new Messages.SpiceMsgcMouseRelease;
if (e.deltaY < 0) if (e.deltaY < 0)
@ -166,8 +150,7 @@ function handle_mousewheel(e)
e.preventDefault(); e.preventDefault();
} }
function handle_keydown(e) function handle_keydown(e) {
{
var key = new Messages.SpiceMsgcKeyDown(e) var key = new Messages.SpiceMsgcKeyDown(e)
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
check_and_update_modifiers(e, key.code, this.sc); check_and_update_modifiers(e, key.code, this.sc);
@ -178,8 +161,7 @@ function handle_keydown(e)
e.preventDefault(); e.preventDefault();
} }
function handle_keyup(e) function handle_keyup(e) {
{
var key = new Messages.SpiceMsgcKeyUp(e) var key = new Messages.SpiceMsgcKeyUp(e)
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
check_and_update_modifiers(e, key.code, this.sc); check_and_update_modifiers(e, key.code, this.sc);
@ -190,9 +172,8 @@ function handle_keyup(e)
e.preventDefault(); e.preventDefault();
} }
function sendCtrlAltDel(sc) function sendCtrlAltDel(sc) {
{ if (sc && sc.inputs && sc.inputs.state === "ready") {
if (sc && sc.inputs && sc.inputs.state === "ready"){
var key = new Messages.SpiceMsgcKeyDown(); var key = new Messages.SpiceMsgcKeyDown();
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
@ -205,22 +186,55 @@ function sendCtrlAltDel(sc)
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key); msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
sc.inputs.send_msg(msg); sc.inputs.send_msg(msg);
if(Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc); if (Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc);
if(Alt_state == false) update_modifier(false, KeyNames.KEY_Alt, sc); if (Alt_state == false) update_modifier(false, KeyNames.KEY_Alt, sc);
} }
} }
function update_modifier(state, code, sc) function sendCtrlAltFN(sc, f) {
{ if (sc && sc.inputs && sc.inputs.state === "ready") {
var keys_code = [
KeyNames.KEY_F1,
KeyNames.KEY_F2,
KeyNames.KEY_F3,
KeyNames.KEY_F4,
KeyNames.KEY_F5,
KeyNames.KEY_F6,
KeyNames.KEY_F7,
KeyNames.KEY_F8,
KeyNames.KEY_F9,
KeyNames.KEY_F10,
KeyNames.KEY_F11,
KeyNames.KEY_F12];
if (keys_code[f] == undefined) {
return;
}
var key = new Messages.SpiceMsgcKeyDown();
var msg = new Messages.SpiceMiniData();
update_modifier(true, KeyNames.KEY_LCtrl, sc);
update_modifier(true, KeyNames.KEY_Alt, sc);
key.code = keys_code[f];
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
sc.inputs.send_msg(msg);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
sc.inputs.send_msg(msg);
if (Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc);
if (Alt_state == false) update_modifier(false, KeyNames.KEY_Alt, sc);
}
}
function update_modifier(state, code, sc) {
var msg = new Messages.SpiceMiniData(); var msg = new Messages.SpiceMiniData();
if (!state) if (!state) {
{
var key = new Messages.SpiceMsgcKeyUp() var key = new Messages.SpiceMsgcKeyUp()
key.code =(0x80|code); key.code = (0x80 | code);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key); msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
} }
else else {
{
var key = new Messages.SpiceMsgcKeyDown() var key = new Messages.SpiceMsgcKeyDown()
key.code = code; key.code = code;
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key); msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
@ -229,10 +243,8 @@ function update_modifier(state, code, sc)
sc.inputs.send_msg(msg); sc.inputs.send_msg(msg);
} }
function check_and_update_modifiers(e, code, sc) function check_and_update_modifiers(e, code, sc) {
{ if (Shift_state === -1) {
if (Shift_state === -1)
{
Shift_state = e.shiftKey; Shift_state = e.shiftKey;
Ctrl_state = e.ctrlKey; Ctrl_state = e.ctrlKey;
Alt_state = e.altKey; Alt_state = e.altKey;
@ -247,37 +259,32 @@ function check_and_update_modifiers(e, code, sc)
Ctrl_state = true; Ctrl_state = true;
else if (code === 0xE0B5) else if (code === 0xE0B5)
Meta_state = true; Meta_state = true;
else if (code === (0x80|KeyNames.KEY_ShiftL)) else if (code === (0x80 | KeyNames.KEY_ShiftL))
Shift_state = false; Shift_state = false;
else if (code === (0x80|KeyNames.KEY_Alt)) else if (code === (0x80 | KeyNames.KEY_Alt))
Alt_state = false; Alt_state = false;
else if (code === (0x80|KeyNames.KEY_LCtrl)) else if (code === (0x80 | KeyNames.KEY_LCtrl))
Ctrl_state = false; Ctrl_state = false;
else if (code === (0x80|0xE0B5)) else if (code === (0x80 | 0xE0B5))
Meta_state = false; Meta_state = false;
if (sc && sc.inputs && sc.inputs.state === "ready") if (sc && sc.inputs && sc.inputs.state === "ready") {
{ if (Shift_state != e.shiftKey) {
if (Shift_state != e.shiftKey)
{
console.log("Shift state out of sync"); console.log("Shift state out of sync");
update_modifier(e.shiftKey, KeyNames.KEY_ShiftL, sc); update_modifier(e.shiftKey, KeyNames.KEY_ShiftL, sc);
Shift_state = e.shiftKey; Shift_state = e.shiftKey;
} }
if (Alt_state != e.altKey) if (Alt_state != e.altKey) {
{
console.log("Alt state out of sync"); console.log("Alt state out of sync");
update_modifier(e.altKey, KeyNames.KEY_Alt, sc); update_modifier(e.altKey, KeyNames.KEY_Alt, sc);
Alt_state = e.altKey; Alt_state = e.altKey;
} }
if (Ctrl_state != e.ctrlKey) if (Ctrl_state != e.ctrlKey) {
{
console.log("Ctrl state out of sync"); console.log("Ctrl state out of sync");
update_modifier(e.ctrlKey, KeyNames.KEY_LCtrl, sc); update_modifier(e.ctrlKey, KeyNames.KEY_LCtrl, sc);
Ctrl_state = e.ctrlKey; Ctrl_state = e.ctrlKey;
} }
if (Meta_state != e.metaKey) if (Meta_state != e.metaKey) {
{
console.log("Meta state out of sync"); console.log("Meta state out of sync");
update_modifier(e.metaKey, 0xE0B5, sc); update_modifier(e.metaKey, 0xE0B5, sc);
Meta_state = e.metaKey; Meta_state = e.metaKey;
@ -286,13 +293,14 @@ function check_and_update_modifiers(e, code, sc)
} }
export { export {
SpiceInputsConn, SpiceInputsConn,
handle_mousemove, handle_mousemove,
handle_mousedown, handle_mousedown,
handle_contextmenu, handle_contextmenu,
handle_mouseup, handle_mouseup,
handle_mousewheel, handle_mousewheel,
handle_keydown, handle_keydown,
handle_keyup, handle_keyup,
sendCtrlAltDel, sendCtrlAltDel,
sendCtrlAltFN
}; };

View file

@ -24,7 +24,7 @@ import { SpiceCursorConn } from './cursor.js';
import { SpiceConn } from './spiceconn.js'; import { SpiceConn } from './spiceconn.js';
import { DEBUG } from './utils.js'; import { DEBUG } from './utils.js';
import { SpiceFileXferTask } from './filexfer.js'; import { SpiceFileXferTask } from './filexfer.js';
import { SpiceInputsConn, sendCtrlAltDel } from './inputs.js'; import { SpiceInputsConn, sendCtrlAltDel, sendCtrlAltFN } from './inputs.js';
import { SpiceDisplayConn } from './display.js'; import { SpiceDisplayConn } from './display.js';
import { SpicePlaybackConn } from './playback.js'; import { SpicePlaybackConn } from './playback.js';
import { SpicePortConn } from './port.js'; import { SpicePortConn } from './port.js';
@ -63,8 +63,7 @@ import { resize_helper, handle_resize } from './resize.js';
** browser, including WebSocket and WebSocket.binaryType == arraybuffer ** browser, including WebSocket and WebSocket.binaryType == arraybuffer
** **
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
function SpiceMainConn() function SpiceMainConn() {
{
if (typeof WebSocket === "undefined") if (typeof WebSocket === "undefined")
throw new Error("WebSocket unavailable. You need to use a different browser."); throw new Error("WebSocket unavailable. You need to use a different browser.");
@ -78,47 +77,42 @@ function SpiceMainConn()
} }
SpiceMainConn.prototype = Object.create(SpiceConn.prototype); SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
SpiceMainConn.prototype.process_channel_message = function(msg) SpiceMainConn.prototype.process_channel_message = function (msg) {
{ if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN) {
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN)
{
this.known_unimplemented(msg.type, "Main Migrate Begin"); this.known_unimplemented(msg.type, "Main Migrate Begin");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_CANCEL) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_CANCEL) {
{
this.known_unimplemented(msg.type, "Main Migrate Cancel"); this.known_unimplemented(msg.type, "Main Migrate Cancel");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_INIT) if (msg.type == Constants.SPICE_MSG_MAIN_INIT) {
{
this.log_info("Connected to " + this.ws.url); this.log_info("Connected to " + this.ws.url);
this.report_success("Connected") this.report_success("Connected")
this.main_init = new Messages.SpiceMsgMainInit(msg.data); this.main_init = new Messages.SpiceMsgMainInit(msg.data);
this.connection_id = this.main_init.session_id; this.connection_id = this.main_init.session_id;
this.agent_tokens = this.main_init.agent_tokens; this.agent_tokens = this.main_init.agent_tokens;
if (DEBUG > 0) if (DEBUG > 0) {
{
// FIXME - there is a lot here we don't handle; mouse modes, agent, // FIXME - there is a lot here we don't handle; mouse modes, agent,
// ram_hint, multi_media_time // ram_hint, multi_media_time
this.log_info("session id " + this.main_init.session_id + this.log_info("session id " + this.main_init.session_id +
" ; display_channels_hint " + this.main_init.display_channels_hint + " ; display_channels_hint " + this.main_init.display_channels_hint +
" ; supported_mouse_modes " + this.main_init.supported_mouse_modes + " ; supported_mouse_modes " + this.main_init.supported_mouse_modes +
" ; current_mouse_mode " + this.main_init.current_mouse_mode + " ; current_mouse_mode " + this.main_init.current_mouse_mode +
" ; agent_connected " + this.main_init.agent_connected + " ; agent_connected " + this.main_init.agent_connected +
" ; agent_tokens " + this.main_init.agent_tokens + " ; agent_tokens " + this.main_init.agent_tokens +
" ; multi_media_time " + this.main_init.multi_media_time + " ; multi_media_time " + this.main_init.multi_media_time +
" ; ram_hint " + this.main_init.ram_hint); " ; ram_hint " + this.main_init.ram_hint);
} }
this.our_mm_time = Date.now(); this.our_mm_time = Date.now();
this.mm_time = this.main_init.multi_media_time; this.mm_time = this.main_init.multi_media_time;
this.handle_mouse_mode(this.main_init.current_mouse_mode, this.handle_mouse_mode(this.main_init.current_mouse_mode,
this.main_init.supported_mouse_modes); this.main_init.supported_mouse_modes);
if (this.main_init.agent_connected) if (this.main_init.agent_connected)
this.connect_agent(); this.connect_agent();
@ -130,45 +124,39 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MOUSE_MODE) if (msg.type == Constants.SPICE_MSG_MAIN_MOUSE_MODE) {
{
var mode = new Messages.SpiceMsgMainMouseMode(msg.data); var mode = new Messages.SpiceMsgMainMouseMode(msg.data);
DEBUG > 0 && this.log_info("Mouse supported modes " + mode.supported_modes + "; current " + mode.current_mode); DEBUG > 0 && this.log_info("Mouse supported modes " + mode.supported_modes + "; current " + mode.current_mode);
this.handle_mouse_mode(mode.current_mode, mode.supported_modes); this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MULTI_MEDIA_TIME) if (msg.type == Constants.SPICE_MSG_MAIN_MULTI_MEDIA_TIME) {
{
this.known_unimplemented(msg.type, "Main Multi Media Time"); this.known_unimplemented(msg.type, "Main Multi Media Time");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_CHANNELS_LIST) if (msg.type == Constants.SPICE_MSG_MAIN_CHANNELS_LIST) {
{
var i; var i;
var chans; var chans;
DEBUG > 0 && console.log("channels"); DEBUG > 0 && console.log("channels");
chans = new Messages.SpiceMsgChannels(msg.data); chans = new Messages.SpiceMsgChannels(msg.data);
for (i = 0; i < chans.channels.length; i++) for (i = 0; i < chans.channels.length; i++) {
{
var conn = { var conn = {
uri: this.ws.url, uri: this.ws.url,
parent: this, parent: this,
connection_id : this.connection_id, connection_id: this.connection_id,
type : chans.channels[i].type, type: chans.channels[i].type,
chan_id : chans.channels[i].id chan_id: chans.channels[i].id
}; };
if (chans.channels[i].type == Constants.SPICE_CHANNEL_DISPLAY) if (chans.channels[i].type == Constants.SPICE_CHANNEL_DISPLAY) {
{
if (chans.channels[i].id == 0) { if (chans.channels[i].id == 0) {
this.display = new SpiceDisplayConn(conn); this.display = new SpiceDisplayConn(conn);
} else { } else {
this.log_warn("The spice-html5 client does not handle multiple heads."); this.log_warn("The spice-html5 client does not handle multiple heads.");
} }
} }
else if (chans.channels[i].type == Constants.SPICE_CHANNEL_INPUTS) else if (chans.channels[i].type == Constants.SPICE_CHANNEL_INPUTS) {
{
this.inputs = new SpiceInputsConn(conn); this.inputs = new SpiceInputsConn(conn);
this.inputs.mouse_mode = this.mouse_mode; this.inputs.mouse_mode = this.mouse_mode;
} }
@ -178,9 +166,8 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
this.cursor = new SpicePlaybackConn(conn); this.cursor = new SpicePlaybackConn(conn);
else if (chans.channels[i].type == Constants.SPICE_CHANNEL_PORT) else if (chans.channels[i].type == Constants.SPICE_CHANNEL_PORT)
this.ports.push(new SpicePortConn(conn)); this.ports.push(new SpicePortConn(conn));
else else {
{ if (!("extra_channels" in this))
if (! ("extra_channels" in this))
this.extra_channels = []; this.extra_channels = [];
this.extra_channels[i] = new SpiceConn(conn); this.extra_channels[i] = new SpiceConn(conn);
this.log_err("Channel type " + this.extra_channels[i].channel_type() + " not implemented"); this.log_err("Channel type " + this.extra_channels[i].channel_type() + " not implemented");
@ -191,29 +178,25 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED) {
{
this.connect_agent(); this.connect_agent();
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS) {
{
var connected_tokens = new Messages.SpiceMsgMainAgentTokens(msg.data); var connected_tokens = new Messages.SpiceMsgMainAgentTokens(msg.data);
this.agent_tokens = connected_tokens.num_tokens; this.agent_tokens = connected_tokens.num_tokens;
this.connect_agent(); this.connect_agent();
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_TOKEN) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_TOKEN) {
{
var remaining_tokens, tokens = new Messages.SpiceMsgMainAgentTokens(msg.data); var remaining_tokens, tokens = new Messages.SpiceMsgMainAgentTokens(msg.data);
this.agent_tokens += tokens.num_tokens; this.agent_tokens += tokens.num_tokens;
this.send_agent_message_queue(); this.send_agent_message_queue();
remaining_tokens = this.agent_tokens; remaining_tokens = this.agent_tokens;
while (remaining_tokens > 0 && this.file_xfer_read_queue.length > 0) while (remaining_tokens > 0 && this.file_xfer_read_queue.length > 0) {
{
var xfer_task = this.file_xfer_read_queue.shift(); var xfer_task = this.file_xfer_read_queue.shift();
this.file_xfer_read(xfer_task, xfer_task.read_bytes); this.file_xfer_read(xfer_task, xfer_task.read_bytes);
remaining_tokens--; remaining_tokens--;
@ -221,24 +204,20 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DISCONNECTED) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DISCONNECTED) {
{
this.agent_connected = false; this.agent_connected = false;
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DATA) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DATA) {
{
var agent_data = new Messages.SpiceMsgMainAgentData(msg.data); var agent_data = new Messages.SpiceMsgMainAgentData(msg.data);
if (agent_data.type == Constants.VD_AGENT_ANNOUNCE_CAPABILITIES) if (agent_data.type == Constants.VD_AGENT_ANNOUNCE_CAPABILITIES) {
{
var agent_caps = new Messages.VDAgentAnnounceCapabilities(agent_data.data); var agent_caps = new Messages.VDAgentAnnounceCapabilities(agent_data.data);
if (agent_caps.request) if (agent_caps.request)
this.announce_agent_capabilities(0); this.announce_agent_capabilities(0);
return true; return true;
} }
else if (agent_data.type == Constants.VD_AGENT_FILE_XFER_STATUS) else if (agent_data.type == Constants.VD_AGENT_FILE_XFER_STATUS) {
{
this.handle_file_xfer_status(new Messages.VDAgentFileXferStatusMessage(agent_data.data)); this.handle_file_xfer_status(new Messages.VDAgentFileXferStatusMessage(agent_data.data));
return true; return true;
} }
@ -246,44 +225,37 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return false; return false;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST) {
{
this.known_unimplemented(msg.type, "Main Migrate Switch Host"); this.known_unimplemented(msg.type, "Main Migrate Switch Host");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_END) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_END) {
{
this.known_unimplemented(msg.type, "Main Migrate End"); this.known_unimplemented(msg.type, "Main Migrate End");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_NAME) if (msg.type == Constants.SPICE_MSG_MAIN_NAME) {
{
this.known_unimplemented(msg.type, "Main Name"); this.known_unimplemented(msg.type, "Main Name");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_UUID) if (msg.type == Constants.SPICE_MSG_MAIN_UUID) {
{
this.known_unimplemented(msg.type, "Main UUID"); this.known_unimplemented(msg.type, "Main UUID");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS) {
{
this.known_unimplemented(msg.type, "Main Migrate Begin Seamless"); this.known_unimplemented(msg.type, "Main Migrate Begin Seamless");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK) {
{
this.known_unimplemented(msg.type, "Main Migrate Dst Seamless ACK"); this.known_unimplemented(msg.type, "Main Migrate Dst Seamless ACK");
return true; return true;
} }
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK) {
{
this.known_unimplemented(msg.type, "Main Migrate Dst Seamless NACK"); this.known_unimplemented(msg.type, "Main Migrate Dst Seamless NACK");
return true; return true;
} }
@ -291,24 +263,20 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return false; return false;
} }
SpiceMainConn.prototype.stop = function(msg) SpiceMainConn.prototype.stop = function (msg) {
{
this.state = "closing"; this.state = "closing";
if (this.inputs) if (this.inputs) {
{
this.inputs.cleanup(); this.inputs.cleanup();
this.inputs = undefined; this.inputs = undefined;
} }
if (this.cursor) if (this.cursor) {
{
this.cursor.cleanup(); this.cursor.cleanup();
this.cursor = undefined; this.cursor = undefined;
} }
if (this.display) if (this.display) {
{
this.display.cleanup(); this.display.cleanup();
this.display.destroy_surfaces(); this.display.destroy_surfaces();
this.display = undefined; this.display = undefined;
@ -322,30 +290,26 @@ SpiceMainConn.prototype.stop = function(msg)
this.extra_channels = undefined; this.extra_channels = undefined;
} }
SpiceMainConn.prototype.send_agent_message_queue = function(message) SpiceMainConn.prototype.send_agent_message_queue = function (message) {
{
if (!this.agent_connected) if (!this.agent_connected)
return; return;
if (message) if (message)
this.agent_msg_queue.push(message); this.agent_msg_queue.push(message);
while (this.agent_tokens > 0 && this.agent_msg_queue.length > 0) while (this.agent_tokens > 0 && this.agent_msg_queue.length > 0) {
{
var mr = this.agent_msg_queue.shift(); var mr = this.agent_msg_queue.shift();
this.send_msg(mr); this.send_msg(mr);
this.agent_tokens--; this.agent_tokens--;
} }
} }
SpiceMainConn.prototype.send_agent_message = function(type, message) SpiceMainConn.prototype.send_agent_message = function (type, message) {
{
var agent_data = new Messages.SpiceMsgcMainAgentData(type, message); var agent_data = new Messages.SpiceMsgcMainAgentData(type, message);
var sb = 0, maxsize = Constants.VD_AGENT_MAX_DATA_SIZE - Messages.SpiceMiniData.prototype.buffer_size(); var sb = 0, maxsize = Constants.VD_AGENT_MAX_DATA_SIZE - Messages.SpiceMiniData.prototype.buffer_size();
var data = new ArrayBuffer(agent_data.buffer_size()); var data = new ArrayBuffer(agent_data.buffer_size());
agent_data.to_buffer(data); agent_data.to_buffer(data);
while (sb < agent_data.buffer_size()) while (sb < agent_data.buffer_size()) {
{
var eb = Math.min(sb + maxsize, agent_data.buffer_size()); var eb = Math.min(sb + maxsize, agent_data.buffer_size());
var mr = new Messages.SpiceMiniData(); var mr = new Messages.SpiceMiniData();
mr.type = Constants.SPICE_MSGC_MAIN_AGENT_DATA; mr.type = Constants.SPICE_MSGC_MAIN_AGENT_DATA;
@ -356,22 +320,19 @@ SpiceMainConn.prototype.send_agent_message = function(type, message)
} }
} }
SpiceMainConn.prototype.announce_agent_capabilities = function(request) SpiceMainConn.prototype.announce_agent_capabilities = function (request) {
{
var caps = new Messages.VDAgentAnnounceCapabilities(request, (1 << Constants.VD_AGENT_CAP_MOUSE_STATE) | var caps = new Messages.VDAgentAnnounceCapabilities(request, (1 << Constants.VD_AGENT_CAP_MOUSE_STATE) |
(1 << Constants.VD_AGENT_CAP_MONITORS_CONFIG) | (1 << Constants.VD_AGENT_CAP_MONITORS_CONFIG) |
(1 << Constants.VD_AGENT_CAP_REPLY)); (1 << Constants.VD_AGENT_CAP_REPLY));
this.send_agent_message(Constants.VD_AGENT_ANNOUNCE_CAPABILITIES, caps); this.send_agent_message(Constants.VD_AGENT_ANNOUNCE_CAPABILITIES, caps);
} }
SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y) SpiceMainConn.prototype.resize_window = function (flags, width, height, depth, x, y) {
{
var monitors_config = new Messages.VDAgentMonitorsConfig(flags, width, height, depth, x, y); var monitors_config = new Messages.VDAgentMonitorsConfig(flags, width, height, depth, x, y);
this.send_agent_message(Constants.VD_AGENT_MONITORS_CONFIG, monitors_config); this.send_agent_message(Constants.VD_AGENT_MONITORS_CONFIG, monitors_config);
} }
SpiceMainConn.prototype.file_xfer_start = function(file) SpiceMainConn.prototype.file_xfer_start = function (file) {
{
var task_id, xfer_start, task; var task_id, xfer_start, task;
task_id = this.file_xfer_task_id++; task_id = this.file_xfer_task_id++;
@ -382,16 +343,13 @@ SpiceMainConn.prototype.file_xfer_start = function(file)
this.send_agent_message(Constants.VD_AGENT_FILE_XFER_START, xfer_start); this.send_agent_message(Constants.VD_AGENT_FILE_XFER_START, xfer_start);
} }
SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status) SpiceMainConn.prototype.handle_file_xfer_status = function (file_xfer_status) {
{
var xfer_error, xfer_task; var xfer_error, xfer_task;
if (!this.file_xfer_tasks[file_xfer_status.id]) if (!this.file_xfer_tasks[file_xfer_status.id]) {
{
return; return;
} }
xfer_task = this.file_xfer_tasks[file_xfer_status.id]; xfer_task = this.file_xfer_tasks[file_xfer_status.id];
switch (file_xfer_status.result) switch (file_xfer_status.result) {
{
case Constants.VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA: case Constants.VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
this.file_xfer_read(xfer_task); this.file_xfer_read(xfer_task);
return; return;
@ -411,8 +369,7 @@ SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
this.file_xfer_completed(xfer_task, xfer_error) this.file_xfer_completed(xfer_task, xfer_error)
} }
SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte) SpiceMainConn.prototype.file_xfer_read = function (file_xfer_task, start_byte) {
{
var FILE_XFER_CHUNK_SIZE = 32 * Constants.VD_AGENT_MAX_DATA_SIZE; var FILE_XFER_CHUNK_SIZE = 32 * Constants.VD_AGENT_MAX_DATA_SIZE;
var _this = this; var _this = this;
var sb, eb; var sb, eb;
@ -420,36 +377,32 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
if (!file_xfer_task || if (!file_xfer_task ||
!this.file_xfer_tasks[file_xfer_task.id] || !this.file_xfer_tasks[file_xfer_task.id] ||
(start_byte > 0 && start_byte == file_xfer_task.file.size)) (start_byte > 0 && start_byte == file_xfer_task.file.size)) {
{
return; return;
} }
if (file_xfer_task.cancelled) if (file_xfer_task.cancelled) {
{
var xfer_status = new Messages.VDAgentFileXferStatusMessage(file_xfer_task.id, var xfer_status = new Messages.VDAgentFileXferStatusMessage(file_xfer_task.id,
Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED); Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED);
this.send_agent_message(Constants.VD_AGENT_FILE_XFER_STATUS, xfer_status); this.send_agent_message(Constants.VD_AGENT_FILE_XFER_STATUS, xfer_status);
delete this.file_xfer_tasks[file_xfer_task.id]; delete this.file_xfer_tasks[file_xfer_task.id];
return; return;
} }
sb = start_byte || 0, sb = start_byte || 0,
eb = Math.min(sb + FILE_XFER_CHUNK_SIZE, file_xfer_task.file.size); eb = Math.min(sb + FILE_XFER_CHUNK_SIZE, file_xfer_task.file.size);
if (!this.agent_tokens) if (!this.agent_tokens) {
{
file_xfer_task.read_bytes = sb; file_xfer_task.read_bytes = sb;
this.file_xfer_read_queue.push(file_xfer_task); this.file_xfer_read_queue.push(file_xfer_task);
return; return;
} }
reader = new FileReader(); reader = new FileReader();
reader.onload = function(e) reader.onload = function (e) {
{
var xfer_data = new Messages.VDAgentFileXferDataMessage(file_xfer_task.id, var xfer_data = new Messages.VDAgentFileXferDataMessage(file_xfer_task.id,
e.target.result.byteLength, e.target.result.byteLength,
e.target.result); e.target.result);
_this.send_agent_message(Constants.VD_AGENT_FILE_XFER_DATA, xfer_data); _this.send_agent_message(Constants.VD_AGENT_FILE_XFER_DATA, xfer_data);
_this.file_xfer_read(file_xfer_task, eb); _this.file_xfer_read(file_xfer_task, eb);
file_xfer_task.update_progressbar(eb); file_xfer_task.update_progressbar(eb);
@ -459,20 +412,18 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
reader.readAsArrayBuffer(slice); reader.readAsArrayBuffer(slice);
} }
SpiceMainConn.prototype.file_xfer_completed = function(file_xfer_task, error) SpiceMainConn.prototype.file_xfer_completed = function (file_xfer_task, error) {
{
if (error) if (error)
this.log_err(error); this.log_err(error);
else else
this.log_info("transfer of '" + file_xfer_task.file.name +"' was successful"); this.log_info("transfer of '" + file_xfer_task.file.name + "' was successful");
file_xfer_task.remove_progressbar(); file_xfer_task.remove_progressbar();
delete this.file_xfer_tasks[file_xfer_task.id]; delete this.file_xfer_tasks[file_xfer_task.id];
} }
SpiceMainConn.prototype.connect_agent = function() SpiceMainConn.prototype.connect_agent = function () {
{
this.agent_connected = true; this.agent_connected = true;
var agent_start = new Messages.SpiceMsgcMainAgentStart(~0); var agent_start = new Messages.SpiceMsgcMainAgentStart(~0);
@ -487,11 +438,9 @@ SpiceMainConn.prototype.connect_agent = function()
} }
SpiceMainConn.prototype.handle_mouse_mode = function(current, supported) SpiceMainConn.prototype.handle_mouse_mode = function (current, supported) {
{
this.mouse_mode = current; this.mouse_mode = current;
if (current != Constants.SPICE_MOUSE_MODE_CLIENT && (supported & Constants.SPICE_MOUSE_MODE_CLIENT)) if (current != Constants.SPICE_MOUSE_MODE_CLIENT && (supported & Constants.SPICE_MOUSE_MODE_CLIENT)) {
{
var mode_request = new Messages.SpiceMsgcMainMouseModeRequest(Constants.SPICE_MOUSE_MODE_CLIENT); var mode_request = new Messages.SpiceMsgcMainMouseModeRequest(Constants.SPICE_MOUSE_MODE_CLIENT);
var mr = new Messages.SpiceMiniData(); var mr = new Messages.SpiceMiniData();
mr.build_msg(Constants.SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request); mr.build_msg(Constants.SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
@ -503,17 +452,17 @@ SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
} }
/* Shift current time to attempt to get a time matching that of the server */ /* Shift current time to attempt to get a time matching that of the server */
SpiceMainConn.prototype.relative_now = function() SpiceMainConn.prototype.relative_now = function () {
{
var ret = (Date.now() - this.our_mm_time) + this.mm_time; var ret = (Date.now() - this.our_mm_time) + this.mm_time;
return ret; return ret;
} }
export { export {
SpiceMainConn, SpiceMainConn,
handle_file_dragover, handle_file_dragover,
handle_file_drop, handle_file_drop,
resize_helper, resize_helper,
handle_resize, handle_resize,
sendCtrlAltDel, sendCtrlAltDel,
sendCtrlAltFN,
}; };

View file

@ -63,7 +63,6 @@ body
#spice-area #spice-area
{ {
height: 100%;
width: 95%; width: 95%;
padding: 0; padding: 0;
margin-left: auto; margin-left: auto;
@ -74,13 +73,13 @@ body
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2); box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
-moz-border-radius: 10px; -moz-border-radius: 10px;
-webkit-border-radius: 10px; -webkit-border-radius: 10px;
border-radius: 10px; border-radius: 1px;
} }
.spice-screen .spice-screen
{ {
min-height: 600px; min-height: 600px;
height: 100%; height: 100%;
margin: 10px; margin: 5px;
padding: 0; padding: 0;
background-color: #333333; background-color: #333333;
} }