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

Merge pull request #288 from catborise/master

various fixes and updates
This commit is contained in:
Anatoliy Guskov 2020-01-24 21:14:43 +02:00 committed by GitHub
commit ff311a609c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 59924 additions and 1958 deletions

View file

@ -1,6 +1,6 @@
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required
from accounts.models import *

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.26 on 2020-01-21 12:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('computes', '0002_compute_details'),
]
operations = [
migrations.AlterField(
model_name='compute',
name='details',
field=models.CharField(blank=True, max_length=64, null=True),
),
migrations.AlterField(
model_name='compute',
name='hostname',
field=models.CharField(max_length=64),
),
migrations.AlterField(
model_name='compute',
name='name',
field=models.CharField(max_length=64),
),
]

View file

@ -6,7 +6,7 @@ class Compute(models.Model):
hostname = models.CharField(max_length=64)
login = models.CharField(max_length=20)
password = models.CharField(max_length=14, blank=True, null=True)
details = models.CharField(max_length=50, null=True, blank=True)
details = models.CharField(max_length=64, null=True, blank=True)
type = models.IntegerField()
def __unicode__(self):

View file

@ -152,7 +152,6 @@
<button type="submit" class="btn btn-primary" name="host_edit">
{% trans "Change" %}
</button>
</div>
</form>
{% endifequal %}

View file

@ -1,7 +1,7 @@
import json
from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from computes.models import Compute

View file

@ -51,8 +51,9 @@ class MyTCPServerHandler(SocketServer.BaseRequestHandler):
pass
gfs.shutdown()
gfs.close()
except RuntimeError, err:
except RuntimeError as err:
self.request.sendall(json.dumps({'return': 'error', 'message': err.message}))
server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
server.serve_forever()

View file

@ -25,8 +25,8 @@ import socket
from webvirtcloud.settings import WS_PORT, WS_HOST, WS_CERT
from vrtManager.connection import CONN_SSH, CONN_SOCKET
from tunnel import Tunnel
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-v",
@ -66,7 +66,6 @@ parser.add_option("-c",
(options, args) = parser.parse_args()
FORMAT = "%(asctime)s - %(name)s - %(levelname)s : %(message)s"
if options.debug:
logging.basicConfig(level=logging.DEBUG, format=FORMAT)
@ -88,8 +87,7 @@ except ImportError:
try:
from novnc.wsproxy import WebSocketProxy
except ImportError:
print('Unable to import a websockify implementation, ' +
'please install one')
print('Unable to import a websockify implementation,\n please install one')
sys.exit(1)
else:
USE_HANDLER = False
@ -220,7 +218,6 @@ if USE_HANDLER:
socket_factory = self.server.socket
self._new_client(daemon, socket_factory)
else:
class NovaWebSocketProxy(WebSocketProxy, CompatibilityMixIn):

View file

@ -53,6 +53,7 @@
</head>
<body>
<div id='main_container' class="container">
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
@ -90,7 +91,7 @@
</div>
</div>
</nav>
<div id='main_container' class="container">
{% block content %}{% endblock %}
</div>
<script src="{% static "js/jquery.js" %}"></script>

View file

@ -26,208 +26,192 @@
{% load i18n %}
{% load staticfiles %}
{% block head %}
<title>WebVirtCloud - Spice Client - Full</title>
<script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
<script src="{% static "js/spice-html5/enums.js" %}"></script>
<script src="{% static "js/spice-html5/atKeynames.js" %}"></script>
<script src="{% static "js/spice-html5/utils.js" %}"></script>
<script src="{% static "js/spice-html5/png.js" %}"></script>
<script src="{% static "js/spice-html5/lz.js" %}"></script>
<script src="{% static "js/spice-html5/quic.js" %}"></script>
<script src="{% static "js/spice-html5/bitmap.js" %}"></script>
<script src="{% static "js/spice-html5/spicedataview.js" %}"></script>
<script src="{% static "js/spice-html5/spicetype.js" %}"></script>
<script src="{% static "js/spice-html5/spicemsg.js" %}"></script>
<script src="{% static "js/spice-html5/wire.js" %}"></script>
<script src="{% static "js/spice-html5/spiceconn.js" %}"></script>
<script src="{% static "js/spice-html5/display.js" %}"></script>
<script src="{% static "js/spice-html5/port.js" %}"></script>
<script src="{% static "js/spice-html5/main.js" %}"></script>
<script src="{% static "js/spice-html5/inputs.js" %}"></script>
<script src="{% static "js/spice-html5/webm.js" %}"></script>
<script src="{% static "js/spice-html5/playback.js" %}"></script>
<script src="{% static "js/spice-html5/simulatecursor.js" %}"></script>
<script src="{% static "js/spice-html5/cursor.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/jsbn.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rsa.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/prng4.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rng.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/sha1.js" %}"></script>
<script src="{% static "js/spice-html5/ticket.js" %}"></script>
<script src="{% static "js/spice-html5/resize.js" %}"></script>
<script src="{% static "js/spice-html5/filexfer.js" %}"></script>
<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
<title>WebVirtCloud - Spice Client - Full</title>
<script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
<script src="{% static "js/spice-html5/enums.js" %}"></script>
<script src="{% static "js/spice-html5/atKeynames.js" %}"></script>
<script src="{% static "js/spice-html5/utils.js" %}"></script>
<script src="{% static "js/spice-html5/png.js" %}"></script>
<script src="{% static "js/spice-html5/lz.js" %}"></script>
<script src="{% static "js/spice-html5/quic.js" %}"></script>
<script src="{% static "js/spice-html5/bitmap.js" %}"></script>
<script src="{% static "js/spice-html5/spicedataview.js" %}"></script>
<script src="{% static "js/spice-html5/spicetype.js" %}"></script>
<script src="{% static "js/spice-html5/spicemsg.js" %}"></script>
<script src="{% static "js/spice-html5/wire.js" %}"></script>
<script src="{% static "js/spice-html5/spiceconn.js" %}"></script>
<script src="{% static "js/spice-html5/display.js" %}"></script>
<script src="{% static "js/spice-html5/port.js" %}"></script>
<script src="{% static "js/spice-html5/main.js" %}"></script>
<script src="{% static "js/spice-html5/inputs.js" %}"></script>
<script src="{% static "js/spice-html5/webm.js" %}"></script>
<script src="{% static "js/spice-html5/playback.js" %}"></script>
<script src="{% static "js/spice-html5/simulatecursor.js" %}"></script>
<script src="{% static "js/spice-html5/cursor.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/jsbn.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rsa.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/prng4.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rng.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/sha1.js" %}"></script>
<script src="{% static "js/spice-html5/ticket.js" %}"></script>
<script src="{% static "js/spice-html5/resize.js" %}"></script>
<script src="{% static "js/spice-html5/filexfer.js" %}"></script>
<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
{% endblock %}
{% block content %}
<div id="login" hidden>
<span class="logo">SPICE</span>
<label for="host">Host:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
<label for="port">Port:</label> <input type='text' id='port' value='{{ ws_port }}'>
<label for="password">Password:</label> <input type='password' id='password' value='{{ console_passwd }}'>
<label for="show_console">Show console </label><input type="checkbox" id="show_console" value="1" onchange="toggle_console()" checked>
<button id="connectButton" onclick="connect();">Start</button>
</div>
<div id="spice-area">
<div id="spice-screen" class="spice-screen"></div>
</div>
<div id="login" hidden>
<span class="logo">SPICE</span>
<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="password">{% trans 'Password' %}:</label> <input type='password' id='password' 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" onclick="connect();">{% trans 'Start' %}</button>
</div>
<div id="spice-area">
<div id="spice-screen" class="spice-screen"></div>
<div id="message-div" class="spice-message"></div>
</div>
<div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here -->
</div>
<div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here -->
</div>
{% endblock %}
{% block foot %}
<script>
var host = null, port = null;
var sc;
<script>
var host = null, port = null;
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;
if (window.location.protocol == 'https:') {
scheme = "wss://";
}
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 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 connect()
{
var host, port, password, scheme = "ws://", uri;
function disconnect() {
console.log(">> disconnect");
if (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');
document.getElementById('spice-area').removeChild(spice_xfer_area);
document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
}
console.log("<< disconnect");
}
host = document.getElementById("host").value;
port = document.getElementById("port").value;
if (window.location.protocol == 'https:') {
scheme = "wss://";
}
password = document.getElementById("password").value;
function agent_connected(sc) {
window.addEventListener('resize', handle_resize);
window.spice_connection = this;
resize_helper(this);
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 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();
}
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', handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', 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';
}
function disconnect()
{
console.log(">> disconnect");
if (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');
document.getElementById('spice-area').removeChild(spice_xfer_area);
document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
}
console.log("<< disconnect");
window.addEventListener('resize', handle_resize);
resize_helper(sc);
}
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
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);
});
function agent_connected(sc)
{
window.addEventListener('resize', handle_resize);
window.spice_connection = this;
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', handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', 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', handle_resize);
resize_helper(sc);
}
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
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);
});
*/
document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
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();
</script>
window.addEventListener('spice-port-event', function(event) {
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
});
*/
document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
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();
</script>
{% endblock %}

View file

@ -27,227 +27,216 @@
{% load staticfiles %}
{% block head %}
<title>WebVirtCloud - Spice - Lite</title>
<script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
<script src="{% static "js/spice-html5/enums.js" %}"></script>
<script src="{% static "js/spice-html5/atKeynames.js" %}"></script>
<script src="{% static "js/spice-html5/utils.js" %}"></script>
<script src="{% static "js/spice-html5/png.js" %}"></script>
<script src="{% static "js/spice-html5/lz.js" %}"></script>
<script src="{% static "js/spice-html5/quic.js" %}"></script>
<script src="{% static "js/spice-html5/bitmap.js" %}"></script>
<script src="{% static "js/spice-html5/spicedataview.js" %}"></script>
<script src="{% static "js/spice-html5/spicetype.js" %}"></script>
<script src="{% static "js/spice-html5/spicemsg.js" %}"></script>
<script src="{% static "js/spice-html5/wire.js" %}"></script>
<script src="{% static "js/spice-html5/spiceconn.js" %}"></script>
<script src="{% static "js/spice-html5/display.js" %}"></script>
<script src="{% static "js/spice-html5/main.js" %}"></script>
<script src="{% static "js/spice-html5/inputs.js" %}"></script>
<script src="{% static "js/spice-html5/webm.js" %}"></script>
<script src="{% static "js/spice-html5/playback.js" %}"></script>
<script src="{% static "js/spice-html5/simulatecursor.js" %}"></script>
<script src="{% static "js/spice-html5/cursor.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/jsbn.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rsa.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/prng4.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rng.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/sha1.js" %}"></script>
<script src="{% static "js/spice-html5/ticket.js" %}"></script>
<script src="{% static "js/spice-html5/resize.js" %}"></script>
<script src="{% static "js/spice-html5/filexfer.js" %}"></script>
<script src="{% static "js/spice-html5/port.js" %}"></script>
<title>WebVirtCloud - Spice - Lite</title>
<script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
<script src="{% static "js/spice-html5/enums.js" %}"></script>
<script src="{% static "js/spice-html5/atKeynames.js" %}"></script>
<script src="{% static "js/spice-html5/utils.js" %}"></script>
<script src="{% static "js/spice-html5/png.js" %}"></script>
<script src="{% static "js/spice-html5/lz.js" %}"></script>
<script src="{% static "js/spice-html5/quic.js" %}"></script>
<script src="{% static "js/spice-html5/bitmap.js" %}"></script>
<script src="{% static "js/spice-html5/spicedataview.js" %}"></script>
<script src="{% static "js/spice-html5/spicetype.js" %}"></script>
<script src="{% static "js/spice-html5/spicemsg.js" %}"></script>
<script src="{% static "js/spice-html5/wire.js" %}"></script>
<script src="{% static "js/spice-html5/spiceconn.js" %}"></script>
<script src="{% static "js/spice-html5/display.js" %}"></script>
<script src="{% static "js/spice-html5/main.js" %}"></script>
<script src="{% static "js/spice-html5/inputs.js" %}"></script>
<script src="{% static "js/spice-html5/webm.js" %}"></script>
<script src="{% static "js/spice-html5/playback.js" %}"></script>
<script src="{% static "js/spice-html5/simulatecursor.js" %}"></script>
<script src="{% static "js/spice-html5/cursor.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/jsbn.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rsa.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/prng4.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/rng.js" %}"></script>
<script src="{% static "js/spice-html5/thirdparty/sha1.js" %}"></script>
<script src="{% static "js/spice-html5/ticket.js" %}"></script>
<script src="{% static "js/spice-html5/resize.js" %}"></script>
<script src="{% static "js/spice-html5/filexfer.js" %}"></script>
<script src="{% static "js/spice-html5/port.js" %}"></script>
<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" %}" />
{% endblock %}
{% block content %}
<div id="spice-area">
<div id="spice-screen" class="spice-screen"></div>
</div>
<div id="spice-area">
<div id="spice-screen" class="spice-screen"></div>
<div id="message-div" class="spice-message"></div>
</div>
<div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here -->
</div>
<div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here -->
</div>
{% endblock %}
{% block foot %}
<script>
var host = null, port = null;
var sc;
var host = null, port = null;
var sc;
function spice_set_cookie(name, value, days) {
var date, expires;
date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toGMTString();
document.cookie = name + "=" + value + expires + "; path=/";
};
function spice_set_cookie(name, value, days) {
var date, expires;
date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toGMTString();
document.cookie = name + "=" + value + expires + "; path=/";
};
function spice_query_var(name, defvalue) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue;
function spice_query_var(name, defvalue) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue;
}
function spice_error(e) {
console.log(e);
disconnect();
if (e.message !== undefined) {
log_error(e.message);
}
else {
log_error('Unknown error');
}
}
function connect() {
var host, port, password, scheme = "ws://", uri;
console.log('>> connect');
// 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)
{
console.log(e);
// If a token variable is passed in, set the parameter in a cookie.
// This is used by nova-spiceproxy.
token = spice_query_var('token', null);
if (token) {
spice_set_cookie('token', token, 1)
}
//password = spice_query_var('password', '');
password = '{{ console_passwd | safe }}';
if (password === 'None') password = '';
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 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();
if (e.message !== undefined) {
log_error(e.message);
}
else {
log_error('Unknown error');
}
}
console.log('<< connect')
}
function connect()
{
var host, port, password, scheme = "ws://", uri;
console.log('>> connect');
// 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.
token = spice_query_var('token', null);
if (token) {
spice_set_cookie('token', token, 1)
}
//password = spice_query_var('password', '');
password = '{{ console_passwd | safe }}';
if (password === 'None') password = '';
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 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();
}
console.log('<< connect')
function disconnect()
{
console.log(">> disconnect");
if (sc) {
sc.stop();
}
function disconnect()
{
console.log(">> disconnect");
if (sc) {
sc.stop();
}
if (window.File && window.FileReader && window.FileList && window.Blob)
{
var spice_xfer_area = document.getElementById('spice-xfer-area');
document.getElementById('spice-area').removeChild(spice_xfer_area);
document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
}
console.log("<< disconnect");
if (window.File && window.FileReader && window.FileList && window.Blob) {
var spice_xfer_area = document.getElementById('spice-xfer-area');
document.getElementById('spice-area').removeChild(spice_xfer_area);
document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
}
console.log("<< disconnect");
}
function agent_connected(sc)
{
window.addEventListener('resize', handle_resize);
window.spice_connection = this;
function agent_connected(sc) {
window.addEventListener('resize', handle_resize);
window.spice_connection = this;
resize_helper(this);
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', handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
}
else
{
console.log("File API is not supported");
}
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', handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
}
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();
}
else {
console.log("File API is not supported");
}
}
/* 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);
});
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();
}
}
window.addEventListener('spice-port-event', function(event) {
DEBUG > 0 && console.log('SPICE port', event.detail.channel.portName, 'event data:', event.detail.spiceEvent);
});
*/
document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
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();
</script>
/* 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);
});
*/
document.getElementById("fullscreen_button").addEventListener('click', fullscreen);
document.getElementById('ctrlaltdel').addEventListener('click', sendCtrlAltDel);
document.getElementById('ctrlaltf1').addEventListener('click', function(){sendCtrlAltFN(0);});
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();
</script>
{% endblock %}

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from computes.models import Compute
from create.models import Flavor

View file

@ -24,121 +24,117 @@
{% include 'errors_block.html' %}
<div class="row">
<div class="col-lg-12">
<div class="table-responsive">
{% if request.user.is_superuser %}
{% if not all_host_vms %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "You don't have any Instance" %}
</div>
</div>
{% else %}
{% ifequal view_style "nongrouped" %}
{% include 'allinstances_index_nongrouped.html' %}
{% endifequal %}
{% ifequal view_style "grouped" %}
{% include 'allinstances_index_grouped.html' %}
{% endifequal %}
{% endif %}
{% else %}
{% if not all_user_vms %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any Instance" %}
</div>
</div>
{% else %}
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
<thead>
<tr>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Status' %}</th>
<th>{% trans 'VCPU' %}</th>
<th>{% trans 'Memory' %}</th>
<th data-sortable="false" style="width: 165px;">{% trans 'Actions' %}</th>
</tr>
</thead>
<tbody class="searchable">
{% for inst, vm in all_user_vms.items %}
<tr>
<td><a href="{% url 'instance' vm.compute_id vm.name %}">{{ vm.name }}</a><br><small><em>{{ vm.title }}</em></small></td>
<td>{% ifequal vm.status 1 %}
<span class="text-success">{% trans "Active" %}</span>
{% endifequal %}
{% ifequal vm.status 5 %}
<span class="text-danger">{% trans "Off" %}</span>
{% endifequal %}
{% ifequal vm.status 3 %}
<span class="text-warning">{% trans "Suspend" %}</span>
{% endifequal %}
</td>
<td>{{ vm.vcpu }}</td>
<td>{{ vm.memory }} {% trans "MB" %}</td>
<td><form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ vm.name }}"/>
<input type="hidden" name="compute_id" value="{{ vm.compute_id }}"/>
{% ifequal vm.status 5 %}
{% if inst.instance.is_template %}
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ vm.compute_id }}, '{{ vm.name }}');">
<span class="glyphicon glyphicon-duplicate"></span>
</button>
{% else %}
<button class="btn btn-sm btn-default" type="submit" name="poweron" title="{% trans "Power On" %}">
<span class="glyphicon glyphicon-play"></span>
</button>
{% endif %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% ifequal vm.status 3 %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
<span class="glyphicon glyphicon-play"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC/Spice Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% ifequal vm.status 1 %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
<span class="glyphicon glyphicon-play"></span>
</button>
<button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ vm.compute_id }}-{{ vm.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% endifequal %}
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endif %}
</div>
</div>
<div class="col-lg-12">
{% if request.user.is_superuser %}
{% if not all_host_vms %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any Instance" %}
</div>
</div>
{% else %}
{% ifequal view_style "nongrouped" %}
{% include 'allinstances_index_nongrouped.html' %}
{% endifequal %}
{% ifequal view_style "grouped" %}
{% include 'allinstances_index_grouped.html' %}
{% endifequal %}
{% endif %}
{% else %}
{% if not all_user_vms %}
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any Instance" %}
</div>
</div>
{% else %}
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
<thead>
<tr>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Status' %}</th>
<th>{% trans 'VCPU' %}</th>
<th>{% trans 'Memory' %}</th>
<th data-sortable="false" style="width: 165px;">{% trans 'Actions' %}</th>
</tr>
</thead>
<tbody class="searchable">
{% for inst, vm in all_user_vms.items %}
<tr>
<td><a href="{% url 'instance' vm.compute_id vm.name %}">{{ vm.name }}</a><br><small><em>{{ vm.title }}</em></small></td>
<td>{% ifequal vm.status 1 %}
<span class="text-success">{% trans "Active" %}</span>
{% endifequal %}
{% ifequal vm.status 5 %}
<span class="text-danger">{% trans "Off" %}</span>
{% endifequal %}
{% ifequal vm.status 3 %}
<span class="text-warning">{% trans "Suspend" %}</span>
{% endifequal %}
</td>
<td>{{ vm.vcpu }}</td>
<td>{{ vm.memory }} {% trans "MB" %}</td>
<td><form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ vm.name }}"/>
<input type="hidden" name="compute_id" value="{{ vm.compute_id }}"/>
{% ifequal vm.status 5 %}
{% if inst.instance.is_template %}
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ vm.compute_id }}, '{{ vm.name }}');">
<span class="glyphicon glyphicon-duplicate"></span>
</button>
{% else %}
<button class="btn btn-sm btn-default" type="submit" name="poweron" title="{% trans "Power On" %}">
<span class="glyphicon glyphicon-play"></span>
</button>
{% endif %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% ifequal vm.status 3 %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
<span class="glyphicon glyphicon-play"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC/Spice Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
{% endifequal %}
{% ifequal vm.status 1 %}
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
<span class="glyphicon glyphicon-play"></span>
</button>
<button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}">
<span class="glyphicon glyphicon-off"></span>
</button>
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ vm.compute_id }}-{{ vm.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% endifequal %}
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endif %}
</div>
{% endblock %}
{% block script %}

View file

@ -4,61 +4,84 @@
{% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %}
{% block content %}
{% include 'pleasewaitdialog.html' %}
<nav class="navbar navbar-default navba navbar-fixed-bottom">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar_bottom" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">{% trans 'Toggle navigation' %}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{% trans 'HOST' %}</a>
</div>
<div id="navbar_bottom" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>
<a class="navbar-link" href="{% url 'overview' compute.id %}">
<i class="fa fa-server"></i>
{{ compute.name }} {% if compute.name != compute.hostname %} - {{ compute.hostname }}{% endif %}
</a>
</li>
<li>
<a href="{% url 'instances' compute.id %}"><i class="fa fa-desktop"></i> {% trans "Instances" %}</a>
</li>
<li class="active">
<a href="{% url 'instance' compute.id vname %}"><i class="fa fa-hdd-o"></i> {{ vname }}</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Page Heading -->
<div class="row">
<div>
<div>
<h3>
{{ vname }}{% if title %}&nbsp;({{ title }}){% endif %}
</h3>
<h3>{{ vname }}{% if title %}&nbsp;({{ title }}){% endif %}</h3>
</div>
<div>
<div>
{% if status == 5 %}
<span class="label label-danger">{% trans "Off" %}</span>
{% endif %}
{% if status == 1 %}
<span class="label label-success">{% trans "Active" %}</span>
{% endif %}
{% if status == 3 %}
<span class="label label-warning">{% trans "Suspend" %}</span>
{% endif %}
|
{% if cur_vcpu %}
{{ cur_vcpu }} {% trans "Vcpu" %}
{% else %}
{{ vcpu }} {% trans "Vcpu" %}
{% endif %}
|
{{ cur_memory }} {% trans "MB" %} {% trans "Ram" %}
|
{% for disk in disks %}
{{ disk.size|filesizeformat }} {% trans "Disk" %} |
{% endfor %}
{% for net in networks %}
{% for ipv4 in net.ipv4|default:"-" %}
{{ ipv4 }} |
{% endfor %}
{% endfor %}
<button
{% if guest_agent == True %}
{% if guest_agent_ready == True %}
class="btn btn-xs btn-success"
title="Guest Agent Enabled & Connected"
{% else %}
class="btn btn-xs btn-default"
title="Guest Agent Enabled but not Connected"
{% endif %}
{% if status == 5 %}
<span class="label label-danger">{% trans "Off" %}</span>
{% endif %}
{% if status == 1 %}
<span class="label label-success">{% trans "Active" %}</span>
{% endif %}
{% if status == 3 %}
<span class="label label-warning">{% trans "Suspend" %}</span>
{% endif %}
|
<span {%if guest_agent == True %}
{% if guest_agent_ready == True %}
class="label label-success"
title="Guest Agent Enabled & Connected"
{% else %}
class="btn btn-xs btn-danger"
title="Guest Agent Not Enabled & Not Connected"
{% endif %} disabled>
<span class="glyphicon glyphicon-flash"></span>
</button>
|
<a href="{% url 'instance' compute.id vname %}" type="button" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span></a>
<em>on</em>
<a href="{% url 'overview' compute.id %}"><span class="label label-primary">{{ compute.name }}{% if compute.name != compute.hostname %} - {{ compute.hostname }}{% endif %} </span></a>
</div>
class="label label-warning"
title="Guest Agent Enabled but not Connected"
{% endif %}
{% else %}
class="label label-danger"
title="Guest Agent Not Enabled & Not Connected"
{% endif %}><i class="fa fa-plug"></i></span>
|
{% if snapshots %}
<i class="fa fa-camera text-primary" title="There are {{ snapshots|length }} snapshot(s)"></i> |
{% endif %}
{% if cur_vcpu %}
{{ cur_vcpu }} {% trans "Vcpu" %}
{% else %}
{{ vcpu }} {% trans "Vcpu" %}
{% endif %}
|
{{ cur_memory }} {% trans "MB" %} {% trans "Ram" %}
|
{% for disk in disks %}
{{ disk.size|filesizeformat }} {% trans "Disk" %} |
{% endfor %}
{% for net in networks %}
{% for ipv4 in net.ipv4 %}
{{ ipv4 }} |
{% endfor %}
{% endfor %}
<a href="{% url 'instance' compute.id vname %}" title="{% trans 'refresh instance info' %}"><span class="fa fa-refresh"></span></a>
</div>
{% if user_quota_msg %}
<span class="label label-warning">{{ user_quota_msg|capfirst }} {% trans "quota reached" %}.</span>
@ -549,54 +572,51 @@
{% endifequal %}
</div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="managesnapshot">
{% ifequal status 5 %}
{% if snapshots %}
<p>{% trans "Choose a snapshot for restore/delete" %}</p>
<div class="table-responsive">
<table class="table">
<thead>
<th>{% trans "Name" %}</th>
<th>{% trans "Date" %}</th>
<th colspan="2">{% trans "Action" %}</th>
</thead>
<tbody>
{% for snap in snapshots %}
<tr>
<td><strong>{{ snap.name }}</strong></td>
<td>{{ snap.date|date:"M d H:i:s" }}</td>
<td style="width:30px;">
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ snap.name }}">
{% ifequal status 5 %}
<button type="submit" class="btn btn-sm btn-default" name="revert_snapshot" title="Revert to this Snapshot" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-save"></span>
</button>
{% else %}
<button type="button" class="btn btn-sm btn-default disabled">
<span class="glyphicon glyphicon-save"></span>
</button>
{% endifequal %}
</form>
</td>
<td style="width:30px;">
<form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ snap.name }}">
<button type="submit" class="btn btn-sm btn-default" name="delete_snapshot" title="Delete Snapshot" onclick="return confirm('{% trans "Are you sure?" %}')">
<span class="glyphicon glyphicon-trash"></span>
{% if snapshots %}
<p>{% trans "Choose a snapshot for restore/delete" %}</p>
<div class="table-responsive">
<table class="table">
<thead>
<th>{% trans "Name" %}</th>
<th>{% trans "Date" %}</th>
<th colspan="2">{% trans "Action" %}</th>
</thead>
<tbody>
{% for snap in snapshots %}
<tr>
<td><strong>{{ snap.name }}</strong></td>
<td>{{ snap.date|date:"M d H:i:s" }}</td>
<td style="width:30px;">
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ snap.name }}">
{% ifequal status 5 %}
<button type="submit" class="btn btn-sm btn-default" name="revert_snapshot" title="Revert to this Snapshot" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-save"></span>
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p>{% trans "You do not have any snapshots" %}</p>
{% endif %}
{% else %}
<button type="button" class="btn btn-sm btn-default disabled"
title="{% trans "To restore snapshots you need Power Off the instance." %}">
<span class="glyphicon glyphicon-save"></span>
</button>
{% endifequal %}
</form>
</td>
<td style="width:30px;">
<form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ snap.name }}">
<button type="submit" class="btn btn-sm btn-default" name="delete_snapshot" title="Delete Snapshot" onclick="return confirm('{% trans "Are you sure?" %}')">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p>{% trans "To restore snapshots you need Power Off the instance." %}</p>
{% endifequal %}
<p>{% trans "You do not have any snapshots" %}</p>
{% endif %}
</div>
</div>
</div>
@ -747,15 +767,13 @@
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
<p style="font-weight:bold;">
{% trans "Instance Media" %}
{% if status == 5 %}
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right" title="Add CD-ROM">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
{% else %}
<button type="submit" type="button" class="btn btn-success disabled pull-right" title="Add CD-ROM" disabled>
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right"
title="Add CD-ROM"
{% if status != 5 %} disabled {% endif %} >
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
{% endif %}
</p>
</form>
{% for cd in media %}

