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

Merge pull request #330 from catborise/console

Console
This commit is contained in:
Anatoliy Guskov 2020-06-25 21:02:36 +03:00 committed by GitHub
commit ce123d1f22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 808 additions and 886 deletions

41
.github/workflows/linter.yml vendored Normal file
View file

@ -0,0 +1,41 @@
# This is a basic workflow to help you get started with Actions
name: linter
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@master
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: install libvirt-dev
run: |
sudo apt-get install -y libvirt-dev
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
if [ -f dev/requirements.txt ]; then pip3 install -r dev/requirements.txt; fi
- name: Super-Linter
uses: github/super-linter@v2.1.0
env:
VALIDATE_RUBY: false
VALIDATE_ANSIBLE: false

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,40 +27,27 @@
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"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </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"
id="dropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
{% trans "Send key(s)" %} {% trans "Send key(s)" %}
</a> </a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
@ -88,20 +70,20 @@
<li class="nav-item" id="fullscreen_button"> <li class="nav-item" id="fullscreen_button">
<a class="nav-link" href='#'>{% trans "Fullscreen" %}</a> <a class="nav-link" href='#'>{% trans "Fullscreen" %}</a>
</li> </li>
{% block navbarmenu %}{% endblock %} {% block navbarmenu %}{% endblock %}
</ul> </ul>
</div> </div>
</nav> </div>
</nav>
{% block content %}{% endblock %}
</div>
<script src="{% static "js/jquery.js" %}"></script>
<script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
{% 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>');
<script>
function log_message(msg,type) {
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>');
if (exist) { if (exist) {
$('#status').remove(); $('#status').remove();
$('body').prepend(status_div); $('body').prepend(status_div);
@ -111,23 +93,24 @@
$('body').prepend(status_div); $('body').prepend(status_div);
status_div.fadeIn(200); status_div.fadeIn(200);
} }
if (type!='danger') { if (type != 'danger') {
status_div.delay(3000).fadeOut(200); 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,23 +27,23 @@
{% 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" %}';
@ -76,8 +76,10 @@
document.getElementById('connectButton').onclick = disconnect; document.getElementById('connectButton').onclick = disconnect;
try { try {
sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div", sc = new SpiceHtml5.SpiceMainConn({
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected }); uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected
});
} }
catch (e) { catch (e) {
alert(e.toString()); alert(e.toString());
@ -150,17 +152,22 @@
*/ */
function fullscreen() { function fullscreen() {
var screen=document.getElementById('spice-screen'); var screen = document.getElementById('spice-screen');
if(screen.requestFullscreen) { if (screen.requestFullscreen) {
screen.requestFullscreen(); screen.requestFullscreen();
} else if(screen.mozRequestFullScreen) { } else if (screen.mozRequestFullScreen) {
screen.mozRequestFullScreen(); screen.mozRequestFullScreen();
} else if(screen.webkitRequestFullscreen) { } else if (screen.webkitRequestFullscreen) {
screen.webkitRequestFullscreen(); screen.webkitRequestFullscreen();
} else if(screen.msRequestFullscreen) { } else if (screen.msRequestFullscreen) {
screen.msRequestFullscreen(); screen.msRequestFullscreen();
} }
} }
function sendctrlaltfn(f) {
SpiceHtml5.sendCtrlAltFN(sc, f);
return false;
}
/* SPICE port event listeners /* SPICE port event listeners
window.addEventListener('spice-port-data', function(event) { window.addEventListener('spice-port-data', function(event) {
// Here we convert data to text, but really we can obtain binary data also // Here we convert data to text, but really we can obtain binary data also
@ -173,19 +180,19 @@
}); });
*/ */
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 }}'>
<label for="show_console">{% trans 'Show console' %}</label><input type="checkbox" id="show_console" value="1"
onchange="toggle_console()" checked>
<button id="connectButton">{% trans 'Start' %}</button> <button id="connectButton">{% trans 'Start' %}</button>
</div> </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,23 +27,23 @@
{% 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;
@ -52,7 +52,7 @@
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=/";
}; };
@ -126,8 +126,10 @@
} }
try { try {
sc = new SpiceHtml5.SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div", sc = new SpiceHtml5.SpiceMainConn({
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected }); uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected
});
} }
catch (e) { catch (e) {
alert(e.toString()); alert(e.toString());
@ -171,18 +173,23 @@
} }
function fullscreen() { function fullscreen() {
var screen=document.getElementById('spice-screen'); var screen = document.getElementById('spice-screen');
if(screen.requestFullscreen) { if (screen.requestFullscreen) {
screen.requestFullscreen(); screen.requestFullscreen();
} else if(screen.mozRequestFullScreen) { } else if (screen.mozRequestFullScreen) {
screen.mozRequestFullScreen(); screen.mozRequestFullScreen();
} else if(screen.webkitRequestFullscreen) { } else if (screen.webkitRequestFullscreen) {
screen.webkitRequestFullscreen(); screen.webkitRequestFullscreen();
} else if(screen.msRequestFullscreen) { } else if (screen.msRequestFullscreen) {
screen.msRequestFullscreen(); screen.msRequestFullscreen();
} }
} }
function sendctrlaltfn(f) {
SpiceHtml5.sendCtrlAltFN(sc, f);
return false;
}
/* SPICE port event listeners /* SPICE port event listeners
window.addEventListener('spice-port-data', function(event) { window.addEventListener('spice-port-data', function(event) {
// Here we convert data to text, but really we can obtain binary data also // Here we convert data to text, but really we can obtain binary data also
@ -195,30 +202,30 @@
}); });
*/ */
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) });
connect(undefined); connect(undefined);
</script> </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,107 +3,78 @@
{% 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
-->
<!-- promise polyfills promises for IE11 -->
<script src="{% static "js/novnc/vendor/promise.js" %}"></script>
<!-- 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 -->
<script type="module" crossorigin="anonymous">
// Load supporting scripts
import * as WebUtil from '{% static "js/novnc/app/webutil.js" %}';
import RFB from '{% static "js/novnc/core/rfb.js" %}'; import RFB from '{% static "js/novnc/core/rfb.js" %}';
var rfb; let rfb;
var desktopName; let desktopName;
// When this function is called we have
// successfully connected to a server
function connectedToServer(e) {
status("Connected to " + desktopName);
}
// This function is called when we are disconnected
function disconnectedFromServer(e) {
if (e.detail.clean) {
status("Disconnected");
} else {
status("Something went wrong, connection is closed");
}
}
// When this function is called, the server requires
// credentials to authenticate
function credentialsAreRequired(e) {
const password = prompt("Password Required:");
rfb.sendCredentials({ password: password });
}
// When this function is called we have received
// a desktop name from the server
function updateDesktopName(e) { function updateDesktopName(e) {
desktopName = e.detail.name; desktopName = e.detail.name;
} }
function credentials(e) {
var html;
var form = document.createElement('form'); // Since most operating systems will catch Ctrl+Alt+Del
form.innerHTML = '<label></label>'; // before they get a chance to be intercepted by the browser,
form.innerHTML += '<input type=password size=10 id="password_input">'; // we provide a way to emulate this key sequence.
form.onsubmit = setPassword; function sendCtrlAltDel() {
rfb.sendCtrlAltDel();
// bypass status() because it sets text content
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
document.getElementById('noVNC_status').innerHTML = '';
document.getElementById('noVNC_status').appendChild(form);
document.getElementById('noVNC_status').querySelector('label').textContent = 'Password Required: ';
}
function setPassword() {
rfb.sendCredentials({ password: document.getElementById('password_input').value });
return false; return false;
} }
function fullscreen() { function fullscreen() {
if (document.fullscreenElement || // alternative standard method if (document.fullscreenElement || // alternative standard method
document.mozFullScreenElement || // currently working methods document.mozFullScreenElement || // currently working methods
@ -135,10 +106,6 @@
rfb.sendCtrlAltFN(f); rfb.sendCtrlAltFN(f);
return false; return false;
} }
function sendCtrlAltDel() {
rfb.sendCtrlAltDel();
return false;
}
function machineShutdown() { function machineShutdown() {
rfb.machineShutdown(); rfb.machineShutdown();
return false; return false;
@ -151,46 +118,30 @@
rfb.machineReset(); rfb.machineReset();
return false; return false;
} }
function status(text, level) {
switch (level) { // Show a status text in the top bar
case 'normal': function status(text) {
case 'warn':
case 'error':
break;
default:
level = "warn";
}
document.getElementById('noVNC_status_bar').className = "noVNC_status_" + level;
document.getElementById('noVNC_status').textContent = text; document.getElementById('noVNC_status').textContent = text;
} }
function connected(e) { // This function extracts the value of one variable from the
document.getElementById('sendCtrlAltDelButton').disabled = false; // query string. If the variable isn't defined in the URL
if (WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:"))) { // it returns the default value instead.
status("Connected (encrypted) to " + desktopName, "normal"); function readQueryVariable(name, defaultValue) {
} else { // A URL with a query parameter can look like this:
status("Connected (unencrypted) to " + desktopName, "normal"); // 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 disconnected(e) { return defaultValue;
document.getElementById('sendCtrlAltDelButton').disabled = true;
updatePowerButtons();
if (e.detail.clean) {
status("Disconnected", "normal");
} else {
status("Something went wrong, connection is closed", "error");
}
}
function updatePowerButtons() {
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;
@ -200,109 +151,80 @@
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
//var host = WebUtil.getConfigVar('host', window.location.hostname); const host = readQueryVariable('host', '{{ ws_host }}');
//var port = WebUtil.getConfigVar('port', window.location.port); let port = readQueryVariable('port', '{{ ws_port }}');
var host = '{{ ws_host }}'; const password = readQueryVariable('password');
var port = '{{ ws_port }}'; const path = readQueryVariable('path', 'websockify');
// 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) {
// if token is already present in the path we should use it
path = WebUtil.injectParamIfMissing(path, "token", token);
WebUtil.createCookie('token', token, 1)
}
(function() {
status("Connecting", "normal");
if ((!host) || (!port)) {
status('Must specify host and port in URL', 'error');
}
var url;
if (WebUtil.getConfigVar('encrypt', (window.location.protocol === "https:"))) {
url = 'wss'; url = 'wss';
} else { } else {
url = 'ws'; url = 'ws';
} }
url += '://' + host; url += '://' + host;
if(port) { if (port) {
url += ':' + port; url += ':' + port;
} }
url += '/' + path; url += '/' + path;
//rfb = new RFB(document.body, url, // Creating a new RFB object will start a new connection
// { repeaterID: WebUtil.getConfigVar('repeaterID', ''),
// shared: WebUtil.getConfigVar('shared', true),
// credentials: { password: password } });
rfb = new RFB(document.getElementById('noVNC_container'), url, rfb = new RFB(document.getElementById('noVNC_container'), url,
{ repeaterID: WebUtil.getConfigVar('repeaterID', ''), { credentials: { password: password } });
shared: WebUtil.getConfigVar('shared', true),
credentials: { password: password } });
rfb.viewOnly = WebUtil.getConfigVar('view_only', false); // Add listeners to important events from the RFB module
rfb.addEventListener("connect", connected); rfb.addEventListener("connect", connectedToServer);
rfb.addEventListener("disconnect", disconnected); rfb.addEventListener("disconnect", disconnectedFromServer);
rfb.addEventListener("capabilities", function () { updatePowerButtons(); }); rfb.addEventListener("credentialsrequired", credentialsAreRequired);
rfb.addEventListener("credentialsrequired", credentials);
rfb.addEventListener("desktopname", updateDesktopName); rfb.addEventListener("desktopname", updateDesktopName);
rfb.scaleViewport = WebUtil.getConfigVar('scale', false); rfb.addEventListener("capabilities", function () { updatePowerButtons(); });
rfb.resizeSession = WebUtil.getConfigVar('resize', false);
})(); // Set parameters that can be changed on an active connection
</script> 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 }});
</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>
<div id='noVNC_container'></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(); var msg = new Messages.SpiceMiniData();
if (!state)
{ 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();
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;
@ -295,4 +302,5 @@ export {
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,30 +77,25 @@ 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 +
@ -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,13 +377,11 @@ 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);
@ -437,16 +392,14 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
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);
@ -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,8 +452,7 @@ 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;
} }
@ -516,4 +464,5 @@ export {
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;
} }