View file

@ -8,7 +8,7 @@ import string
import random
from bisect import insort
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required
@ -663,7 +663,7 @@ def instance(request, compute_id, vname):
if 'add_cdrom' in request.POST and allow_admin_or_not_template:
bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
target = get_new_disk_dev(media, disks, bus)
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
conn.attach_disk("", target, disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True)
msg = _('Add CD-ROM: ' + target)
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')

View file

@ -1,6 +1,6 @@
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from computes.models import Compute
from interfaces.forms import AddInterface

View file

@ -1,6 +1,6 @@
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from instances.models import Instance
from logs.models import Logs

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from computes.models import Compute
from networks.forms import AddNetPool
@ -44,7 +44,7 @@ def networks(request, compute_id):
msg = _("Network pool name already in use")
error_messages.append(msg)
if data['forward'] == 'bridge' and data['bridge_name'] == '':
error_messages.append('Please enter bridge name')
error_messages.append(_('Please enter bridge name'))
if data['subnet']:
ipv4 = True
gateway4, netmask4, dhcp4 = network_size(data['subnet'], data['dhcp4'])
@ -52,7 +52,7 @@ def networks(request, compute_id):
ipv6 = True
gateway6, prefix6, dhcp6 = network_size(data['subnet6'], data['dhcp6'])
if prefix6 != '64':
error_messages.append('For libvirt, the IPv6 network prefix must be /64')
error_messages.append(_('For libvirt, the IPv6 network prefix must be /64'))
if not error_messages:
conn.create_network(data['name'],
data['forward'],
@ -113,7 +113,7 @@ def network(request, compute_id, pool):
ipv6_network = ip_network
ipv6_fixed_address = conn.get_dhcp_host_addr(family)
else:
raise Exception("Unknown Network Family")
raise Exception(_("Unknown Network Family"))
xml = conn._XMLDesc(0)
except libvirtError as lib_err:
@ -163,7 +163,7 @@ def network(request, compute_id, pool):
try:
ret_val = conn.modify_fixed_address(name, address, mac_duid, family)
messages.success(request, "{} Fixed Address Operation Completed.".format(family.upper()))
messages.success(request, _("{} Fixed Address Operation Completed.").format(family.upper()))
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err.message)
@ -173,7 +173,7 @@ def network(request, compute_id, pool):
ip = request.POST.get('address', '')
family = request.POST.get('family', 'ipv4')
conn.delete_fixed_address(ip, family)
messages.success(request, "{} Fixed Address is Deleted.".format(family.upper()))
messages.success(request, _("{} Fixed Address is Deleted.").format(family.upper()))
return HttpResponseRedirect(request.get_full_path())
if 'modify_dhcp_range' in request.POST:
range_start = request.POST.get('range_start', '')
@ -181,7 +181,7 @@ def network(request, compute_id, pool):
family = request.POST.get('family', 'ipv4')
try:
conn.modify_dhcp_range(range_start, range_end, family)
messages.success(request, "{} DHCP Range is Changed.".format(family.upper()))
messages.success(request, _("{} DHCP Range is Changed.").format(family.upper()))
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err.message)
@ -204,10 +204,10 @@ def network(request, compute_id, pool):
try:
conn.set_qos(qos_dir, average, peak, burst)
if conn.is_active():
messages.success(request, "{} Qos is set. Network XML is changed.".format(qos_dir.capitalize()) +
"Stop and start network to activate new config")
messages.success(request, _("{} Qos is set. Network XML is changed.").format(qos_dir.capitalize()) +
_("Stop and start network to activate new config"))
else:
messages.success(request, "{} Qos is set".format(qos_dir.capitalize()))
messages.success(request, _("{} Qos is set").format(qos_dir.capitalize()))
except libvirtError as le:
messages.error(request, le.message)
return HttpResponseRedirect(request.get_full_path())
@ -216,10 +216,10 @@ def network(request, compute_id, pool):
conn.unset_qos(qos_dir)
if conn.is_active():
messages.success(request, "{} Qos is deleted. Network XML is changed. ".format(qos_dir.capitalize()) +
"Stop and start network to activate new config.")
messages.success(request, _("{} Qos is deleted. Network XML is changed. ").format(qos_dir.capitalize()) +
_("Stop and start network to activate new config."))
else:
messages.success(request, "{} Qos is deleted".format(qos_dir.capitalize()))
messages.success(request, _("{} Qos is deleted").format(qos_dir.capitalize()))
return HttpResponseRedirect(request.get_full_path())
conn.close()

View file

@ -4,7 +4,7 @@ from __future__ import unicode_literals
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from computes.models import Compute
from vrtManager import util

View file

@ -1,6 +1,6 @@
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from computes.models import Compute
from secrets.forms import AddSecret

File diff suppressed because one or more lines are too long

View file

@ -82,6 +82,8 @@
* 2) Use the keyboards native set and translate it to common keysyms.
*/
var KeyNames = {
/*
* definition of the AT84/MF101/MF102 Keyboard:
* ============================================================
@ -89,95 +91,99 @@
* Key Name Main Also (hex) (dec)
* ---------------- ---------- ------- ------ ------
*/
KEY_Escape :/* Escape 0x01 */ 1,
KEY_1 :/* 1 ! 0x02 */ 2,
KEY_2 :/* 2 @ 0x03 */ 3,
KEY_3 :/* 3 # 0x04 */ 4,
KEY_4 :/* 4 $ 0x05 */ 5,
KEY_5 :/* 5 % 0x06 */ 6,
KEY_6 :/* 6 ^ 0x07 */ 7,
KEY_7 :/* 7 & 0x08 */ 8,
KEY_8 :/* 8 * 0x09 */ 9,
KEY_9 :/* 9 ( 0x0a */ 10,
KEY_0 :/* 0 ) 0x0b */ 11,
KEY_Minus :/* - (Minus) _ (Under) 0x0c */ 12,
KEY_Equal :/* = (Equal) + 0x0d */ 13,
KEY_BackSpace :/* Back Space 0x0e */ 14,
KEY_Tab :/* Tab 0x0f */ 15,
KEY_Q :/* Q 0x10 */ 16,
KEY_W :/* W 0x11 */ 17,
KEY_E :/* E 0x12 */ 18,
KEY_R :/* R 0x13 */ 19,
KEY_T :/* T 0x14 */ 20,
KEY_Y :/* Y 0x15 */ 21,
KEY_U :/* U 0x16 */ 22,
KEY_I :/* I 0x17 */ 23,
KEY_O :/* O 0x18 */ 24,
KEY_P :/* P 0x19 */ 25,
KEY_LBrace :/* [ { 0x1a */ 26,
KEY_RBrace :/* ] } 0x1b */ 27,
KEY_Enter :/* Enter 0x1c */ 28,
KEY_LCtrl :/* Ctrl(left) 0x1d */ 29,
KEY_A :/* A 0x1e */ 30,
KEY_S :/* S 0x1f */ 31,
KEY_D :/* D 0x20 */ 32,
KEY_F :/* F 0x21 */ 33,
KEY_G :/* G 0x22 */ 34,
KEY_H :/* H 0x23 */ 35,
KEY_J :/* J 0x24 */ 36,
KEY_K :/* K 0x25 */ 37,
KEY_L :/* L 0x26 */ 38,
KEY_SemiColon :/* ;(SemiColon) :(Colon) 0x27 */ 39,
KEY_Quote :/* ' (Apostr) " (Quote) 0x28 */ 40,
KEY_Tilde :/* ` (Accent) ~ (Tilde) 0x29 */ 41,
KEY_ShiftL :/* Shift(left) 0x2a */ 42,
KEY_BSlash :/* \(BckSlash) |(VertBar)0x2b */ 43,
KEY_Z :/* Z 0x2c */ 44,
KEY_X :/* X 0x2d */ 45,
KEY_C :/* C 0x2e */ 46,
KEY_V :/* V 0x2f */ 47,
KEY_B :/* B 0x30 */ 48,
KEY_N :/* N 0x31 */ 49,
KEY_M :/* M 0x32 */ 50,
KEY_Comma :/* , (Comma) < (Less) 0x33 */ 51,
KEY_Period :/* . (Period) >(Greater)0x34 */ 52,
KEY_Slash :/* / (Slash) ? 0x35 */ 53,
KEY_ShiftR :/* Shift(right) 0x36 */ 54,
KEY_KP_Multiply :/* * 0x37 */ 55,
KEY_Alt :/* Alt(left) 0x38 */ 56,
KEY_Space :/* (SpaceBar) 0x39 */ 57,
KEY_CapsLock :/* CapsLock 0x3a */ 58,
KEY_F1 :/* F1 0x3b */ 59,
KEY_F2 :/* F2 0x3c */ 60,
KEY_F3 :/* F3 0x3d */ 61,
KEY_F4 :/* F4 0x3e */ 62,
KEY_F5 :/* F5 0x3f */ 63,
KEY_F6 :/* F6 0x40 */ 64,
KEY_F7 :/* F7 0x41 */ 65,
KEY_F8 :/* F8 0x42 */ 66,
KEY_F9 :/* F9 0x43 */ 67,
KEY_F10 :/* F10 0x44 */ 68,
KEY_NumLock :/* NumLock 0x45 */ 69,
KEY_ScrollLock :/* ScrollLock 0x46 */ 70,
KEY_KP_7 :/* 7 Home 0x47 */ 71,
KEY_KP_8 :/* 8 Up 0x48 */ 72,
KEY_KP_9 :/* 9 PgUp 0x49 */ 73,
KEY_KP_Minus :/* - (Minus) 0x4a */ 74,
KEY_KP_4 :/* 4 Left 0x4b */ 75,
KEY_KP_5 :/* 5 0x4c */ 76,
KEY_KP_6 :/* 6 Right 0x4d */ 77,
KEY_KP_Plus :/* + (Plus) 0x4e */ 78,
KEY_KP_1 :/* 1 End 0x4f */ 79,
KEY_KP_2 :/* 2 Down 0x50 */ 80,
KEY_KP_3 :/* 3 PgDown 0x51 */ 81,
KEY_KP_0 :/* 0 Insert 0x52 */ 82,
KEY_KP_Decimal :/* . (Decimal) Delete 0x53 */ 83,
KEY_SysRequest :/* SysRequest 0x54 */ 84,
/* NOTUSED 0x55 */
KEY_Less :/* < (Less) >(Greater) 0x56 */ 86,
KEY_F11 :/* F11 0x57 */ 87,
KEY_F12 :/* F12 0x58 */ 88,
var KEY_Escape =/* Escape 0x01 */ 1
var KEY_1 =/* 1 ! 0x02 */ 2
var KEY_2 =/* 2 @ 0x03 */ 3
var KEY_3 =/* 3 # 0x04 */ 4
var KEY_4 =/* 4 $ 0x05 */ 5
var KEY_5 =/* 5 % 0x06 */ 6
var KEY_6 =/* 6 ^ 0x07 */ 7
var KEY_7 =/* 7 & 0x08 */ 8
var KEY_8 =/* 8 * 0x09 */ 9
var KEY_9 =/* 9 ( 0x0a */ 10
var KEY_0 =/* 0 ) 0x0b */ 11
var KEY_Minus =/* - (Minus) _ (Under) 0x0c */ 12
var KEY_Equal =/* = (Equal) + 0x0d */ 13
var KEY_BackSpace =/* Back Space 0x0e */ 14
var KEY_Tab =/* Tab 0x0f */ 15
var KEY_Q =/* Q 0x10 */ 16
var KEY_W =/* W 0x11 */ 17
var KEY_E =/* E 0x12 */ 18
var KEY_R =/* R 0x13 */ 19
var KEY_T =/* T 0x14 */ 20
var KEY_Y =/* Y 0x15 */ 21
var KEY_U =/* U 0x16 */ 22
var KEY_I =/* I 0x17 */ 23
var KEY_O =/* O 0x18 */ 24
var KEY_P =/* P 0x19 */ 25
var KEY_LBrace =/* [ { 0x1a */ 26
var KEY_RBrace =/* ] } 0x1b */ 27
var KEY_Enter =/* Enter 0x1c */ 28
var KEY_LCtrl =/* Ctrl(left) 0x1d */ 29
var KEY_A =/* A 0x1e */ 30
var KEY_S =/* S 0x1f */ 31
var KEY_D =/* D 0x20 */ 32
var KEY_F =/* F 0x21 */ 33
var KEY_G =/* G 0x22 */ 34
var KEY_H =/* H 0x23 */ 35
var KEY_J =/* J 0x24 */ 36
var KEY_K =/* K 0x25 */ 37
var KEY_L =/* L 0x26 */ 38
var KEY_SemiColon =/* ;(SemiColon) :(Colon) 0x27 */ 39
var KEY_Quote =/* ' (Apostr) " (Quote) 0x28 */ 40
var KEY_Tilde =/* ` (Accent) ~ (Tilde) 0x29 */ 41
var KEY_ShiftL =/* Shift(left) 0x2a */ 42
var KEY_BSlash =/* \(BckSlash) |(VertBar)0x2b */ 43
var KEY_Z =/* Z 0x2c */ 44
var KEY_X =/* X 0x2d */ 45
var KEY_C =/* C 0x2e */ 46
var KEY_V =/* V 0x2f */ 47
var KEY_B =/* B 0x30 */ 48
var KEY_N =/* N 0x31 */ 49
var KEY_M =/* M 0x32 */ 50
var KEY_Comma =/* , (Comma) < (Less) 0x33 */ 51
var KEY_Period =/* . (Period) >(Greater)0x34 */ 52
var KEY_Slash =/* / (Slash) ? 0x35 */ 53
var KEY_ShiftR =/* Shift(right) 0x36 */ 54
var KEY_KP_Multiply =/* * 0x37 */ 55
var KEY_Alt =/* Alt(left) 0x38 */ 56
var KEY_Space =/* (SpaceBar) 0x39 */ 57
var KEY_CapsLock =/* CapsLock 0x3a */ 58
var KEY_F1 =/* F1 0x3b */ 59
var KEY_F2 =/* F2 0x3c */ 60
var KEY_F3 =/* F3 0x3d */ 61
var KEY_F4 =/* F4 0x3e */ 62
var KEY_F5 =/* F5 0x3f */ 63
var KEY_F6 =/* F6 0x40 */ 64
var KEY_F7 =/* F7 0x41 */ 65
var KEY_F8 =/* F8 0x42 */ 66
var KEY_F9 =/* F9 0x43 */ 67
var KEY_F10 =/* F10 0x44 */ 68
var KEY_NumLock =/* NumLock 0x45 */ 69
var KEY_ScrollLock =/* ScrollLock 0x46 */ 70
var KEY_KP_7 =/* 7 Home 0x47 */ 71
var KEY_KP_8 =/* 8 Up 0x48 */ 72
var KEY_KP_9 =/* 9 PgUp 0x49 */ 73
var KEY_KP_Minus =/* - (Minus) 0x4a */ 74
var KEY_KP_4 =/* 4 Left 0x4b */ 75
var KEY_KP_5 =/* 5 0x4c */ 76
var KEY_KP_6 =/* 6 Right 0x4d */ 77
var KEY_KP_Plus =/* + (Plus) 0x4e */ 78
var KEY_KP_1 =/* 1 End 0x4f */ 79
var KEY_KP_2 =/* 2 Down 0x50 */ 80
var KEY_KP_3 =/* 3 PgDown 0x51 */ 81
var KEY_KP_0 =/* 0 Insert 0x52 */ 82
var KEY_KP_Decimal =/* . (Decimal) Delete 0x53 */ 83
var KEY_SysReqest =/* SysReqest 0x54 */ 84
/* NOTUSED 0x55 */
var KEY_Less =/* < (Less) >(Greater) 0x56 */ 86
var KEY_F11 =/* F11 0x57 */ 87
var KEY_F12 =/* F12 0x58 */ 88
KEY_Prefix0 :/* special 0x60 */ 96,
KEY_Prefix1 :/* specail 0x61 */ 97,
};
var KEY_Prefix0 =/* special 0x60 */ 96
var KEY_Prefix1 =/* specail 0x61 */ 97
export {
KeyNames,
};

View file

@ -23,16 +23,19 @@
** bitmap.js
** Handle SPICE_IMAGE_TYPE_BITMAP
**--------------------------------------------------------------------------*/
import { Constants } from './enums.js';
function convert_spice_bitmap_to_web(context, spice_bitmap)
{
var ret;
var offset, x, src_offset = 0, src_dec = 0;
var u8 = new Uint8Array(spice_bitmap.data);
if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT &&
spice_bitmap.format != SPICE_BITMAP_FMT_RGBA)
if (spice_bitmap.format != Constants.SPICE_BITMAP_FMT_32BIT &&
spice_bitmap.format != Constants.SPICE_BITMAP_FMT_RGBA)
return undefined;
if (!(spice_bitmap.flags & SPICE_BITMAP_FLAGS_TOP_DOWN))
if (!(spice_bitmap.flags & Constants.SPICE_BITMAP_FLAGS_TOP_DOWN))
{
src_offset = (spice_bitmap.y - 1 ) * spice_bitmap.stride;
src_dec = 2 * spice_bitmap.stride;
@ -47,7 +50,7 @@ function convert_spice_bitmap_to_web(context, spice_bitmap)
ret.data[offset + 2 ] = u8[src_offset + 0];
// FIXME - We effectively treat all images as having SPICE_IMAGE_FLAGS_HIGH_BITS_SET
if (spice_bitmap.format == SPICE_BITMAP_FMT_32BIT)
if (spice_bitmap.format == Constants.SPICE_BITMAP_FMT_32BIT)
ret.data[offset + 3] = 255;
else
ret.data[offset + 3] = u8[src_offset];
@ -55,3 +58,7 @@ function convert_spice_bitmap_to_web(context, spice_bitmap)
return ret;
}
export {
convert_spice_bitmap_to_web,
};

View file

@ -18,6 +18,15 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import { create_rgba_png } from './png.js';
import { Constants } from './enums.js';
import { DEBUG } from './utils.js';
import {
SpiceMsgCursorInit,
SpiceMsgCursorSet,
} from './spicemsg.js';
import { SpiceSimulateCursor } from './simulatecursor.js';
import { SpiceConn } from './spiceconn.js';
/*----------------------------------------------------------------------------
** SpiceCursorConn
@ -31,12 +40,12 @@ function SpiceCursorConn()
SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
SpiceCursorConn.prototype.process_channel_message = function(msg)
{
if (msg.type == SPICE_MSG_CURSOR_INIT)
if (msg.type == Constants.SPICE_MSG_CURSOR_INIT)
{
var cursor_init = new SpiceMsgCursorInit(msg.data);
DEBUG > 1 && console.log("SpiceMsgCursorInit");
if (this.parent && this.parent.inputs &&
this.parent.inputs.mouse_mode == SPICE_MOUSE_MODE_SERVER)
this.parent.inputs.mouse_mode == Constants.SPICE_MOUSE_MODE_SERVER)
{
// FIXME - this imagines that the server actually
// provides the current cursor position,
@ -49,11 +58,11 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_CURSOR_SET)
if (msg.type == Constants.SPICE_MSG_CURSOR_SET)
{
var cursor_set = new SpiceMsgCursorSet(msg.data);
DEBUG > 1 && console.log("SpiceMsgCursorSet");
if (cursor_set.flags & SPICE_CURSOR_FLAGS_NONE)
if (cursor_set.flags & Constants.SPICE_CURSOR_FLAGS_NONE)
{
document.getElementById(this.parent.screen_id).style.cursor = "none";
return true;
@ -62,7 +71,7 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
if (cursor_set.flags > 0)
this.log_warn("FIXME: No support for cursor flags " + cursor_set.flags);
if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
if (cursor_set.cursor.header.type != Constants.SPICE_CURSOR_TYPE_ALPHA)
{
this.log_warn("FIXME: No support for cursor type " + cursor_set.cursor.header.type);
return false;
@ -73,39 +82,39 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_CURSOR_MOVE)
if (msg.type == Constants.SPICE_MSG_CURSOR_MOVE)
{
this.known_unimplemented(msg.type, "Cursor Move");
return true;
}
if (msg.type == SPICE_MSG_CURSOR_HIDE)
if (msg.type == Constants.SPICE_MSG_CURSOR_HIDE)
{
DEBUG > 1 && console.log("SpiceMsgCursorHide");
document.getElementById(this.parent.screen_id).style.cursor = "none";
return true;
}
if (msg.type == SPICE_MSG_CURSOR_TRAIL)
if (msg.type == Constants.SPICE_MSG_CURSOR_TRAIL)
{
this.known_unimplemented(msg.type, "Cursor Trail");
return true;
}
if (msg.type == SPICE_MSG_CURSOR_RESET)
if (msg.type == Constants.SPICE_MSG_CURSOR_RESET)
{
DEBUG > 1 && console.log("SpiceMsgCursorReset");
document.getElementById(this.parent.screen_id).style.cursor = "auto";
return true;
}
if (msg.type == SPICE_MSG_CURSOR_INVAL_ONE)
if (msg.type == Constants.SPICE_MSG_CURSOR_INVAL_ONE)
{
this.known_unimplemented(msg.type, "Cursor Inval One");
return true;
}
if (msg.type == SPICE_MSG_CURSOR_INVAL_ALL)
if (msg.type == Constants.SPICE_MSG_CURSOR_INVAL_ALL)
{
DEBUG > 1 && console.log("SpiceMsgCursorInvalAll");
// FIXME - There may be something useful to do here...
@ -117,7 +126,7 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
SpiceCursorConn.prototype.set_cursor = function(cursor)
{
var pngstr = create_rgba_png(cursor.header.height, cursor.header.width, cursor.data);
var pngstr = create_rgba_png(cursor.header.width, cursor.header.height, cursor.data);
var curstr = 'url(data:image/png,' + pngstr + ') ' +
cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
var screen = document.getElementById(this.parent.screen_id);
@ -126,3 +135,7 @@ SpiceCursorConn.prototype.set_cursor = function(cursor)
if (window.getComputedStyle(screen, null).cursor == 'auto')
SpiceSimulateCursor.simulate_cursor(this, cursor, screen, pngstr);
}
export {
SpiceCursorConn,
};

View file

@ -18,6 +18,16 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import * as Webm from './webm.js';
import * as Messages from './spicemsg.js';
import * as Quic from './quic.js';
import * as Utils from './utils.js';
import * as Inputs from './inputs.js';
import { Constants } from './enums.js';
import { SpiceConn } from './spiceconn.js';
import { SpiceRect } from './spicetype.js';
import { convert_spice_lz_to_web } from './lz.js';
import { convert_spice_bitmap_to_web } from './bitmap.js';
/*----------------------------------------------------------------------------
** FIXME: putImageData does not support Alpha blending
@ -62,37 +72,37 @@ function SpiceDisplayConn()
SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
SpiceDisplayConn.prototype.process_channel_message = function(msg)
{
if (msg.type == SPICE_MSG_DISPLAY_MODE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_MODE)
{
this.known_unimplemented(msg.type, "Display Mode");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_MARK)
if (msg.type == Constants.SPICE_MSG_DISPLAY_MARK)
{
// FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
this.known_unimplemented(msg.type, "Display Mark");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_RESET)
if (msg.type == Constants.SPICE_MSG_DISPLAY_RESET)
{
DEBUG > 2 && console.log("Display reset");
Utils.DEBUG > 2 && console.log("Display reset");
this.surfaces[this.primary_surface].canvas.context.restore();
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_COPY)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_COPY)
{
var draw_copy = new SpiceMsgDisplayDrawCopy(msg.data);
var draw_copy = new Messages.SpiceMsgDisplayDrawCopy(msg.data);
DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
Utils.DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
if (! draw_copy.base.box.is_same_size(draw_copy.data.src_area))
this.log_warn("FIXME: DrawCopy src_area is a different size than base.box; we do not handle that yet.");
if (draw_copy.base.clip.type != SPICE_CLIP_TYPE_NONE)
if (draw_copy.base.clip.type != Constants.SPICE_CLIP_TYPE_NONE)
this.log_warn("FIXME: DrawCopy we don't handle clipping yet");
if (draw_copy.data.rop_descriptor != SPICE_ROPD_OP_PUT)
if (draw_copy.data.rop_descriptor != Constants.SPICE_ROPD_OP_PUT)
this.log_warn("FIXME: DrawCopy we don't handle ropd type: " + draw_copy.data.rop_descriptor);
if (draw_copy.data.mask.flags)
this.log_warn("FIXME: DrawCopy we don't handle mask flag: " + draw_copy.data.mask.flags);
@ -102,14 +112,14 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
if (draw_copy.data && draw_copy.data.src_bitmap)
{
if (draw_copy.data.src_bitmap.descriptor.flags &&
draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_CACHE_ME &&
draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
draw_copy.data.src_bitmap.descriptor.flags != Constants.SPICE_IMAGE_FLAGS_CACHE_ME &&
draw_copy.data.src_bitmap.descriptor.flags != Constants.SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
{
this.log_warn("FIXME: DrawCopy unhandled image flags: " + draw_copy.data.src_bitmap.descriptor.flags);
DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
Utils.DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
}
if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_QUIC)
{
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
if (! draw_copy.data.src_bitmap.quic)
@ -117,7 +127,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
this.log_warn("FIXME: DrawCopy could not handle this QUIC file.");
return false;
}
var source_img = convert_spice_quic_to_web(canvas.context,
var source_img = Quic.convert_spice_quic_to_web(canvas.context,
draw_copy.data.src_bitmap.quic);
return this.draw_copy_helper(
@ -125,12 +135,12 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
src_area: draw_copy.data.src_area,
image_data: source_img,
tag: "copyquic." + draw_copy.data.src_bitmap.quic.type,
has_alpha: (draw_copy.data.src_bitmap.quic.type == QUIC_IMAGE_TYPE_RGBA ? true : false) ,
has_alpha: (draw_copy.data.src_bitmap.quic.type == Quic.Constants.QUIC_IMAGE_TYPE_RGBA ? true : false) ,
descriptor : draw_copy.data.src_bitmap.descriptor
});
}
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE ||
draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_FROM_CACHE ||
draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
{
if (! this.cache || ! this.cache[draw_copy.data.src_bitmap.descriptor.id])
{
@ -149,7 +159,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
/* FIXME - LOSSLESS CACHE ramifications not understood or handled */
}
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_SURFACE)
{
var source_context = this.surfaces[draw_copy.data.src_bitmap.surface_id].canvas.context;
var target_context = this.surfaces[draw_copy.base.surface_id].canvas.context;
@ -174,11 +184,11 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
src_area: computed_src_area,
image_data: source_img,
tag: "copysurf." + draw_copy.data.src_bitmap.surface_id,
has_alpha: this.surfaces[draw_copy.data.src_bitmap.surface_id].format == SPICE_SURFACE_FMT_32_xRGB ? false : true,
has_alpha: this.surfaces[draw_copy.data.src_bitmap.surface_id].format == Constants.SPICE_SURFACE_FMT_32_xRGB ? false : true,
descriptor : draw_copy.data.src_bitmap.descriptor
});
}
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_JPEG)
{
if (! draw_copy.data.src_bitmap.jpeg)
{
@ -211,7 +221,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_JPEG_ALPHA)
{
if (! draw_copy.data.src_bitmap.jpeg_alpha)
{
@ -240,7 +250,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
sc : this,
};
if (this.surfaces[draw_copy.base.surface_id].format == SPICE_SURFACE_FMT_32_ARGB)
if (this.surfaces[draw_copy.base.surface_id].format == Constants.SPICE_SURFACE_FMT_32_ARGB)
{
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
@ -252,7 +262,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_BITMAP)
{
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
if (! draw_copy.data.src_bitmap.bitmap)
@ -275,11 +285,11 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
src_area: draw_copy.data.src_area,
image_data: source_img,
tag: "bitmap." + draw_copy.data.src_bitmap.bitmap.format,
has_alpha: draw_copy.data.src_bitmap.bitmap == SPICE_BITMAP_FMT_32BIT ? false : true,
has_alpha: draw_copy.data.src_bitmap.bitmap == Constants.SPICE_BITMAP_FMT_32BIT ? false : true,
descriptor : draw_copy.data.src_bitmap.descriptor
});
}
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_LZ_RGB)
{
var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
if (! draw_copy.data.src_bitmap.lz_rgb)
@ -302,7 +312,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
src_area: draw_copy.data.src_area,
image_data: source_img,
tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type,
has_alpha: draw_copy.data.src_bitmap.lz_rgb.type == LZ_IMAGE_TYPE_RGBA ? true : false ,
has_alpha: draw_copy.data.src_bitmap.lz_rgb.type == Constants.LZ_IMAGE_TYPE_RGBA ? true : false ,
descriptor : draw_copy.data.src_bitmap.descriptor
});
}
@ -318,20 +328,20 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return false;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_FILL)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_FILL)
{
var draw_fill = new SpiceMsgDisplayDrawFill(msg.data);
var draw_fill = new Messages.SpiceMsgDisplayDrawFill(msg.data);
DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
Utils.DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
if (draw_fill.data.rop_descriptor != SPICE_ROPD_OP_PUT)
if (draw_fill.data.rop_descriptor != Constants.SPICE_ROPD_OP_PUT)
this.log_warn("FIXME: DrawFill we don't handle ropd type: " + draw_fill.data.rop_descriptor);
if (draw_fill.data.mask.flags)
this.log_warn("FIXME: DrawFill we don't handle mask flag: " + draw_fill.data.mask.flags);
if (draw_fill.data.mask.bitmap)
this.log_warn("FIXME: DrawFill we don't handle mask");
if (draw_fill.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
if (draw_fill.data.brush.type == Constants.SPICE_BRUSH_TYPE_SOLID)
{
// FIXME - do brushes ever have alpha?
var color = draw_fill.data.brush.color & 0xffffff;
@ -343,7 +353,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
draw_fill.base.box.right - draw_fill.base.box.left,
draw_fill.base.box.bottom - draw_fill.base.box.top);
if (DUMP_DRAWS && this.parent.dump_id)
if (Utils.DUMP_DRAWS && this.parent.dump_id)
{
var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('width', this.surfaces[draw_fill.base.surface_id].canvas.width);
@ -367,65 +377,65 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_OPAQUE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_OPAQUE)
{
this.known_unimplemented(msg.type, "Display Draw Opaque");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_BLEND)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_BLEND)
{
this.known_unimplemented(msg.type, "Display Draw Blend");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_BLACKNESS)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_BLACKNESS)
{
this.known_unimplemented(msg.type, "Display Draw Blackness");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_WHITENESS)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_WHITENESS)
{
this.known_unimplemented(msg.type, "Display Draw Whiteness");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_INVERS)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_INVERS)
{
this.known_unimplemented(msg.type, "Display Draw Invers");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_ROP3)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_ROP3)
{
this.known_unimplemented(msg.type, "Display Draw ROP3");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_STROKE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_STROKE)
{
this.known_unimplemented(msg.type, "Display Draw Stroke");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_TRANSPARENT)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_TRANSPARENT)
{
this.known_unimplemented(msg.type, "Display Draw Transparent");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND)
{
this.known_unimplemented(msg.type, "Display Draw Alpha Blend");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_COPY_BITS)
if (msg.type == Constants.SPICE_MSG_DISPLAY_COPY_BITS)
{
var copy_bits = new SpiceMsgDisplayCopyBits(msg.data);
var copy_bits = new Messages.SpiceMsgDisplayCopyBits(msg.data);
DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
Utils.DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
var source_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
var source_context = source_canvas.context;
@ -442,7 +452,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
//source_context.putImageData(source_img, copy_bits.base.box.left, copy_bits.base.box.top);
putImageDataWithAlpha(source_context, source_img, copy_bits.base.box.left, copy_bits.base.box.top);
if (DUMP_DRAWS && this.parent.dump_id)
if (Utils.DUMP_DRAWS && this.parent.dump_id)
{
var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('width', width);
@ -457,36 +467,36 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS)
if (msg.type == Constants.SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS)
{
this.known_unimplemented(msg.type, "Display Inval All Pixmaps");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_INVAL_PALETTE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_INVAL_PALETTE)
{
this.known_unimplemented(msg.type, "Display Inval Palette");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
if (msg.type == Constants.SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
{
this.known_unimplemented(msg.type, "Inval All Palettes");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_SURFACE_CREATE)
{
if (! ("surfaces" in this))
this.surfaces = [];
var m = new SpiceMsgSurfaceCreate(msg.data);
DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id
var m = new Messages.SpiceMsgSurfaceCreate(msg.data);
Utils.DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id
+ "; " + m.surface.width + "x" + m.surface.height
+ "; format " + m.surface.format
+ "; flags " + m.surface.flags);
if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB &&
m.surface.format != SPICE_SURFACE_FMT_32_ARGB)
if (m.surface.format != Constants.SPICE_SURFACE_FMT_32_xRGB &&
m.surface.format != Constants.SPICE_SURFACE_FMT_32_ARGB)
{
this.log_warn("FIXME: cannot handle surface format " + m.surface.format + " yet.");
return false;
@ -499,14 +509,14 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
canvas.setAttribute('tabindex', m.surface.surface_id);
canvas.context = canvas.getContext("2d");
if (DUMP_CANVASES && this.parent.dump_id)
if (Utils.DUMP_CANVASES && this.parent.dump_id)
document.getElementById(this.parent.dump_id).appendChild(canvas);
m.surface.canvas = canvas;
m.surface.draw_count = 0;
this.surfaces[m.surface.surface_id] = m.surface;
if (m.surface.flags & SPICE_SURFACE_FLAGS_PRIMARY)
if (m.surface.flags & Constants.SPICE_SURFACE_FLAGS_PRIMARY)
{
this.primary_surface = m.surface.surface_id;
@ -521,18 +531,18 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_SURFACE_DESTROY)
if (msg.type == Constants.SPICE_MSG_DISPLAY_SURFACE_DESTROY)
{
var m = new SpiceMsgSurfaceDestroy(msg.data);
DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id);
var m = new Messages.SpiceMsgSurfaceDestroy(msg.data);
Utils.DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id);
this.delete_surface(m.surface_id);
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_CREATE)
{
var m = new SpiceMsgDisplayStreamCreate(msg.data);
STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamCreate id" + m.id + "; type " + m.codec_type +
var m = new Messages.SpiceMsgDisplayStreamCreate(msg.data);
Utils.STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamCreate id" + m.id + "; type " + m.codec_type +
"; width " + m.stream_width + "; height " + m.stream_height +
"; left " + m.dest.left + "; top " + m.dest.top
);
@ -543,7 +553,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
else
this.streams[m.id] = m;
if (m.codec_type == SPICE_VIDEO_CODEC_TYPE_VP8)
if (m.codec_type == Constants.SPICE_VIDEO_CODEC_TYPE_VP8)
{
var media = new MediaSource();
var v = document.createElement("video");
@ -579,21 +589,21 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
media.spiceconn = this;
v.spice_stream = s;
}
else if (m.codec_type == SPICE_VIDEO_CODEC_TYPE_MJPEG)
else if (m.codec_type == Constants.SPICE_VIDEO_CODEC_TYPE_MJPEG)
this.streams[m.id].frames_loading = 0;
else
console.log("Unhandled stream codec: "+m.codec_type);
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA ||
msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DATA ||
msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
{
var m;
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
m = new SpiceMsgDisplayStreamDataSized(msg.data);
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
m = new Messages.SpiceMsgDisplayStreamDataSized(msg.data);
else
m = new SpiceMsgDisplayStreamData(msg.data);
m = new Messages.SpiceMsgDisplayStreamData(msg.data);
if (!this.streams[m.base.id])
{
@ -603,20 +613,20 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
var time_until_due = m.base.multi_media_time - this.parent.relative_now();
if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
if (this.streams[m.base.id].codec_type === Constants.SPICE_VIDEO_CODEC_TYPE_MJPEG)
process_mjpeg_stream_data(this, m, time_until_due);
if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_VP8)
if (this.streams[m.base.id].codec_type === Constants.SPICE_VIDEO_CODEC_TYPE_VP8)
process_video_stream_data(this.streams[m.base.id], m);
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT)
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT)
{
var m = new SpiceMsgDisplayStreamActivateReport(msg.data);
var m = new Messages.SpiceMsgDisplayStreamActivateReport(msg.data);
var report = new SpiceMsgcDisplayStreamReport(m.stream_id, m.unique_id);
var report = new Messages.SpiceMsgcDisplayStreamReport(m.stream_id, m.unique_id);
if (this.streams[m.stream_id])
{
this.streams[m.stream_id].report = report;
@ -627,20 +637,20 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_CLIP)
{
var m = new SpiceMsgDisplayStreamClip(msg.data);
STREAM_DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
var m = new Messages.SpiceMsgDisplayStreamClip(msg.data);
Utils.STREAM_DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
this.streams[m.id].clip = m.clip;
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DESTROY)
{
var m = new SpiceMsgDisplayStreamDestroy(msg.data);
STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamDestroy id" + m.id);
var m = new Messages.SpiceMsgDisplayStreamDestroy(msg.data);
Utils.STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamDestroy id" + m.id);
if (this.streams[m.id].codec_type == SPICE_VIDEO_CODEC_TYPE_VP8)
if (this.streams[m.id].codec_type == Constants.SPICE_VIDEO_CODEC_TYPE_VP8)
{
document.getElementById(this.parent.screen_id).removeChild(this.streams[m.id].video);
this.streams[m.id].source_buffer = null;
@ -651,30 +661,30 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL)
if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL)
{
this.known_unimplemented(msg.type, "Display Stream Destroy All");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_INVAL_LIST)
if (msg.type == Constants.SPICE_MSG_DISPLAY_INVAL_LIST)
{
var m = new SpiceMsgDisplayInvalList(msg.data);
var m = new Messages.SpiceMsgDisplayInvalList(msg.data);
var i;
DEBUG > 1 && console.log(this.type + ": MsgInvalList " + m.count + " items");
Utils.DEBUG > 1 && console.log(this.type + ": MsgInvalList " + m.count + " items");
for (i = 0; i < m.count; i++)
if (this.cache[m.resources[i].id] != undefined)
delete this.cache[m.resources[i].id];
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_MONITORS_CONFIG)
if (msg.type == Constants.SPICE_MSG_DISPLAY_MONITORS_CONFIG)
{
this.known_unimplemented(msg.type, "Display Monitors Config");
return true;
}
if (msg.type == SPICE_MSG_DISPLAY_DRAW_COMPOSITE)
if (msg.type == Constants.SPICE_MSG_DISPLAY_DRAW_COMPOSITE)
{
this.known_unimplemented(msg.type, "Display Draw Composite");
return true;
@ -686,7 +696,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
SpiceDisplayConn.prototype.delete_surface = function(surface_id)
{
var canvas = document.getElementById("spice_surface_" + surface_id);
if (DUMP_CANVASES && this.parent.dump_id)
if (Utils.DUMP_CANVASES && this.parent.dump_id)
document.getElementById(this.parent.dump_id).removeChild(canvas);
if (this.primary_surface == surface_id)
{
@ -707,7 +717,7 @@ SpiceDisplayConn.prototype.draw_copy_helper = function(o)
{
/* FIXME - This is based on trial + error, not a serious thoughtful
analysis of what Spice requires. See display.js for more. */
if (this.surfaces[o.base.surface_id].format == SPICE_SURFACE_FMT_32_xRGB)
if (this.surfaces[o.base.surface_id].format == Constants.SPICE_SURFACE_FMT_32_xRGB)
{
stripAlpha(o.image_data);
canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
@ -724,14 +734,14 @@ SpiceDisplayConn.prototype.draw_copy_helper = function(o)
this.log_warn("FIXME: DrawCopy not shifting draw copies just yet...");
}
if (o.descriptor && (o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
if (o.descriptor && (o.descriptor.flags & Constants.SPICE_IMAGE_FLAGS_CACHE_ME))
{
if (! ("cache" in this))
this.cache = {};
this.cache[o.descriptor.id] = o.image_data;
}
if (DUMP_DRAWS && this.parent.dump_id)
if (Utils.DUMP_DRAWS && this.parent.dump_id)
{
var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('width', o.image_data.width);
@ -769,6 +779,12 @@ SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
str += "; src_bitmap type " + draw.data.src_bitmap.descriptor.type + ", flags " + draw.data.src_bitmap.descriptor.flags;
if (draw.data.src_bitmap.surface_id !== undefined)
str += "; src_bitmap surface_id " + draw.data.src_bitmap.surface_id;
if (draw.data.src_bitmap.bitmap)
str += "; BITMAP format " + draw.data.src_bitmap.bitmap.format +
"; flags " + draw.data.src_bitmap.bitmap.flags +
"; x " + draw.data.src_bitmap.bitmap.x +
"; y " + draw.data.src_bitmap.bitmap.y +
"; stride " + draw.data.src_bitmap.bitmap.stride ;
if (draw.data.src_bitmap.quic)
str += "; QUIC type " + draw.data.src_bitmap.quic.type +
"; width " + draw.data.src_bitmap.quic.width +
@ -788,9 +804,9 @@ SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
if (draw.data.brush)
{
if (draw.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
if (draw.data.brush.type == Constants.SPICE_BRUSH_TYPE_SOLID)
str += "; brush.color 0x" + draw.data.brush.color.toString(16);
if (draw.data.brush.type == SPICE_BRUSH_TYPE_PATTERN)
if (draw.data.brush.type == Constants.SPICE_BRUSH_TYPE_PATTERN)
{
str += "; brush.pat ";
if (draw.data.brush.pattern.pat != null)
@ -824,15 +840,15 @@ SpiceDisplayConn.prototype.hook_events = function()
{
var canvas = this.surfaces[this.primary_surface].canvas;
canvas.sc = this.parent;
canvas.addEventListener('mousemove', handle_mousemove);
canvas.addEventListener('mousedown', handle_mousedown);
canvas.addEventListener('contextmenu', handle_contextmenu);
canvas.addEventListener('mouseup', handle_mouseup);
canvas.addEventListener('keydown', handle_keydown);
canvas.addEventListener('keyup', handle_keyup);
canvas.addEventListener('mousemove', Inputs.handle_mousemove);
canvas.addEventListener('mousedown', Inputs.handle_mousedown);
canvas.addEventListener('contextmenu', Inputs.handle_contextmenu);
canvas.addEventListener('mouseup', Inputs.handle_mouseup);
canvas.addEventListener('keydown', Inputs.handle_keydown);
canvas.addEventListener('keyup', Inputs.handle_keyup);
canvas.addEventListener('mouseout', handle_mouseout);
canvas.addEventListener('mouseover', handle_mouseover);
canvas.addEventListener('wheel', handle_mousewheel);
canvas.addEventListener('wheel', Inputs.handle_mousewheel);
canvas.focus();
}
}
@ -842,15 +858,15 @@ SpiceDisplayConn.prototype.unhook_events = function()
if (this.primary_surface !== undefined)
{
var canvas = this.surfaces[this.primary_surface].canvas;
canvas.removeEventListener('mousemove', handle_mousemove);
canvas.removeEventListener('mousedown', handle_mousedown);
canvas.removeEventListener('contextmenu', handle_contextmenu);
canvas.removeEventListener('mouseup', handle_mouseup);
canvas.removeEventListener('keydown', handle_keydown);
canvas.removeEventListener('keyup', handle_keyup);
canvas.removeEventListener('mousemove', Inputs.handle_mousemove);
canvas.removeEventListener('mousedown', Inputs.handle_mousedown);
canvas.removeEventListener('contextmenu', Inputs.handle_contextmenu);
canvas.removeEventListener('mouseup', Inputs.handle_mouseup);
canvas.removeEventListener('keydown', Inputs.handle_keydown);
canvas.removeEventListener('keyup', Inputs.handle_keyup);
canvas.removeEventListener('mouseout', handle_mouseout);
canvas.removeEventListener('mouseover', handle_mouseover);
canvas.removeEventListener('wheel', handle_mousewheel);
canvas.removeEventListener('wheel', Inputs.handle_mousewheel);
}
}
@ -883,7 +899,7 @@ function handle_draw_jpeg_onload()
var temp_canvas = null;
var context;
if (this.o.sc.streams[this.o.id])
if ("streams" in this.o.sc && this.o.sc.streams[this.o.id])
this.o.sc.streams[this.o.id].frames_loading--;
/*------------------------------------------------------------
@ -896,7 +912,7 @@ function handle_draw_jpeg_onload()
// This can happen; if the jpeg image loads after our surface
// has been destroyed (e.g. open a menu, close it quickly),
// we'll find we have no surface.
DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost surface " + this.o.base.surface_id);
Utils.DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost surface " + this.o.base.surface_id);
temp_canvas = document.createElement("canvas");
temp_canvas.setAttribute('width', this.o.base.box.right);
temp_canvas.setAttribute('height', this.o.base.box.bottom);
@ -918,7 +934,7 @@ function handle_draw_jpeg_onload()
context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
if (this.o.descriptor &&
(this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
(this.o.descriptor.flags & Constants.SPICE_IMAGE_FLAGS_CACHE_ME))
{
if (! ("cache" in this.o.sc))
this.o.sc.cache = {};
@ -936,10 +952,10 @@ function handle_draw_jpeg_onload()
// Give the Garbage collector a clue to recycle this; avoids
// fairly massive memory leaks during video playback
this.onload = undefined;
this.src = EMPTY_GIF_IMAGE;
this.src = Utils.EMPTY_GIF_IMAGE;
if (this.o.descriptor &&
(this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
(this.o.descriptor.flags & Constants.SPICE_IMAGE_FLAGS_CACHE_ME))
{
if (! ("cache" in this.o.sc))
this.o.sc.cache = {};
@ -953,7 +969,7 @@ function handle_draw_jpeg_onload()
if (temp_canvas == null)
{
if (DUMP_DRAWS && this.o.sc.parent.dump_id)
if (Utils.DUMP_DRAWS && this.o.sc.parent.dump_id)
{
var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('id', this.o.tag + "." +
@ -992,7 +1008,7 @@ function process_mjpeg_stream_data(sc, m, time_until_due)
tmpstr += '0';
tmpstr += m.data[i].toString(16);
}
var strm_base = new SpiceMsgDisplayBase();
var strm_base = new Messages.SpiceMsgDisplayBase();
strm_base.surface_id = sc.streams[m.base.id].surface_id;
strm_base.box = m.dest || sc.streams[m.base.id].dest;
strm_base.clip = sc.streams[m.base.id].clip;
@ -1022,8 +1038,8 @@ function process_stream_data_report(sc, id, msg_mmtime, time_until_due)
sc.streams[id].report.end_frame_mm_time = msg_mmtime;
sc.streams[id].report.last_frame_delay = time_until_due;
var msg = new SpiceMiniData();
msg.build_msg(SPICE_MSGC_DISPLAY_STREAM_REPORT, sc.streams[id].report);
var msg = new Messages.SpiceMiniData();
msg.build_msg(Constants.SPICE_MSGC_DISPLAY_STREAM_REPORT, sc.streams[id].report);
sc.send_msg(msg);
sc.streams[id].report.start_frame_mm_time = 0;
@ -1040,10 +1056,10 @@ function handle_video_source_open(e)
if (stream.source_buffer)
return;
var s = this.addSourceBuffer(SPICE_VP8_CODEC);
var s = this.addSourceBuffer(Webm.Constants.SPICE_VP8_CODEC);
if (! s)
{
p.log_err('Codec ' + SPICE_VP8_CODEC + ' not available.');
p.log_err('Codec ' + Webm.Constants.SPICE_VP8_CODEC + ' not available.');
return;
}
@ -1053,9 +1069,9 @@ function handle_video_source_open(e)
listen_for_video_events(stream);
var h = new webm_Header();
var te = new webm_VideoTrackEntry(this.stream.stream_width, this.stream.stream_height);
var t = new webm_Tracks(te);
var h = new Webm.Header();
var te = new Webm.VideoTrackEntry(this.stream.stream_width, this.stream.stream_height);
var t = new Webm.Tracks(te);
var mb = new ArrayBuffer(h.buffer_size() + t.buffer_size())
@ -1117,7 +1133,7 @@ function handle_append_video_buffer_done(e)
if (!stream.video)
{
if (STREAM_DEBUG > 0)
if (Utils.STREAM_DEBUG > 0)
console.log("Stream id " + stream.id + " received updateend after video is gone.");
return;
}
@ -1130,8 +1146,8 @@ function handle_append_video_buffer_done(e)
stream.video.currentTime = stream.video.buffered.start(stream.video.buffered.length - 1);
}
if (STREAM_DEBUG > 1)
console.log(stream.video.currentTime + ":id " + stream.id + " updateend " + dump_media_element(stream.video));
if (Utils.STREAM_DEBUG > 1)
console.log(stream.video.currentTime + ":id " + stream.id + " updateend " + Utils.dump_media_element(stream.video));
}
function handle_video_buffer_error(e)
@ -1161,7 +1177,7 @@ function push_or_queue(stream, msg, mb)
function video_simple_block(stream, msg, keyframe)
{
var simple = new webm_SimpleBlock(msg.base.multi_media_time - stream.cluster_time, msg.data, keyframe);
var simple = new Webm.SimpleBlock(msg.base.multi_media_time - stream.cluster_time, msg.data, keyframe);
var mb = new ArrayBuffer(simple.buffer_size());
simple.to_buffer(mb);
@ -1171,7 +1187,7 @@ function video_simple_block(stream, msg, keyframe)
function new_video_cluster(stream, msg)
{
stream.cluster_time = msg.base.multi_media_time;
var c = new webm_Cluster(stream.cluster_time - stream.start_time, msg.data);
var c = new Webm.Cluster(stream.cluster_time - stream.start_time, msg.data);
var mb = new ArrayBuffer(c.buffer_size());
c.to_buffer(mb);
@ -1189,7 +1205,7 @@ function process_video_stream_data(stream, msg)
new_video_cluster(stream, msg);
}
else if (msg.base.multi_media_time - stream.cluster_time >= MAX_CLUSTER_TIME)
else if (msg.base.multi_media_time - stream.cluster_time >= Webm.Constants.MAX_CLUSTER_TIME)
new_video_cluster(stream, msg);
else
video_simple_block(stream, msg, false);
@ -1200,18 +1216,18 @@ function video_handle_event_debug(e)
var s = this.spice_stream;
if (s.video)
{
if (STREAM_DEBUG > 0 || s.video.buffered.len > 1)
if (Utils.STREAM_DEBUG > 0 || s.video.buffered.len > 1)
console.log(s.video.currentTime + ":id " + s.id + " event " + e.type +
dump_media_element(s.video));
Utils.dump_media_element(s.video));
}
if (STREAM_DEBUG > 1 && s.media)
console.log(" media_source " + dump_media_source(s.media));
if (Utils.STREAM_DEBUG > 1 && s.media)
console.log(" media_source " + Utils.dump_media_source(s.media));
if (STREAM_DEBUG > 1 && s.source_buffer)
console.log(" source_buffer " + dump_source_buffer(s.source_buffer));
if (Utils.STREAM_DEBUG > 1 && s.source_buffer)
console.log(" source_buffer " + Utils.dump_source_buffer(s.source_buffer));
if (STREAM_DEBUG > 1 || s.queue.length > 1)
if (Utils.STREAM_DEBUG > 1 || s.queue.length > 1)
console.log(' queue len ' + s.queue.length + '; append_okay: ' + s.append_okay);
}
@ -1240,8 +1256,12 @@ function listen_for_video_events(stream)
];
video_0_events.forEach(video_debug_listen_for_one_event, stream.video);
if (STREAM_DEBUG > 0)
if (Utils.STREAM_DEBUG > 0)
video_1_events.forEach(video_debug_listen_for_one_event, stream.video);
if (STREAM_DEBUG > 1)
if (Utils.STREAM_DEBUG > 1)
video_2_events.forEach(video_debug_listen_for_one_event, stream.video);
}
export {
SpiceDisplayConn,
};

View file

@ -23,355 +23,350 @@
** enums.js
** 'constants' for Spice
**--------------------------------------------------------------------------*/
var SPICE_MAGIC = "REDQ";
var SPICE_VERSION_MAJOR = 2;
var SPICE_VERSION_MINOR = 2;
export var Constants = {
SPICE_MAGIC : "REDQ",
SPICE_VERSION_MAJOR : 2,
SPICE_VERSION_MINOR : 2,
var SPICE_CONNECT_TIMEOUT = (30 * 1000);
SPICE_CONNECT_TIMEOUT : (30 * 1000),
var SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION = 0;
var SPICE_COMMON_CAP_AUTH_SPICE = 1;
var SPICE_COMMON_CAP_AUTH_SASL = 2;
var SPICE_COMMON_CAP_MINI_HEADER = 3;
SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION : 0,
SPICE_COMMON_CAP_AUTH_SPICE : 1,
SPICE_COMMON_CAP_AUTH_SASL : 2,
SPICE_COMMON_CAP_MINI_HEADER : 3,
var SPICE_TICKET_KEY_PAIR_LENGTH = 1024;
var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34);
SPICE_TICKET_KEY_PAIR_LENGTH : 1024,
SPICE_TICKET_PUBKEY_BYTES : (1024 / 8 +34), // (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34)
var SPICE_LINK_ERR_OK = 0,
SPICE_LINK_ERR_ERROR = 1,
SPICE_LINK_ERR_INVALID_MAGIC = 2,
SPICE_LINK_ERR_INVALID_DATA = 3,
SPICE_LINK_ERR_VERSION_MISMATCH = 4,
SPICE_LINK_ERR_NEED_SECURED = 5,
SPICE_LINK_ERR_NEED_UNSECURED = 6,
SPICE_LINK_ERR_PERMISSION_DENIED = 7,
SPICE_LINK_ERR_BAD_CONNECTION_ID = 8,
SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9;
SPICE_LINK_ERR_OK : 0,
SPICE_LINK_ERR_ERROR : 1,
SPICE_LINK_ERR_INVALID_MAGIC : 2,
SPICE_LINK_ERR_INVALID_DATA : 3,
SPICE_LINK_ERR_VERSION_MISMATCH : 4,
SPICE_LINK_ERR_NEED_SECURED : 5,
SPICE_LINK_ERR_NEED_UNSECURED : 6,
SPICE_LINK_ERR_PERMISSION_DENIED : 7,
SPICE_LINK_ERR_BAD_CONNECTION_ID : 8,
SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE : 9,
var SPICE_MSG_MIGRATE = 1;
var SPICE_MSG_MIGRATE_DATA = 2;
var SPICE_MSG_SET_ACK = 3;
var SPICE_MSG_PING = 4;
var SPICE_MSG_WAIT_FOR_CHANNELS = 5;
var SPICE_MSG_DISCONNECTING = 6;
var SPICE_MSG_NOTIFY = 7;
var SPICE_MSG_LIST = 8;
SPICE_MSG_MIGRATE : 1,
SPICE_MSG_MIGRATE_DATA : 2,
SPICE_MSG_SET_ACK : 3,
SPICE_MSG_PING : 4,
SPICE_MSG_WAIT_FOR_CHANNELS : 5,
SPICE_MSG_DISCONNECTING : 6,
SPICE_MSG_NOTIFY : 7,
SPICE_MSG_LIST : 8,
var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101;
var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102;
var SPICE_MSG_MAIN_INIT = 103;
var SPICE_MSG_MAIN_CHANNELS_LIST = 104;
var SPICE_MSG_MAIN_MOUSE_MODE = 105;
var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106;
var SPICE_MSG_MAIN_AGENT_CONNECTED = 107;
var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108;
var SPICE_MSG_MAIN_AGENT_DATA = 109;
var SPICE_MSG_MAIN_AGENT_TOKEN = 110;
var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111;
var SPICE_MSG_MAIN_MIGRATE_END = 112;
var SPICE_MSG_MAIN_NAME = 113;
var SPICE_MSG_MAIN_UUID = 114;
var SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS = 115;
var SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS = 116;
var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK = 117;
var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK = 118;
var SPICE_MSG_END_MAIN = 119;
SPICE_MSG_MAIN_MIGRATE_BEGIN : 101,
SPICE_MSG_MAIN_MIGRATE_CANCEL : 102,
SPICE_MSG_MAIN_INIT : 103,
SPICE_MSG_MAIN_CHANNELS_LIST : 104,
SPICE_MSG_MAIN_MOUSE_MODE : 105,
SPICE_MSG_MAIN_MULTI_MEDIA_TIME : 106,
SPICE_MSG_MAIN_AGENT_CONNECTED : 107,
SPICE_MSG_MAIN_AGENT_DISCONNECTED : 108,
SPICE_MSG_MAIN_AGENT_DATA : 109,
SPICE_MSG_MAIN_AGENT_TOKEN : 110,
SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST : 111,
SPICE_MSG_MAIN_MIGRATE_END : 112,
SPICE_MSG_MAIN_NAME : 113,
SPICE_MSG_MAIN_UUID : 114,
SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS : 115,
SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS : 116,
SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK : 117,
SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK : 118,
SPICE_MSG_END_MAIN : 119,
var SPICE_MSGC_ACK_SYNC = 1;
var SPICE_MSGC_ACK = 2;
var SPICE_MSGC_PONG = 3;
var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4;
var SPICE_MSGC_MIGRATE_DATA = 5;
var SPICE_MSGC_DISCONNECTING = 6;
SPICE_MSGC_ACK_SYNC : 1,
SPICE_MSGC_ACK : 2,
SPICE_MSGC_PONG : 3,
SPICE_MSGC_MIGRATE_FLUSH_MARK : 4,
SPICE_MSGC_MIGRATE_DATA : 5,
SPICE_MSGC_DISCONNECTING : 6,
var SPICE_MSGC_MAIN_CLIENT_INFO = 101;
var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102;
var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103;
var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104;
var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105;
var SPICE_MSGC_MAIN_AGENT_START = 106;
var SPICE_MSGC_MAIN_AGENT_DATA = 107;
var SPICE_MSGC_MAIN_AGENT_TOKEN = 108;
var SPICE_MSGC_MAIN_MIGRATE_END = 109;
var SPICE_MSGC_END_MAIN = 110;
SPICE_MSGC_MAIN_CLIENT_INFO : 101,
SPICE_MSGC_MAIN_MIGRATE_CONNECTED : 102,
SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR : 103,
SPICE_MSGC_MAIN_ATTACH_CHANNELS : 104,
SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST : 105,
SPICE_MSGC_MAIN_AGENT_START : 106,
SPICE_MSGC_MAIN_AGENT_DATA : 107,
SPICE_MSGC_MAIN_AGENT_TOKEN : 108,
SPICE_MSGC_MAIN_MIGRATE_END : 109,
SPICE_MSGC_END_MAIN : 110,
var SPICE_MSG_DISPLAY_MODE = 101;
var SPICE_MSG_DISPLAY_MARK = 102;
var SPICE_MSG_DISPLAY_RESET = 103;
var SPICE_MSG_DISPLAY_COPY_BITS = 104;
var SPICE_MSG_DISPLAY_INVAL_LIST = 105;
var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106;
var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107;
var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108;
SPICE_MSG_DISPLAY_MODE : 101,
SPICE_MSG_DISPLAY_MARK : 102,
SPICE_MSG_DISPLAY_RESET : 103,
SPICE_MSG_DISPLAY_COPY_BITS : 104,
SPICE_MSG_DISPLAY_INVAL_LIST : 105,
SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS : 106,
SPICE_MSG_DISPLAY_INVAL_PALETTE : 107,
SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES: 108,
var SPICE_MSG_DISPLAY_STREAM_CREATE = 122;
var SPICE_MSG_DISPLAY_STREAM_DATA = 123;
var SPICE_MSG_DISPLAY_STREAM_CLIP = 124;
var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125;
var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126;
SPICE_MSG_DISPLAY_STREAM_CREATE : 122,
SPICE_MSG_DISPLAY_STREAM_DATA : 123,
SPICE_MSG_DISPLAY_STREAM_CLIP : 124,
SPICE_MSG_DISPLAY_STREAM_DESTROY : 125,
SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL: 126,
var SPICE_MSG_DISPLAY_DRAW_FILL = 302;
var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303;
var SPICE_MSG_DISPLAY_DRAW_COPY = 304;
var SPICE_MSG_DISPLAY_DRAW_BLEND = 305;
var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306;
var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307;
var SPICE_MSG_DISPLAY_DRAW_INVERS = 308;
var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309;
var SPICE_MSG_DISPLAY_DRAW_STROKE = 310;
var SPICE_MSG_DISPLAY_DRAW_TEXT = 311;
var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312;
var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313;
var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314;
var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315;
var SPICE_MSG_DISPLAY_STREAM_DATA_SIZED = 316;
var SPICE_MSG_DISPLAY_MONITORS_CONFIG = 317;
var SPICE_MSG_DISPLAY_DRAW_COMPOSITE = 318;
var SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT = 319;
SPICE_MSG_DISPLAY_DRAW_FILL : 302,
SPICE_MSG_DISPLAY_DRAW_OPAQUE : 303,
SPICE_MSG_DISPLAY_DRAW_COPY : 304,
SPICE_MSG_DISPLAY_DRAW_BLEND : 305,
SPICE_MSG_DISPLAY_DRAW_BLACKNESS : 306,
SPICE_MSG_DISPLAY_DRAW_WHITENESS : 307,
SPICE_MSG_DISPLAY_DRAW_INVERS : 308,
SPICE_MSG_DISPLAY_DRAW_ROP3 : 309,
SPICE_MSG_DISPLAY_DRAW_STROKE : 310,
SPICE_MSG_DISPLAY_DRAW_TEXT : 311,
SPICE_MSG_DISPLAY_DRAW_TRANSPARENT : 312,
SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND : 313,
SPICE_MSG_DISPLAY_SURFACE_CREATE : 314,
SPICE_MSG_DISPLAY_SURFACE_DESTROY : 315,
SPICE_MSG_DISPLAY_STREAM_DATA_SIZED : 316,
SPICE_MSG_DISPLAY_MONITORS_CONFIG : 317,
SPICE_MSG_DISPLAY_DRAW_COMPOSITE : 318,
SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT : 319,
var SPICE_MSGC_DISPLAY_INIT = 101;
var SPICE_MSGC_DISPLAY_STREAM_REPORT = 102;
SPICE_MSGC_DISPLAY_INIT : 101,
SPICE_MSGC_DISPLAY_STREAM_REPORT : 102,
var SPICE_MSG_INPUTS_INIT = 101;
var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102;
SPICE_MSG_INPUTS_INIT : 101,
SPICE_MSG_INPUTS_KEY_MODIFIERS : 102,
var SPICE_MSG_INPUTS_MOUSE_MOTION_ACK = 111;
SPICE_MSG_INPUTS_MOUSE_MOTION_ACK : 111,
var SPICE_MSGC_INPUTS_KEY_DOWN = 101;
var SPICE_MSGC_INPUTS_KEY_UP = 102;
var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103;
SPICE_MSGC_INPUTS_KEY_DOWN : 101,
SPICE_MSGC_INPUTS_KEY_UP : 102,
SPICE_MSGC_INPUTS_KEY_MODIFIERS : 103,
var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111;
var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112;
var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113;
var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114;
SPICE_MSGC_INPUTS_MOUSE_MOTION : 111,
SPICE_MSGC_INPUTS_MOUSE_POSITION : 112,
SPICE_MSGC_INPUTS_MOUSE_PRESS : 113,
SPICE_MSGC_INPUTS_MOUSE_RELEASE : 114,
var SPICE_MSG_CURSOR_INIT = 101;
var SPICE_MSG_CURSOR_RESET = 102;
var SPICE_MSG_CURSOR_SET = 103;
var SPICE_MSG_CURSOR_MOVE = 104;
var SPICE_MSG_CURSOR_HIDE = 105;
var SPICE_MSG_CURSOR_TRAIL = 106;
var SPICE_MSG_CURSOR_INVAL_ONE = 107;
var SPICE_MSG_CURSOR_INVAL_ALL = 108;
SPICE_MSG_CURSOR_INIT : 101,
SPICE_MSG_CURSOR_RESET : 102,
SPICE_MSG_CURSOR_SET : 103,
SPICE_MSG_CURSOR_MOVE : 104,
SPICE_MSG_CURSOR_HIDE : 105,
SPICE_MSG_CURSOR_TRAIL : 106,
SPICE_MSG_CURSOR_INVAL_ONE : 107,
SPICE_MSG_CURSOR_INVAL_ALL : 108,
var SPICE_MSG_PLAYBACK_DATA = 101;
var SPICE_MSG_PLAYBACK_MODE = 102;
var SPICE_MSG_PLAYBACK_START = 103;
var SPICE_MSG_PLAYBACK_STOP = 104;
var SPICE_MSG_PLAYBACK_VOLUME = 105;
var SPICE_MSG_PLAYBACK_MUTE = 106;
var SPICE_MSG_PLAYBACK_LATENCY = 107;
SPICE_MSG_PLAYBACK_DATA : 101,
SPICE_MSG_PLAYBACK_MODE : 102,
SPICE_MSG_PLAYBACK_START : 103,
SPICE_MSG_PLAYBACK_STOP : 104,
SPICE_MSG_PLAYBACK_VOLUME : 105,
SPICE_MSG_PLAYBACK_MUTE : 106,
SPICE_MSG_PLAYBACK_LATENCY : 107,
var SPICE_MSG_SPICEVMC_DATA = 101;
var SPICE_MSG_PORT_INIT = 201;
var SPICE_MSG_PORT_EVENT = 202;
var SPICE_MSG_END_PORT = 203;
SPICE_MSG_SPICEVMC_DATA : 101,
SPICE_MSG_PORT_INIT : 201,
SPICE_MSG_PORT_EVENT : 202,
SPICE_MSG_END_PORT : 203,
var SPICE_MSGC_SPICEVMC_DATA = 101;
var SPICE_MSGC_PORT_EVENT = 201;
var SPICE_MSGC_END_PORT = 202;
SPICE_MSGC_SPICEVMC_DATA : 101,
SPICE_MSGC_PORT_EVENT : 201,
SPICE_MSGC_END_PORT : 202,
var SPICE_PLAYBACK_CAP_CELT_0_5_1 = 0;
var SPICE_PLAYBACK_CAP_VOLUME = 1;
var SPICE_PLAYBACK_CAP_LATENCY = 2;
var SPICE_PLAYBACK_CAP_OPUS = 3;
SPICE_PLAYBACK_CAP_CELT_0_5_1 : 0,
SPICE_PLAYBACK_CAP_VOLUME : 1,
SPICE_PLAYBACK_CAP_LATENCY : 2,
SPICE_PLAYBACK_CAP_OPUS : 3,
var SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE = 0;
var SPICE_MAIN_CAP_NAME_AND_UUID = 1;
var SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS = 2;
var SPICE_MAIN_CAP_SEAMLESS_MIGRATE = 3;
SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE : 0,
SPICE_MAIN_CAP_NAME_AND_UUID : 1,
SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS : 2,
SPICE_MAIN_CAP_SEAMLESS_MIGRATE : 3,
var SPICE_DISPLAY_CAP_SIZED_STREAM = 0;
var SPICE_DISPLAY_CAP_MONITORS_CONFIG = 1;
var SPICE_DISPLAY_CAP_COMPOSITE = 2;
var SPICE_DISPLAY_CAP_A8_SURFACE = 3;
var SPICE_DISPLAY_CAP_STREAM_REPORT = 4;
var SPICE_DISPLAY_CAP_LZ4_COMPRESSION = 5;
var SPICE_DISPLAY_CAP_PREF_COMPRESSION = 6;
var SPICE_DISPLAY_CAP_GL_SCANOUT = 7;
var SPICE_DISPLAY_CAP_MULTI_CODEC = 8;
var SPICE_DISPLAY_CAP_CODEC_MJPEG = 9;
var SPICE_DISPLAY_CAP_CODEC_VP8 = 10;
SPICE_DISPLAY_CAP_SIZED_STREAM : 0,
SPICE_DISPLAY_CAP_MONITORS_CONFIG : 1,
SPICE_DISPLAY_CAP_COMPOSITE : 2,
SPICE_DISPLAY_CAP_A8_SURFACE : 3,
SPICE_DISPLAY_CAP_STREAM_REPORT : 4,
SPICE_DISPLAY_CAP_LZ4_COMPRESSION : 5,
SPICE_DISPLAY_CAP_PREF_COMPRESSION : 6,
SPICE_DISPLAY_CAP_GL_SCANOUT : 7,
SPICE_DISPLAY_CAP_MULTI_CODEC : 8,
SPICE_DISPLAY_CAP_CODEC_MJPEG : 9,
SPICE_DISPLAY_CAP_CODEC_VP8 : 10,
var SPICE_AUDIO_DATA_MODE_INVALID = 0;
var SPICE_AUDIO_DATA_MODE_RAW = 1;
var SPICE_AUDIO_DATA_MODE_CELT_0_5_1 = 2;
var SPICE_AUDIO_DATA_MODE_OPUS = 3;
SPICE_AUDIO_DATA_MODE_INVALID : 0,
SPICE_AUDIO_DATA_MODE_RAW : 1,
SPICE_AUDIO_DATA_MODE_CELT_0_5_1 : 2,
SPICE_AUDIO_DATA_MODE_OPUS : 3,
var SPICE_AUDIO_FMT_INVALID = 0;
var SPICE_AUDIO_FMT_S16 = 1;
SPICE_AUDIO_FMT_INVALID : 0,
SPICE_AUDIO_FMT_S16 : 1,
var SPICE_CHANNEL_MAIN = 1;
var SPICE_CHANNEL_DISPLAY = 2;
var SPICE_CHANNEL_INPUTS = 3;
var SPICE_CHANNEL_CURSOR = 4;
var SPICE_CHANNEL_PLAYBACK = 5;
var SPICE_CHANNEL_RECORD = 6;
var SPICE_CHANNEL_TUNNEL = 7;
var SPICE_CHANNEL_SMARTCARD = 8;
var SPICE_CHANNEL_USBREDIR = 9;
var SPICE_CHANNEL_PORT = 10;
var SPICE_CHANNEL_WEBDAV = 11;
SPICE_CHANNEL_MAIN : 1,
SPICE_CHANNEL_DISPLAY : 2,
SPICE_CHANNEL_INPUTS : 3,
SPICE_CHANNEL_CURSOR : 4,
SPICE_CHANNEL_PLAYBACK : 5,
SPICE_CHANNEL_RECORD : 6,
SPICE_CHANNEL_TUNNEL : 7,
SPICE_CHANNEL_SMARTCARD : 8,
SPICE_CHANNEL_USBREDIR : 9,
SPICE_CHANNEL_PORT : 10,
SPICE_CHANNEL_WEBDAV : 11,
var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0);
SPICE_SURFACE_FLAGS_PRIMARY : (1 << 0),
var SPICE_NOTIFY_SEVERITY_INFO = 0;
var SPICE_NOTIFY_SEVERITY_WARN = 1;
var SPICE_NOTIFY_SEVERITY_ERROR = 2;
SPICE_NOTIFY_SEVERITY_INFO : 0,
SPICE_NOTIFY_SEVERITY_WARN : 1,
SPICE_NOTIFY_SEVERITY_ERROR : 2,
var SPICE_MOUSE_MODE_SERVER = (1 << 0),
SPICE_MOUSE_MODE_CLIENT = (1 << 1),
SPICE_MOUSE_MODE_MASK = 0x3;
SPICE_MOUSE_MODE_SERVER : (1 << 0),
SPICE_MOUSE_MODE_CLIENT : (1 << 1),
SPICE_MOUSE_MODE_MASK : 0x3,
var SPICE_CLIP_TYPE_NONE = 0;
var SPICE_CLIP_TYPE_RECTS = 1;
SPICE_CLIP_TYPE_NONE : 0,
SPICE_CLIP_TYPE_RECTS : 1,
var SPICE_IMAGE_TYPE_BITMAP = 0;
var SPICE_IMAGE_TYPE_QUIC = 1;
var SPICE_IMAGE_TYPE_RESERVED = 2;
var SPICE_IMAGE_TYPE_LZ_PLT = 100;
var SPICE_IMAGE_TYPE_LZ_RGB = 101;
var SPICE_IMAGE_TYPE_GLZ_RGB = 102;
var SPICE_IMAGE_TYPE_FROM_CACHE = 103;
var SPICE_IMAGE_TYPE_SURFACE = 104;
var SPICE_IMAGE_TYPE_JPEG = 105;
var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106;
var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107;
var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108;
SPICE_IMAGE_TYPE_BITMAP : 0,
SPICE_IMAGE_TYPE_QUIC : 1,
SPICE_IMAGE_TYPE_RESERVED : 2,
SPICE_IMAGE_TYPE_LZ_PLT : 100,
SPICE_IMAGE_TYPE_LZ_RGB : 101,
SPICE_IMAGE_TYPE_GLZ_RGB : 102,
SPICE_IMAGE_TYPE_FROM_CACHE : 103,
SPICE_IMAGE_TYPE_SURFACE : 104,
SPICE_IMAGE_TYPE_JPEG : 105,
SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS : 106,
SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB : 107,
SPICE_IMAGE_TYPE_JPEG_ALPHA : 108,
var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0),
SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1),
SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2);
SPICE_IMAGE_FLAGS_CACHE_ME : (1 << 0),
SPICE_IMAGE_FLAGS_HIGH_BITS_SET : (1 << 1),
SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME : (1 << 2),
var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0),
SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1),
SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2),
SPICE_BITMAP_FLAGS_MASK = 0x7;
SPICE_BITMAP_FLAGS_PAL_CACHE_ME : (1 << 0),
SPICE_BITMAP_FLAGS_PAL_FROM_CACHE : (1 << 1),
SPICE_BITMAP_FLAGS_TOP_DOWN : (1 << 2),
SPICE_BITMAP_FLAGS_MASK : 0x7,
var SPICE_BITMAP_FMT_INVALID = 0,
SPICE_BITMAP_FMT_1BIT_LE = 1,
SPICE_BITMAP_FMT_1BIT_BE = 2,
SPICE_BITMAP_FMT_4BIT_LE = 3,
SPICE_BITMAP_FMT_4BIT_BE = 4,
SPICE_BITMAP_FMT_8BIT = 5,
SPICE_BITMAP_FMT_16BIT = 6,
SPICE_BITMAP_FMT_24BIT = 7,
SPICE_BITMAP_FMT_32BIT = 8,
SPICE_BITMAP_FMT_RGBA = 9;
SPICE_BITMAP_FMT_INVALID : 0,
SPICE_BITMAP_FMT_1BIT_LE : 1,
SPICE_BITMAP_FMT_1BIT_BE : 2,
SPICE_BITMAP_FMT_4BIT_LE : 3,
SPICE_BITMAP_FMT_4BIT_BE : 4,
SPICE_BITMAP_FMT_8BIT : 5,
SPICE_BITMAP_FMT_16BIT : 6,
SPICE_BITMAP_FMT_24BIT : 7,
SPICE_BITMAP_FMT_32BIT : 8,
SPICE_BITMAP_FMT_RGBA : 9,
var SPICE_CURSOR_FLAGS_NONE = (1 << 0),
SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1),
SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2),
SPICE_CURSOR_FLAGS_MASK = 0x7;
SPICE_CURSOR_FLAGS_NONE : (1 << 0),
SPICE_CURSOR_FLAGS_CACHE_ME : (1 << 1),
SPICE_CURSOR_FLAGS_FROM_CACHE : (1 << 2),
SPICE_CURSOR_FLAGS_MASK : 0x7,
var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0),
SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1),
SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2),
SPICE_MOUSE_BUTTON_MASK_MASK = 0x7;
SPICE_MOUSE_BUTTON_MASK_LEFT : (1 << 0),
SPICE_MOUSE_BUTTON_MASK_MIDDLE : (1 << 1),
SPICE_MOUSE_BUTTON_MASK_RIGHT : (1 << 2),
SPICE_MOUSE_BUTTON_MASK_MASK : 0x7,
var SPICE_MOUSE_BUTTON_INVALID = 0;
var SPICE_MOUSE_BUTTON_LEFT = 1;
var SPICE_MOUSE_BUTTON_MIDDLE = 2;
var SPICE_MOUSE_BUTTON_RIGHT = 3;
var SPICE_MOUSE_BUTTON_UP = 4;
var SPICE_MOUSE_BUTTON_DOWN = 5;
SPICE_MOUSE_BUTTON_INVALID : 0,
SPICE_MOUSE_BUTTON_LEFT : 1,
SPICE_MOUSE_BUTTON_MIDDLE : 2,
SPICE_MOUSE_BUTTON_RIGHT : 3,
SPICE_MOUSE_BUTTON_UP : 4,
SPICE_MOUSE_BUTTON_DOWN : 5,
var SPICE_BRUSH_TYPE_NONE = 0,
SPICE_BRUSH_TYPE_SOLID = 1,
SPICE_BRUSH_TYPE_PATTERN = 2;
SPICE_BRUSH_TYPE_NONE : 0,
SPICE_BRUSH_TYPE_SOLID : 1,
SPICE_BRUSH_TYPE_PATTERN : 2,
var SPICE_SURFACE_FMT_INVALID = 0,
SPICE_SURFACE_FMT_1_A = 1,
SPICE_SURFACE_FMT_8_A = 8,
SPICE_SURFACE_FMT_16_555 = 16,
SPICE_SURFACE_FMT_32_xRGB = 32,
SPICE_SURFACE_FMT_16_565 = 80,
SPICE_SURFACE_FMT_32_ARGB = 96;
SPICE_SURFACE_FMT_INVALID : 0,
SPICE_SURFACE_FMT_1_A : 1,
SPICE_SURFACE_FMT_8_A : 8,
SPICE_SURFACE_FMT_16_555 : 16,
SPICE_SURFACE_FMT_32_xRGB : 32,
SPICE_SURFACE_FMT_16_565 : 80,
SPICE_SURFACE_FMT_32_ARGB : 96,
var SPICE_ROPD_INVERS_SRC = (1 << 0),
SPICE_ROPD_INVERS_BRUSH = (1 << 1),
SPICE_ROPD_INVERS_DEST = (1 << 2),
SPICE_ROPD_OP_PUT = (1 << 3),
SPICE_ROPD_OP_OR = (1 << 4),
SPICE_ROPD_OP_AND = (1 << 5),
SPICE_ROPD_OP_XOR = (1 << 6),
SPICE_ROPD_OP_BLACKNESS = (1 << 7),
SPICE_ROPD_OP_WHITENESS = (1 << 8),
SPICE_ROPD_OP_INVERS = (1 << 9),
SPICE_ROPD_INVERS_RES = (1 << 10),
SPICE_ROPD_MASK = 0x7ff;
SPICE_ROPD_INVERS_SRC : (1 << 0),
SPICE_ROPD_INVERS_BRUSH : (1 << 1),
SPICE_ROPD_INVERS_DEST : (1 << 2),
SPICE_ROPD_OP_PUT : (1 << 3),
SPICE_ROPD_OP_OR : (1 << 4),
SPICE_ROPD_OP_AND : (1 << 5),
SPICE_ROPD_OP_XOR : (1 << 6),
SPICE_ROPD_OP_BLACKNESS : (1 << 7),
SPICE_ROPD_OP_WHITENESS : (1 << 8),
SPICE_ROPD_OP_INVERS : (1 << 9),
SPICE_ROPD_INVERS_RES : (1 << 10),
SPICE_ROPD_MASK : 0x7ff,
var LZ_IMAGE_TYPE_INVALID = 0,
LZ_IMAGE_TYPE_PLT1_LE = 1,
LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette
LZ_IMAGE_TYPE_PLT4_LE = 3,
LZ_IMAGE_TYPE_PLT4_BE = 4,
LZ_IMAGE_TYPE_PLT8 = 5,
LZ_IMAGE_TYPE_RGB16 = 6,
LZ_IMAGE_TYPE_RGB24 = 7,
LZ_IMAGE_TYPE_RGB32 = 8,
LZ_IMAGE_TYPE_RGBA = 9,
LZ_IMAGE_TYPE_XXXA = 10;
LZ_IMAGE_TYPE_INVALID : 0,
LZ_IMAGE_TYPE_PLT1_LE : 1,
LZ_IMAGE_TYPE_PLT1_BE : 2, // PLT stands for palette
LZ_IMAGE_TYPE_PLT4_LE : 3,
LZ_IMAGE_TYPE_PLT4_BE : 4,
LZ_IMAGE_TYPE_PLT8 : 5,
LZ_IMAGE_TYPE_RGB16 : 6,
LZ_IMAGE_TYPE_RGB24 : 7,
LZ_IMAGE_TYPE_RGB32 : 8,
LZ_IMAGE_TYPE_RGBA : 9,
LZ_IMAGE_TYPE_XXXA : 10,
var QUIC_IMAGE_TYPE_INVALID = 0,
QUIC_IMAGE_TYPE_GRAY = 1,
QUIC_IMAGE_TYPE_RGB16 = 2,
QUIC_IMAGE_TYPE_RGB24 = 3,
QUIC_IMAGE_TYPE_RGB32 = 4,
QUIC_IMAGE_TYPE_RGBA = 5;
var SPICE_INPUT_MOTION_ACK_BUNCH = 4;
SPICE_INPUT_MOTION_ACK_BUNCH : 4,
var SPICE_CURSOR_TYPE_ALPHA = 0,
SPICE_CURSOR_TYPE_MONO = 1,
SPICE_CURSOR_TYPE_COLOR4 = 2,
SPICE_CURSOR_TYPE_COLOR8 = 3,
SPICE_CURSOR_TYPE_COLOR16 = 4,
SPICE_CURSOR_TYPE_COLOR24 = 5,
SPICE_CURSOR_TYPE_COLOR32 = 6;
SPICE_CURSOR_TYPE_ALPHA : 0,
SPICE_CURSOR_TYPE_MONO : 1,
SPICE_CURSOR_TYPE_COLOR4 : 2,
SPICE_CURSOR_TYPE_COLOR8 : 3,
SPICE_CURSOR_TYPE_COLOR16 : 4,
SPICE_CURSOR_TYPE_COLOR24 : 5,
SPICE_CURSOR_TYPE_COLOR32 : 6,
var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
var SPICE_VIDEO_CODEC_TYPE_VP8 = 2;
SPICE_VIDEO_CODEC_TYPE_MJPEG : 1,
SPICE_VIDEO_CODEC_TYPE_VP8 : 2,
var VD_AGENT_PROTOCOL = 1;
var VD_AGENT_MAX_DATA_SIZE = 2048;
VD_AGENT_PROTOCOL : 1,
VD_AGENT_MAX_DATA_SIZE : 2048,
var VD_AGENT_MOUSE_STATE = 1,
VD_AGENT_MONITORS_CONFIG = 2,
VD_AGENT_REPLY = 3,
VD_AGENT_CLIPBOARD = 4,
VD_AGENT_DISPLAY_CONFIG = 5,
VD_AGENT_ANNOUNCE_CAPABILITIES = 6,
VD_AGENT_CLIPBOARD_GRAB = 7,
VD_AGENT_CLIPBOARD_REQUEST = 8,
VD_AGENT_CLIPBOARD_RELEASE = 9,
VD_AGENT_FILE_XFER_START =10,
VD_AGENT_FILE_XFER_STATUS =11,
VD_AGENT_FILE_XFER_DATA =12,
VD_AGENT_CLIENT_DISCONNECTED =13,
VD_AGENT_MAX_CLIPBOARD =14;
VD_AGENT_MOUSE_STATE : 1,
VD_AGENT_MONITORS_CONFIG : 2,
VD_AGENT_REPLY : 3,
VD_AGENT_CLIPBOARD : 4,
VD_AGENT_DISPLAY_CONFIG : 5,
VD_AGENT_ANNOUNCE_CAPABILITIES : 6,
VD_AGENT_CLIPBOARD_GRAB : 7,
VD_AGENT_CLIPBOARD_REQUEST : 8,
VD_AGENT_CLIPBOARD_RELEASE : 9,
VD_AGENT_FILE_XFER_START :10,
VD_AGENT_FILE_XFER_STATUS :11,
VD_AGENT_FILE_XFER_DATA :12,
VD_AGENT_CLIENT_DISCONNECTED :13,
VD_AGENT_MAX_CLIPBOARD :14,
var VD_AGENT_CAP_MOUSE_STATE = 0,
VD_AGENT_CAP_MONITORS_CONFIG = 1,
VD_AGENT_CAP_REPLY = 2,
VD_AGENT_CAP_CLIPBOARD = 3,
VD_AGENT_CAP_DISPLAY_CONFIG = 4,
VD_AGENT_CAP_CLIPBOARD_BY_DEMAND = 5,
VD_AGENT_CAP_CLIPBOARD_SELECTION = 6,
VD_AGENT_CAP_SPARSE_MONITORS_CONFIG = 7,
VD_AGENT_CAP_GUEST_LINEEND_LF = 8,
VD_AGENT_CAP_GUEST_LINEEND_CRLF = 9,
VD_AGENT_CAP_MAX_CLIPBOARD = 10,
VD_AGENT_END_CAP = 11;
VD_AGENT_CAP_MOUSE_STATE : 0,
VD_AGENT_CAP_MONITORS_CONFIG : 1,
VD_AGENT_CAP_REPLY : 2,
VD_AGENT_CAP_CLIPBOARD : 3,
VD_AGENT_CAP_DISPLAY_CONFIG : 4,
VD_AGENT_CAP_CLIPBOARD_BY_DEMAND : 5,
VD_AGENT_CAP_CLIPBOARD_SELECTION : 6,
VD_AGENT_CAP_SPARSE_MONITORS_CONFIG : 7,
VD_AGENT_CAP_GUEST_LINEEND_LF : 8,
VD_AGENT_CAP_GUEST_LINEEND_CRLF : 9,
VD_AGENT_CAP_MAX_CLIPBOARD : 10,
VD_AGENT_END_CAP : 11,
var VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA = 0,
VD_AGENT_FILE_XFER_STATUS_CANCELLED = 1,
VD_AGENT_FILE_XFER_STATUS_ERROR = 2,
VD_AGENT_FILE_XFER_STATUS_SUCCESS = 3;
VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA : 0,
VD_AGENT_FILE_XFER_STATUS_CANCELLED : 1,
VD_AGENT_FILE_XFER_STATUS_ERROR : 2,
VD_AGENT_FILE_XFER_STATUS_SUCCESS : 3,
};

View file

@ -86,3 +86,9 @@ function handle_file_drop(e)
}
}
export {
SpiceFileXferTask,
handle_file_dragover,
handle_file_drop,
};

View file

@ -18,6 +18,12 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import * as Messages from './spicemsg.js';
import { Constants } from './enums.js';
import { KeyNames } from './atKeynames.js';
import { SpiceConn } from './spiceconn.js';
import { DEBUG } from './utils.js';
/*----------------------------------------------------------------------------
** Modifier Keystates
** These need to be tracked because focus in and out can get the keyboard
@ -45,26 +51,26 @@ function SpiceInputsConn()
SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
SpiceInputsConn.prototype.process_channel_message = function(msg)
{
if (msg.type == SPICE_MSG_INPUTS_INIT)
if (msg.type == Constants.SPICE_MSG_INPUTS_INIT)
{
var inputs_init = new SpiceMsgInputsInit(msg.data);
var inputs_init = new Messages.SpiceMsgInputsInit(msg.data);
this.keyboard_modifiers = inputs_init.keyboard_modifiers;
DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers);
// FIXME - We don't do anything with the keyboard modifiers...
return true;
}
if (msg.type == SPICE_MSG_INPUTS_KEY_MODIFIERS)
if (msg.type == Constants.SPICE_MSG_INPUTS_KEY_MODIFIERS)
{
var key = new SpiceMsgInputsKeyModifiers(msg.data);
var key = new Messages.SpiceMsgInputsKeyModifiers(msg.data);
this.keyboard_modifiers = key.keyboard_modifiers;
DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers);
// FIXME - We don't do anything with the keyboard modifiers...
return true;
}
if (msg.type == SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
if (msg.type == Constants.SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
{
DEBUG > 1 && console.log("mouse motion ack");
this.waiting_for_ack -= SPICE_INPUT_MOTION_ACK_BUNCH;
this.waiting_for_ack -= Constants.SPICE_INPUT_MOTION_ACK_BUNCH;
return true;
}
return false;
@ -74,21 +80,21 @@ SpiceInputsConn.prototype.process_channel_message = function(msg)
function handle_mousemove(e)
{
var msg = new SpiceMiniData();
var msg = new Messages.SpiceMiniData();
var move;
if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
if (this.sc.mouse_mode == Constants.SPICE_MOUSE_MODE_CLIENT)
{
move = new SpiceMsgcMousePosition(this.sc, e)
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
move = new Messages.SpiceMsgcMousePosition(this.sc, e)
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
}
else
{
move = new SpiceMsgcMouseMotion(this.sc, e)
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
move = new Messages.SpiceMsgcMouseMotion(this.sc, e)
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
}
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
{
if (this.sc.inputs.waiting_for_ack < (2 * 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.waiting_for_ack++;
@ -111,9 +117,9 @@ function handle_mousemove(e)
function handle_mousedown(e)
{
var press = new SpiceMsgcMousePress(this.sc, e)
var msg = new SpiceMiniData();
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
var press = new Messages.SpiceMsgcMousePress(this.sc, e)
var msg = new Messages.SpiceMiniData();
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg);
@ -128,9 +134,9 @@ function handle_contextmenu(e)
function handle_mouseup(e)
{
var release = new SpiceMsgcMouseRelease(this.sc, e)
var msg = new SpiceMiniData();
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
var release = new Messages.SpiceMsgcMouseRelease(this.sc, e)
var msg = new Messages.SpiceMiniData();
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg);
@ -139,21 +145,21 @@ function handle_mouseup(e)
function handle_mousewheel(e)
{
var press = new SpiceMsgcMousePress;
var release = new SpiceMsgcMouseRelease;
var press = new Messages.SpiceMsgcMousePress;
var release = new Messages.SpiceMsgcMouseRelease;
if (e.deltaY < 0)
press.button = release.button = SPICE_MOUSE_BUTTON_UP;
press.button = release.button = Constants.SPICE_MOUSE_BUTTON_UP;
else
press.button = release.button = SPICE_MOUSE_BUTTON_DOWN;
press.button = release.button = Constants.SPICE_MOUSE_BUTTON_DOWN;
press.buttons_state = 0;
release.buttons_state = 0;
var msg = new SpiceMiniData();
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
var msg = new Messages.SpiceMiniData();
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg);
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg);
@ -162,10 +168,10 @@ function handle_mousewheel(e)
function handle_keydown(e)
{
var key = new SpiceMsgcKeyDown(e)
var msg = new SpiceMiniData();
var key = new Messages.SpiceMsgcKeyDown(e)
var msg = new Messages.SpiceMiniData();
check_and_update_modifiers(e, key.code, this.sc);
msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg);
@ -174,74 +180,50 @@ function handle_keydown(e)
function handle_keyup(e)
{
var key = new SpiceMsgcKeyUp(e)
var msg = new SpiceMiniData();
var key = new Messages.SpiceMsgcKeyUp(e)
var msg = new Messages.SpiceMiniData();
check_and_update_modifiers(e, key.code, this.sc);
msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg);
e.preventDefault();
}
function sendCtrlAltDel()
function sendCtrlAltDel(sc)
{
if (sc && sc.inputs && sc.inputs.state === "ready"){
var key = new SpiceMsgcKeyDown();
var msg = new SpiceMiniData();
var key = new Messages.SpiceMsgcKeyDown();
var msg = new Messages.SpiceMiniData();
update_modifier(true, KEY_LCtrl, sc);
update_modifier(true, KEY_Alt, sc);
update_modifier(true, KeyNames.KEY_LCtrl, sc);
update_modifier(true, KeyNames.KEY_Alt, sc);
key.code = KEY_KP_Decimal;
msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
key.code = KeyNames.KEY_KP_Decimal;
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
sc.inputs.send_msg(msg);
msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
sc.inputs.send_msg(msg);
if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc);
if(Alt_state == false) update_modifier(false, KEY_Alt, sc);
}
}
function sendCtrlAltFN(f) {
if (sc && sc.inputs && sc.inputs.state === "ready"){
var keys_code=[KEY_F1,KEY_F2,KEY_F3,KEY_F4,KEY_F5,KEY_F6,KEY_F7,KEY_F8,KEY_F9,KEY_F10,KEY_F11,KEY_F12];
if (keys_code[f]==undefined) {
return;
}
var key = new SpiceMsgcKeyDown();
var msg = new SpiceMiniData();
update_modifier(true, KEY_LCtrl, sc);
update_modifier(true, KEY_Alt, sc);
key.code = keys_code[f];
msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
sc.inputs.send_msg(msg);
msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
sc.inputs.send_msg(msg);
if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc);
if(Alt_state == false) update_modifier(false, KEY_Alt, sc);
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 SpiceMiniData();
var msg = new Messages.SpiceMiniData();
if (!state)
{
var key = new SpiceMsgcKeyUp()
var key = new Messages.SpiceMsgcKeyUp()
key.code =(0x80|code);
msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
}
else
{
var key = new SpiceMsgcKeyDown()
var key = new Messages.SpiceMsgcKeyDown()
key.code = code;
msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
}
sc.inputs.send_msg(msg);
@ -257,19 +239,19 @@ function check_and_update_modifiers(e, code, sc)
Meta_state = e.metaKey;
}
if (code === KEY_ShiftL)
if (code === KeyNames.KEY_ShiftL)
Shift_state = true;
else if (code === KEY_Alt)
else if (code === KeyNames.KEY_Alt)
Alt_state = true;
else if (code === KEY_LCtrl)
else if (code === KeyNames.KEY_LCtrl)
Ctrl_state = true;
else if (code === 0xE0B5)
Meta_state = true;
else if (code === (0x80|KEY_ShiftL))
else if (code === (0x80|KeyNames.KEY_ShiftL))
Shift_state = false;
else if (code === (0x80|KEY_Alt))
else if (code === (0x80|KeyNames.KEY_Alt))
Alt_state = false;
else if (code === (0x80|KEY_LCtrl))
else if (code === (0x80|KeyNames.KEY_LCtrl))
Ctrl_state = false;
else if (code === (0x80|0xE0B5))
Meta_state = false;
@ -279,19 +261,19 @@ function check_and_update_modifiers(e, code, sc)
if (Shift_state != e.shiftKey)
{
console.log("Shift state out of sync");
update_modifier(e.shiftKey, KEY_ShiftL, sc);
update_modifier(e.shiftKey, KeyNames.KEY_ShiftL, sc);
Shift_state = e.shiftKey;
}
if (Alt_state != e.altKey)
{
console.log("Alt state out of sync");
update_modifier(e.altKey, KEY_Alt, sc);
update_modifier(e.altKey, KeyNames.KEY_Alt, sc);
Alt_state = e.altKey;
}
if (Ctrl_state != e.ctrlKey)
{
console.log("Ctrl state out of sync");
update_modifier(e.ctrlKey, KEY_LCtrl, sc);
update_modifier(e.ctrlKey, KeyNames.KEY_LCtrl, sc);
Ctrl_state = e.ctrlKey;
}
if (Meta_state != e.metaKey)
@ -302,3 +284,15 @@ function check_and_update_modifiers(e, code, sc)
}
}
}
export {
SpiceInputsConn,
handle_mousemove,
handle_mousedown,
handle_contextmenu,
handle_mouseup,
handle_mousewheel,
handle_keydown,
handle_keyup,
sendCtrlAltDel,
};

View file

@ -18,6 +18,7 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import { Constants } from './enums.js';
/*----------------------------------------------------------------------------
** lz.js
@ -30,6 +31,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
var op = 0;
var ctrl;
var ctr = 0;
var i = 0;
for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl = in_buf[encoder++])
{
@ -62,7 +64,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
}
}
len += 1;
if (type == LZ_IMAGE_TYPE_RGBA)
if (type == Constants.LZ_IMAGE_TYPE_RGBA)
len += 2;
ofs += 1;
@ -72,7 +74,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
var b = ref;
//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha " + out_buf[(b*4)+3] + " dupped into pixel " + op + " through pixel " + (op + len));
for (; len; --len) {
if (type == LZ_IMAGE_TYPE_RGBA)
if (type == Constants.LZ_IMAGE_TYPE_RGBA)
{
out_buf[(op*4) + 3] = out_buf[(b*4)+3];
}
@ -86,7 +88,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
} else {
//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op + " through " + (op + len) + " from " + ref);
for (; len; --len) {
if (type == LZ_IMAGE_TYPE_RGBA)
if (type == Constants.LZ_IMAGE_TYPE_RGBA)
{
out_buf[(op*4) + 3] = out_buf[(ref*4)+3];
}
@ -101,7 +103,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
} else {
ctrl++;
if (type == LZ_IMAGE_TYPE_RGBA)
if (type == Constants.LZ_IMAGE_TYPE_RGBA)
{
//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
out_buf[(op*4) + 3] = in_buf[encoder++];
@ -119,7 +121,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
for (--ctrl; ctrl; ctrl--) {
if (type == LZ_IMAGE_TYPE_RGBA)
if (type == Constants.LZ_IMAGE_TYPE_RGBA)
{
//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
out_buf[(op*4) + 3] = in_buf[encoder++];
@ -157,26 +159,30 @@ function flip_image_data(img)
function convert_spice_lz_to_web(context, lz_image)
{
var at;
if (lz_image.type === LZ_IMAGE_TYPE_RGB32 || lz_image.type === LZ_IMAGE_TYPE_RGBA)
if (lz_image.type === Constants.LZ_IMAGE_TYPE_RGB32 || lz_image.type === Constants.LZ_IMAGE_TYPE_RGBA)
{
var u8 = new Uint8Array(lz_image.data);
var ret = context.createImageData(lz_image.width, lz_image.height);
at = lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGB32, lz_image.type != LZ_IMAGE_TYPE_RGBA);
at = lz_rgb32_decompress(u8, 0, ret.data, Constants.LZ_IMAGE_TYPE_RGB32, lz_image.type != Constants.LZ_IMAGE_TYPE_RGBA);
if (!lz_image.top_down)
flip_image_data(ret);
if (lz_image.type == LZ_IMAGE_TYPE_RGBA)
lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false);
if (lz_image.type == Constants.LZ_IMAGE_TYPE_RGBA)
lz_rgb32_decompress(u8, at, ret.data, Constants.LZ_IMAGE_TYPE_RGBA, false);
}
else if (lz_image.type === LZ_IMAGE_TYPE_XXXA)
else if (lz_image.type === Constants.LZ_IMAGE_TYPE_XXXA)
{
var u8 = new Uint8Array(lz_image.data);
var ret = context.createImageData(lz_image.width, lz_image.height);
lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGBA, false);
lz_rgb32_decompress(u8, 0, ret.data, Constants.LZ_IMAGE_TYPE_RGBA, false);
}
else
return undefined;
return ret;
}
export {
convert_spice_lz_to_web,
};

View file

@ -18,6 +18,19 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import * as Messages from './spicemsg.js';
import { Constants } from './enums.js';
import { SpiceCursorConn } from './cursor.js';
import { SpiceConn } from './spiceconn.js';
import { DEBUG } from './utils.js';
import { SpiceFileXferTask } from './filexfer.js';
import { SpiceInputsConn, sendCtrlAltDel } from './inputs.js';
import { SpiceDisplayConn } from './display.js';
import { SpicePlaybackConn } from './playback.js';
import { SpicePortConn } from './port.js';
import { handle_file_dragover, handle_file_drop } from './filexfer.js';
import { resize_helper, handle_resize } from './resize.js';
/*----------------------------------------------------------------------------
** SpiceMainConn
** This is the master Javascript class for establishing and
@ -43,6 +56,8 @@
** onagent (optional) If given, a function to be called when
** a VD agent is connected; a good opportunity
** to request a resize
** onsuccess (optional) If given, a function to be called when the
** session is successfully connected
**
** Throws error if there are troubles. Requires a modern (by 2012 standards)
** browser, including WebSocket and WebSocket.binaryType == arraybuffer
@ -65,23 +80,23 @@ function SpiceMainConn()
SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
SpiceMainConn.prototype.process_channel_message = function(msg)
{
if (msg.type == SPICE_MSG_MAIN_MIGRATE_BEGIN)
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN)
{
this.known_unimplemented(msg.type, "Main Migrate Begin");
return true;
}
if (msg.type == SPICE_MSG_MAIN_MIGRATE_CANCEL)
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_CANCEL)
{
this.known_unimplemented(msg.type, "Main Migrate Cancel");
return true;
}
if (msg.type == SPICE_MSG_MAIN_INIT)
if (msg.type == Constants.SPICE_MSG_MAIN_INIT)
{
this.log_info("Connected to " + this.ws.url);
this.report_success("Connected")
this.main_init = new SpiceMsgMainInit(msg.data);
this.main_init = new Messages.SpiceMsgMainInit(msg.data);
this.connection_id = this.main_init.session_id;
this.agent_tokens = this.main_init.agent_tokens;
@ -108,33 +123,33 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
if (this.main_init.agent_connected)
this.connect_agent();
var attach = new SpiceMiniData;
attach.type = SPICE_MSGC_MAIN_ATTACH_CHANNELS;
var attach = new Messages.SpiceMiniData;
attach.type = Constants.SPICE_MSGC_MAIN_ATTACH_CHANNELS;
attach.size = attach.buffer_size();
this.send_msg(attach);
return true;
}
if (msg.type == SPICE_MSG_MAIN_MOUSE_MODE)
if (msg.type == Constants.SPICE_MSG_MAIN_MOUSE_MODE)
{
var mode = new 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);
this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
return true;
}
if (msg.type == 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");
return true;
}
if (msg.type == SPICE_MSG_MAIN_CHANNELS_LIST)
if (msg.type == Constants.SPICE_MSG_MAIN_CHANNELS_LIST)
{
var i;
var chans;
DEBUG > 0 && console.log("channels");
chans = new SpiceMsgChannels(msg.data);
chans = new Messages.SpiceMsgChannels(msg.data);
for (i = 0; i < chans.channels.length; i++)
{
var conn = {
@ -144,23 +159,24 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
type : chans.channels[i].type,
chan_id : chans.channels[i].id
};
if (chans.channels[i].type == SPICE_CHANNEL_DISPLAY)
if (chans.channels[i].type == Constants.SPICE_CHANNEL_DISPLAY)
{
if (this.display !== undefined)
this.log_warn("The spice-html5 client does not handle multiple heads.");
else
if (chans.channels[i].id == 0) {
this.display = new SpiceDisplayConn(conn);
} else {
this.log_warn("The spice-html5 client does not handle multiple heads.");
}
}
else if (chans.channels[i].type == SPICE_CHANNEL_INPUTS)
else if (chans.channels[i].type == Constants.SPICE_CHANNEL_INPUTS)
{
this.inputs = new SpiceInputsConn(conn);
this.inputs.mouse_mode = this.mouse_mode;
}
else if (chans.channels[i].type == SPICE_CHANNEL_CURSOR)
else if (chans.channels[i].type == Constants.SPICE_CHANNEL_CURSOR)
this.cursor = new SpiceCursorConn(conn);
else if (chans.channels[i].type == SPICE_CHANNEL_PLAYBACK)
else if (chans.channels[i].type == Constants.SPICE_CHANNEL_PLAYBACK)
this.cursor = new SpicePlaybackConn(conn);
else if (chans.channels[i].type == SPICE_CHANNEL_PORT)
else if (chans.channels[i].type == Constants.SPICE_CHANNEL_PORT)
this.ports.push(new SpicePortConn(conn));
else
{
@ -175,23 +191,23 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED)
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED)
{
this.connect_agent();
return true;
}
if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
{
var connected_tokens = new SpiceMsgMainAgentTokens(msg.data);
var connected_tokens = new Messages.SpiceMsgMainAgentTokens(msg.data);
this.agent_tokens = connected_tokens.num_tokens;
this.connect_agent();
return true;
}
if (msg.type == SPICE_MSG_MAIN_AGENT_TOKEN)
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_TOKEN)
{
var remaining_tokens, tokens = new SpiceMsgMainAgentTokens(msg.data);
var remaining_tokens, tokens = new Messages.SpiceMsgMainAgentTokens(msg.data);
this.agent_tokens += tokens.num_tokens;
this.send_agent_message_queue();
@ -205,68 +221,68 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_MAIN_AGENT_DISCONNECTED)
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DISCONNECTED)
{
this.agent_connected = false;
return true;
}
if (msg.type == SPICE_MSG_MAIN_AGENT_DATA)
if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DATA)
{
var agent_data = new SpiceMsgMainAgentData(msg.data);
if (agent_data.type == VD_AGENT_ANNOUNCE_CAPABILITIES)
var agent_data = new Messages.SpiceMsgMainAgentData(msg.data);
if (agent_data.type == Constants.VD_AGENT_ANNOUNCE_CAPABILITIES)
{
var agent_caps = new VDAgentAnnounceCapabilities(agent_data.data);
var agent_caps = new Messages.VDAgentAnnounceCapabilities(agent_data.data);
if (agent_caps.request)
this.announce_agent_capabilities(0);
return true;
}
else if (agent_data.type == VD_AGENT_FILE_XFER_STATUS)
else if (agent_data.type == Constants.VD_AGENT_FILE_XFER_STATUS)
{
this.handle_file_xfer_status(new VDAgentFileXferStatusMessage(agent_data.data));
this.handle_file_xfer_status(new Messages.VDAgentFileXferStatusMessage(agent_data.data));
return true;
}
return false;
}
if (msg.type == 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");
return true;
}
if (msg.type == SPICE_MSG_MAIN_MIGRATE_END)
if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_END)
{
this.known_unimplemented(msg.type, "Main Migrate End");
return true;
}
if (msg.type == SPICE_MSG_MAIN_NAME)
if (msg.type == Constants.SPICE_MSG_MAIN_NAME)
{
this.known_unimplemented(msg.type, "Main Name");
return true;
}
if (msg.type == SPICE_MSG_MAIN_UUID)
if (msg.type == Constants.SPICE_MSG_MAIN_UUID)
{
this.known_unimplemented(msg.type, "Main UUID");
return true;
}
if (msg.type == 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");
return true;
}
if (msg.type == 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");
return true;
}
if (msg.type == 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");
return true;
@ -324,15 +340,15 @@ SpiceMainConn.prototype.send_agent_message_queue = function(message)
SpiceMainConn.prototype.send_agent_message = function(type, message)
{
var agent_data = new SpiceMsgcMainAgentData(type, message);
var sb = 0, maxsize = VD_AGENT_MAX_DATA_SIZE - SpiceMiniData.prototype.buffer_size();
var agent_data = new Messages.SpiceMsgcMainAgentData(type, message);
var sb = 0, maxsize = Constants.VD_AGENT_MAX_DATA_SIZE - Messages.SpiceMiniData.prototype.buffer_size();
var data = new ArrayBuffer(agent_data.buffer_size());
agent_data.to_buffer(data);
while (sb < agent_data.buffer_size())
{
var eb = Math.min(sb + maxsize, agent_data.buffer_size());
var mr = new SpiceMiniData();
mr.type = SPICE_MSGC_MAIN_AGENT_DATA;
var mr = new Messages.SpiceMiniData();
mr.type = Constants.SPICE_MSGC_MAIN_AGENT_DATA;
mr.size = eb - sb;
mr.data = data.slice(sb, eb);
this.send_agent_message_queue(mr);
@ -342,16 +358,16 @@ SpiceMainConn.prototype.send_agent_message = function(type, message)
SpiceMainConn.prototype.announce_agent_capabilities = function(request)
{
var caps = new VDAgentAnnounceCapabilities(request, (1 << VD_AGENT_CAP_MOUSE_STATE) |
(1 << VD_AGENT_CAP_MONITORS_CONFIG) |
(1 << VD_AGENT_CAP_REPLY));
this.send_agent_message(VD_AGENT_ANNOUNCE_CAPABILITIES, caps);
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_REPLY));
this.send_agent_message(Constants.VD_AGENT_ANNOUNCE_CAPABILITIES, caps);
}
SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
{
var monitors_config = new VDAgentMonitorsConfig(flags, width, height, depth, x, y);
this.send_agent_message(VD_AGENT_MONITORS_CONFIG, monitors_config);
var monitors_config = new Messages.VDAgentMonitorsConfig(flags, width, height, depth, x, y);
this.send_agent_message(Constants.VD_AGENT_MONITORS_CONFIG, monitors_config);
}
SpiceMainConn.prototype.file_xfer_start = function(file)
@ -362,8 +378,8 @@ SpiceMainConn.prototype.file_xfer_start = function(file)
task = new SpiceFileXferTask(task_id, file);
task.create_progressbar();
this.file_xfer_tasks[task_id] = task;
xfer_start = new VDAgentFileXferStartMessage(task_id, file.name, file.size);
this.send_agent_message(VD_AGENT_FILE_XFER_START, xfer_start);
xfer_start = new Messages.VDAgentFileXferStartMessage(task_id, file.name, file.size);
this.send_agent_message(Constants.VD_AGENT_FILE_XFER_START, xfer_start);
}
SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
@ -376,16 +392,16 @@ SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
xfer_task = this.file_xfer_tasks[file_xfer_status.id];
switch (file_xfer_status.result)
{
case VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
case Constants.VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
this.file_xfer_read(xfer_task);
return;
case VD_AGENT_FILE_XFER_STATUS_CANCELLED:
case Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED:
xfer_error = "transfer is cancelled by spice agent";
break;
case VD_AGENT_FILE_XFER_STATUS_ERROR:
case Constants.VD_AGENT_FILE_XFER_STATUS_ERROR:
xfer_error = "some errors occurred in the spice agent";
break;
case VD_AGENT_FILE_XFER_STATUS_SUCCESS:
case Constants.VD_AGENT_FILE_XFER_STATUS_SUCCESS:
break;
default:
xfer_error = "unhandled status type: " + file_xfer_status.result;
@ -397,7 +413,7 @@ SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
{
var FILE_XFER_CHUNK_SIZE = 32 * VD_AGENT_MAX_DATA_SIZE;
var FILE_XFER_CHUNK_SIZE = 32 * Constants.VD_AGENT_MAX_DATA_SIZE;
var _this = this;
var sb, eb;
var slice, reader;
@ -411,9 +427,9 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
if (file_xfer_task.cancelled)
{
var xfer_status = new VDAgentFileXferStatusMessage(file_xfer_task.id,
VD_AGENT_FILE_XFER_STATUS_CANCELLED);
this.send_agent_message(VD_AGENT_FILE_XFER_STATUS, xfer_status);
var xfer_status = new Messages.VDAgentFileXferStatusMessage(file_xfer_task.id,
Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED);
this.send_agent_message(Constants.VD_AGENT_FILE_XFER_STATUS, xfer_status);
delete this.file_xfer_tasks[file_xfer_task.id];
return;
}
@ -431,10 +447,10 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
reader = new FileReader();
reader.onload = function(e)
{
var xfer_data = new VDAgentFileXferDataMessage(file_xfer_task.id,
var xfer_data = new Messages.VDAgentFileXferDataMessage(file_xfer_task.id,
e.target.result.byteLength,
e.target.result);
_this.send_agent_message(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);
file_xfer_task.update_progressbar(eb);
};
@ -459,9 +475,9 @@ SpiceMainConn.prototype.connect_agent = function()
{
this.agent_connected = true;
var agent_start = new SpiceMsgcMainAgentStart(~0);
var mr = new SpiceMiniData();
mr.build_msg(SPICE_MSGC_MAIN_AGENT_START, agent_start);
var agent_start = new Messages.SpiceMsgcMainAgentStart(~0);
var mr = new Messages.SpiceMiniData();
mr.build_msg(Constants.SPICE_MSGC_MAIN_AGENT_START, agent_start);
this.send_msg(mr);
this.announce_agent_capabilities(1);
@ -474,11 +490,11 @@ SpiceMainConn.prototype.connect_agent = function()
SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
{
this.mouse_mode = current;
if (current != SPICE_MOUSE_MODE_CLIENT && (supported & SPICE_MOUSE_MODE_CLIENT))
if (current != Constants.SPICE_MOUSE_MODE_CLIENT && (supported & Constants.SPICE_MOUSE_MODE_CLIENT))
{
var mode_request = new SpiceMsgcMainMouseModeRequest(SPICE_MOUSE_MODE_CLIENT);
var mr = new SpiceMiniData();
mr.build_msg(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
var mode_request = new Messages.SpiceMsgcMainMouseModeRequest(Constants.SPICE_MOUSE_MODE_CLIENT);
var mr = new Messages.SpiceMiniData();
mr.build_msg(Constants.SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
this.send_msg(mr);
}
@ -492,3 +508,12 @@ SpiceMainConn.prototype.relative_now = function()
var ret = (Date.now() - this.our_mm_time) + this.mm_time;
return ret;
}
export {
SpiceMainConn,
handle_file_dragover,
handle_file_drop,
resize_helper,
handle_resize,
sendCtrlAltDel,
};

View file

@ -22,6 +22,13 @@
** SpicePlaybackConn
** Drive the Spice Playback channel (sound out)
**--------------------------------------------------------------------------*/
import * as Utils from './utils.js';
import * as Webm from './webm.js';
import * as Messages from './spicemsg.js';
import { Constants } from './enums.js';
import { SpiceConn } from './spiceconn.js';
function SpicePlaybackConn()
{
SpiceConn.apply(this, arguments);
@ -40,25 +47,25 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
return false;
}
if (msg.type == SPICE_MSG_PLAYBACK_START)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_START)
{
var start = new SpiceMsgPlaybackStart(msg.data);
var start = new Messages.SpiceMsgPlaybackStart(msg.data);
PLAYBACK_DEBUG > 0 && console.log("PlaybackStart; frequency " + start.frequency);
Utils.PLAYBACK_DEBUG > 0 && console.log("PlaybackStart; frequency " + start.frequency);
if (start.frequency != OPUS_FREQUENCY)
if (start.frequency != Webm.Constants.OPUS_FREQUENCY)
{
this.log_err('This player cannot handle frequency ' + start.frequency);
return false;
}
if (start.channels != OPUS_CHANNELS)
if (start.channels != Webm.Constants.OPUS_CHANNELS)
{
this.log_err('This player cannot handle ' + start.channels + ' channels');
return false;
}
if (start.format != SPICE_AUDIO_FMT_S16)
if (start.format != Constants.SPICE_AUDIO_FMT_S16)
{
this.log_err('This player cannot format ' + start.format);
return false;
@ -85,9 +92,9 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
}
}
if (msg.type == SPICE_MSG_PLAYBACK_DATA)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_DATA)
{
var data = new SpiceMsgPlaybackData(msg.data);
var data = new Messages.SpiceMsgPlaybackData(msg.data);
if (! this.source_buffer)
return true;
@ -115,28 +122,28 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
will resync.
*/
if (this.start_time != 0 && data.time != (this.last_data_time + EXPECTED_PACKET_DURATION))
if (this.start_time != 0 && data.time != (this.last_data_time + Webm.Constants.EXPECTED_PACKET_DURATION))
{
if (Math.abs(data.time - (EXPECTED_PACKET_DURATION + this.last_data_time)) < MAX_CLUSTER_TIME)
if (Math.abs(data.time - (Webm.Constants.EXPECTED_PACKET_DURATION + this.last_data_time)) < Webm.Constants.MAX_CLUSTER_TIME)
{
PLAYBACK_DEBUG > 1 && console.log("Hacking time of " + data.time + " to " +
(this.last_data_time + EXPECTED_PACKET_DURATION));
data.time = this.last_data_time + EXPECTED_PACKET_DURATION;
Utils.PLAYBACK_DEBUG > 1 && console.log("Hacking time of " + data.time + " to " +
(this.last_data_time + Webm.Constants.EXPECTED_PACKET_DURATION));
data.time = this.last_data_time + Webm.Constants.EXPECTED_PACKET_DURATION;
}
else
{
PLAYBACK_DEBUG > 1 && console.log("Apparent gap in audio time; now is " + data.time + " last was " + this.last_data_time);
Utils.PLAYBACK_DEBUG > 1 && console.log("Apparent gap in audio time; now is " + data.time + " last was " + this.last_data_time);
}
}
this.last_data_time = data.time;
PLAYBACK_DEBUG > 1 && console.log("PlaybackData; time " + data.time + "; length " + data.data.byteLength);
Utils.PLAYBACK_DEBUG > 1 && console.log("PlaybackData; time " + data.time + "; length " + data.data.byteLength);
if (this.start_time == 0)
this.start_playback(data);
else if (data.time - this.cluster_time >= MAX_CLUSTER_TIME)
else if (data.time - this.cluster_time >= Webm.Constants.MAX_CLUSTER_TIME)
this.new_cluster(data);
else
@ -145,10 +152,10 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_PLAYBACK_MODE)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_MODE)
{
var mode = new SpiceMsgPlaybackMode(msg.data);
if (mode.mode != SPICE_AUDIO_DATA_MODE_OPUS)
var mode = new Messages.SpiceMsgPlaybackMode(msg.data);
if (mode.mode != Constants.SPICE_AUDIO_DATA_MODE_OPUS)
{
this.log_err('This player cannot handle mode ' + mode.mode);
delete this.source_buffer;
@ -156,9 +163,9 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
return true;
}
if (msg.type == SPICE_MSG_PLAYBACK_STOP)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_STOP)
{
PLAYBACK_DEBUG > 0 && console.log("PlaybackStop");
Utils.PLAYBACK_DEBUG > 0 && console.log("PlaybackStop");
if (this.source_buffer)
{
document.getElementById(this.parent.screen_id).removeChild(this.audio);
@ -176,19 +183,19 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
}
}
if (msg.type == SPICE_MSG_PLAYBACK_VOLUME)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_VOLUME)
{
this.known_unimplemented(msg.type, "Playback Volume");
return true;
}
if (msg.type == SPICE_MSG_PLAYBACK_MUTE)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_MUTE)
{
this.known_unimplemented(msg.type, "Playback Mute");
return true;
}
if (msg.type == SPICE_MSG_PLAYBACK_LATENCY)
if (msg.type == Constants.SPICE_MSG_PLAYBACK_LATENCY)
{
this.known_unimplemented(msg.type, "Playback Latency");
return true;
@ -201,9 +208,9 @@ SpicePlaybackConn.prototype.start_playback = function(data)
{
this.start_time = data.time;
var h = new webm_Header();
var te = new webm_AudioTrackEntry;
var t = new webm_Tracks(te);
var h = new Webm.Header();
var te = new Webm.AudioTrackEntry;
var t = new Webm.Tracks(te);
var mb = new ArrayBuffer(h.buffer_size() + t.buffer_size())
@ -221,7 +228,7 @@ SpicePlaybackConn.prototype.new_cluster = function(data)
{
this.cluster_time = data.time;
var c = new webm_Cluster(data.time - this.start_time);
var c = new Webm.Cluster(data.time - this.start_time);
var mb = new ArrayBuffer(c.buffer_size());
this.bytes_written += c.to_buffer(mb);
@ -236,7 +243,7 @@ SpicePlaybackConn.prototype.new_cluster = function(data)
SpicePlaybackConn.prototype.simple_block = function(data, keyframe)
{
var sb = new webm_SimpleBlock(data.time - this.cluster_time, data.data, keyframe);
var sb = new Webm.SimpleBlock(data.time - this.cluster_time, data.data, keyframe);
var mb = new ArrayBuffer(sb.buffer_size());
this.bytes_written += sb.to_buffer(mb);
@ -254,14 +261,14 @@ function handle_source_open(e)
if (p.source_buffer)
return;
p.source_buffer = this.addSourceBuffer(SPICE_PLAYBACK_CODEC);
p.source_buffer = this.addSourceBuffer(Webm.Constants.SPICE_PLAYBACK_CODEC);
if (! p.source_buffer)
{
p.log_err('Codec ' + SPICE_PLAYBACK_CODEC + ' not available.');
p.log_err('Codec ' + Webm.Constants.SPICE_PLAYBACK_CODEC + ' not available.');
return;
}
if (PLAYBACK_DEBUG > 0)
if (Utils.PLAYBACK_DEBUG > 0)
playback_handle_event_debug.call(this, e);
listen_for_audio_events(p);
@ -315,7 +322,7 @@ function handle_append_buffer_done(e)
{
var p = this.spiceconn;
if (PLAYBACK_DEBUG > 1)
if (Utils.PLAYBACK_DEBUG > 1)
playback_handle_event_debug.call(this, e);
if (p.queue.length > 0)
@ -352,18 +359,18 @@ function playback_handle_event_debug(e)
var p = this.spiceconn;
if (p.audio)
{
if (PLAYBACK_DEBUG > 0 || p.audio.buffered.len > 1)
if (Utils.PLAYBACK_DEBUG > 0 || p.audio.buffered.len > 1)
console.log(p.audio.currentTime + ": event " + e.type +
dump_media_element(p.audio));
Utils.dump_media_element(p.audio));
}
if (PLAYBACK_DEBUG > 1 && p.media_source)
console.log(" media_source " + dump_media_source(p.media_source));
if (Utils.PLAYBACK_DEBUG > 1 && p.media_source)
console.log(" media_source " + Utils.dump_media_source(p.media_source));
if (PLAYBACK_DEBUG > 1 && p.source_buffer)
console.log(" source_buffer " + dump_source_buffer(p.source_buffer));
if (Utils.PLAYBACK_DEBUG > 1 && p.source_buffer)
console.log(" source_buffer " + Utils.dump_source_buffer(p.source_buffer));
if (PLAYBACK_DEBUG > 0 || p.queue.length > 1)
if (Utils.PLAYBACK_DEBUG > 0 || p.queue.length > 1)
console.log(' queue len ' + p.queue.length + '; append_okay: ' + p.append_okay);
}
@ -391,8 +398,12 @@ function listen_for_audio_events(spiceconn)
];
audio_0_events.forEach(playback_debug_listen_for_one_event, spiceconn.audio);
if (PLAYBACK_DEBUG > 0)
if (Utils.PLAYBACK_DEBUG > 0)
audio_1_events.forEach(playback_debug_listen_for_one_event, spiceconn.audio);
if (PLAYBACK_DEBUG > 1)
if (Utils.PLAYBACK_DEBUG > 1)
audio_2_events.forEach(playback_debug_listen_for_one_event, spiceconn.audio);
}
export {
SpicePlaybackConn,
};

View file

@ -22,6 +22,8 @@
** crc logic from rfc2083 ported to Javascript
**--------------------------------------------------------------------------*/
import { SpiceDataView } from './spicedataview.js';
var rfc2083_crc_table = Array(256);
var rfc2083_crc_table_computed = 0;
/* Make the table for a fast CRC. */
@ -254,3 +256,7 @@ function create_rgba_png(width, height, bytes)
return "%89PNG%0D%0A%1A%0A" + str;
}
export {
create_rgba_png,
};

View file

@ -19,6 +19,11 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import { Constants } from './enums.js';
import { DEBUG } from './utils.js';
import { SpiceConn } from './spiceconn.js';
import { SpiceMsgPortInit } from './spicemsg.js';
/*----------------------------------------------------------------------------
** SpicePortConn
** Drive the Spice Port Channel
@ -34,7 +39,7 @@ SpicePortConn.prototype = Object.create(SpiceConn.prototype);
SpicePortConn.prototype.process_channel_message = function(msg)
{
if (msg.type == SPICE_MSG_PORT_INIT)
if (msg.type == Constants.SPICE_MSG_PORT_INIT)
{
if (this.port_name === null)
{
@ -47,7 +52,7 @@ SpicePortConn.prototype.process_channel_message = function(msg)
DEBUG > 0 && console.log('SPICE port: Port', this.port_name, 'is already initialized.');
}
else if (msg.type == SPICE_MSG_PORT_EVENT)
else if (msg.type == Constants.SPICE_MSG_PORT_EVENT)
{
DEBUG > 0 && console.log('SPICE port: Port event received for', this.portName, msg);
var event = new CustomEvent('spice-port-event', {
@ -62,7 +67,7 @@ SpicePortConn.prototype.process_channel_message = function(msg)
window.dispatchEvent(event);
return true;
}
else if (msg.type == SPICE_MSG_SPICEVMC_DATA)
else if (msg.type == Constants.SPICE_MSG_SPICEVMC_DATA)
{
DEBUG > 0 && console.log('SPICE port: Data received in port', this.portName, msg);
var event = new CustomEvent('spice-port-data', {
@ -83,3 +88,7 @@ SpicePortConn.prototype.process_channel_message = function(msg)
return false;
};
export {
SpicePortConn,
};

View file

@ -22,12 +22,15 @@
var encoder;
var QUIC_IMAGE_TYPE_INVALID = 0;
var QUIC_IMAGE_TYPE_GRAY = 1;
var QUIC_IMAGE_TYPE_RGB16 = 2;
var QUIC_IMAGE_TYPE_RGB24 = 3;
var QUIC_IMAGE_TYPE_RGB32 = 4;
var QUIC_IMAGE_TYPE_RGBA = 5;
var Constants = {
QUIC_IMAGE_TYPE_INVALID : 0,
QUIC_IMAGE_TYPE_GRAY : 1,
QUIC_IMAGE_TYPE_RGB16 : 2,
QUIC_IMAGE_TYPE_RGB24 : 3,
QUIC_IMAGE_TYPE_RGB32 : 4,
QUIC_IMAGE_TYPE_RGBA : 5,
};
var DEFevol = 3;
var DEFwmimax = 6;
var DEFwminext = 2048;
@ -191,17 +194,17 @@ function family_init(family, bpc, limit)
function quic_image_bpc(type)
{
switch (type) {
case QUIC_IMAGE_TYPE_GRAY:
case Constants.QUIC_IMAGE_TYPE_GRAY:
return 8;
case QUIC_IMAGE_TYPE_RGB16:
case Constants.QUIC_IMAGE_TYPE_RGB16:
return 5;
case QUIC_IMAGE_TYPE_RGB24:
case Constants.QUIC_IMAGE_TYPE_RGB24:
return 8;
case QUIC_IMAGE_TYPE_RGB32:
case Constants.QUIC_IMAGE_TYPE_RGB32:
return 8;
case QUIC_IMAGE_TYPE_RGBA:
case Constants.QUIC_IMAGE_TYPE_RGBA:
return 8;
case QUIC_IMAGE_TYPE_INVALID:
case Constants.QUIC_IMAGE_TYPE_INVALID:
default:
console.log("quic: bad image type\n");
return 0;
@ -1189,8 +1192,8 @@ QuicEncoder.prototype.quic_decode = function(buf, stride)
switch (this.type)
{
case QUIC_IMAGE_TYPE_RGB32:
case QUIC_IMAGE_TYPE_RGB24:
case Constants.QUIC_IMAGE_TYPE_RGB32:
case Constants.QUIC_IMAGE_TYPE_RGB24:
this.channels[0].correlate_row.zero = 0;
this.channels[1].correlate_row.zero = 0;
this.channels[2].correlate_row.zero = 0;
@ -1208,11 +1211,11 @@ QuicEncoder.prototype.quic_decode = function(buf, stride)
this.rows_completed++;
};
break;
case QUIC_IMAGE_TYPE_RGB16:
case Constants.QUIC_IMAGE_TYPE_RGB16:
console.log("quic: unsupported output format\n");
return false;
break;
case QUIC_IMAGE_TYPE_RGBA:
case Constants.QUIC_IMAGE_TYPE_RGBA:
this.channels[0].correlate_row.zero = 0;
this.channels[1].correlate_row.zero = 0;
this.channels[2].correlate_row.zero = 0;
@ -1237,12 +1240,12 @@ QuicEncoder.prototype.quic_decode = function(buf, stride)
}
break;
case QUIC_IMAGE_TYPE_GRAY:
case Constants.QUIC_IMAGE_TYPE_GRAY:
console.log("quic: unsupported output format\n");
return false;
break;
case QUIC_IMAGE_TYPE_INVALID:
case Constants.QUIC_IMAGE_TYPE_INVALID:
default:
console.log("quic: bad image type\n");
return false;
@ -1255,8 +1258,8 @@ QuicEncoder.prototype.simple_quic_decode = function(buf)
var stride = 4; /* FIXME - proper stride calc please */
if (!this.quic_decode_begin(buf))
return undefined;
if (this.type != QUIC_IMAGE_TYPE_RGB32 && this.type != QUIC_IMAGE_TYPE_RGB24
&& this.type != QUIC_IMAGE_TYPE_RGBA)
if (this.type != Constants.QUIC_IMAGE_TYPE_RGB32 && this.type != Constants.QUIC_IMAGE_TYPE_RGB24
&& this.type != Constants.QUIC_IMAGE_TYPE_RGBA)
return undefined;
var out = new Uint8Array(this.width*this.height*4);
out[0] = 69;
@ -1299,7 +1302,7 @@ function convert_spice_quic_to_web(context, spice_quic)
ret.data[i + 0] = spice_quic.outptr[i + 2];
ret.data[i + 1] = spice_quic.outptr[i + 1];
ret.data[i + 2] = spice_quic.outptr[i + 0];
if (spice_quic.type !== QUIC_IMAGE_TYPE_RGBA)
if (spice_quic.type !== Constants.QUIC_IMAGE_TYPE_RGBA)
ret.data[i + 3] = 255;
else
ret.data[i + 3] = 255 - spice_quic.outptr[i + 3];
@ -1334,3 +1337,9 @@ if (need_init)
if (!encoder)
throw("quic: failed to create encoder");
}
export {
Constants,
SpiceQuic,
convert_spice_quic_to_web,
};

View file

@ -42,26 +42,29 @@ function resize_helper(sc)
var h = window.innerHeight - 20;
/* Screen height based on debug console visibility */
if (window.getComputedStyle(m).getPropertyValue("display") == 'none')
if (m != null)
{
/* Get console height from spice.css .spice-message */
var mh = parseInt(window.getComputedStyle(m).getPropertyValue("height"), 10);
h = h - mh;
}
else
{
/* Show both div elements - spice-area and message-div */
h = h - m.offsetHeight - m.clientHeight;
if (window.getComputedStyle(m).getPropertyValue("display") == 'none')
{
/* Get console height from spice.css .spice-message */
var mh = parseInt(window.getComputedStyle(m).getPropertyValue("height"), 10);
h = h - mh;
}
else
{
/* Show both div elements - spice-area and message-div */
h = h - m.offsetHeight - m.clientHeight;
}
}
/* Xorg requires height be a multiple of 8; round up */
/* Xorg requires height be a multiple of 8; round down */
if (h % 8 > 0)
h += (8 - (h % 8));
h -= (h % 8);
/* Xorg requires width be a multiple of 8; round up */
/* Xorg requires width be a multiple of 8; round down */
if (w % 8 > 0)
w += (8 - (w % 8));
w -= (w % 8);
sc.resize_window(0, w, h, 32, 0, 0);
@ -80,3 +83,8 @@ function handle_resize(e)
sc.spice_resize_timer = window.setTimeout(resize_helper, 200, sc);
}
export {
resize_helper,
handle_resize,
};

View file

@ -25,6 +25,10 @@
** is a preloaded cursor available, we will use that. Failing that, we will
** simulate a cursor using an image that is moved around the screen.
**--------------------------------------------------------------------------*/
import { SpiceDataView } from './spicedataview.js';
import { hex_sha1 } from './thirdparty/sha1.js';
var SpiceSimulateCursor = {
cursors : new Array(),
@ -200,3 +204,5 @@ SpiceSimulateCursor.ICONDIRENTRY.prototype =
return 16;
}
};
export { SpiceSimulateCursor };

View file

@ -26,6 +26,25 @@
** display, inputs, and cursor channels. See main.js for
** usage.
**--------------------------------------------------------------------------*/
import { Constants } from './enums.js';
import { SpiceWireReader } from './wire.js';
import {
SpiceLinkHeader,
SpiceLinkMess,
SpiceLinkReply,
SpiceLinkAuthTicket,
SpiceLinkAuthReply,
SpiceMiniData,
SpiceMsgcDisplayInit,
SpiceMsgSetAck,
SpiceMsgcAckSync,
SpiceMsgNotify,
} from './spicemsg.js';
import { DEBUG } from './utils.js';
import * as Webm from './webm.js';
import { rsa_encrypt } from './ticket.js';
function SpiceConn(o)
{
if (o === undefined || o.uri === undefined || ! o.uri)
@ -37,7 +56,7 @@ function SpiceConn(o)
throw new Error("WebSocket doesn't support binaryType. Try a different browser.");
this.connection_id = o.connection_id !== undefined ? o.connection_id : 0;
this.type = o.type !== undefined ? o.type : SPICE_CHANNEL_MAIN;
this.type = o.type !== undefined ? o.type : Constants.SPICE_CHANNEL_MAIN;
this.chan_id = o.chan_id !== undefined ? o.chan_id : 0;
if (o.parent !== undefined)
{
@ -107,7 +126,7 @@ function SpiceConn(o)
if (this.ws.readyState == 2 || this.ws.readyState == 3)
throw new Error("Unable to connect to " + o.uri);
this.timeout = window.setTimeout(spiceconn_timeout, SPICE_CONNECT_TIMEOUT, this);
this.timeout = window.setTimeout(spiceconn_timeout, Constants.SPICE_CONNECT_TIMEOUT, this);
}
SpiceConn.prototype =
@ -122,31 +141,31 @@ SpiceConn.prototype =
msg.channel_id = this.chan_id;
msg.common_caps.push(
(1 << SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION) |
(1 << SPICE_COMMON_CAP_MINI_HEADER)
(1 << Constants.SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION) |
(1 << Constants.SPICE_COMMON_CAP_MINI_HEADER)
);
if (msg.channel_type == SPICE_CHANNEL_PLAYBACK)
if (msg.channel_type == Constants.SPICE_CHANNEL_PLAYBACK)
{
var caps = 0;
if ('MediaSource' in window && MediaSource.isTypeSupported(SPICE_PLAYBACK_CODEC))
caps |= (1 << SPICE_PLAYBACK_CAP_OPUS);
if ('MediaSource' in window && MediaSource.isTypeSupported(Webm.Constants.SPICE_PLAYBACK_CODEC))
caps |= (1 << Constants.SPICE_PLAYBACK_CAP_OPUS);
msg.channel_caps.push(caps);
}
else if (msg.channel_type == SPICE_CHANNEL_MAIN)
else if (msg.channel_type == Constants.SPICE_CHANNEL_MAIN)
{
msg.channel_caps.push(
(1 << SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS)
(1 << Constants.SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS)
);
}
else if (msg.channel_type == SPICE_CHANNEL_DISPLAY)
else if (msg.channel_type == Constants.SPICE_CHANNEL_DISPLAY)
{
var caps = (1 << SPICE_DISPLAY_CAP_SIZED_STREAM) |
(1 << SPICE_DISPLAY_CAP_STREAM_REPORT) |
(1 << SPICE_DISPLAY_CAP_MULTI_CODEC) |
(1 << SPICE_DISPLAY_CAP_CODEC_MJPEG);
if ('MediaSource' in window && MediaSource.isTypeSupported(SPICE_VP8_CODEC))
caps |= (1 << SPICE_DISPLAY_CAP_CODEC_VP8);
var caps = (1 << Constants.SPICE_DISPLAY_CAP_SIZED_STREAM) |
(1 << Constants.SPICE_DISPLAY_CAP_STREAM_REPORT) |
(1 << Constants.SPICE_DISPLAY_CAP_MULTI_CODEC) |
(1 << Constants.SPICE_DISPLAY_CAP_CODEC_MJPEG);
if ('MediaSource' in window && MediaSource.isTypeSupported(Webm.Constants.SPICE_VP8_CODEC))
caps |= (1 << Constants.SPICE_DISPLAY_CAP_CODEC_VP8);
msg.channel_caps.push(caps);
}
@ -164,7 +183,7 @@ SpiceConn.prototype =
send_ticket: function(ticket)
{
var hdr = new SpiceLinkAuthTicket();
hdr.auth_mechanism = SPICE_COMMON_CAP_AUTH_SPICE;
hdr.auth_mechanism = Constants.SPICE_COMMON_CAP_AUTH_SPICE;
// FIXME - we need to implement RSA to make this work right
hdr.encrypted_data = ticket;
var mb = new ArrayBuffer(hdr.buffer_size());
@ -226,7 +245,7 @@ SpiceConn.prototype =
else if (this.state == "start")
{
this.reply_hdr = new SpiceLinkHeader(mb);
if (this.reply_hdr.magic != SPICE_MAGIC)
if (this.reply_hdr.magic != Constants.SPICE_MAGIC)
{
this.state = "error";
var e = new Error('Error: magic mismatch: ' + this.reply_hdr.magic);
@ -261,16 +280,16 @@ SpiceConn.prototype =
else if (this.state == "ticket")
{
this.auth_reply = new SpiceLinkAuthReply(mb);
if (this.auth_reply.auth_code == SPICE_LINK_ERR_OK)
if (this.auth_reply.auth_code == Constants.SPICE_LINK_ERR_OK)
{
DEBUG > 0 && console.log(this.type + ': Connected');
if (this.type == SPICE_CHANNEL_DISPLAY)
if (this.type == Constants.SPICE_CHANNEL_DISPLAY)
{
// FIXME - pixmap and glz dictionary config info?
var dinit = new SpiceMsgcDisplayInit();
var reply = new SpiceMiniData();
reply.build_msg(SPICE_MSGC_DISPLAY_INIT, dinit);
reply.build_msg(Constants.SPICE_MSGC_DISPLAY_INIT, dinit);
DEBUG > 0 && console.log("Request display init");
this.send_msg(reply);
}
@ -285,7 +304,7 @@ SpiceConn.prototype =
else
{
this.state = "error";
if (this.auth_reply.auth_code == SPICE_LINK_ERR_PERMISSION_DENIED)
if (this.auth_reply.auth_code == Constants.SPICE_LINK_ERR_PERMISSION_DENIED)
{
var e = new Error("Permission denied.");
}
@ -300,7 +319,7 @@ SpiceConn.prototype =
process_common_messages : function(msg)
{
if (msg.type == SPICE_MSG_SET_ACK)
if (msg.type == Constants.SPICE_MSG_SET_ACK)
{
var ack = new SpiceMsgSetAck(msg.data);
// FIXME - what to do with generation?
@ -309,16 +328,16 @@ SpiceConn.prototype =
this.msgs_until_ack = this.ack_window;
var ackack = new SpiceMsgcAckSync(ack);
var reply = new SpiceMiniData();
reply.build_msg(SPICE_MSGC_ACK_SYNC, ackack);
reply.build_msg(Constants.SPICE_MSGC_ACK_SYNC, ackack);
this.send_msg(reply);
return true;
}
if (msg.type == SPICE_MSG_PING)
if (msg.type == Constants.SPICE_MSG_PING)
{
DEBUG > 1 && console.log("ping!");
var pong = new SpiceMiniData;
pong.type = SPICE_MSGC_PONG;
pong.type = Constants.SPICE_MSGC_PONG;
if (msg.data)
{
pong.data = msg.data.slice(0, 12);
@ -328,13 +347,13 @@ SpiceConn.prototype =
return true;
}
if (msg.type == SPICE_MSG_NOTIFY)
if (msg.type == Constants.SPICE_MSG_NOTIFY)
{
// FIXME - Visibility + what
var notify = new SpiceMsgNotify(msg.data);
if (notify.severity == SPICE_NOTIFY_SEVERITY_ERROR)
if (notify.severity == Constants.SPICE_NOTIFY_SEVERITY_ERROR)
this.log_err(notify.message);
else if (notify.severity == SPICE_NOTIFY_SEVERITY_WARN )
else if (notify.severity == Constants.SPICE_NOTIFY_SEVERITY_WARN )
this.log_warn(notify.message);
else
this.log_info(notify.message);
@ -370,41 +389,41 @@ SpiceConn.prototype =
{
this.msgs_until_ack = this.ack_window;
var ack = new SpiceMiniData();
ack.type = SPICE_MSGC_ACK;
ack.type = Constants.SPICE_MSGC_ACK;
this.send_msg(ack);
DEBUG > 1 && console.log(this.type + ": sent ack");
}
}
var delta = Date.now() - start;
if (DEBUG > 0 || delta > GAP_DETECTION_THRESHOLD)
if (DEBUG > 0 || delta > Webm.Constants.GAP_DETECTION_THRESHOLD)
console.log("delta " + this.channel_type() + ":" + msg.type + " " + delta);
return rc;
},
channel_type: function()
{
if (this.type == SPICE_CHANNEL_MAIN)
if (this.type == Constants.SPICE_CHANNEL_MAIN)
return "main";
else if (this.type == SPICE_CHANNEL_DISPLAY)
else if (this.type == Constants.SPICE_CHANNEL_DISPLAY)
return "display";
else if (this.type == SPICE_CHANNEL_INPUTS)
else if (this.type == Constants.SPICE_CHANNEL_INPUTS)
return "inputs";
else if (this.type == SPICE_CHANNEL_CURSOR)
else if (this.type == Constants.SPICE_CHANNEL_CURSOR)
return "cursor";
else if (this.type == SPICE_CHANNEL_PLAYBACK)
else if (this.type == Constants.SPICE_CHANNEL_PLAYBACK)
return "playback";
else if (this.type == SPICE_CHANNEL_RECORD)
else if (this.type == Constants.SPICE_CHANNEL_RECORD)
return "record";
else if (this.type == SPICE_CHANNEL_TUNNEL)
else if (this.type == Constants.SPICE_CHANNEL_TUNNEL)
return "tunnel";
else if (this.type == SPICE_CHANNEL_SMARTCARD)
else if (this.type == Constants.SPICE_CHANNEL_SMARTCARD)
return "smartcard";
else if (this.type == SPICE_CHANNEL_USBREDIR)
else if (this.type == Constants.SPICE_CHANNEL_USBREDIR)
return "usbredir";
else if (this.type == SPICE_CHANNEL_PORT)
else if (this.type == Constants.SPICE_CHANNEL_PORT)
return "port";
else if (this.type == SPICE_CHANNEL_WEBDAV)
else if (this.type == Constants.SPICE_CHANNEL_WEBDAV)
return "webdav";
return "unknown-" + this.type;
@ -501,3 +520,7 @@ function spiceconn_timeout(sc)
{
SpiceConn.prototype.handle_timeout.call(sc);
}
export {
SpiceConn,
};

View file

@ -118,3 +118,7 @@ SpiceDataView.prototype = {
this.setUint32(byteOffset + low, (w & 0x00000000ffffffff), littleEndian);
},
}
export {
SpiceDataView,
};

View file

@ -24,11 +24,31 @@
** a spice server. This file should arguably be generated from
** spice.proto, but it was instead put together by hand.
**--------------------------------------------------------------------------*/
import { Constants } from './enums.js';
import { SpiceDataView } from './spicedataview.js';
import { create_rsa_from_mb } from './ticket.js';
import {
SpiceChannelId,
SpiceRect,
SpiceClip,
SpiceCopy,
SpiceFill,
SpicePoint,
SpiceSurface,
SpicePoint16,
SpiceCursor,
} from './spicetype.js';
import {
keycode_to_start_scan,
keycode_to_end_scan,
} from './utils.js';
function SpiceLinkHeader(a, at)
{
this.magic = SPICE_MAGIC;
this.major_version = SPICE_VERSION_MAJOR;
this.minor_version = SPICE_VERSION_MINOR;
this.magic = Constants.SPICE_MAGIC;
this.major_version = Constants.SPICE_VERSION_MAJOR;
this.minor_version = Constants.SPICE_VERSION_MINOR;
this.size = 0;
if (a !== undefined)
this.from_buffer(a, at);
@ -160,7 +180,7 @@ SpiceLinkReply.prototype =
this.error = dv.getUint32(at, true); at += 4;
this.pub_key = create_rsa_from_mb(a, at);
at += SPICE_TICKET_PUBKEY_BYTES;
at += Constants.SPICE_TICKET_PUBKEY_BYTES;
var num_common_caps = dv.getUint32(at, true); at += 4;
var num_channel_caps = dv.getUint32(at, true); at += 4;
@ -195,7 +215,7 @@ SpiceLinkAuthTicket.prototype =
var i;
var dv = new SpiceDataView(a);
dv.setUint32(at, this.auth_mechanism, true); at += 4;
for (i = 0; i < SPICE_TICKET_KEY_PAIR_LENGTH / 8; i++)
for (i = 0; i < Constants.SPICE_TICKET_KEY_PAIR_LENGTH / 8; i++)
{
if (this.encrypted_data && i < this.encrypted_data.length)
dv.setUint8(at, this.encrypted_data[i], true);
@ -206,7 +226,7 @@ SpiceLinkAuthTicket.prototype =
},
buffer_size: function()
{
return 4 + (SPICE_TICKET_KEY_PAIR_LENGTH / 8);
return 4 + (Constants.SPICE_TICKET_KEY_PAIR_LENGTH / 8);
}
}
@ -461,7 +481,7 @@ SpiceMsgcMainAgentStart.prototype =
function SpiceMsgcMainAgentData(type, data)
{
this.protocol = VD_AGENT_PROTOCOL;
this.protocol = Constants.VD_AGENT_PROTOCOL;
this.type = type;
this.opaque = 0;
this.size = data.buffer_size();
@ -932,13 +952,11 @@ function SpiceMsgcMousePosition(sc, e)
this.buttons_state = sc.buttons_state;
if (e)
{
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
this.x = e.offsetX;
this.y = e.offsetY;
this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft + scrollLeft;
this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop + scrollTop;
sc.mousex = this.x;
sc.mousey = this.y;
sc.mousex = e.offsetX;
sc.mousey = e.offsetY;
}
else
{
@ -971,16 +989,16 @@ function SpiceMsgcMouseMotion(sc, e)
this.buttons_state = sc.buttons_state;
if (e)
{
this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
this.x = e.offsetX;
this.y = e.offsetY;
if (sc.mousex !== undefined)
{
this.x -= sc.mousex;
this.y -= sc.mousey;
}
sc.mousex = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
sc.mousey = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
sc.mousex = e.offsetX;
sc.mousey = e.offsetY;
}
else
{
@ -1002,8 +1020,8 @@ function SpiceMsgcMousePress(sc, e)
}
else
{
this.button = SPICE_MOUSE_BUTTON_LEFT;
this.buttons_state = SPICE_MOUSE_BUTTON_MASK_LEFT;
this.button = Constants.SPICE_MOUSE_BUTTON_LEFT;
this.buttons_state = Constants.SPICE_MOUSE_BUTTON_MASK_LEFT;
}
}
@ -1033,7 +1051,7 @@ function SpiceMsgcMouseRelease(sc, e)
}
else
{
this.button = SPICE_MOUSE_BUTTON_LEFT;
this.button = Constants.SPICE_MOUSE_BUTTON_LEFT;
this.buttons_state = 0;
}
}
@ -1296,3 +1314,58 @@ SpiceMsgPortInit.prototype =
this.name = a.slice(offset, offset + namesize - 1);
}
}
export {
SpiceLinkHeader,
SpiceLinkMess,
SpiceLinkReply,
SpiceLinkAuthTicket,
SpiceLinkAuthReply,
SpiceMiniData,
SpiceMsgChannels,
SpiceMsgMainInit,
SpiceMsgMainMouseMode,
SpiceMsgMainAgentData,
SpiceMsgMainAgentTokens,
SpiceMsgSetAck,
SpiceMsgcAckSync,
SpiceMsgcMainMouseModeRequest,
SpiceMsgcMainAgentStart,
SpiceMsgcMainAgentData,
VDAgentAnnounceCapabilities,
VDAgentMonitorsConfig,
VDAgentFileXferStatusMessage,
VDAgentFileXferStartMessage,
VDAgentFileXferDataMessage,
SpiceMsgNotify,
SpiceMsgcDisplayInit,
SpiceMsgDisplayBase,
SpiceMsgDisplayDrawCopy,
SpiceMsgDisplayDrawFill,
SpiceMsgDisplayCopyBits,
SpiceMsgSurfaceCreate,
SpiceMsgSurfaceDestroy,
SpiceMsgInputsInit,
SpiceMsgInputsKeyModifiers,
SpiceMsgCursorInit,
SpiceMsgPlaybackData,
SpiceMsgPlaybackMode,
SpiceMsgPlaybackStart,
SpiceMsgCursorSet,
SpiceMsgcMousePosition,
SpiceMsgcMouseMotion,
SpiceMsgcMousePress,
SpiceMsgcMouseRelease,
SpiceMsgcKeyDown,
SpiceMsgcKeyUp,
SpiceMsgDisplayStreamCreate,
SpiceStreamDataHeader,
SpiceMsgDisplayStreamData,
SpiceMsgDisplayStreamDataSized,
SpiceMsgDisplayStreamClip,
SpiceMsgDisplayStreamDestroy,
SpiceMsgDisplayStreamActivateReport,
SpiceMsgcDisplayStreamReport,
SpiceMsgDisplayInvalList,
SpiceMsgPortInit,
};

View file

@ -25,6 +25,9 @@
** to and from the server.
**--------------------------------------------------------------------------*/
import { Constants } from './enums.js';
import { SpiceQuic } from './quic.js';
function SpiceChannelId()
{
}
@ -92,7 +95,7 @@ SpiceClip.prototype =
from_dv: function(dv, at, mb)
{
this.type = dv.getUint8(at, true); at ++;
if (this.type == SPICE_CLIP_TYPE_RECTS)
if (this.type == Constants.SPICE_CLIP_TYPE_RECTS)
{
this.rects = new SpiceClipRects();
at = this.rects.from_dv(dv, at, mb);
@ -151,7 +154,7 @@ SpiceBitmap.prototype =
this.x = dv.getUint32(at, true); at += 4;
this.y = dv.getUint32(at, true); at += 4;
this.stride = dv.getUint32(at, true); at += 4;
if (this.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)
if (this.flags & Constants.SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)
{
this.palette_id = dv.getUint64(at, true); at += 8;
}
@ -185,7 +188,7 @@ SpiceImage.prototype =
this.descriptor = new SpiceImageDescriptor;
at = this.descriptor.from_dv(dv, at, mb);
if (this.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
if (this.descriptor.type == Constants.SPICE_IMAGE_TYPE_LZ_RGB)
{
this.lz_rgb = new Object();
this.lz_rgb.length = dv.getUint32(at, true); at += 4;
@ -210,18 +213,18 @@ SpiceImage.prototype =
}
if (this.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
if (this.descriptor.type == Constants.SPICE_IMAGE_TYPE_BITMAP)
{
this.bitmap = new SpiceBitmap;
at = this.bitmap.from_dv(dv, at, mb);
}
if (this.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
if (this.descriptor.type == Constants.SPICE_IMAGE_TYPE_SURFACE)
{
this.surface_id = dv.getUint32(at, true); at += 4;
}
if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
if (this.descriptor.type == Constants.SPICE_IMAGE_TYPE_JPEG)
{
this.jpeg = new Object;
this.jpeg.data_size = dv.getUint32(at, true); at += 4;
@ -229,7 +232,7 @@ SpiceImage.prototype =
at += this.jpeg.data.byteLength;
}
if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
if (this.descriptor.type == Constants.SPICE_IMAGE_TYPE_JPEG_ALPHA)
{
this.jpeg_alpha = new Object;
this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1;
@ -260,7 +263,7 @@ SpiceImage.prototype =
at += this.jpeg_alpha.alpha.data.byteLength;
}
if (this.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
if (this.descriptor.type == Constants.SPICE_IMAGE_TYPE_QUIC)
{
this.quic = new SpiceQuic;
at = this.quic.from_dv(dv, at, mb);
@ -327,11 +330,11 @@ SpiceBrush.prototype =
from_dv: function(dv, at, mb)
{
this.type = dv.getUint8(at, true); at ++;
if (this.type == SPICE_BRUSH_TYPE_SOLID)
if (this.type == Constants.SPICE_BRUSH_TYPE_SOLID)
{
this.color = dv.getUint32(at, true); at += 4;
}
else if (this.type == SPICE_BRUSH_TYPE_PATTERN)
else if (this.type == Constants.SPICE_BRUSH_TYPE_PATTERN)
{
this.pattern = new SpicePattern;
at = this.pattern.from_dv(dv, at, mb);
@ -439,7 +442,7 @@ SpiceCursor.prototype =
from_dv: function(dv, at, mb)
{
this.flags = dv.getUint16(at, true); at += 2;
if (this.flags & SPICE_CURSOR_FLAGS_NONE)
if (this.flags & Constants.SPICE_CURSOR_FLAGS_NONE)
this.header = null;
else
{
@ -471,3 +474,24 @@ SpiceSurface.prototype =
/* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are
completely unimplemented */
export {
SpiceChannelId,
SpiceRect,
SpiceClipRects,
SpiceClip,
SpiceImageDescriptor,
SpicePalette,
SpiceBitmap,
SpiceImage,
SpiceQMask,
SpicePattern,
SpiceBrush,
SpiceFill,
SpiceCopy,
SpicePoint16,
SpicePoint,
SpiceCursorHeader,
SpiceCursor,
SpiceSurface,
};

View file

@ -0,0 +1,15 @@
Custom Browser ES Module Loader
===============================
This is a module loader using babel and the ES Module Loader polyfill.
It's based heavily on
https://github.com/ModuleLoader/browser-es-module-loader, but uses
WebWorkers to compile the modules in the background.
To generate, run `rollup -c` in this directory, and then run `browserify
src/babel-worker.js > dist/babel-worker.js`.
LICENSE
-------
MIT

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
import nodeResolve from 'rollup-plugin-node-resolve';
export default {
entry: 'src/browser-es-module-loader.js',
dest: 'dist/browser-es-module-loader.js',
format: 'umd',
moduleName: 'BrowserESModuleLoader',
sourceMap: true,
plugins: [
nodeResolve(),
],
// skip rollup warnings (specifically the eval warning)
onwarn: function() {}
};

View file

@ -0,0 +1,25 @@
/*import { transform as babelTransform } from 'babel-core';
import babelTransformDynamicImport from 'babel-plugin-syntax-dynamic-import';
import babelTransformES2015ModulesSystemJS from 'babel-plugin-transform-es2015-modules-systemjs';*/
// sadly, due to how rollup works, we can't use es6 imports here
var babelTransform = require('babel-core').transform;
var babelTransformDynamicImport = require('babel-plugin-syntax-dynamic-import');
var babelTransformES2015ModulesSystemJS = require('babel-plugin-transform-es2015-modules-systemjs');
var babelPresetES2015 = require('babel-preset-es2015');
self.onmessage = function (evt) {
// transform source with Babel
var output = babelTransform(evt.data.source, {
compact: false,
filename: evt.data.key + '!transpiled',
sourceFileName: evt.data.key,
moduleIds: false,
sourceMaps: 'inline',
babelrc: false,
plugins: [babelTransformDynamicImport, babelTransformES2015ModulesSystemJS],
presets: [babelPresetES2015],
});
self.postMessage({key: evt.data.key, code: output.code, source: evt.data.source});
};

View file

@ -0,0 +1,280 @@
import RegisterLoader from 'es-module-loader/core/register-loader.js';
import { InternalModuleNamespace as ModuleNamespace } from 'es-module-loader/core/loader-polyfill.js';
import { baseURI, global, isBrowser } from 'es-module-loader/core/common.js';
import { resolveIfNotPlain } from 'es-module-loader/core/resolve.js';
var loader;
// <script type="module"> support
var anonSources = {};
if (typeof document != 'undefined' && document.getElementsByTagName) {
var handleError = function(err) {
// dispatch an error event so that we can display in errors in browsers
// that don't yet support unhandledrejection
if (window.onunhandledrejection === undefined) {
try {
var evt = new Event('error');
} catch (_eventError) {
var evt = document.createEvent('Event');
evt.initEvent('error', true, true);
}
evt.message = err.message;
if (err.fileName) {
evt.filename = err.fileName;
evt.lineno = err.lineNumber;
evt.colno = err.columnNumber;
} else if (err.sourceURL) {
evt.filename = err.sourceURL;
evt.lineno = err.line;
evt.colno = err.column;
}
evt.error = err;
window.dispatchEvent(evt);
}
// throw so it still shows up in the console
throw err;
}
var ready = function() {
document.removeEventListener('DOMContentLoaded', ready, false );
var anonCnt = 0;
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
var script = scripts[i];
if (script.type == 'module' && !script.loaded) {
script.loaded = true;
if (script.src) {
loader.import(script.src).catch(handleError);
}
// anonymous modules supported via a custom naming scheme and registry
else {
var uri = './<anon' + ++anonCnt + '>.js';
if (script.id !== ""){
uri = "./" + script.id;
}
var anonName = resolveIfNotPlain(uri, baseURI);
anonSources[anonName] = script.innerHTML;
loader.import(anonName).catch(handleError);
}
}
}
}
// simple DOM ready
if (document.readyState !== 'loading')
setTimeout(ready);
else
document.addEventListener('DOMContentLoaded', ready, false);
}
function BrowserESModuleLoader(baseKey) {
if (baseKey)
this.baseKey = resolveIfNotPlain(baseKey, baseURI) || resolveIfNotPlain('./' + baseKey, baseURI);
RegisterLoader.call(this);
var loader = this;
// ensure System.register is available
global.System = global.System || {};
if (typeof global.System.register == 'function')
var prevRegister = global.System.register;
global.System.register = function() {
loader.register.apply(loader, arguments);
if (prevRegister)
prevRegister.apply(this, arguments);
};
}
BrowserESModuleLoader.prototype = Object.create(RegisterLoader.prototype);
// normalize is never given a relative name like "./x", that part is already handled
BrowserESModuleLoader.prototype[RegisterLoader.resolve] = function(key, parent) {
var resolved = RegisterLoader.prototype[RegisterLoader.resolve].call(this, key, parent || this.baseKey) || key;
if (!resolved)
throw new RangeError('ES module loader does not resolve plain module names, resolving "' + key + '" to ' + parent);
return resolved;
};
function xhrFetch(url, resolve, reject) {
var xhr = new XMLHttpRequest();
var load = function(source) {
resolve(xhr.responseText);
}
var error = function() {
reject(new Error('XHR error' + (xhr.status ? ' (' + xhr.status + (xhr.statusText ? ' ' + xhr.statusText : '') + ')' : '') + ' loading ' + url));
}
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// in Chrome on file:/// URLs, status is 0
if (xhr.status == 0) {
if (xhr.responseText) {
load();
}
else {
// when responseText is empty, wait for load or error event
// to inform if it is a 404 or empty file
xhr.addEventListener('error', error);
xhr.addEventListener('load', load);
}
}
else if (xhr.status === 200) {
load();
}
else {
error();
}
}
};
xhr.open("GET", url, true);
xhr.send(null);
}
var WorkerPool = function (script, size) {
var current = document.currentScript;
// IE doesn't support currentScript
if (!current) {
// Find an entry with out basename
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src.indexOf("browser-es-module-loader.js") !== -1) {
current = scripts[i];
break;
}
}
if (!current)
throw Error("Could not find own <script> element");
}
script = current.src.substr(0, current.src.lastIndexOf("/")) + "/" + script;
this._workers = new Array(size);
this._ind = 0;
this._size = size;
this._jobs = 0;
this.onmessage = undefined;
this._stopTimeout = undefined;
for (var i = 0; i < size; i++) {
var wrkr = new Worker(script);
wrkr._count = 0;
wrkr._ind = i;
wrkr.onmessage = this._onmessage.bind(this, wrkr);
wrkr.onerror = this._onerror.bind(this);
this._workers[i] = wrkr;
}
this._checkJobs();
};
WorkerPool.prototype = {
postMessage: function (msg) {
if (this._stopTimeout !== undefined) {
clearTimeout(this._stopTimeout);
this._stopTimeout = undefined;
}
var wrkr = this._workers[this._ind % this._size];
wrkr._count++;
this._jobs++;
wrkr.postMessage(msg);
this._ind++;
},
_onmessage: function (wrkr, evt) {
wrkr._count--;
this._jobs--;
this.onmessage(evt, wrkr);
this._checkJobs();
},
_onerror: function(err) {
try {
var evt = new Event('error');
} catch (_eventError) {
var evt = document.createEvent('Event');
evt.initEvent('error', true, true);
}
evt.message = err.message;
evt.filename = err.filename;
evt.lineno = err.lineno;
evt.colno = err.colno;
evt.error = err.error;
window.dispatchEvent(evt);
},
_checkJobs: function () {
if (this._jobs === 0 && this._stopTimeout === undefined) {
// wait for 2s of inactivity before stopping (that should be enough for local loading)
this._stopTimeout = setTimeout(this._stop.bind(this), 2000);
}
},
_stop: function () {
this._workers.forEach(function(wrkr) {
wrkr.terminate();
});
}
};
var promiseMap = new Map();
var babelWorker = new WorkerPool('babel-worker.js', 3);
babelWorker.onmessage = function (evt) {
var promFuncs = promiseMap.get(evt.data.key);
promFuncs.resolve(evt.data);
promiseMap.delete(evt.data.key);
};
// instantiate just needs to run System.register
// so we fetch the source, convert into the Babel System module format, then evaluate it
BrowserESModuleLoader.prototype[RegisterLoader.instantiate] = function(key, processAnonRegister) {
var loader = this;
// load as ES with Babel converting into System.register
return new Promise(function(resolve, reject) {
// anonymous module
if (anonSources[key]) {
resolve(anonSources[key])
anonSources[key] = undefined;
}
// otherwise we fetch
else {
xhrFetch(key, resolve, reject);
}
})
.then(function(source) {
// check our cache first
var cacheEntry = localStorage.getItem(key);
if (cacheEntry) {
cacheEntry = JSON.parse(cacheEntry);
// TODO: store a hash instead
if (cacheEntry.source === source) {
return Promise.resolve({key: key, code: cacheEntry.code, source: cacheEntry.source});
}
}
return new Promise(function (resolve, reject) {
promiseMap.set(key, {resolve: resolve, reject: reject});
babelWorker.postMessage({key: key, source: source});
});
}).then(function (data) {
// evaluate without require, exports and module variables
// we leave module in for now to allow module.require access
try {
var cacheEntry = JSON.stringify({source: data.source, code: data.code});
localStorage.setItem(key, cacheEntry);
} catch (e) {
if (window.console) {
window.console.warn('Unable to cache transpiled version of ' + key + ': ' + e);
}
}
(0, eval)(data.code + '\n//# sourceURL=' + data.key + '!transpiled');
processAnonRegister();
});
};
// create a default loader instance in the browser
if (isBrowser)
loader = new BrowserESModuleLoader();
export default BrowserESModuleLoader;

View file

@ -587,3 +587,7 @@ BigInteger.prototype.modPowInt = bnModPowInt;
// "constants"
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);
export {
BigInteger,
};

View file

@ -77,3 +77,8 @@ function prng_newstate() {
// Pool size must be a multiple of 4 and greater than 32.
// An array of bytes the size of the pool will be passed to init()
var rng_psize = 256;
export {
prng_newstate,
rng_psize,
};

View file

@ -33,6 +33,7 @@
// Random number generator - requires a PRNG backend, e.g. prng4.js
import { prng_newstate, rng_psize } from './prng4.js';
// For best results, put code like
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
@ -100,3 +101,7 @@ function rng_get_bytes(ba) {
function SecureRandom() {}
SecureRandom.prototype.nextBytes = rng_get_bytes;
export {
SecureRandom,
};

View file

@ -1,4 +1,5 @@
// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
// Converted into an ES6 module
/*
* Copyright (c) 2003-2005 Tom Wu
@ -33,6 +34,8 @@
// Depends on jsbn.js and rng.js
import { BigInteger } from './jsbn.js';
import { SecureRandom } from './rng.js';
// Version 1.1: support utf-8 encoding in pkcs1pad2
@ -144,3 +147,7 @@ RSAKey.prototype.doPublic = RSADoPublic;
RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt;
//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
export {
RSAKey,
};

View file

@ -1,346 +1,351 @@
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS 180-1
* Version 2.2 Copyright Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
/* Downloaded 6/1/2012 from the above address by Jeremy White.
License reproduce here for completeness:
Copyright (c) 1998 - 2009, Paul Johnston & Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
function hex_hmac_sha1(k, d)
{ return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
function b64_hmac_sha1(k, d)
{ return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
function any_hmac_sha1(k, d, e)
{ return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
/*
* Perform a simple self-test to see if the VM is working
*/
function sha1_vm_test()
{
return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
}
/*
* Calculate the SHA1 of a raw string
*/
function rstr_sha1(s)
{
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
}
/*
* Calculate the HMAC-SHA1 of a key and some data (raw strings)
*/
function rstr_hmac_sha1(key, data)
{
var bkey = rstr2binb(key);
if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
var ipad = Array(16), opad = Array(16);
for(var i = 0; i < 16; i++)
{
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
}
/*
* Convert a raw string to a hex string
*/
function rstr2hex(input)
{
try { hexcase } catch(e) { hexcase=0; }
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var output = "";
var x;
for(var i = 0; i < input.length; i++)
{
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F)
+ hex_tab.charAt( x & 0x0F);
}
return output;
}
/*
* Convert a raw string to a base-64 string
*/
function rstr2b64(input)
{
try { b64pad } catch(e) { b64pad=''; }
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var output = "";
var len = input.length;
for(var i = 0; i < len; i += 3)
{
var triplet = (input.charCodeAt(i) << 16)
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
| (i + 2 < len ? input.charCodeAt(i+2) : 0);
for(var j = 0; j < 4; j++)
{
if(i * 8 + j * 6 > input.length * 8) output += b64pad;
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
}
}
return output;
}
/*
* Convert a raw string to an arbitrary string encoding
*/
function rstr2any(input, encoding)
{
var divisor = encoding.length;
var remainders = Array();
var i, q, x, quotient;
/* Convert to an array of 16-bit big-endian values, forming the dividend */
var dividend = Array(Math.ceil(input.length / 2));
for(i = 0; i < dividend.length; i++)
{
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
}
/*
* Repeatedly perform a long division. The binary array forms the dividend,
* the length of the encoding is the divisor. Once computed, the quotient
* forms the dividend for the next step. We stop when the dividend is zero.
* All remainders are stored for later use.
*/
while(dividend.length > 0)
{
quotient = Array();
x = 0;
for(i = 0; i < dividend.length; i++)
{
x = (x << 16) + dividend[i];
q = Math.floor(x / divisor);
x -= q * divisor;
if(quotient.length > 0 || q > 0)
quotient[quotient.length] = q;
}
remainders[remainders.length] = x;
dividend = quotient;
}
/* Convert the remainders to the output string */
var output = "";
for(i = remainders.length - 1; i >= 0; i--)
output += encoding.charAt(remainders[i]);
/* Append leading zero equivalents */
var full_length = Math.ceil(input.length * 8 /
(Math.log(encoding.length) / Math.log(2)))
for(i = output.length; i < full_length; i++)
output = encoding[0] + output;
return output;
}
/*
* Encode a string as utf-8.
* For efficiency, this assumes the input is valid utf-16.
*/
function str2rstr_utf8(input)
{
var output = "";
var i = -1;
var x, y;
while(++i < input.length)
{
/* Decode utf-16 surrogate pairs */
x = input.charCodeAt(i);
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
{
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
i++;
}
/* Encode output as utf-8 */
if(x <= 0x7F)
output += String.fromCharCode(x);
else if(x <= 0x7FF)
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
0x80 | ( x & 0x3F));
else if(x <= 0xFFFF)
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
else if(x <= 0x1FFFFF)
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
0x80 | ((x >>> 12) & 0x3F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
}
return output;
}
/*
* Encode a string as utf-16
*/
function str2rstr_utf16le(input)
{
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
(input.charCodeAt(i) >>> 8) & 0xFF);
return output;
}
function str2rstr_utf16be(input)
{
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
input.charCodeAt(i) & 0xFF);
return output;
}
/*
* Convert a raw string to an array of big-endian words
* Characters >255 have their high-byte silently ignored.
*/
function rstr2binb(input)
{
var output = Array(input.length >> 2);
for(var i = 0; i < output.length; i++)
output[i] = 0;
for(var i = 0; i < input.length * 8; i += 8)
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
return output;
}
/*
* Convert an array of big-endian words to a string
*/
function binb2rstr(input)
{
var output = "";
for(var i = 0; i < input.length * 32; i += 8)
output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
return output;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function binb_sha1(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16) w[j] = x[i + j];
else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = bit_rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
function sha1_ft(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
/*
* Determine the appropriate additive constant for the current iteration
*/
function sha1_kt(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS 180-1
* Version 2.2 Copyright Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
/* Downloaded 6/1/2012 from the above address by Jeremy White.
License reproduce here for completeness:
Copyright (c) 1998 - 2009, Paul Johnston & Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
function hex_hmac_sha1(k, d)
{ return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
function b64_hmac_sha1(k, d)
{ return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
function any_hmac_sha1(k, d, e)
{ return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
/*
* Perform a simple self-test to see if the VM is working
*/
function sha1_vm_test()
{
return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
}
/*
* Calculate the SHA1 of a raw string
*/
function rstr_sha1(s)
{
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
}
/*
* Calculate the HMAC-SHA1 of a key and some data (raw strings)
*/
function rstr_hmac_sha1(key, data)
{
var bkey = rstr2binb(key);
if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
var ipad = Array(16), opad = Array(16);
for(var i = 0; i < 16; i++)
{
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
}
/*
* Convert a raw string to a hex string
*/
function rstr2hex(input)
{
try { hexcase } catch(e) { hexcase=0; }
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var output = "";
var x;
for(var i = 0; i < input.length; i++)
{
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F)
+ hex_tab.charAt( x & 0x0F);
}
return output;
}
/*
* Convert a raw string to a base-64 string
*/
function rstr2b64(input)
{
try { b64pad } catch(e) { b64pad=''; }
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var output = "";
var len = input.length;
for(var i = 0; i < len; i += 3)
{
var triplet = (input.charCodeAt(i) << 16)
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
| (i + 2 < len ? input.charCodeAt(i+2) : 0);
for(var j = 0; j < 4; j++)
{
if(i * 8 + j * 6 > input.length * 8) output += b64pad;
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
}
}
return output;
}
/*
* Convert a raw string to an arbitrary string encoding
*/
function rstr2any(input, encoding)
{
var divisor = encoding.length;
var remainders = Array();
var i, q, x, quotient;
/* Convert to an array of 16-bit big-endian values, forming the dividend */
var dividend = Array(Math.ceil(input.length / 2));
for(i = 0; i < dividend.length; i++)
{
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
}
/*
* Repeatedly perform a long division. The binary array forms the dividend,
* the length of the encoding is the divisor. Once computed, the quotient
* forms the dividend for the next step. We stop when the dividend is zero.
* All remainders are stored for later use.
*/
while(dividend.length > 0)
{
quotient = Array();
x = 0;
for(i = 0; i < dividend.length; i++)
{
x = (x << 16) + dividend[i];
q = Math.floor(x / divisor);
x -= q * divisor;
if(quotient.length > 0 || q > 0)
quotient[quotient.length] = q;
}
remainders[remainders.length] = x;
dividend = quotient;
}
/* Convert the remainders to the output string */
var output = "";
for(i = remainders.length - 1; i >= 0; i--)
output += encoding.charAt(remainders[i]);
/* Append leading zero equivalents */
var full_length = Math.ceil(input.length * 8 /
(Math.log(encoding.length) / Math.log(2)))
for(i = output.length; i < full_length; i++)
output = encoding[0] + output;
return output;
}
/*
* Encode a string as utf-8.
* For efficiency, this assumes the input is valid utf-16.
*/
function str2rstr_utf8(input)
{
var output = "";
var i = -1;
var x, y;
while(++i < input.length)
{
/* Decode utf-16 surrogate pairs */
x = input.charCodeAt(i);
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
{
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
i++;
}
/* Encode output as utf-8 */
if(x <= 0x7F)
output += String.fromCharCode(x);
else if(x <= 0x7FF)
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
0x80 | ( x & 0x3F));
else if(x <= 0xFFFF)
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
else if(x <= 0x1FFFFF)
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
0x80 | ((x >>> 12) & 0x3F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
}
return output;
}
/*
* Encode a string as utf-16
*/
function str2rstr_utf16le(input)
{
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
(input.charCodeAt(i) >>> 8) & 0xFF);
return output;
}
function str2rstr_utf16be(input)
{
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
input.charCodeAt(i) & 0xFF);
return output;
}
/*
* Convert a raw string to an array of big-endian words
* Characters >255 have their high-byte silently ignored.
*/
function rstr2binb(input)
{
var output = Array(input.length >> 2);
for(var i = 0; i < output.length; i++)
output[i] = 0;
for(var i = 0; i < input.length * 8; i += 8)
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
return output;
}
/*
* Convert an array of big-endian words to a string
*/
function binb2rstr(input)
{
var output = "";
for(var i = 0; i < input.length * 32; i += 8)
output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
return output;
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function binb_sha1(x, len)
{
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16) w[j] = x[i + j];
else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = bit_rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
function sha1_ft(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
/*
* Determine the appropriate additive constant for the current iteration
*/
function sha1_kt(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
export {
hex_sha1,
rstr_sha1,
};

View file

@ -18,6 +18,11 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import { RSAKey } from './thirdparty/rsa.js';
import { BigInteger } from './thirdparty/jsbn.js';
import { SecureRandom } from './thirdparty/rng.js';
import { rstr_sha1 } from './thirdparty/sha1.js';
var SHA_DIGEST_LENGTH = 20;
/*----------------------------------------------------------------------------
@ -248,3 +253,8 @@ function rsa_encrypt(rsa, str)
ret[i / 2] = parseInt(h.substring(i, i + 2), 16);
return ret;
}
export {
create_rsa_from_mb,
rsa_encrypt,
};

View file

@ -18,6 +18,8 @@
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/
import { KeyNames } from './atKeynames.js';
/*----------------------------------------------------------------------------
** Utility settings and functions for Spice
**--------------------------------------------------------------------------*/
@ -112,129 +114,142 @@ function arraybuffer_to_str(buf) {
}
/*----------------------------------------------------------------------------
** Converting keycodes to AT scancodes is very hard.
** luckly there are some resources on the web and in the Xorg driver that help
** us figure out what browser dependent keycodes match to what scancodes.
**
** This will most likely not work for non US keyboard and browsers other than
** modern Chrome and FireFox.
** Converting browser keycodes to AT scancodes is very hard.
** Spice transmits keys using the original AT scan codes, often
** described as 'Scan Code Set 1'.
** There is a confusion of other scan codes; Xorg synthesizes it's
** own in the same atKeynames.c file that has the XT codes.
** Scan code set 2 and 3 are more common, and use different values.
** Further, there is no formal specification for keycodes
** returned by browsers, so we have done our mapping largely with
** empirical testing.
** There has been little rigorous testing with International keyboards,
** and this would be an easy area for non English speakers to contribute.
**--------------------------------------------------------------------------*/
var common_scanmap = [];
common_scanmap['Q'.charCodeAt(0)] = KEY_Q;
common_scanmap['W'.charCodeAt(0)] = KEY_W;
common_scanmap['E'.charCodeAt(0)] = KEY_E;
common_scanmap['R'.charCodeAt(0)] = KEY_R;
common_scanmap['T'.charCodeAt(0)] = KEY_T;
common_scanmap['Y'.charCodeAt(0)] = KEY_Y;
common_scanmap['U'.charCodeAt(0)] = KEY_U;
common_scanmap['I'.charCodeAt(0)] = KEY_I;
common_scanmap['O'.charCodeAt(0)] = KEY_O;
common_scanmap['P'.charCodeAt(0)] = KEY_P;
common_scanmap['A'.charCodeAt(0)] = KEY_A;
common_scanmap['S'.charCodeAt(0)] = KEY_S;
common_scanmap['D'.charCodeAt(0)] = KEY_D;
common_scanmap['F'.charCodeAt(0)] = KEY_F;
common_scanmap['G'.charCodeAt(0)] = KEY_G;
common_scanmap['H'.charCodeAt(0)] = KEY_H;
common_scanmap['J'.charCodeAt(0)] = KEY_J;
common_scanmap['K'.charCodeAt(0)] = KEY_K;
common_scanmap['L'.charCodeAt(0)] = KEY_L;
common_scanmap['Z'.charCodeAt(0)] = KEY_Z;
common_scanmap['X'.charCodeAt(0)] = KEY_X;
common_scanmap['C'.charCodeAt(0)] = KEY_C;
common_scanmap['V'.charCodeAt(0)] = KEY_V;
common_scanmap['B'.charCodeAt(0)] = KEY_B;
common_scanmap['N'.charCodeAt(0)] = KEY_N;
common_scanmap['M'.charCodeAt(0)] = KEY_M;
common_scanmap[' '.charCodeAt(0)] = KEY_Space;
common_scanmap[13] = KEY_Enter;
common_scanmap[27] = KEY_Escape;
common_scanmap[8] = KEY_BackSpace;
common_scanmap[9] = KEY_Tab;
common_scanmap[16] = KEY_ShiftL;
common_scanmap[17] = KEY_LCtrl;
common_scanmap[18] = KEY_Alt;
common_scanmap[20] = KEY_CapsLock;
common_scanmap[144] = KEY_NumLock;
common_scanmap[112] = KEY_F1;
common_scanmap[113] = KEY_F2;
common_scanmap[114] = KEY_F3;
common_scanmap[115] = KEY_F4;
common_scanmap[116] = KEY_F5;
common_scanmap[117] = KEY_F6;
common_scanmap[118] = KEY_F7;
common_scanmap[119] = KEY_F8;
common_scanmap[120] = KEY_F9;
common_scanmap[121] = KEY_F10;
common_scanmap[122] = KEY_F11;
common_scanmap[123] = KEY_F12;
/* These extended scancodes do not line up with values from atKeynames */
common_scanmap[42] = 99;
common_scanmap[19] = 101; // Break
common_scanmap[111] = 0xE035; // KP_Divide
common_scanmap[106] = 0xE037; // KP_Multiply
common_scanmap[36] = 0xE047; // Home
common_scanmap[38] = 0xE048; // Up
common_scanmap[33] = 0xE049; // PgUp
common_scanmap[37] = 0xE04B; // Left
common_scanmap[39] = 0xE04D; // Right
common_scanmap[35] = 0xE04F; // End
common_scanmap[40] = 0xE050; // Down
common_scanmap[34] = 0xE051; // PgDown
common_scanmap[45] = 0xE052; // Insert
common_scanmap[46] = 0xE053; // Delete
common_scanmap[44] = 0x2A37; // Print
/* The following appear to be keycodes that work in most browsers */
common_scanmap['1'.charCodeAt(0)] = KeyNames.KEY_1;
common_scanmap['2'.charCodeAt(0)] = KeyNames.KEY_2;
common_scanmap['3'.charCodeAt(0)] = KeyNames.KEY_3;
common_scanmap['4'.charCodeAt(0)] = KeyNames.KEY_4;
common_scanmap['5'.charCodeAt(0)] = KeyNames.KEY_5;
common_scanmap['6'.charCodeAt(0)] = KeyNames.KEY_6;
common_scanmap['7'.charCodeAt(0)] = KeyNames.KEY_7;
common_scanmap['8'.charCodeAt(0)] = KeyNames.KEY_8;
common_scanmap['9'.charCodeAt(0)] = KeyNames.KEY_9;
common_scanmap['0'.charCodeAt(0)] = KeyNames.KEY_0;
common_scanmap[145] = KeyNames.KEY_ScrollLock;
common_scanmap[103] = KeyNames.KEY_KP_7;
common_scanmap[104] = KeyNames.KEY_KP_8;
common_scanmap[105] = KeyNames.KEY_KP_9;
common_scanmap[100] = KeyNames.KEY_KP_4;
common_scanmap[101] = KeyNames.KEY_KP_5;
common_scanmap[102] = KeyNames.KEY_KP_6;
common_scanmap[107] = KeyNames.KEY_KP_Plus;
common_scanmap[97] = KeyNames.KEY_KP_1;
common_scanmap[98] = KeyNames.KEY_KP_2;
common_scanmap[99] = KeyNames.KEY_KP_3;
common_scanmap[96] = KeyNames.KEY_KP_0;
common_scanmap[109] = KeyNames.KEY_Minus;
common_scanmap[110] = KeyNames.KEY_KP_Decimal;
common_scanmap[191] = KeyNames.KEY_Slash;
common_scanmap[190] = KeyNames.KEY_Period;
common_scanmap[188] = KeyNames.KEY_Comma;
common_scanmap[220] = KeyNames.KEY_BSlash;
common_scanmap[192] = KeyNames.KEY_Tilde;
common_scanmap[222] = KeyNames.KEY_Quote;
common_scanmap[219] = KeyNames.KEY_LBrace;
common_scanmap[221] = KeyNames.KEY_RBrace;
/* These are not common between ALL browsers but are between Firefox and DOM3 */
common_scanmap['1'.charCodeAt(0)] = KEY_1;
common_scanmap['2'.charCodeAt(0)] = KEY_2;
common_scanmap['3'.charCodeAt(0)] = KEY_3;
common_scanmap['4'.charCodeAt(0)] = KEY_4;
common_scanmap['5'.charCodeAt(0)] = KEY_5;
common_scanmap['6'.charCodeAt(0)] = KEY_6;
common_scanmap['7'.charCodeAt(0)] = KEY_7;
common_scanmap['8'.charCodeAt(0)] = KEY_8;
common_scanmap['9'.charCodeAt(0)] = KEY_9;
common_scanmap['0'.charCodeAt(0)] = KEY_0;
common_scanmap[145] = KEY_ScrollLock;
common_scanmap[103] = KEY_KP_7;
common_scanmap[104] = KEY_KP_8;
common_scanmap[105] = KEY_KP_9;
common_scanmap[100] = KEY_KP_4;
common_scanmap[101] = KEY_KP_5;
common_scanmap[102] = KEY_KP_6;
common_scanmap[107] = KEY_KP_Plus;
common_scanmap[97] = KEY_KP_1;
common_scanmap[98] = KEY_KP_2;
common_scanmap[99] = KEY_KP_3;
common_scanmap[96] = KEY_KP_0;
common_scanmap[110] = KEY_KP_Decimal;
common_scanmap[191] = KEY_Slash;
common_scanmap[190] = KEY_Period;
common_scanmap[188] = KEY_Comma;
common_scanmap[220] = KEY_BSlash;
common_scanmap[192] = KEY_Tilde;
common_scanmap[222] = KEY_Quote;
common_scanmap[219] = KEY_LBrace;
common_scanmap[221] = KEY_RBrace;
common_scanmap['Q'.charCodeAt(0)] = KeyNames.KEY_Q;
common_scanmap['W'.charCodeAt(0)] = KeyNames.KEY_W;
common_scanmap['E'.charCodeAt(0)] = KeyNames.KEY_E;
common_scanmap['R'.charCodeAt(0)] = KeyNames.KEY_R;
common_scanmap['T'.charCodeAt(0)] = KeyNames.KEY_T;
common_scanmap['Y'.charCodeAt(0)] = KeyNames.KEY_Y;
common_scanmap['U'.charCodeAt(0)] = KeyNames.KEY_U;
common_scanmap['I'.charCodeAt(0)] = KeyNames.KEY_I;
common_scanmap['O'.charCodeAt(0)] = KeyNames.KEY_O;
common_scanmap['P'.charCodeAt(0)] = KeyNames.KEY_P;
common_scanmap['A'.charCodeAt(0)] = KeyNames.KEY_A;
common_scanmap['S'.charCodeAt(0)] = KeyNames.KEY_S;
common_scanmap['D'.charCodeAt(0)] = KeyNames.KEY_D;
common_scanmap['F'.charCodeAt(0)] = KeyNames.KEY_F;
common_scanmap['G'.charCodeAt(0)] = KeyNames.KEY_G;
common_scanmap['H'.charCodeAt(0)] = KeyNames.KEY_H;
common_scanmap['J'.charCodeAt(0)] = KeyNames.KEY_J;
common_scanmap['K'.charCodeAt(0)] = KeyNames.KEY_K;
common_scanmap['L'.charCodeAt(0)] = KeyNames.KEY_L;
common_scanmap['Z'.charCodeAt(0)] = KeyNames.KEY_Z;
common_scanmap['X'.charCodeAt(0)] = KeyNames.KEY_X;
common_scanmap['C'.charCodeAt(0)] = KeyNames.KEY_C;
common_scanmap['V'.charCodeAt(0)] = KeyNames.KEY_V;
common_scanmap['B'.charCodeAt(0)] = KeyNames.KEY_B;
common_scanmap['N'.charCodeAt(0)] = KeyNames.KEY_N;
common_scanmap['M'.charCodeAt(0)] = KeyNames.KEY_M;
common_scanmap[' '.charCodeAt(0)] = KeyNames.KEY_Space;
common_scanmap[13] = KeyNames.KEY_Enter;
common_scanmap[27] = KeyNames.KEY_Escape;
common_scanmap[8] = KeyNames.KEY_BackSpace;
common_scanmap[9] = KeyNames.KEY_Tab;
common_scanmap[16] = KeyNames.KEY_ShiftL;
common_scanmap[17] = KeyNames.KEY_LCtrl;
common_scanmap[18] = KeyNames.KEY_Alt;
common_scanmap[20] = KeyNames.KEY_CapsLock;
common_scanmap[44] = KeyNames.KEY_SysReqest;
common_scanmap[144] = KeyNames.KEY_NumLock;
common_scanmap[112] = KeyNames.KEY_F1;
common_scanmap[113] = KeyNames.KEY_F2;
common_scanmap[114] = KeyNames.KEY_F3;
common_scanmap[115] = KeyNames.KEY_F4;
common_scanmap[116] = KeyNames.KEY_F5;
common_scanmap[117] = KeyNames.KEY_F6;
common_scanmap[118] = KeyNames.KEY_F7;
common_scanmap[119] = KeyNames.KEY_F8;
common_scanmap[120] = KeyNames.KEY_F9;
common_scanmap[121] = KeyNames.KEY_F10;
common_scanmap[122] = KeyNames.KEY_F11;
common_scanmap[123] = KeyNames.KEY_F12;
common_scanmap[91] = 0xE05B; //KEY_LMeta
common_scanmap[92] = 0xE05C; //KEY_RMeta
common_scanmap[93] = 0xE05D; //KEY_Menu
/* TODO: Break and Print are complex scan codes. XSpice cheats and
uses Xorg synthesized codes to simplify them. Fixing this will
require XSpice to handle the scan codes correctly, and then
fix spice-html5 to send the complex scan codes. */
common_scanmap[42] = 99; // Print, XSpice only
common_scanmap[19] = 101;// Break, XSpice only
/* Handle the so called 'GREY' keys, for the extended keys that
were grey on the original AT keyboard. These are
prefixed, as they were on the PS/2 controller, with an
0xE0 byte to indicate that they are extended */
common_scanmap[111] = 0xE0 | (KeyNames.KEY_Slash << 8);// KP_Divide
common_scanmap[106] = 0xE0 | (KeyNames.KEY_KP_Multiply << 8); // KP_Multiply
common_scanmap[36] = 0xE0 | (KeyNames.KEY_KP_7 << 8); // Home
common_scanmap[38] = 0xE0 | (KeyNames.KEY_KP_8 << 8); // Up
common_scanmap[33] = 0xE0 | (KeyNames.KEY_KP_9 << 8); // PgUp
common_scanmap[37] = 0xE0 | (KeyNames.KEY_KP_4 << 8); // Left
common_scanmap[39] = 0xE0 | (KeyNames.KEY_KP_6 << 8); // Right
common_scanmap[35] = 0xE0 | (KeyNames.KEY_KP_1 << 8); // End
common_scanmap[40] = 0xE0 | (KeyNames.KEY_KP_2 << 8); // Down
common_scanmap[34] = 0xE0 | (KeyNames.KEY_KP_3 << 8); // PgDown
common_scanmap[45] = 0xE0 | (KeyNames.KEY_KP_0 << 8); // Insert
common_scanmap[46] = 0xE0 | (KeyNames.KEY_KP_Decimal << 8); // Delete
common_scanmap[91] = 0xE0 | (0x5B << 8); //KeyNames.KEY_LMeta
common_scanmap[92] = 0xE0 | (0x5C << 8); //KeyNames.KEY_RMeta
common_scanmap[93] = 0xE0 | (0x5D << 8); //KeyNames.KEY_Menu
/* Firefox/Mozilla codes */
var firefox_scanmap = [];
firefox_scanmap[173] = KEY_Minus;
firefox_scanmap[109] = KEY_Minus;
firefox_scanmap[61] = KEY_Equal;
firefox_scanmap[59] = KEY_SemiColon;
firefox_scanmap[173] = KeyNames.KEY_Minus;
firefox_scanmap[61] = KeyNames.KEY_Equal;
firefox_scanmap[59] = KeyNames.KEY_SemiColon;
/* DOM3 codes */
var DOM_scanmap = [];
DOM_scanmap[189] = KEY_Minus;
DOM_scanmap[187] = KEY_Equal;
DOM_scanmap[186] = KEY_SemiColon;
DOM_scanmap[189] = KeyNames.KEY_Minus;
DOM_scanmap[187] = KeyNames.KEY_Equal;
DOM_scanmap[186] = KeyNames.KEY_SemiColon;
function get_scancode(code)
{
@ -258,11 +273,7 @@ function keycode_to_start_scan(code)
return 0;
}
if (scancode < 0x100) {
return scancode;
} else {
return 0xe0 | ((scancode - 0x100) << 8);
}
return scancode;
}
function keycode_to_end_scan(code)
@ -274,7 +285,7 @@ function keycode_to_end_scan(code)
if (scancode < 0x100) {
return scancode | 0x80;
} else {
return 0x80e0 | ((scancode - 0x100) << 8);
return scancode | 0x8000;
}
}
@ -330,3 +341,20 @@ function dump_timerange(tr)
return ret;
}
export {
DEBUG,
PLAYBACK_DEBUG,
STREAM_DEBUG,
DUMP_DRAWS,
DUMP_CANVASES,
EMPTY_GIF_IMAGE,
combine_array_buffers,
hexdump_buffer,
arraybuffer_to_str,
keycode_to_start_scan,
keycode_to_end_scan,
dump_media_element,
dump_media_source,
dump_source_buffer,
};

View file

@ -76,18 +76,20 @@ var WEBM_SIMPLE_BLOCK = [ 0xA3 ] ;
/*----------------------------------------------------------------------------
** Various OPUS / Webm constants
**--------------------------------------------------------------------------*/
var CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME = 1 << 7;
var Constants = {
CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 1 << 7,
var OPUS_FREQUENCY = 48000;
var OPUS_CHANNELS = 2;
OPUS_FREQUENCY : 48000,
OPUS_CHANNELS : 2,
var SPICE_PLAYBACK_CODEC = 'audio/webm; codecs="opus"';
var MAX_CLUSTER_TIME = 1000;
SPICE_PLAYBACK_CODEC : 'audio/webm; codecs="opus"',
MAX_CLUSTER_TIME : 1000,
var EXPECTED_PACKET_DURATION = 10;
var GAP_DETECTION_THRESHOLD = 50;
EXPECTED_PACKET_DURATION : 10,
GAP_DETECTION_THRESHOLD : 50,
var SPICE_VP8_CODEC = 'video/webm; codecs="vp8"';
SPICE_VP8_CODEC : 'video/webm; codecs="vp8"',
};
/*----------------------------------------------------------------------------
** EBML utility functions
@ -275,7 +277,7 @@ function webm_Audio(frequency)
{
this.id = WEBM_AUDIO;
this.sampling_frequency = frequency;
this.channels = OPUS_CHANNELS;
this.channels = Constants.OPUS_CHANNELS;
}
webm_Audio.prototype =
@ -407,12 +409,12 @@ function webm_AudioTrackEntry()
this.seek_pre_roll = 0; // 80000000; // fixme - check
this.codec_delay = 80000000; // Must match codec_private.preskip
this.codec_id = "A_OPUS";
this.audio = new webm_Audio(OPUS_FREQUENCY);
this.audio = new webm_Audio(Constants.OPUS_FREQUENCY);
// See: http://tools.ietf.org/html/draft-terriberry-oggopus-01
this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead
0x01, // Version
OPUS_CHANNELS,
Constants.OPUS_CHANNELS,
0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at 48kHz
0x80, 0xbb, 0x00, 0x00, // 48000
0x00, 0x00, // Output gain
@ -597,7 +599,7 @@ webm_SimpleBlock.prototype =
at = EBML_write_u64_data_len(this.data.byteLength + 4, dv, at);
at = EBML_write_u1_data_len(1, dv, at); // Track #
dv.setUint16(at, this.timecode); at += 2; // timecode - relative to cluster
dv.setUint8(at, this.keyframe ? CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 0); at += 1; // flags
dv.setUint8(at, this.keyframe ? Constants.CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 0); at += 1; // flags
// FIXME - There should be a better way to copy
var u8 = new Uint8Array(this.data);
@ -645,3 +647,15 @@ webm_Header.prototype =
this.info.buffer_size();
},
}
export {
Constants,
webm_Audio as Audio,
webm_Video as Video,
webm_AudioTrackEntry as AudioTrackEntry,
webm_VideoTrackEntry as VideoTrackEntry,
webm_Tracks as Tracks,
webm_Cluster as Cluster,
webm_SimpleBlock as SimpleBlock,
webm_Header as Header,
};

View file

@ -24,6 +24,10 @@
** callback. It will optionally save and pass along a header, useful in processing
** the mini message format.
**--------------------------------------------------------------------------------------*/
import { DEBUG } from './utils.js';
import { combine_array_buffers } from './utils.js';
function SpiceWireReader(sc, callback)
{
this.sc = sc;
@ -121,3 +125,7 @@ function wire_blob_catcher(e)
DEBUG > 1 && console.log("id " + this.wire_reader.sc.connection_id +"; type " + this.wire_reader.sc.type);
SpiceWireReader.prototype.inbound.call(this.wire_reader, e.data);
}
export {
SpiceWireReader,
};

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from computes.models import Compute
from storages.forms import AddStgPool, AddImage, CloneImage

View file

@ -650,7 +650,7 @@ class wvmInstance(wvmConnect):
cache_mode=None, io_mode=None, discard_mode=None, detect_zeroes_mode=None):
additionals = ''
if cache_mode is not None and cache_mode != 'default':
if cache_mode is not None and cache_mode != 'default' and disk_device != 'cdrom':
additionals += "cache='%s' " % cache_mode
if io_mode is not None and io_mode != 'default':
additionals += "io='%s' " % io_mode
@ -666,7 +666,7 @@ class wvmInstance(wvmConnect):
xml_disk += "<driver name='%s' type='%s' %s/>" % (driver_name, driver_type, additionals)
xml_disk += """<source file='%s'/>
<target dev='%s' bus='%s'/>""" % (source, target_dev, target_bus)
if readonly:
if readonly or disk_device == 'cdrom':
xml_disk += """<readonly/>"""
if shareable:
xml_disk += """<shareable/>"""

View file

@ -12,8 +12,6 @@ urlpatterns = [
url(r'^computes/', include('computes.urls')),
url(r'^logs/', include('logs.urls')),
url(r'^datasource/', include('datasource.urls')),
url(r'^console/$', console, name='console'),
# (r'^admin/', include(admin.site.urls)),
#url(r'^admin/', include(admin.site.urls)),
]

View file

@ -4,7 +4,7 @@ WSGI config for webvirtcloud project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""
import os