1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 23:25:24 +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.shortcuts import render
from django.http import HttpResponseRedirect 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.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from accounts.models import * 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) hostname = models.CharField(max_length=64)
login = models.CharField(max_length=20) login = models.CharField(max_length=20)
password = models.CharField(max_length=14, blank=True, null=True) 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() type = models.IntegerField()
def __unicode__(self): def __unicode__(self):

View file

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

View file

@ -1,7 +1,7 @@
import json import json
from django.utils import timezone from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect 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.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute

View file

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

View file

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

View file

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

View file

@ -26,7 +26,6 @@
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<title>WebVirtCloud - Spice Client - Full</title> <title>WebVirtCloud - Spice Client - Full</title>
<script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script> <script src="{% static "js/spice-html5/spicearraybuffer.js" %}"></script>
<script src="{% static "js/spice-html5/enums.js" %}"></script> <script src="{% static "js/spice-html5/enums.js" %}"></script>
@ -58,29 +57,28 @@
<script src="{% static "js/spice-html5/resize.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/filexfer.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 %} {% endblock %}
{% block content %} {% block content %}
<div id="login" hidden> <div id="login" hidden>
<span class="logo">SPICE</span> <span class="logo">SPICE</span>
<label for="host">Host:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost --> <label for="host">{% trans 'Host' %}:</label> <input type='text' id='host' value='{{ ws_host }}'> <!-- localhost -->
<label for="port">Port:</label> <input type='text' id='port' value='{{ ws_port }}'> <label for="port">{% trans 'Port' %}:</label> <input type='text' id='port' value='{{ ws_port }}'>
<label for="password">Password:</label> <input type='password' id='password' value='{{ console_passwd }}'> <label for="password">{% trans '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> <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();">Start</button> <button id="connectButton" onclick="connect();">{% trans 'Start' %}</button>
</div> </div>
<div id="spice-area"> <div id="spice-area">
<div id="spice-screen" class="spice-screen"></div> <div id="spice-screen" class="spice-screen"></div>
</div>
<div id="message-div" class="spice-message"></div> <div id="message-div" class="spice-message"></div>
</div>
<div id="debug-div"> <div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here --> <!-- If DUMPXXX is turned on, dumped images will go here -->
</div> </div>
{% endblock %} {% endblock %}
{% block foot %} {% block foot %}
@ -89,13 +87,11 @@
var host = null, port = null; var host = null, port = null;
var sc; var sc;
function spice_error(e) function spice_error(e) {
{
disconnect(); disconnect();
} }
function connect() function connect() {
{
var host, port, password, scheme = "ws://", uri; var host, port, password, scheme = "ws://", uri;
host = document.getElementById("host").value; host = document.getElementById("host").value;
@ -105,7 +101,6 @@
} }
password = document.getElementById("password").value; password = document.getElementById("password").value;
if ((!host) || (!port)) { if ((!host) || (!port)) {
console.log("must set host and port"); console.log("must set host and port");
return; return;
@ -120,8 +115,7 @@
document.getElementById('connectButton').innerHTML = "Stop"; document.getElementById('connectButton').innerHTML = "Stop";
document.getElementById('connectButton').onclick = disconnect; document.getElementById('connectButton').onclick = disconnect;
try try {
{
sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div", 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 }); message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
} }
@ -130,20 +124,16 @@
alert(e.toString()); alert(e.toString());
disconnect(); disconnect();
} }
} }
function disconnect() function disconnect() {
{
console.log(">> disconnect"); console.log(">> disconnect");
if (sc) { if (sc) {
sc.stop(); sc.stop();
} }
document.getElementById('connectButton').innerHTML = "Start"; document.getElementById('connectButton').innerHTML = "Start";
document.getElementById('connectButton').onclick = connect; document.getElementById('connectButton').onclick = connect;
if (window.File && window.FileReader && window.FileList && window.Blob) if (window.File && window.FileReader && window.FileList && window.Blob) {
{
var spice_xfer_area = document.getElementById('spice-xfer-area'); var spice_xfer_area = document.getElementById('spice-xfer-area');
document.getElementById('spice-area').removeChild(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('dragover', handle_file_dragover, false);
@ -152,38 +142,32 @@
console.log("<< disconnect"); console.log("<< disconnect");
} }
function agent_connected(sc) function agent_connected(sc) {
{
window.addEventListener('resize', handle_resize); window.addEventListener('resize', handle_resize);
window.spice_connection = this; window.spice_connection = this;
resize_helper(this); resize_helper(this);
if (window.File && window.FileReader && window.FileList && window.Blob) if (window.File && window.FileReader && window.FileList && window.Blob) {
{
var spice_xfer_area = document.createElement("div"); var spice_xfer_area = document.createElement("div");
spice_xfer_area.setAttribute('id', 'spice-xfer-area'); spice_xfer_area.setAttribute('id', 'spice-xfer-area');
document.getElementById('spice-area').appendChild(spice_xfer_area); document.getElementById('spice-area').appendChild(spice_xfer_area);
document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false); document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false); document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
} }
else else {
{
console.log("File API is not supported"); console.log("File API is not supported");
} }
} }
function toggle_console() function toggle_console() {
{
var checkbox = document.getElementById('show_console'); var checkbox = document.getElementById('show_console');
var m = document.getElementById('message-div'); var m = document.getElementById('message-div');
if (checkbox.checked) if (checkbox.checked) {
{
m.style.display = 'block'; m.style.display = 'block';
} }
else else {
{
m.style.display = 'none'; m.style.display = 'none';
} }

View file

@ -62,13 +62,11 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div id="spice-area"> <div id="spice-area">
<div id="spice-screen" class="spice-screen"></div> <div id="spice-screen" class="spice-screen"></div>
</div>
<div id="message-div" class="spice-message"></div> <div id="message-div" class="spice-message"></div>
</div>
<div id="debug-div"> <div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here --> <!-- If DUMPXXX is turned on, dumped images will go here -->
@ -93,8 +91,7 @@
return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue; return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defvalue;
} }
function spice_error(e) function spice_error(e) {
{
console.log(e); console.log(e);
disconnect(); disconnect();
if (e.message !== undefined) { if (e.message !== undefined) {
@ -105,8 +102,7 @@
} }
} }
function connect() function connect() {
{
var host, port, password, scheme = "ws://", uri; var host, port, password, scheme = "ws://", uri;
console.log('>> connect'); console.log('>> connect');
// By default, use the host and port of server that served this file // By default, use the host and port of server that served this file
@ -159,17 +155,14 @@
uri += path[0] == '/' ? path : ('/' + path); uri += path[0] == '/' ? path : ('/' + path);
} }
try try {
{
sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div", 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 }); message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
} }
catch (e) catch (e) {
{
alert(e.toString()); alert(e.toString());
disconnect(); disconnect();
} }
console.log('<< connect') console.log('<< connect')
} }
@ -179,8 +172,7 @@
if (sc) { if (sc) {
sc.stop(); sc.stop();
} }
if (window.File && window.FileReader && window.FileList && window.Blob) if (window.File && window.FileReader && window.FileList && window.Blob) {
{
var spice_xfer_area = document.getElementById('spice-xfer-area'); var spice_xfer_area = document.getElementById('spice-xfer-area');
document.getElementById('spice-area').removeChild(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('dragover', handle_file_dragover, false);
@ -189,23 +181,20 @@
console.log("<< disconnect"); console.log("<< disconnect");
} }
function agent_connected(sc) function agent_connected(sc) {
{
window.addEventListener('resize', handle_resize); window.addEventListener('resize', handle_resize);
window.spice_connection = this; window.spice_connection = this;
resize_helper(this); resize_helper(this);
if (window.File && window.FileReader && window.FileList && window.Blob) if (window.File && window.FileReader && window.FileList && window.Blob) {
{
var spice_xfer_area = document.createElement("div"); var spice_xfer_area = document.createElement("div");
spice_xfer_area.setAttribute('id', 'spice-xfer-area'); spice_xfer_area.setAttribute('id', 'spice-xfer-area');
document.getElementById('spice-area').appendChild(spice_xfer_area); document.getElementById('spice-area').appendChild(spice_xfer_area);
document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false); document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false);
document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false); document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
} }
else else {
{
console.log("File API is not supported"); console.log("File API is not supported");
} }
} }

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _ 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 django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from create.models import Flavor from create.models import Flavor

View file

@ -24,15 +24,13 @@
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
<div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="table-responsive">
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
{% if not all_host_vms %} {% if not all_host_vms %}
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-warning alert-dismissable"> <div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times</button> <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" %} <i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any Instance" %}
</div> </div>
</div> </div>
{% else %} {% else %}
@ -138,8 +136,6 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
</div>
</div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/sortable.min.js" %}"></script> <script src="{% static "js/sortable.min.js" %}"></script>

View file

@ -4,14 +4,40 @@
{% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %} {% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %}
{% block content %} {% block content %}
{% include 'pleasewaitdialog.html' %} {% include 'pleasewaitdialog.html' %}
<!-- Page Heading --> <nav class="navbar navbar-default navba navbar-fixed-bottom">
<div class="row"> <div class="container">
<div> <div class="navbar-header">
<h3> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar_bottom" aria-expanded="false" aria-controls="navbar">
{{ vname }}{% if title %}&nbsp;({{ title }}){% endif %} <span class="sr-only">{% trans 'Toggle navigation' %}</span>
</h3> <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>
<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> <div>
<div>
<h3>{{ vname }}{% if title %}&nbsp;({{ title }}){% endif %}</h3>
</div>
<div> <div>
{% if status == 5 %} {% if status == 5 %}
<span class="label label-danger">{% trans "Off" %}</span> <span class="label label-danger">{% trans "Off" %}</span>
@ -23,6 +49,22 @@
<span class="label label-warning">{% trans "Suspend" %}</span> <span class="label label-warning">{% trans "Suspend" %}</span>
{% endif %} {% endif %}
| |
<span {%if guest_agent == True %}
{% if guest_agent_ready == True %}
class="label label-success"
title="Guest Agent Enabled & Connected"
{% else %}
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 %} {% if cur_vcpu %}
{{ cur_vcpu }} {% trans "Vcpu" %} {{ cur_vcpu }} {% trans "Vcpu" %}
{% else %} {% else %}
@ -35,30 +77,11 @@
{{ disk.size|filesizeformat }} {% trans "Disk" %} | {{ disk.size|filesizeformat }} {% trans "Disk" %} |
{% endfor %} {% endfor %}
{% for net in networks %} {% for net in networks %}
{% for ipv4 in net.ipv4|default:"-" %} {% for ipv4 in net.ipv4 %}
{{ ipv4 }} | {{ ipv4 }} |
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
<button <a href="{% url 'instance' compute.id vname %}" title="{% trans 'refresh instance info' %}"><span class="fa fa-refresh"></span></a>
{% 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 %}
{% 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>
</div> </div>
{% if user_quota_msg %} {% if user_quota_msg %}
<span class="label label-warning">{{ user_quota_msg|capfirst }} {% trans "quota reached" %}.</span> <span class="label label-warning">{{ user_quota_msg|capfirst }} {% trans "quota reached" %}.</span>
@ -549,7 +572,6 @@
{% endifequal %} {% endifequal %}
</div> </div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="managesnapshot"> <div role="tabpanel" class="tab-pane tab-pane-bordered" id="managesnapshot">
{% ifequal status 5 %}
{% if snapshots %} {% if snapshots %}
<p>{% trans "Choose a snapshot for restore/delete" %}</p> <p>{% trans "Choose a snapshot for restore/delete" %}</p>
<div class="table-responsive"> <div class="table-responsive">
@ -572,7 +594,8 @@
<span class="glyphicon glyphicon-save"></span> <span class="glyphicon glyphicon-save"></span>
</button> </button>
{% else %} {% else %}
<button type="button" class="btn btn-sm btn-default disabled"> <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> <span class="glyphicon glyphicon-save"></span>
</button> </button>
{% endifequal %} {% endifequal %}
@ -594,9 +617,6 @@
{% else %} {% else %}
<p>{% trans "You do not have any snapshots" %}</p> <p>{% trans "You do not have any snapshots" %}</p>
{% endif %} {% endif %}
{% else %}
<p>{% trans "To restore snapshots you need Power Off the instance." %}</p>
{% endifequal %}
</div> </div>
</div> </div>
</div> </div>
@ -747,15 +767,13 @@
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %} <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
<p style="font-weight:bold;"> <p style="font-weight:bold;">
{% trans "Instance Media" %} {% trans "Instance Media" %}
{% if status == 5 %}
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right" title="Add CD-ROM"> <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> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button> </button>
{% else %}
<button type="submit" type="button" class="btn btn-success disabled pull-right" title="Add CD-ROM" disabled>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
{% endif %}
</p> </p>
</form> </form>
{% for cd in media %} {% for cd in media %}

View file

@ -8,7 +8,7 @@ import string
import random import random
from bisect import insort from bisect import insort
from django.http import HttpResponse, HttpResponseRedirect 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.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required 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: if 'add_cdrom' in request.POST and allow_admin_or_not_template:
bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata') bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
target = get_new_disk_dev(media, disks, bus) 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) msg = _('Add CD-ROM: ' + target)
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks') return HttpResponseRedirect(request.get_full_path() + '#disks')

View file

@ -1,6 +1,6 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect 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 django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from interfaces.forms import AddInterface from interfaces.forms import AddInterface

View file

@ -1,6 +1,6 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect 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 django.contrib.auth.decorators import login_required
from instances.models import Instance from instances.models import Instance
from logs.models import Logs from logs.models import Logs

View file

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

View file

@ -4,7 +4,7 @@ from __future__ import unicode_literals
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext_lazy as _ 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 django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from vrtManager import util from vrtManager import util

View file

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

View file

@ -23,16 +23,19 @@
** bitmap.js ** bitmap.js
** Handle SPICE_IMAGE_TYPE_BITMAP ** Handle SPICE_IMAGE_TYPE_BITMAP
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
import { Constants } from './enums.js';
function convert_spice_bitmap_to_web(context, spice_bitmap) function convert_spice_bitmap_to_web(context, spice_bitmap)
{ {
var ret; var ret;
var offset, x, src_offset = 0, src_dec = 0; var offset, x, src_offset = 0, src_dec = 0;
var u8 = new Uint8Array(spice_bitmap.data); var u8 = new Uint8Array(spice_bitmap.data);
if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT && if (spice_bitmap.format != Constants.SPICE_BITMAP_FMT_32BIT &&
spice_bitmap.format != SPICE_BITMAP_FMT_RGBA) spice_bitmap.format != Constants.SPICE_BITMAP_FMT_RGBA)
return undefined; 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_offset = (spice_bitmap.y - 1 ) * spice_bitmap.stride;
src_dec = 2 * 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]; ret.data[offset + 2 ] = u8[src_offset + 0];
// FIXME - We effectively treat all images as having SPICE_IMAGE_FLAGS_HIGH_BITS_SET // 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; ret.data[offset + 3] = 255;
else else
ret.data[offset + 3] = u8[src_offset]; ret.data[offset + 3] = u8[src_offset];
@ -55,3 +58,7 @@ function convert_spice_bitmap_to_web(context, spice_bitmap)
return ret; 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/>. 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 ** SpiceCursorConn
@ -31,12 +40,12 @@ function SpiceCursorConn()
SpiceCursorConn.prototype = Object.create(SpiceConn.prototype); SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
SpiceCursorConn.prototype.process_channel_message = function(msg) 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); var cursor_init = new SpiceMsgCursorInit(msg.data);
DEBUG > 1 && console.log("SpiceMsgCursorInit"); DEBUG > 1 && console.log("SpiceMsgCursorInit");
if (this.parent && this.parent.inputs && 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 // FIXME - this imagines that the server actually
// provides the current cursor position, // provides the current cursor position,
@ -49,11 +58,11 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == SPICE_MSG_CURSOR_SET) if (msg.type == Constants.SPICE_MSG_CURSOR_SET)
{ {
var cursor_set = new SpiceMsgCursorSet(msg.data); var cursor_set = new SpiceMsgCursorSet(msg.data);
DEBUG > 1 && console.log("SpiceMsgCursorSet"); 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"; document.getElementById(this.parent.screen_id).style.cursor = "none";
return true; return true;
@ -62,7 +71,7 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
if (cursor_set.flags > 0) if (cursor_set.flags > 0)
this.log_warn("FIXME: No support for cursor flags " + cursor_set.flags); 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); this.log_warn("FIXME: No support for cursor type " + cursor_set.cursor.header.type);
return false; return false;
@ -73,39 +82,39 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == SPICE_MSG_CURSOR_MOVE) if (msg.type == Constants.SPICE_MSG_CURSOR_MOVE)
{ {
this.known_unimplemented(msg.type, "Cursor Move"); this.known_unimplemented(msg.type, "Cursor Move");
return true; return true;
} }
if (msg.type == SPICE_MSG_CURSOR_HIDE) if (msg.type == Constants.SPICE_MSG_CURSOR_HIDE)
{ {
DEBUG > 1 && console.log("SpiceMsgCursorHide"); DEBUG > 1 && console.log("SpiceMsgCursorHide");
document.getElementById(this.parent.screen_id).style.cursor = "none"; document.getElementById(this.parent.screen_id).style.cursor = "none";
return true; return true;
} }
if (msg.type == SPICE_MSG_CURSOR_TRAIL) if (msg.type == Constants.SPICE_MSG_CURSOR_TRAIL)
{ {
this.known_unimplemented(msg.type, "Cursor Trail"); this.known_unimplemented(msg.type, "Cursor Trail");
return true; return true;
} }
if (msg.type == SPICE_MSG_CURSOR_RESET) if (msg.type == Constants.SPICE_MSG_CURSOR_RESET)
{ {
DEBUG > 1 && console.log("SpiceMsgCursorReset"); DEBUG > 1 && console.log("SpiceMsgCursorReset");
document.getElementById(this.parent.screen_id).style.cursor = "auto"; document.getElementById(this.parent.screen_id).style.cursor = "auto";
return true; 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"); this.known_unimplemented(msg.type, "Cursor Inval One");
return true; return true;
} }
if (msg.type == SPICE_MSG_CURSOR_INVAL_ALL) if (msg.type == Constants.SPICE_MSG_CURSOR_INVAL_ALL)
{ {
DEBUG > 1 && console.log("SpiceMsgCursorInvalAll"); DEBUG > 1 && console.log("SpiceMsgCursorInvalAll");
// FIXME - There may be something useful to do here... // 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) 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 + ') ' + var curstr = 'url(data:image/png,' + pngstr + ') ' +
cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default"; cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
var screen = document.getElementById(this.parent.screen_id); 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') if (window.getComputedStyle(screen, null).cursor == 'auto')
SpiceSimulateCursor.simulate_cursor(this, cursor, screen, pngstr); 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/>. 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 ** FIXME: putImageData does not support Alpha blending
@ -62,37 +72,37 @@ function SpiceDisplayConn()
SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype); SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
SpiceDisplayConn.prototype.process_channel_message = function(msg) 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"); this.known_unimplemented(msg.type, "Display Mode");
return true; 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) // FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
this.known_unimplemented(msg.type, "Display Mark"); this.known_unimplemented(msg.type, "Display Mark");
return true; 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(); this.surfaces[this.primary_surface].canvas.context.restore();
return true; 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)) 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."); 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"); 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); this.log_warn("FIXME: DrawCopy we don't handle ropd type: " + draw_copy.data.rop_descriptor);
if (draw_copy.data.mask.flags) if (draw_copy.data.mask.flags)
this.log_warn("FIXME: DrawCopy we don't handle mask flag: " + 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 && draw_copy.data.src_bitmap)
{ {
if (draw_copy.data.src_bitmap.descriptor.flags && 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 != Constants.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_HIGH_BITS_SET)
{ {
this.log_warn("FIXME: DrawCopy unhandled image flags: " + draw_copy.data.src_bitmap.descriptor.flags); 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; var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
if (! draw_copy.data.src_bitmap.quic) 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."); this.log_warn("FIXME: DrawCopy could not handle this QUIC file.");
return false; 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); draw_copy.data.src_bitmap.quic);
return this.draw_copy_helper( return this.draw_copy_helper(
@ -125,12 +135,12 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
src_area: draw_copy.data.src_area, src_area: draw_copy.data.src_area,
image_data: source_img, image_data: source_img,
tag: "copyquic." + draw_copy.data.src_bitmap.quic.type, 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 descriptor : draw_copy.data.src_bitmap.descriptor
}); });
} }
else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE || else if (draw_copy.data.src_bitmap.descriptor.type == Constants.SPICE_IMAGE_TYPE_FROM_CACHE ||
draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS) 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]) 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 */ /* 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 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; 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, src_area: computed_src_area,
image_data: source_img, image_data: source_img,
tag: "copysurf." + draw_copy.data.src_bitmap.surface_id, 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 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) if (! draw_copy.data.src_bitmap.jpeg)
{ {
@ -211,7 +221,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true; 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) if (! draw_copy.data.src_bitmap.jpeg_alpha)
{ {
@ -240,7 +250,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
sc : this, 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; var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
@ -252,7 +262,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true; 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; var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
if (! draw_copy.data.src_bitmap.bitmap) 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, src_area: draw_copy.data.src_area,
image_data: source_img, image_data: source_img,
tag: "bitmap." + draw_copy.data.src_bitmap.bitmap.format, 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 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; var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
if (! draw_copy.data.src_bitmap.lz_rgb) 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, src_area: draw_copy.data.src_area,
image_data: source_img, image_data: source_img,
tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type, 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 descriptor : draw_copy.data.src_bitmap.descriptor
}); });
} }
@ -318,20 +328,20 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return false; 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); this.log_warn("FIXME: DrawFill we don't handle ropd type: " + draw_fill.data.rop_descriptor);
if (draw_fill.data.mask.flags) if (draw_fill.data.mask.flags)
this.log_warn("FIXME: DrawFill we don't handle mask flag: " + 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) if (draw_fill.data.mask.bitmap)
this.log_warn("FIXME: DrawFill we don't handle mask"); 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? // FIXME - do brushes ever have alpha?
var color = draw_fill.data.brush.color & 0xffffff; 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.right - draw_fill.base.box.left,
draw_fill.base.box.bottom - draw_fill.base.box.top); 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"); var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('width', this.surfaces[draw_fill.base.surface_id].canvas.width); 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; 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"); this.known_unimplemented(msg.type, "Display Draw Opaque");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Blend");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Blackness");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Whiteness");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Invers");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw ROP3");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Stroke");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Transparent");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Alpha Blend");
return true; 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_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
var source_context = source_canvas.context; 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); //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); 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"); var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('width', width); debug_canvas.setAttribute('width', width);
@ -457,36 +467,36 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true; 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"); this.known_unimplemented(msg.type, "Display Inval All Pixmaps");
return true; 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"); this.known_unimplemented(msg.type, "Display Inval Palette");
return true; 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"); this.known_unimplemented(msg.type, "Inval All Palettes");
return true; return true;
} }
if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE) if (msg.type == Constants.SPICE_MSG_DISPLAY_SURFACE_CREATE)
{ {
if (! ("surfaces" in this)) if (! ("surfaces" in this))
this.surfaces = []; this.surfaces = [];
var m = new SpiceMsgSurfaceCreate(msg.data); var m = new Messages.SpiceMsgSurfaceCreate(msg.data);
DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id Utils.DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id
+ "; " + m.surface.width + "x" + m.surface.height + "; " + m.surface.width + "x" + m.surface.height
+ "; format " + m.surface.format + "; format " + m.surface.format
+ "; flags " + m.surface.flags); + "; flags " + m.surface.flags);
if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB && if (m.surface.format != Constants.SPICE_SURFACE_FMT_32_xRGB &&
m.surface.format != SPICE_SURFACE_FMT_32_ARGB) m.surface.format != Constants.SPICE_SURFACE_FMT_32_ARGB)
{ {
this.log_warn("FIXME: cannot handle surface format " + m.surface.format + " yet."); this.log_warn("FIXME: cannot handle surface format " + m.surface.format + " yet.");
return false; return false;
@ -499,14 +509,14 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
canvas.setAttribute('tabindex', m.surface.surface_id); canvas.setAttribute('tabindex', m.surface.surface_id);
canvas.context = canvas.getContext("2d"); 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); document.getElementById(this.parent.dump_id).appendChild(canvas);
m.surface.canvas = canvas; m.surface.canvas = canvas;
m.surface.draw_count = 0; m.surface.draw_count = 0;
this.surfaces[m.surface.surface_id] = m.surface; 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; this.primary_surface = m.surface.surface_id;
@ -521,18 +531,18 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true; 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); var m = new Messages.SpiceMsgSurfaceDestroy(msg.data);
DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id); Utils.DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id);
this.delete_surface(m.surface_id); this.delete_surface(m.surface_id);
return true; 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); var m = new Messages.SpiceMsgDisplayStreamCreate(msg.data);
STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamCreate id" + m.id + "; type " + m.codec_type + Utils.STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamCreate id" + m.id + "; type " + m.codec_type +
"; width " + m.stream_width + "; height " + m.stream_height + "; width " + m.stream_width + "; height " + m.stream_height +
"; left " + m.dest.left + "; top " + m.dest.top "; left " + m.dest.left + "; top " + m.dest.top
); );
@ -543,7 +553,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
else else
this.streams[m.id] = m; 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 media = new MediaSource();
var v = document.createElement("video"); var v = document.createElement("video");
@ -579,21 +589,21 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
media.spiceconn = this; media.spiceconn = this;
v.spice_stream = s; 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; this.streams[m.id].frames_loading = 0;
else else
console.log("Unhandled stream codec: "+m.codec_type); console.log("Unhandled stream codec: "+m.codec_type);
return true; return true;
} }
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA || if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DATA ||
msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
{ {
var m; var m;
if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) if (msg.type == Constants.SPICE_MSG_DISPLAY_STREAM_DATA_SIZED)
m = new SpiceMsgDisplayStreamDataSized(msg.data); m = new Messages.SpiceMsgDisplayStreamDataSized(msg.data);
else else
m = new SpiceMsgDisplayStreamData(msg.data); m = new Messages.SpiceMsgDisplayStreamData(msg.data);
if (!this.streams[m.base.id]) 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(); 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); 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); process_video_stream_data(this.streams[m.base.id], m);
return true; 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]) if (this.streams[m.stream_id])
{ {
this.streams[m.stream_id].report = report; this.streams[m.stream_id].report = report;
@ -627,20 +637,20 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true; 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); var m = new Messages.SpiceMsgDisplayStreamClip(msg.data);
STREAM_DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id); Utils.STREAM_DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
this.streams[m.id].clip = m.clip; this.streams[m.id].clip = m.clip;
return true; 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); var m = new Messages.SpiceMsgDisplayStreamDestroy(msg.data);
STREAM_DEBUG > 0 && console.log(this.type + ": MsgStreamDestroy id" + m.id); 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); document.getElementById(this.parent.screen_id).removeChild(this.streams[m.id].video);
this.streams[m.id].source_buffer = null; this.streams[m.id].source_buffer = null;
@ -651,30 +661,30 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
return true; 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"); this.known_unimplemented(msg.type, "Display Stream Destroy All");
return true; 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; 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++) for (i = 0; i < m.count; i++)
if (this.cache[m.resources[i].id] != undefined) if (this.cache[m.resources[i].id] != undefined)
delete this.cache[m.resources[i].id]; delete this.cache[m.resources[i].id];
return true; 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"); this.known_unimplemented(msg.type, "Display Monitors Config");
return true; 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"); this.known_unimplemented(msg.type, "Display Draw Composite");
return true; return true;
@ -686,7 +696,7 @@ SpiceDisplayConn.prototype.process_channel_message = function(msg)
SpiceDisplayConn.prototype.delete_surface = function(surface_id) SpiceDisplayConn.prototype.delete_surface = function(surface_id)
{ {
var canvas = document.getElementById("spice_surface_" + 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); document.getElementById(this.parent.dump_id).removeChild(canvas);
if (this.primary_surface == surface_id) 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 /* FIXME - This is based on trial + error, not a serious thoughtful
analysis of what Spice requires. See display.js for more. */ 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); stripAlpha(o.image_data);
canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top); 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..."); 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)) if (! ("cache" in this))
this.cache = {}; this.cache = {};
this.cache[o.descriptor.id] = o.image_data; 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"); var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('width', o.image_data.width); 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; 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) if (draw.data.src_bitmap.surface_id !== undefined)
str += "; src_bitmap surface_id " + draw.data.src_bitmap.surface_id; 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) if (draw.data.src_bitmap.quic)
str += "; QUIC type " + draw.data.src_bitmap.quic.type + str += "; QUIC type " + draw.data.src_bitmap.quic.type +
"; width " + draw.data.src_bitmap.quic.width + "; 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)
{ {
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); 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 "; str += "; brush.pat ";
if (draw.data.brush.pattern.pat != null) if (draw.data.brush.pattern.pat != null)
@ -824,15 +840,15 @@ SpiceDisplayConn.prototype.hook_events = function()
{ {
var canvas = this.surfaces[this.primary_surface].canvas; var canvas = this.surfaces[this.primary_surface].canvas;
canvas.sc = this.parent; canvas.sc = this.parent;
canvas.addEventListener('mousemove', handle_mousemove); canvas.addEventListener('mousemove', Inputs.handle_mousemove);
canvas.addEventListener('mousedown', handle_mousedown); canvas.addEventListener('mousedown', Inputs.handle_mousedown);
canvas.addEventListener('contextmenu', handle_contextmenu); canvas.addEventListener('contextmenu', Inputs.handle_contextmenu);
canvas.addEventListener('mouseup', handle_mouseup); canvas.addEventListener('mouseup', Inputs.handle_mouseup);
canvas.addEventListener('keydown', handle_keydown); canvas.addEventListener('keydown', Inputs.handle_keydown);
canvas.addEventListener('keyup', handle_keyup); canvas.addEventListener('keyup', Inputs.handle_keyup);
canvas.addEventListener('mouseout', handle_mouseout); canvas.addEventListener('mouseout', handle_mouseout);
canvas.addEventListener('mouseover', handle_mouseover); canvas.addEventListener('mouseover', handle_mouseover);
canvas.addEventListener('wheel', handle_mousewheel); canvas.addEventListener('wheel', Inputs.handle_mousewheel);
canvas.focus(); canvas.focus();
} }
} }
@ -842,15 +858,15 @@ SpiceDisplayConn.prototype.unhook_events = function()
if (this.primary_surface !== undefined) if (this.primary_surface !== undefined)
{ {
var canvas = this.surfaces[this.primary_surface].canvas; var canvas = this.surfaces[this.primary_surface].canvas;
canvas.removeEventListener('mousemove', handle_mousemove); canvas.removeEventListener('mousemove', Inputs.handle_mousemove);
canvas.removeEventListener('mousedown', handle_mousedown); canvas.removeEventListener('mousedown', Inputs.handle_mousedown);
canvas.removeEventListener('contextmenu', handle_contextmenu); canvas.removeEventListener('contextmenu', Inputs.handle_contextmenu);
canvas.removeEventListener('mouseup', handle_mouseup); canvas.removeEventListener('mouseup', Inputs.handle_mouseup);
canvas.removeEventListener('keydown', handle_keydown); canvas.removeEventListener('keydown', Inputs.handle_keydown);
canvas.removeEventListener('keyup', handle_keyup); canvas.removeEventListener('keyup', Inputs.handle_keyup);
canvas.removeEventListener('mouseout', handle_mouseout); canvas.removeEventListener('mouseout', handle_mouseout);
canvas.removeEventListener('mouseover', handle_mouseover); 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 temp_canvas = null;
var context; 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--; 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 // This can happen; if the jpeg image loads after our surface
// has been destroyed (e.g. open a menu, close it quickly), // has been destroyed (e.g. open a menu, close it quickly),
// we'll find we have no surface. // 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 = document.createElement("canvas");
temp_canvas.setAttribute('width', this.o.base.box.right); temp_canvas.setAttribute('width', this.o.base.box.right);
temp_canvas.setAttribute('height', this.o.base.box.bottom); 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); context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
if (this.o.descriptor && 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)) if (! ("cache" in this.o.sc))
this.o.sc.cache = {}; this.o.sc.cache = {};
@ -936,10 +952,10 @@ function handle_draw_jpeg_onload()
// Give the Garbage collector a clue to recycle this; avoids // Give the Garbage collector a clue to recycle this; avoids
// fairly massive memory leaks during video playback // fairly massive memory leaks during video playback
this.onload = undefined; this.onload = undefined;
this.src = EMPTY_GIF_IMAGE; this.src = Utils.EMPTY_GIF_IMAGE;
if (this.o.descriptor && 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)) if (! ("cache" in this.o.sc))
this.o.sc.cache = {}; this.o.sc.cache = {};
@ -953,7 +969,7 @@ function handle_draw_jpeg_onload()
if (temp_canvas == null) 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"); var debug_canvas = document.createElement("canvas");
debug_canvas.setAttribute('id', this.o.tag + "." + debug_canvas.setAttribute('id', this.o.tag + "." +
@ -992,7 +1008,7 @@ function process_mjpeg_stream_data(sc, m, time_until_due)
tmpstr += '0'; tmpstr += '0';
tmpstr += m.data[i].toString(16); 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.surface_id = sc.streams[m.base.id].surface_id;
strm_base.box = m.dest || sc.streams[m.base.id].dest; strm_base.box = m.dest || sc.streams[m.base.id].dest;
strm_base.clip = sc.streams[m.base.id].clip; 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.end_frame_mm_time = msg_mmtime;
sc.streams[id].report.last_frame_delay = time_until_due; sc.streams[id].report.last_frame_delay = time_until_due;
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
msg.build_msg(SPICE_MSGC_DISPLAY_STREAM_REPORT, sc.streams[id].report); msg.build_msg(Constants.SPICE_MSGC_DISPLAY_STREAM_REPORT, sc.streams[id].report);
sc.send_msg(msg); sc.send_msg(msg);
sc.streams[id].report.start_frame_mm_time = 0; sc.streams[id].report.start_frame_mm_time = 0;
@ -1040,10 +1056,10 @@ function handle_video_source_open(e)
if (stream.source_buffer) if (stream.source_buffer)
return; return;
var s = this.addSourceBuffer(SPICE_VP8_CODEC); var s = this.addSourceBuffer(Webm.Constants.SPICE_VP8_CODEC);
if (! s) if (! s)
{ {
p.log_err('Codec ' + SPICE_VP8_CODEC + ' not available.'); p.log_err('Codec ' + Webm.Constants.SPICE_VP8_CODEC + ' not available.');
return; return;
} }
@ -1053,9 +1069,9 @@ function handle_video_source_open(e)
listen_for_video_events(stream); listen_for_video_events(stream);
var h = new webm_Header(); var h = new Webm.Header();
var te = new webm_VideoTrackEntry(this.stream.stream_width, this.stream.stream_height); var te = new Webm.VideoTrackEntry(this.stream.stream_width, this.stream.stream_height);
var t = new webm_Tracks(te); var t = new Webm.Tracks(te);
var mb = new ArrayBuffer(h.buffer_size() + t.buffer_size()) 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.video)
{ {
if (STREAM_DEBUG > 0) if (Utils.STREAM_DEBUG > 0)
console.log("Stream id " + stream.id + " received updateend after video is gone."); console.log("Stream id " + stream.id + " received updateend after video is gone.");
return; return;
} }
@ -1130,8 +1146,8 @@ function handle_append_video_buffer_done(e)
stream.video.currentTime = stream.video.buffered.start(stream.video.buffered.length - 1); stream.video.currentTime = stream.video.buffered.start(stream.video.buffered.length - 1);
} }
if (STREAM_DEBUG > 1) if (Utils.STREAM_DEBUG > 1)
console.log(stream.video.currentTime + ":id " + stream.id + " updateend " + dump_media_element(stream.video)); console.log(stream.video.currentTime + ":id " + stream.id + " updateend " + Utils.dump_media_element(stream.video));
} }
function handle_video_buffer_error(e) function handle_video_buffer_error(e)
@ -1161,7 +1177,7 @@ function push_or_queue(stream, msg, mb)
function video_simple_block(stream, msg, keyframe) 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()); var mb = new ArrayBuffer(simple.buffer_size());
simple.to_buffer(mb); simple.to_buffer(mb);
@ -1171,7 +1187,7 @@ function video_simple_block(stream, msg, keyframe)
function new_video_cluster(stream, msg) function new_video_cluster(stream, msg)
{ {
stream.cluster_time = msg.base.multi_media_time; 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()); var mb = new ArrayBuffer(c.buffer_size());
c.to_buffer(mb); c.to_buffer(mb);
@ -1189,7 +1205,7 @@ function process_video_stream_data(stream, msg)
new_video_cluster(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); new_video_cluster(stream, msg);
else else
video_simple_block(stream, msg, false); video_simple_block(stream, msg, false);
@ -1200,18 +1216,18 @@ function video_handle_event_debug(e)
var s = this.spice_stream; var s = this.spice_stream;
if (s.video) 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 + 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) if (Utils.STREAM_DEBUG > 1 && s.media)
console.log(" media_source " + dump_media_source(s.media)); console.log(" media_source " + Utils.dump_media_source(s.media));
if (STREAM_DEBUG > 1 && s.source_buffer) if (Utils.STREAM_DEBUG > 1 && s.source_buffer)
console.log(" source_buffer " + dump_source_buffer(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); 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); 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); 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); video_2_events.forEach(video_debug_listen_for_one_event, stream.video);
} }
export {
SpiceDisplayConn,
};

View file

@ -23,355 +23,350 @@
** enums.js ** enums.js
** 'constants' for Spice ** 'constants' for Spice
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
var SPICE_MAGIC = "REDQ"; export var Constants = {
var SPICE_VERSION_MAJOR = 2; SPICE_MAGIC : "REDQ",
var SPICE_VERSION_MINOR = 2; 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; SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION : 0,
var SPICE_COMMON_CAP_AUTH_SPICE = 1; SPICE_COMMON_CAP_AUTH_SPICE : 1,
var SPICE_COMMON_CAP_AUTH_SASL = 2; SPICE_COMMON_CAP_AUTH_SASL : 2,
var SPICE_COMMON_CAP_MINI_HEADER = 3; SPICE_COMMON_CAP_MINI_HEADER : 3,
var SPICE_TICKET_KEY_PAIR_LENGTH = 1024; SPICE_TICKET_KEY_PAIR_LENGTH : 1024,
var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34); SPICE_TICKET_PUBKEY_BYTES : (1024 / 8 +34), // (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34)
var SPICE_LINK_ERR_OK = 0, SPICE_LINK_ERR_OK : 0,
SPICE_LINK_ERR_ERROR = 1, SPICE_LINK_ERR_ERROR : 1,
SPICE_LINK_ERR_INVALID_MAGIC = 2, SPICE_LINK_ERR_INVALID_MAGIC : 2,
SPICE_LINK_ERR_INVALID_DATA = 3, SPICE_LINK_ERR_INVALID_DATA : 3,
SPICE_LINK_ERR_VERSION_MISMATCH = 4, SPICE_LINK_ERR_VERSION_MISMATCH : 4,
SPICE_LINK_ERR_NEED_SECURED = 5, SPICE_LINK_ERR_NEED_SECURED : 5,
SPICE_LINK_ERR_NEED_UNSECURED = 6, SPICE_LINK_ERR_NEED_UNSECURED : 6,
SPICE_LINK_ERR_PERMISSION_DENIED = 7, SPICE_LINK_ERR_PERMISSION_DENIED : 7,
SPICE_LINK_ERR_BAD_CONNECTION_ID = 8, SPICE_LINK_ERR_BAD_CONNECTION_ID : 8,
SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9; SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE : 9,
var SPICE_MSG_MIGRATE = 1; SPICE_MSG_MIGRATE : 1,
var SPICE_MSG_MIGRATE_DATA = 2; SPICE_MSG_MIGRATE_DATA : 2,
var SPICE_MSG_SET_ACK = 3; SPICE_MSG_SET_ACK : 3,
var SPICE_MSG_PING = 4; SPICE_MSG_PING : 4,
var SPICE_MSG_WAIT_FOR_CHANNELS = 5; SPICE_MSG_WAIT_FOR_CHANNELS : 5,
var SPICE_MSG_DISCONNECTING = 6; SPICE_MSG_DISCONNECTING : 6,
var SPICE_MSG_NOTIFY = 7; SPICE_MSG_NOTIFY : 7,
var SPICE_MSG_LIST = 8; SPICE_MSG_LIST : 8,
var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101; SPICE_MSG_MAIN_MIGRATE_BEGIN : 101,
var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102; SPICE_MSG_MAIN_MIGRATE_CANCEL : 102,
var SPICE_MSG_MAIN_INIT = 103; SPICE_MSG_MAIN_INIT : 103,
var SPICE_MSG_MAIN_CHANNELS_LIST = 104; SPICE_MSG_MAIN_CHANNELS_LIST : 104,
var SPICE_MSG_MAIN_MOUSE_MODE = 105; SPICE_MSG_MAIN_MOUSE_MODE : 105,
var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106; SPICE_MSG_MAIN_MULTI_MEDIA_TIME : 106,
var SPICE_MSG_MAIN_AGENT_CONNECTED = 107; SPICE_MSG_MAIN_AGENT_CONNECTED : 107,
var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108; SPICE_MSG_MAIN_AGENT_DISCONNECTED : 108,
var SPICE_MSG_MAIN_AGENT_DATA = 109; SPICE_MSG_MAIN_AGENT_DATA : 109,
var SPICE_MSG_MAIN_AGENT_TOKEN = 110; SPICE_MSG_MAIN_AGENT_TOKEN : 110,
var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111; SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST : 111,
var SPICE_MSG_MAIN_MIGRATE_END = 112; SPICE_MSG_MAIN_MIGRATE_END : 112,
var SPICE_MSG_MAIN_NAME = 113; SPICE_MSG_MAIN_NAME : 113,
var SPICE_MSG_MAIN_UUID = 114; SPICE_MSG_MAIN_UUID : 114,
var SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS = 115; SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS : 115,
var SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS = 116; SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS : 116,
var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK = 117; SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK : 117,
var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK = 118; SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK : 118,
var SPICE_MSG_END_MAIN = 119; SPICE_MSG_END_MAIN : 119,
var SPICE_MSGC_ACK_SYNC = 1; SPICE_MSGC_ACK_SYNC : 1,
var SPICE_MSGC_ACK = 2; SPICE_MSGC_ACK : 2,
var SPICE_MSGC_PONG = 3; SPICE_MSGC_PONG : 3,
var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4; SPICE_MSGC_MIGRATE_FLUSH_MARK : 4,
var SPICE_MSGC_MIGRATE_DATA = 5; SPICE_MSGC_MIGRATE_DATA : 5,
var SPICE_MSGC_DISCONNECTING = 6; SPICE_MSGC_DISCONNECTING : 6,
var SPICE_MSGC_MAIN_CLIENT_INFO = 101; SPICE_MSGC_MAIN_CLIENT_INFO : 101,
var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102; SPICE_MSGC_MAIN_MIGRATE_CONNECTED : 102,
var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103; SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR : 103,
var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104; SPICE_MSGC_MAIN_ATTACH_CHANNELS : 104,
var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105; SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST : 105,
var SPICE_MSGC_MAIN_AGENT_START = 106; SPICE_MSGC_MAIN_AGENT_START : 106,
var SPICE_MSGC_MAIN_AGENT_DATA = 107; SPICE_MSGC_MAIN_AGENT_DATA : 107,
var SPICE_MSGC_MAIN_AGENT_TOKEN = 108; SPICE_MSGC_MAIN_AGENT_TOKEN : 108,
var SPICE_MSGC_MAIN_MIGRATE_END = 109; SPICE_MSGC_MAIN_MIGRATE_END : 109,
var SPICE_MSGC_END_MAIN = 110; SPICE_MSGC_END_MAIN : 110,
var SPICE_MSG_DISPLAY_MODE = 101; SPICE_MSG_DISPLAY_MODE : 101,
var SPICE_MSG_DISPLAY_MARK = 102; SPICE_MSG_DISPLAY_MARK : 102,
var SPICE_MSG_DISPLAY_RESET = 103; SPICE_MSG_DISPLAY_RESET : 103,
var SPICE_MSG_DISPLAY_COPY_BITS = 104; SPICE_MSG_DISPLAY_COPY_BITS : 104,
var SPICE_MSG_DISPLAY_INVAL_LIST = 105; SPICE_MSG_DISPLAY_INVAL_LIST : 105,
var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106; SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS : 106,
var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107; SPICE_MSG_DISPLAY_INVAL_PALETTE : 107,
var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108; SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES: 108,
var SPICE_MSG_DISPLAY_STREAM_CREATE = 122; SPICE_MSG_DISPLAY_STREAM_CREATE : 122,
var SPICE_MSG_DISPLAY_STREAM_DATA = 123; SPICE_MSG_DISPLAY_STREAM_DATA : 123,
var SPICE_MSG_DISPLAY_STREAM_CLIP = 124; SPICE_MSG_DISPLAY_STREAM_CLIP : 124,
var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125; SPICE_MSG_DISPLAY_STREAM_DESTROY : 125,
var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126; SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL: 126,
var SPICE_MSG_DISPLAY_DRAW_FILL = 302; SPICE_MSG_DISPLAY_DRAW_FILL : 302,
var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303; SPICE_MSG_DISPLAY_DRAW_OPAQUE : 303,
var SPICE_MSG_DISPLAY_DRAW_COPY = 304; SPICE_MSG_DISPLAY_DRAW_COPY : 304,
var SPICE_MSG_DISPLAY_DRAW_BLEND = 305; SPICE_MSG_DISPLAY_DRAW_BLEND : 305,
var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306; SPICE_MSG_DISPLAY_DRAW_BLACKNESS : 306,
var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307; SPICE_MSG_DISPLAY_DRAW_WHITENESS : 307,
var SPICE_MSG_DISPLAY_DRAW_INVERS = 308; SPICE_MSG_DISPLAY_DRAW_INVERS : 308,
var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309; SPICE_MSG_DISPLAY_DRAW_ROP3 : 309,
var SPICE_MSG_DISPLAY_DRAW_STROKE = 310; SPICE_MSG_DISPLAY_DRAW_STROKE : 310,
var SPICE_MSG_DISPLAY_DRAW_TEXT = 311; SPICE_MSG_DISPLAY_DRAW_TEXT : 311,
var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312; SPICE_MSG_DISPLAY_DRAW_TRANSPARENT : 312,
var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313; SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND : 313,
var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314; SPICE_MSG_DISPLAY_SURFACE_CREATE : 314,
var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315; SPICE_MSG_DISPLAY_SURFACE_DESTROY : 315,
var SPICE_MSG_DISPLAY_STREAM_DATA_SIZED = 316; SPICE_MSG_DISPLAY_STREAM_DATA_SIZED : 316,
var SPICE_MSG_DISPLAY_MONITORS_CONFIG = 317; SPICE_MSG_DISPLAY_MONITORS_CONFIG : 317,
var SPICE_MSG_DISPLAY_DRAW_COMPOSITE = 318; SPICE_MSG_DISPLAY_DRAW_COMPOSITE : 318,
var SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT = 319; SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT : 319,
var SPICE_MSGC_DISPLAY_INIT = 101; SPICE_MSGC_DISPLAY_INIT : 101,
var SPICE_MSGC_DISPLAY_STREAM_REPORT = 102; SPICE_MSGC_DISPLAY_STREAM_REPORT : 102,
var SPICE_MSG_INPUTS_INIT = 101; SPICE_MSG_INPUTS_INIT : 101,
var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102; 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; SPICE_MSGC_INPUTS_KEY_DOWN : 101,
var SPICE_MSGC_INPUTS_KEY_UP = 102; SPICE_MSGC_INPUTS_KEY_UP : 102,
var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103; SPICE_MSGC_INPUTS_KEY_MODIFIERS : 103,
var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111; SPICE_MSGC_INPUTS_MOUSE_MOTION : 111,
var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112; SPICE_MSGC_INPUTS_MOUSE_POSITION : 112,
var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113; SPICE_MSGC_INPUTS_MOUSE_PRESS : 113,
var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114; SPICE_MSGC_INPUTS_MOUSE_RELEASE : 114,
var SPICE_MSG_CURSOR_INIT = 101; SPICE_MSG_CURSOR_INIT : 101,
var SPICE_MSG_CURSOR_RESET = 102; SPICE_MSG_CURSOR_RESET : 102,
var SPICE_MSG_CURSOR_SET = 103; SPICE_MSG_CURSOR_SET : 103,
var SPICE_MSG_CURSOR_MOVE = 104; SPICE_MSG_CURSOR_MOVE : 104,
var SPICE_MSG_CURSOR_HIDE = 105; SPICE_MSG_CURSOR_HIDE : 105,
var SPICE_MSG_CURSOR_TRAIL = 106; SPICE_MSG_CURSOR_TRAIL : 106,
var SPICE_MSG_CURSOR_INVAL_ONE = 107; SPICE_MSG_CURSOR_INVAL_ONE : 107,
var SPICE_MSG_CURSOR_INVAL_ALL = 108; SPICE_MSG_CURSOR_INVAL_ALL : 108,
var SPICE_MSG_PLAYBACK_DATA = 101; SPICE_MSG_PLAYBACK_DATA : 101,
var SPICE_MSG_PLAYBACK_MODE = 102; SPICE_MSG_PLAYBACK_MODE : 102,
var SPICE_MSG_PLAYBACK_START = 103; SPICE_MSG_PLAYBACK_START : 103,
var SPICE_MSG_PLAYBACK_STOP = 104; SPICE_MSG_PLAYBACK_STOP : 104,
var SPICE_MSG_PLAYBACK_VOLUME = 105; SPICE_MSG_PLAYBACK_VOLUME : 105,
var SPICE_MSG_PLAYBACK_MUTE = 106; SPICE_MSG_PLAYBACK_MUTE : 106,
var SPICE_MSG_PLAYBACK_LATENCY = 107; SPICE_MSG_PLAYBACK_LATENCY : 107,
var SPICE_MSG_SPICEVMC_DATA = 101; SPICE_MSG_SPICEVMC_DATA : 101,
var SPICE_MSG_PORT_INIT = 201; SPICE_MSG_PORT_INIT : 201,
var SPICE_MSG_PORT_EVENT = 202; SPICE_MSG_PORT_EVENT : 202,
var SPICE_MSG_END_PORT = 203; SPICE_MSG_END_PORT : 203,
var SPICE_MSGC_SPICEVMC_DATA = 101; SPICE_MSGC_SPICEVMC_DATA : 101,
var SPICE_MSGC_PORT_EVENT = 201; SPICE_MSGC_PORT_EVENT : 201,
var SPICE_MSGC_END_PORT = 202; SPICE_MSGC_END_PORT : 202,
var SPICE_PLAYBACK_CAP_CELT_0_5_1 = 0; SPICE_PLAYBACK_CAP_CELT_0_5_1 : 0,
var SPICE_PLAYBACK_CAP_VOLUME = 1; SPICE_PLAYBACK_CAP_VOLUME : 1,
var SPICE_PLAYBACK_CAP_LATENCY = 2; SPICE_PLAYBACK_CAP_LATENCY : 2,
var SPICE_PLAYBACK_CAP_OPUS = 3; SPICE_PLAYBACK_CAP_OPUS : 3,
var SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE = 0; SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE : 0,
var SPICE_MAIN_CAP_NAME_AND_UUID = 1; SPICE_MAIN_CAP_NAME_AND_UUID : 1,
var SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS = 2; SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS : 2,
var SPICE_MAIN_CAP_SEAMLESS_MIGRATE = 3; SPICE_MAIN_CAP_SEAMLESS_MIGRATE : 3,
var SPICE_DISPLAY_CAP_SIZED_STREAM = 0; SPICE_DISPLAY_CAP_SIZED_STREAM : 0,
var SPICE_DISPLAY_CAP_MONITORS_CONFIG = 1; SPICE_DISPLAY_CAP_MONITORS_CONFIG : 1,
var SPICE_DISPLAY_CAP_COMPOSITE = 2; SPICE_DISPLAY_CAP_COMPOSITE : 2,
var SPICE_DISPLAY_CAP_A8_SURFACE = 3; SPICE_DISPLAY_CAP_A8_SURFACE : 3,
var SPICE_DISPLAY_CAP_STREAM_REPORT = 4; SPICE_DISPLAY_CAP_STREAM_REPORT : 4,
var SPICE_DISPLAY_CAP_LZ4_COMPRESSION = 5; SPICE_DISPLAY_CAP_LZ4_COMPRESSION : 5,
var SPICE_DISPLAY_CAP_PREF_COMPRESSION = 6; SPICE_DISPLAY_CAP_PREF_COMPRESSION : 6,
var SPICE_DISPLAY_CAP_GL_SCANOUT = 7; SPICE_DISPLAY_CAP_GL_SCANOUT : 7,
var SPICE_DISPLAY_CAP_MULTI_CODEC = 8; SPICE_DISPLAY_CAP_MULTI_CODEC : 8,
var SPICE_DISPLAY_CAP_CODEC_MJPEG = 9; SPICE_DISPLAY_CAP_CODEC_MJPEG : 9,
var SPICE_DISPLAY_CAP_CODEC_VP8 = 10; SPICE_DISPLAY_CAP_CODEC_VP8 : 10,
var SPICE_AUDIO_DATA_MODE_INVALID = 0; SPICE_AUDIO_DATA_MODE_INVALID : 0,
var SPICE_AUDIO_DATA_MODE_RAW = 1; SPICE_AUDIO_DATA_MODE_RAW : 1,
var SPICE_AUDIO_DATA_MODE_CELT_0_5_1 = 2; SPICE_AUDIO_DATA_MODE_CELT_0_5_1 : 2,
var SPICE_AUDIO_DATA_MODE_OPUS = 3; SPICE_AUDIO_DATA_MODE_OPUS : 3,
var SPICE_AUDIO_FMT_INVALID = 0; SPICE_AUDIO_FMT_INVALID : 0,
var SPICE_AUDIO_FMT_S16 = 1; SPICE_AUDIO_FMT_S16 : 1,
var SPICE_CHANNEL_MAIN = 1; SPICE_CHANNEL_MAIN : 1,
var SPICE_CHANNEL_DISPLAY = 2; SPICE_CHANNEL_DISPLAY : 2,
var SPICE_CHANNEL_INPUTS = 3; SPICE_CHANNEL_INPUTS : 3,
var SPICE_CHANNEL_CURSOR = 4; SPICE_CHANNEL_CURSOR : 4,
var SPICE_CHANNEL_PLAYBACK = 5; SPICE_CHANNEL_PLAYBACK : 5,
var SPICE_CHANNEL_RECORD = 6; SPICE_CHANNEL_RECORD : 6,
var SPICE_CHANNEL_TUNNEL = 7; SPICE_CHANNEL_TUNNEL : 7,
var SPICE_CHANNEL_SMARTCARD = 8; SPICE_CHANNEL_SMARTCARD : 8,
var SPICE_CHANNEL_USBREDIR = 9; SPICE_CHANNEL_USBREDIR : 9,
var SPICE_CHANNEL_PORT = 10; SPICE_CHANNEL_PORT : 10,
var SPICE_CHANNEL_WEBDAV = 11; SPICE_CHANNEL_WEBDAV : 11,
var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0); SPICE_SURFACE_FLAGS_PRIMARY : (1 << 0),
var SPICE_NOTIFY_SEVERITY_INFO = 0; SPICE_NOTIFY_SEVERITY_INFO : 0,
var SPICE_NOTIFY_SEVERITY_WARN = 1; SPICE_NOTIFY_SEVERITY_WARN : 1,
var SPICE_NOTIFY_SEVERITY_ERROR = 2; SPICE_NOTIFY_SEVERITY_ERROR : 2,
var SPICE_MOUSE_MODE_SERVER = (1 << 0), SPICE_MOUSE_MODE_SERVER : (1 << 0),
SPICE_MOUSE_MODE_CLIENT = (1 << 1), SPICE_MOUSE_MODE_CLIENT : (1 << 1),
SPICE_MOUSE_MODE_MASK = 0x3; SPICE_MOUSE_MODE_MASK : 0x3,
var SPICE_CLIP_TYPE_NONE = 0; SPICE_CLIP_TYPE_NONE : 0,
var SPICE_CLIP_TYPE_RECTS = 1; SPICE_CLIP_TYPE_RECTS : 1,
var SPICE_IMAGE_TYPE_BITMAP = 0; SPICE_IMAGE_TYPE_BITMAP : 0,
var SPICE_IMAGE_TYPE_QUIC = 1; SPICE_IMAGE_TYPE_QUIC : 1,
var SPICE_IMAGE_TYPE_RESERVED = 2; SPICE_IMAGE_TYPE_RESERVED : 2,
var SPICE_IMAGE_TYPE_LZ_PLT = 100; SPICE_IMAGE_TYPE_LZ_PLT : 100,
var SPICE_IMAGE_TYPE_LZ_RGB = 101; SPICE_IMAGE_TYPE_LZ_RGB : 101,
var SPICE_IMAGE_TYPE_GLZ_RGB = 102; SPICE_IMAGE_TYPE_GLZ_RGB : 102,
var SPICE_IMAGE_TYPE_FROM_CACHE = 103; SPICE_IMAGE_TYPE_FROM_CACHE : 103,
var SPICE_IMAGE_TYPE_SURFACE = 104; SPICE_IMAGE_TYPE_SURFACE : 104,
var SPICE_IMAGE_TYPE_JPEG = 105; SPICE_IMAGE_TYPE_JPEG : 105,
var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106; SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS : 106,
var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107; SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB : 107,
var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108; SPICE_IMAGE_TYPE_JPEG_ALPHA : 108,
var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0), SPICE_IMAGE_FLAGS_CACHE_ME : (1 << 0),
SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1), SPICE_IMAGE_FLAGS_HIGH_BITS_SET : (1 << 1),
SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2); SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME : (1 << 2),
var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0), SPICE_BITMAP_FLAGS_PAL_CACHE_ME : (1 << 0),
SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1), SPICE_BITMAP_FLAGS_PAL_FROM_CACHE : (1 << 1),
SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2), SPICE_BITMAP_FLAGS_TOP_DOWN : (1 << 2),
SPICE_BITMAP_FLAGS_MASK = 0x7; SPICE_BITMAP_FLAGS_MASK : 0x7,
var SPICE_BITMAP_FMT_INVALID = 0, SPICE_BITMAP_FMT_INVALID : 0,
SPICE_BITMAP_FMT_1BIT_LE = 1, SPICE_BITMAP_FMT_1BIT_LE : 1,
SPICE_BITMAP_FMT_1BIT_BE = 2, SPICE_BITMAP_FMT_1BIT_BE : 2,
SPICE_BITMAP_FMT_4BIT_LE = 3, SPICE_BITMAP_FMT_4BIT_LE : 3,
SPICE_BITMAP_FMT_4BIT_BE = 4, SPICE_BITMAP_FMT_4BIT_BE : 4,
SPICE_BITMAP_FMT_8BIT = 5, SPICE_BITMAP_FMT_8BIT : 5,
SPICE_BITMAP_FMT_16BIT = 6, SPICE_BITMAP_FMT_16BIT : 6,
SPICE_BITMAP_FMT_24BIT = 7, SPICE_BITMAP_FMT_24BIT : 7,
SPICE_BITMAP_FMT_32BIT = 8, SPICE_BITMAP_FMT_32BIT : 8,
SPICE_BITMAP_FMT_RGBA = 9; SPICE_BITMAP_FMT_RGBA : 9,
var SPICE_CURSOR_FLAGS_NONE = (1 << 0), SPICE_CURSOR_FLAGS_NONE : (1 << 0),
SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1), SPICE_CURSOR_FLAGS_CACHE_ME : (1 << 1),
SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2), SPICE_CURSOR_FLAGS_FROM_CACHE : (1 << 2),
SPICE_CURSOR_FLAGS_MASK = 0x7; SPICE_CURSOR_FLAGS_MASK : 0x7,
var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0), SPICE_MOUSE_BUTTON_MASK_LEFT : (1 << 0),
SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1), SPICE_MOUSE_BUTTON_MASK_MIDDLE : (1 << 1),
SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2), SPICE_MOUSE_BUTTON_MASK_RIGHT : (1 << 2),
SPICE_MOUSE_BUTTON_MASK_MASK = 0x7; SPICE_MOUSE_BUTTON_MASK_MASK : 0x7,
var SPICE_MOUSE_BUTTON_INVALID = 0; SPICE_MOUSE_BUTTON_INVALID : 0,
var SPICE_MOUSE_BUTTON_LEFT = 1; SPICE_MOUSE_BUTTON_LEFT : 1,
var SPICE_MOUSE_BUTTON_MIDDLE = 2; SPICE_MOUSE_BUTTON_MIDDLE : 2,
var SPICE_MOUSE_BUTTON_RIGHT = 3; SPICE_MOUSE_BUTTON_RIGHT : 3,
var SPICE_MOUSE_BUTTON_UP = 4; SPICE_MOUSE_BUTTON_UP : 4,
var SPICE_MOUSE_BUTTON_DOWN = 5; SPICE_MOUSE_BUTTON_DOWN : 5,
var SPICE_BRUSH_TYPE_NONE = 0, SPICE_BRUSH_TYPE_NONE : 0,
SPICE_BRUSH_TYPE_SOLID = 1, SPICE_BRUSH_TYPE_SOLID : 1,
SPICE_BRUSH_TYPE_PATTERN = 2; SPICE_BRUSH_TYPE_PATTERN : 2,
var SPICE_SURFACE_FMT_INVALID = 0, SPICE_SURFACE_FMT_INVALID : 0,
SPICE_SURFACE_FMT_1_A = 1, SPICE_SURFACE_FMT_1_A : 1,
SPICE_SURFACE_FMT_8_A = 8, SPICE_SURFACE_FMT_8_A : 8,
SPICE_SURFACE_FMT_16_555 = 16, SPICE_SURFACE_FMT_16_555 : 16,
SPICE_SURFACE_FMT_32_xRGB = 32, SPICE_SURFACE_FMT_32_xRGB : 32,
SPICE_SURFACE_FMT_16_565 = 80, SPICE_SURFACE_FMT_16_565 : 80,
SPICE_SURFACE_FMT_32_ARGB = 96; SPICE_SURFACE_FMT_32_ARGB : 96,
var SPICE_ROPD_INVERS_SRC = (1 << 0), SPICE_ROPD_INVERS_SRC : (1 << 0),
SPICE_ROPD_INVERS_BRUSH = (1 << 1), SPICE_ROPD_INVERS_BRUSH : (1 << 1),
SPICE_ROPD_INVERS_DEST = (1 << 2), SPICE_ROPD_INVERS_DEST : (1 << 2),
SPICE_ROPD_OP_PUT = (1 << 3), SPICE_ROPD_OP_PUT : (1 << 3),
SPICE_ROPD_OP_OR = (1 << 4), SPICE_ROPD_OP_OR : (1 << 4),
SPICE_ROPD_OP_AND = (1 << 5), SPICE_ROPD_OP_AND : (1 << 5),
SPICE_ROPD_OP_XOR = (1 << 6), SPICE_ROPD_OP_XOR : (1 << 6),
SPICE_ROPD_OP_BLACKNESS = (1 << 7), SPICE_ROPD_OP_BLACKNESS : (1 << 7),
SPICE_ROPD_OP_WHITENESS = (1 << 8), SPICE_ROPD_OP_WHITENESS : (1 << 8),
SPICE_ROPD_OP_INVERS = (1 << 9), SPICE_ROPD_OP_INVERS : (1 << 9),
SPICE_ROPD_INVERS_RES = (1 << 10), SPICE_ROPD_INVERS_RES : (1 << 10),
SPICE_ROPD_MASK = 0x7ff; SPICE_ROPD_MASK : 0x7ff,
var LZ_IMAGE_TYPE_INVALID = 0, LZ_IMAGE_TYPE_INVALID : 0,
LZ_IMAGE_TYPE_PLT1_LE = 1, LZ_IMAGE_TYPE_PLT1_LE : 1,
LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette LZ_IMAGE_TYPE_PLT1_BE : 2, // PLT stands for palette
LZ_IMAGE_TYPE_PLT4_LE = 3, LZ_IMAGE_TYPE_PLT4_LE : 3,
LZ_IMAGE_TYPE_PLT4_BE = 4, LZ_IMAGE_TYPE_PLT4_BE : 4,
LZ_IMAGE_TYPE_PLT8 = 5, LZ_IMAGE_TYPE_PLT8 : 5,
LZ_IMAGE_TYPE_RGB16 = 6, LZ_IMAGE_TYPE_RGB16 : 6,
LZ_IMAGE_TYPE_RGB24 = 7, LZ_IMAGE_TYPE_RGB24 : 7,
LZ_IMAGE_TYPE_RGB32 = 8, LZ_IMAGE_TYPE_RGB32 : 8,
LZ_IMAGE_TYPE_RGBA = 9, LZ_IMAGE_TYPE_RGBA : 9,
LZ_IMAGE_TYPE_XXXA = 10; LZ_IMAGE_TYPE_XXXA : 10,
var QUIC_IMAGE_TYPE_INVALID = 0, SPICE_INPUT_MOTION_ACK_BUNCH : 4,
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;
var SPICE_CURSOR_TYPE_ALPHA = 0, SPICE_CURSOR_TYPE_ALPHA : 0,
SPICE_CURSOR_TYPE_MONO = 1, SPICE_CURSOR_TYPE_MONO : 1,
SPICE_CURSOR_TYPE_COLOR4 = 2, SPICE_CURSOR_TYPE_COLOR4 : 2,
SPICE_CURSOR_TYPE_COLOR8 = 3, SPICE_CURSOR_TYPE_COLOR8 : 3,
SPICE_CURSOR_TYPE_COLOR16 = 4, SPICE_CURSOR_TYPE_COLOR16 : 4,
SPICE_CURSOR_TYPE_COLOR24 = 5, SPICE_CURSOR_TYPE_COLOR24 : 5,
SPICE_CURSOR_TYPE_COLOR32 = 6; SPICE_CURSOR_TYPE_COLOR32 : 6,
var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1; SPICE_VIDEO_CODEC_TYPE_MJPEG : 1,
var SPICE_VIDEO_CODEC_TYPE_VP8 = 2; SPICE_VIDEO_CODEC_TYPE_VP8 : 2,
var VD_AGENT_PROTOCOL = 1; VD_AGENT_PROTOCOL : 1,
var VD_AGENT_MAX_DATA_SIZE = 2048; VD_AGENT_MAX_DATA_SIZE : 2048,
var VD_AGENT_MOUSE_STATE = 1, VD_AGENT_MOUSE_STATE : 1,
VD_AGENT_MONITORS_CONFIG = 2, VD_AGENT_MONITORS_CONFIG : 2,
VD_AGENT_REPLY = 3, VD_AGENT_REPLY : 3,
VD_AGENT_CLIPBOARD = 4, VD_AGENT_CLIPBOARD : 4,
VD_AGENT_DISPLAY_CONFIG = 5, VD_AGENT_DISPLAY_CONFIG : 5,
VD_AGENT_ANNOUNCE_CAPABILITIES = 6, VD_AGENT_ANNOUNCE_CAPABILITIES : 6,
VD_AGENT_CLIPBOARD_GRAB = 7, VD_AGENT_CLIPBOARD_GRAB : 7,
VD_AGENT_CLIPBOARD_REQUEST = 8, VD_AGENT_CLIPBOARD_REQUEST : 8,
VD_AGENT_CLIPBOARD_RELEASE = 9, VD_AGENT_CLIPBOARD_RELEASE : 9,
VD_AGENT_FILE_XFER_START =10, VD_AGENT_FILE_XFER_START :10,
VD_AGENT_FILE_XFER_STATUS =11, VD_AGENT_FILE_XFER_STATUS :11,
VD_AGENT_FILE_XFER_DATA =12, VD_AGENT_FILE_XFER_DATA :12,
VD_AGENT_CLIENT_DISCONNECTED =13, VD_AGENT_CLIENT_DISCONNECTED :13,
VD_AGENT_MAX_CLIPBOARD =14; VD_AGENT_MAX_CLIPBOARD :14,
var VD_AGENT_CAP_MOUSE_STATE = 0, VD_AGENT_CAP_MOUSE_STATE : 0,
VD_AGENT_CAP_MONITORS_CONFIG = 1, VD_AGENT_CAP_MONITORS_CONFIG : 1,
VD_AGENT_CAP_REPLY = 2, VD_AGENT_CAP_REPLY : 2,
VD_AGENT_CAP_CLIPBOARD = 3, VD_AGENT_CAP_CLIPBOARD : 3,
VD_AGENT_CAP_DISPLAY_CONFIG = 4, VD_AGENT_CAP_DISPLAY_CONFIG : 4,
VD_AGENT_CAP_CLIPBOARD_BY_DEMAND = 5, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND : 5,
VD_AGENT_CAP_CLIPBOARD_SELECTION = 6, VD_AGENT_CAP_CLIPBOARD_SELECTION : 6,
VD_AGENT_CAP_SPARSE_MONITORS_CONFIG = 7, VD_AGENT_CAP_SPARSE_MONITORS_CONFIG : 7,
VD_AGENT_CAP_GUEST_LINEEND_LF = 8, VD_AGENT_CAP_GUEST_LINEEND_LF : 8,
VD_AGENT_CAP_GUEST_LINEEND_CRLF = 9, VD_AGENT_CAP_GUEST_LINEEND_CRLF : 9,
VD_AGENT_CAP_MAX_CLIPBOARD = 10, VD_AGENT_CAP_MAX_CLIPBOARD : 10,
VD_AGENT_END_CAP = 11; VD_AGENT_END_CAP : 11,
var VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA = 0, VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA : 0,
VD_AGENT_FILE_XFER_STATUS_CANCELLED = 1, VD_AGENT_FILE_XFER_STATUS_CANCELLED : 1,
VD_AGENT_FILE_XFER_STATUS_ERROR = 2, VD_AGENT_FILE_XFER_STATUS_ERROR : 2,
VD_AGENT_FILE_XFER_STATUS_SUCCESS = 3; 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/>. 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 ** Modifier Keystates
** These need to be tracked because focus in and out can get the keyboard ** 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 = Object.create(SpiceConn.prototype);
SpiceInputsConn.prototype.process_channel_message = function(msg) 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; this.keyboard_modifiers = inputs_init.keyboard_modifiers;
DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers); DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers);
// FIXME - We don't do anything with the keyboard modifiers... // FIXME - We don't do anything with the keyboard modifiers...
return true; return true;
} }
if (msg.type == 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; this.keyboard_modifiers = key.keyboard_modifiers;
DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers); DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers);
// FIXME - We don't do anything with the keyboard modifiers... // FIXME - We don't do anything with the keyboard modifiers...
return true; return true;
} }
if (msg.type == SPICE_MSG_INPUTS_MOUSE_MOTION_ACK) if (msg.type == Constants.SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
{ {
DEBUG > 1 && console.log("mouse motion ack"); DEBUG > 1 && console.log("mouse motion ack");
this.waiting_for_ack -= SPICE_INPUT_MOTION_ACK_BUNCH; this.waiting_for_ack -= Constants.SPICE_INPUT_MOTION_ACK_BUNCH;
return true; return true;
} }
return false; return false;
@ -74,21 +80,21 @@ SpiceInputsConn.prototype.process_channel_message = function(msg)
function handle_mousemove(e) function handle_mousemove(e)
{ {
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
var move; 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) move = new Messages.SpiceMsgcMousePosition(this.sc, e)
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
} }
else else
{ {
move = new SpiceMsgcMouseMotion(this.sc, e) move = new Messages.SpiceMsgcMouseMotion(this.sc, e)
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
} }
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
{ {
if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH)) if (this.sc.inputs.waiting_for_ack < (2 * Constants.SPICE_INPUT_MOTION_ACK_BUNCH))
{ {
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
this.sc.inputs.waiting_for_ack++; this.sc.inputs.waiting_for_ack++;
@ -111,9 +117,9 @@ function handle_mousemove(e)
function handle_mousedown(e) function handle_mousedown(e)
{ {
var press = new SpiceMsgcMousePress(this.sc, e) var press = new Messages.SpiceMsgcMousePress(this.sc, e)
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
@ -128,9 +134,9 @@ function handle_contextmenu(e)
function handle_mouseup(e) function handle_mouseup(e)
{ {
var release = new SpiceMsgcMouseRelease(this.sc, e) var release = new Messages.SpiceMsgcMouseRelease(this.sc, e)
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
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") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
@ -139,21 +145,21 @@ function handle_mouseup(e)
function handle_mousewheel(e) function handle_mousewheel(e)
{ {
var press = new SpiceMsgcMousePress; var press = new Messages.SpiceMsgcMousePress;
var release = new SpiceMsgcMouseRelease; var release = new Messages.SpiceMsgcMouseRelease;
if (e.deltaY < 0) if (e.deltaY < 0)
press.button = release.button = SPICE_MOUSE_BUTTON_UP; press.button = release.button = Constants.SPICE_MOUSE_BUTTON_UP;
else else
press.button = release.button = SPICE_MOUSE_BUTTON_DOWN; press.button = release.button = Constants.SPICE_MOUSE_BUTTON_DOWN;
press.buttons_state = 0; press.buttons_state = 0;
release.buttons_state = 0; release.buttons_state = 0;
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press); msg.build_msg(Constants.SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg); 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") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
@ -162,10 +168,10 @@ function handle_mousewheel(e)
function handle_keydown(e) function handle_keydown(e)
{ {
var key = new SpiceMsgcKeyDown(e) var key = new Messages.SpiceMsgcKeyDown(e)
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
check_and_update_modifiers(e, key.code, this.sc); 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") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
@ -174,74 +180,50 @@ function handle_keydown(e)
function handle_keyup(e) function handle_keyup(e)
{ {
var key = new SpiceMsgcKeyUp(e) var key = new Messages.SpiceMsgcKeyUp(e)
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
check_and_update_modifiers(e, key.code, this.sc); 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") if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
this.sc.inputs.send_msg(msg); this.sc.inputs.send_msg(msg);
e.preventDefault(); e.preventDefault();
} }
function sendCtrlAltDel() function sendCtrlAltDel(sc)
{ {
if (sc && sc.inputs && sc.inputs.state === "ready"){ if (sc && sc.inputs && sc.inputs.state === "ready"){
var key = new SpiceMsgcKeyDown(); var key = new Messages.SpiceMsgcKeyDown();
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
update_modifier(true, KEY_LCtrl, sc); update_modifier(true, KeyNames.KEY_LCtrl, sc);
update_modifier(true, KEY_Alt, sc); update_modifier(true, KeyNames.KEY_Alt, sc);
key.code = KEY_KP_Decimal; key.code = KeyNames.KEY_KP_Decimal;
msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key); msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_DOWN, key);
sc.inputs.send_msg(msg); 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); sc.inputs.send_msg(msg);
if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc); if(Ctrl_state == false) update_modifier(false, KeyNames.KEY_LCtrl, sc);
if(Alt_state == false) update_modifier(false, KEY_Alt, sc); if(Alt_state == false) update_modifier(false, KeyNames.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);
} }
} }
function update_modifier(state, code, sc) function update_modifier(state, code, sc)
{ {
var msg = new SpiceMiniData(); var msg = new Messages.SpiceMiniData();
if (!state) if (!state)
{ {
var key = new SpiceMsgcKeyUp() var key = new Messages.SpiceMsgcKeyUp()
key.code =(0x80|code); key.code =(0x80|code);
msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key); msg.build_msg(Constants.SPICE_MSGC_INPUTS_KEY_UP, key);
} }
else else
{ {
var key = new SpiceMsgcKeyDown() var key = new Messages.SpiceMsgcKeyDown()
key.code = code; 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); sc.inputs.send_msg(msg);
@ -257,19 +239,19 @@ function check_and_update_modifiers(e, code, sc)
Meta_state = e.metaKey; Meta_state = e.metaKey;
} }
if (code === KEY_ShiftL) if (code === KeyNames.KEY_ShiftL)
Shift_state = true; Shift_state = true;
else if (code === KEY_Alt) else if (code === KeyNames.KEY_Alt)
Alt_state = true; Alt_state = true;
else if (code === KEY_LCtrl) else if (code === KeyNames.KEY_LCtrl)
Ctrl_state = true; Ctrl_state = true;
else if (code === 0xE0B5) else if (code === 0xE0B5)
Meta_state = true; Meta_state = true;
else if (code === (0x80|KEY_ShiftL)) else if (code === (0x80|KeyNames.KEY_ShiftL))
Shift_state = false; Shift_state = false;
else if (code === (0x80|KEY_Alt)) else if (code === (0x80|KeyNames.KEY_Alt))
Alt_state = false; Alt_state = false;
else if (code === (0x80|KEY_LCtrl)) else if (code === (0x80|KeyNames.KEY_LCtrl))
Ctrl_state = false; Ctrl_state = false;
else if (code === (0x80|0xE0B5)) else if (code === (0x80|0xE0B5))
Meta_state = false; Meta_state = false;
@ -279,19 +261,19 @@ function check_and_update_modifiers(e, code, sc)
if (Shift_state != e.shiftKey) if (Shift_state != e.shiftKey)
{ {
console.log("Shift state out of sync"); console.log("Shift state out of sync");
update_modifier(e.shiftKey, KEY_ShiftL, sc); update_modifier(e.shiftKey, KeyNames.KEY_ShiftL, sc);
Shift_state = e.shiftKey; Shift_state = e.shiftKey;
} }
if (Alt_state != e.altKey) if (Alt_state != e.altKey)
{ {
console.log("Alt state out of sync"); console.log("Alt state out of sync");
update_modifier(e.altKey, KEY_Alt, sc); update_modifier(e.altKey, KeyNames.KEY_Alt, sc);
Alt_state = e.altKey; Alt_state = e.altKey;
} }
if (Ctrl_state != e.ctrlKey) if (Ctrl_state != e.ctrlKey)
{ {
console.log("Ctrl state out of sync"); console.log("Ctrl state out of sync");
update_modifier(e.ctrlKey, KEY_LCtrl, sc); update_modifier(e.ctrlKey, KeyNames.KEY_LCtrl, sc);
Ctrl_state = e.ctrlKey; Ctrl_state = e.ctrlKey;
} }
if (Meta_state != e.metaKey) if (Meta_state != e.metaKey)
@ -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/>. along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Constants } from './enums.js';
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
** lz.js ** lz.js
@ -30,6 +31,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
var op = 0; var op = 0;
var ctrl; var ctrl;
var ctr = 0; var ctr = 0;
var i = 0;
for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl = in_buf[encoder++]) 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; len += 1;
if (type == LZ_IMAGE_TYPE_RGBA) if (type == Constants.LZ_IMAGE_TYPE_RGBA)
len += 2; len += 2;
ofs += 1; ofs += 1;
@ -72,7 +74,7 @@ function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
var b = ref; 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)); //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) { 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]; 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 { } else {
//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op + " through " + (op + len) + " from " + ref); //if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op + " through " + (op + len) + " from " + ref);
for (; len; --len) { 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]; 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 { } else {
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); //console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
out_buf[(op*4) + 3] = in_buf[encoder++]; 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--) { 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); //console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
out_buf[(op*4) + 3] = in_buf[encoder++]; 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) function convert_spice_lz_to_web(context, lz_image)
{ {
var at; 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 u8 = new Uint8Array(lz_image.data);
var ret = context.createImageData(lz_image.width, lz_image.height); 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) if (!lz_image.top_down)
flip_image_data(ret); flip_image_data(ret);
if (lz_image.type == LZ_IMAGE_TYPE_RGBA) if (lz_image.type == Constants.LZ_IMAGE_TYPE_RGBA)
lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false); 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 u8 = new Uint8Array(lz_image.data);
var ret = context.createImageData(lz_image.width, lz_image.height); 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 else
return undefined; return undefined;
return ret; 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/>. 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 ** SpiceMainConn
** This is the master Javascript class for establishing and ** This is the master Javascript class for establishing and
@ -43,6 +56,8 @@
** onagent (optional) If given, a function to be called when ** onagent (optional) If given, a function to be called when
** a VD agent is connected; a good opportunity ** a VD agent is connected; a good opportunity
** to request a resize ** 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) ** Throws error if there are troubles. Requires a modern (by 2012 standards)
** browser, including WebSocket and WebSocket.binaryType == arraybuffer ** browser, including WebSocket and WebSocket.binaryType == arraybuffer
@ -65,23 +80,23 @@ function SpiceMainConn()
SpiceMainConn.prototype = Object.create(SpiceConn.prototype); SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
SpiceMainConn.prototype.process_channel_message = function(msg) SpiceMainConn.prototype.process_channel_message = function(msg)
{ {
if (msg.type == SPICE_MSG_MAIN_MIGRATE_BEGIN) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN)
{ {
this.known_unimplemented(msg.type, "Main Migrate Begin"); this.known_unimplemented(msg.type, "Main Migrate Begin");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_MIGRATE_CANCEL) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_CANCEL)
{ {
this.known_unimplemented(msg.type, "Main Migrate Cancel"); this.known_unimplemented(msg.type, "Main Migrate Cancel");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_INIT) if (msg.type == Constants.SPICE_MSG_MAIN_INIT)
{ {
this.log_info("Connected to " + this.ws.url); this.log_info("Connected to " + this.ws.url);
this.report_success("Connected") this.report_success("Connected")
this.main_init = new SpiceMsgMainInit(msg.data); this.main_init = new Messages.SpiceMsgMainInit(msg.data);
this.connection_id = this.main_init.session_id; this.connection_id = this.main_init.session_id;
this.agent_tokens = this.main_init.agent_tokens; this.agent_tokens = this.main_init.agent_tokens;
@ -108,33 +123,33 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
if (this.main_init.agent_connected) if (this.main_init.agent_connected)
this.connect_agent(); this.connect_agent();
var attach = new SpiceMiniData; var attach = new Messages.SpiceMiniData;
attach.type = SPICE_MSGC_MAIN_ATTACH_CHANNELS; attach.type = Constants.SPICE_MSGC_MAIN_ATTACH_CHANNELS;
attach.size = attach.buffer_size(); attach.size = attach.buffer_size();
this.send_msg(attach); this.send_msg(attach);
return true; 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); DEBUG > 0 && this.log_info("Mouse supported modes " + mode.supported_modes + "; current " + mode.current_mode);
this.handle_mouse_mode(mode.current_mode, mode.supported_modes); this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_MULTI_MEDIA_TIME) if (msg.type == Constants.SPICE_MSG_MAIN_MULTI_MEDIA_TIME)
{ {
this.known_unimplemented(msg.type, "Main Multi Media Time"); this.known_unimplemented(msg.type, "Main Multi Media Time");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_CHANNELS_LIST) if (msg.type == Constants.SPICE_MSG_MAIN_CHANNELS_LIST)
{ {
var i; var i;
var chans; var chans;
DEBUG > 0 && console.log("channels"); DEBUG > 0 && console.log("channels");
chans = new SpiceMsgChannels(msg.data); chans = new Messages.SpiceMsgChannels(msg.data);
for (i = 0; i < chans.channels.length; i++) for (i = 0; i < chans.channels.length; i++)
{ {
var conn = { var conn = {
@ -144,23 +159,24 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
type : chans.channels[i].type, type : chans.channels[i].type,
chan_id : chans.channels[i].id chan_id : chans.channels[i].id
}; };
if (chans.channels[i].type == SPICE_CHANNEL_DISPLAY) if (chans.channels[i].type == Constants.SPICE_CHANNEL_DISPLAY)
{ {
if (this.display !== undefined) if (chans.channels[i].id == 0) {
this.log_warn("The spice-html5 client does not handle multiple heads.");
else
this.display = new SpiceDisplayConn(conn); 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 = new SpiceInputsConn(conn);
this.inputs.mouse_mode = this.mouse_mode; 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); 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); 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)); this.ports.push(new SpicePortConn(conn));
else else
{ {
@ -175,23 +191,23 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_CONNECTED)
{ {
this.connect_agent(); this.connect_agent();
return true; return true;
} }
if (msg.type == 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.agent_tokens = connected_tokens.num_tokens;
this.connect_agent(); this.connect_agent();
return true; 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.agent_tokens += tokens.num_tokens;
this.send_agent_message_queue(); this.send_agent_message_queue();
@ -205,68 +221,68 @@ SpiceMainConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_AGENT_DISCONNECTED) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DISCONNECTED)
{ {
this.agent_connected = false; this.agent_connected = false;
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_AGENT_DATA) if (msg.type == Constants.SPICE_MSG_MAIN_AGENT_DATA)
{ {
var agent_data = new SpiceMsgMainAgentData(msg.data); var agent_data = new Messages.SpiceMsgMainAgentData(msg.data);
if (agent_data.type == VD_AGENT_ANNOUNCE_CAPABILITIES) 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) if (agent_caps.request)
this.announce_agent_capabilities(0); this.announce_agent_capabilities(0);
return true; 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 true;
} }
return false; 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"); this.known_unimplemented(msg.type, "Main Migrate Switch Host");
return true; 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"); this.known_unimplemented(msg.type, "Main Migrate End");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_NAME) if (msg.type == Constants.SPICE_MSG_MAIN_NAME)
{ {
this.known_unimplemented(msg.type, "Main Name"); this.known_unimplemented(msg.type, "Main Name");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_UUID) if (msg.type == Constants.SPICE_MSG_MAIN_UUID)
{ {
this.known_unimplemented(msg.type, "Main UUID"); this.known_unimplemented(msg.type, "Main UUID");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS)
{ {
this.known_unimplemented(msg.type, "Main Migrate Begin Seamless"); this.known_unimplemented(msg.type, "Main Migrate Begin Seamless");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK)
{ {
this.known_unimplemented(msg.type, "Main Migrate Dst Seamless ACK"); this.known_unimplemented(msg.type, "Main Migrate Dst Seamless ACK");
return true; return true;
} }
if (msg.type == SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK) if (msg.type == Constants.SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK)
{ {
this.known_unimplemented(msg.type, "Main Migrate Dst Seamless NACK"); this.known_unimplemented(msg.type, "Main Migrate Dst Seamless NACK");
return true; return true;
@ -324,15 +340,15 @@ SpiceMainConn.prototype.send_agent_message_queue = function(message)
SpiceMainConn.prototype.send_agent_message = function(type, message) SpiceMainConn.prototype.send_agent_message = function(type, message)
{ {
var agent_data = new SpiceMsgcMainAgentData(type, message); var agent_data = new Messages.SpiceMsgcMainAgentData(type, message);
var sb = 0, maxsize = VD_AGENT_MAX_DATA_SIZE - SpiceMiniData.prototype.buffer_size(); var sb = 0, maxsize = Constants.VD_AGENT_MAX_DATA_SIZE - Messages.SpiceMiniData.prototype.buffer_size();
var data = new ArrayBuffer(agent_data.buffer_size()); var data = new ArrayBuffer(agent_data.buffer_size());
agent_data.to_buffer(data); agent_data.to_buffer(data);
while (sb < agent_data.buffer_size()) while (sb < agent_data.buffer_size())
{ {
var eb = Math.min(sb + maxsize, agent_data.buffer_size()); var eb = Math.min(sb + maxsize, agent_data.buffer_size());
var mr = new SpiceMiniData(); var mr = new Messages.SpiceMiniData();
mr.type = SPICE_MSGC_MAIN_AGENT_DATA; mr.type = Constants.SPICE_MSGC_MAIN_AGENT_DATA;
mr.size = eb - sb; mr.size = eb - sb;
mr.data = data.slice(sb, eb); mr.data = data.slice(sb, eb);
this.send_agent_message_queue(mr); 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) SpiceMainConn.prototype.announce_agent_capabilities = function(request)
{ {
var caps = new VDAgentAnnounceCapabilities(request, (1 << VD_AGENT_CAP_MOUSE_STATE) | var caps = new Messages.VDAgentAnnounceCapabilities(request, (1 << Constants.VD_AGENT_CAP_MOUSE_STATE) |
(1 << VD_AGENT_CAP_MONITORS_CONFIG) | (1 << Constants.VD_AGENT_CAP_MONITORS_CONFIG) |
(1 << VD_AGENT_CAP_REPLY)); (1 << Constants.VD_AGENT_CAP_REPLY));
this.send_agent_message(VD_AGENT_ANNOUNCE_CAPABILITIES, caps); this.send_agent_message(Constants.VD_AGENT_ANNOUNCE_CAPABILITIES, caps);
} }
SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y) SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
{ {
var monitors_config = new VDAgentMonitorsConfig(flags, width, height, depth, x, y); var monitors_config = new Messages.VDAgentMonitorsConfig(flags, width, height, depth, x, y);
this.send_agent_message(VD_AGENT_MONITORS_CONFIG, monitors_config); this.send_agent_message(Constants.VD_AGENT_MONITORS_CONFIG, monitors_config);
} }
SpiceMainConn.prototype.file_xfer_start = function(file) SpiceMainConn.prototype.file_xfer_start = function(file)
@ -362,8 +378,8 @@ SpiceMainConn.prototype.file_xfer_start = function(file)
task = new SpiceFileXferTask(task_id, file); task = new SpiceFileXferTask(task_id, file);
task.create_progressbar(); task.create_progressbar();
this.file_xfer_tasks[task_id] = task; this.file_xfer_tasks[task_id] = task;
xfer_start = new VDAgentFileXferStartMessage(task_id, file.name, file.size); xfer_start = new Messages.VDAgentFileXferStartMessage(task_id, file.name, file.size);
this.send_agent_message(VD_AGENT_FILE_XFER_START, xfer_start); this.send_agent_message(Constants.VD_AGENT_FILE_XFER_START, xfer_start);
} }
SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status) SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
@ -376,16 +392,16 @@ SpiceMainConn.prototype.handle_file_xfer_status = function(file_xfer_status)
xfer_task = this.file_xfer_tasks[file_xfer_status.id]; xfer_task = this.file_xfer_tasks[file_xfer_status.id];
switch (file_xfer_status.result) switch (file_xfer_status.result)
{ {
case VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA: case Constants.VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
this.file_xfer_read(xfer_task); this.file_xfer_read(xfer_task);
return; return;
case VD_AGENT_FILE_XFER_STATUS_CANCELLED: case Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED:
xfer_error = "transfer is cancelled by spice agent"; xfer_error = "transfer is cancelled by spice agent";
break; 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"; xfer_error = "some errors occurred in the spice agent";
break; break;
case VD_AGENT_FILE_XFER_STATUS_SUCCESS: case Constants.VD_AGENT_FILE_XFER_STATUS_SUCCESS:
break; break;
default: default:
xfer_error = "unhandled status type: " + file_xfer_status.result; 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) 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 _this = this;
var sb, eb; var sb, eb;
var slice, reader; var slice, reader;
@ -411,9 +427,9 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
if (file_xfer_task.cancelled) if (file_xfer_task.cancelled)
{ {
var xfer_status = new VDAgentFileXferStatusMessage(file_xfer_task.id, var xfer_status = new Messages.VDAgentFileXferStatusMessage(file_xfer_task.id,
VD_AGENT_FILE_XFER_STATUS_CANCELLED); Constants.VD_AGENT_FILE_XFER_STATUS_CANCELLED);
this.send_agent_message(VD_AGENT_FILE_XFER_STATUS, xfer_status); this.send_agent_message(Constants.VD_AGENT_FILE_XFER_STATUS, xfer_status);
delete this.file_xfer_tasks[file_xfer_task.id]; delete this.file_xfer_tasks[file_xfer_task.id];
return; return;
} }
@ -431,10 +447,10 @@ SpiceMainConn.prototype.file_xfer_read = function(file_xfer_task, start_byte)
reader = new FileReader(); reader = new FileReader();
reader.onload = function(e) 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.byteLength,
e.target.result); 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); _this.file_xfer_read(file_xfer_task, eb);
file_xfer_task.update_progressbar(eb); file_xfer_task.update_progressbar(eb);
}; };
@ -459,9 +475,9 @@ SpiceMainConn.prototype.connect_agent = function()
{ {
this.agent_connected = true; this.agent_connected = true;
var agent_start = new SpiceMsgcMainAgentStart(~0); var agent_start = new Messages.SpiceMsgcMainAgentStart(~0);
var mr = new SpiceMiniData(); var mr = new Messages.SpiceMiniData();
mr.build_msg(SPICE_MSGC_MAIN_AGENT_START, agent_start); mr.build_msg(Constants.SPICE_MSGC_MAIN_AGENT_START, agent_start);
this.send_msg(mr); this.send_msg(mr);
this.announce_agent_capabilities(1); this.announce_agent_capabilities(1);
@ -474,11 +490,11 @@ SpiceMainConn.prototype.connect_agent = function()
SpiceMainConn.prototype.handle_mouse_mode = function(current, supported) SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
{ {
this.mouse_mode = current; this.mouse_mode = current;
if (current != 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 mode_request = new Messages.SpiceMsgcMainMouseModeRequest(Constants.SPICE_MOUSE_MODE_CLIENT);
var mr = new SpiceMiniData(); var mr = new Messages.SpiceMiniData();
mr.build_msg(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request); mr.build_msg(Constants.SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
this.send_msg(mr); this.send_msg(mr);
} }
@ -492,3 +508,12 @@ SpiceMainConn.prototype.relative_now = function()
var ret = (Date.now() - this.our_mm_time) + this.mm_time; var ret = (Date.now() - this.our_mm_time) + this.mm_time;
return ret; return ret;
} }
export {
SpiceMainConn,
handle_file_dragover,
handle_file_drop,
resize_helper,
handle_resize,
sendCtrlAltDel,
};

View file

@ -22,6 +22,13 @@
** SpicePlaybackConn ** SpicePlaybackConn
** Drive the Spice Playback channel (sound out) ** 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() function SpicePlaybackConn()
{ {
SpiceConn.apply(this, arguments); SpiceConn.apply(this, arguments);
@ -40,25 +47,25 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
return false; 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); this.log_err('This player cannot handle frequency ' + start.frequency);
return false; return false;
} }
if (start.channels != OPUS_CHANNELS) if (start.channels != Webm.Constants.OPUS_CHANNELS)
{ {
this.log_err('This player cannot handle ' + start.channels + ' channels'); this.log_err('This player cannot handle ' + start.channels + ' channels');
return false; 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); this.log_err('This player cannot format ' + start.format);
return false; 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) if (! this.source_buffer)
return true; return true;
@ -115,28 +122,28 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
will resync. 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 " + Utils.PLAYBACK_DEBUG > 1 && console.log("Hacking time of " + data.time + " to " +
(this.last_data_time + EXPECTED_PACKET_DURATION)); (this.last_data_time + Webm.Constants.EXPECTED_PACKET_DURATION));
data.time = this.last_data_time + EXPECTED_PACKET_DURATION; data.time = this.last_data_time + Webm.Constants.EXPECTED_PACKET_DURATION;
} }
else 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; 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) if (this.start_time == 0)
this.start_playback(data); 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); this.new_cluster(data);
else else
@ -145,10 +152,10 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
return true; return true;
} }
if (msg.type == SPICE_MSG_PLAYBACK_MODE) if (msg.type == Constants.SPICE_MSG_PLAYBACK_MODE)
{ {
var mode = new SpiceMsgPlaybackMode(msg.data); var mode = new Messages.SpiceMsgPlaybackMode(msg.data);
if (mode.mode != SPICE_AUDIO_DATA_MODE_OPUS) if (mode.mode != Constants.SPICE_AUDIO_DATA_MODE_OPUS)
{ {
this.log_err('This player cannot handle mode ' + mode.mode); this.log_err('This player cannot handle mode ' + mode.mode);
delete this.source_buffer; delete this.source_buffer;
@ -156,9 +163,9 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg)
return true; 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) if (this.source_buffer)
{ {
document.getElementById(this.parent.screen_id).removeChild(this.audio); 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"); this.known_unimplemented(msg.type, "Playback Volume");
return true; return true;
} }
if (msg.type == SPICE_MSG_PLAYBACK_MUTE) if (msg.type == Constants.SPICE_MSG_PLAYBACK_MUTE)
{ {
this.known_unimplemented(msg.type, "Playback Mute"); this.known_unimplemented(msg.type, "Playback Mute");
return true; return true;
} }
if (msg.type == SPICE_MSG_PLAYBACK_LATENCY) if (msg.type == Constants.SPICE_MSG_PLAYBACK_LATENCY)
{ {
this.known_unimplemented(msg.type, "Playback Latency"); this.known_unimplemented(msg.type, "Playback Latency");
return true; return true;
@ -201,9 +208,9 @@ SpicePlaybackConn.prototype.start_playback = function(data)
{ {
this.start_time = data.time; this.start_time = data.time;
var h = new webm_Header(); var h = new Webm.Header();
var te = new webm_AudioTrackEntry; var te = new Webm.AudioTrackEntry;
var t = new webm_Tracks(te); var t = new Webm.Tracks(te);
var mb = new ArrayBuffer(h.buffer_size() + t.buffer_size()) 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; 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()); var mb = new ArrayBuffer(c.buffer_size());
this.bytes_written += c.to_buffer(mb); this.bytes_written += c.to_buffer(mb);
@ -236,7 +243,7 @@ SpicePlaybackConn.prototype.new_cluster = function(data)
SpicePlaybackConn.prototype.simple_block = function(data, keyframe) 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()); var mb = new ArrayBuffer(sb.buffer_size());
this.bytes_written += sb.to_buffer(mb); this.bytes_written += sb.to_buffer(mb);
@ -254,14 +261,14 @@ function handle_source_open(e)
if (p.source_buffer) if (p.source_buffer)
return; return;
p.source_buffer = this.addSourceBuffer(SPICE_PLAYBACK_CODEC); p.source_buffer = this.addSourceBuffer(Webm.Constants.SPICE_PLAYBACK_CODEC);
if (! p.source_buffer) 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; return;
} }
if (PLAYBACK_DEBUG > 0) if (Utils.PLAYBACK_DEBUG > 0)
playback_handle_event_debug.call(this, e); playback_handle_event_debug.call(this, e);
listen_for_audio_events(p); listen_for_audio_events(p);
@ -315,7 +322,7 @@ function handle_append_buffer_done(e)
{ {
var p = this.spiceconn; var p = this.spiceconn;
if (PLAYBACK_DEBUG > 1) if (Utils.PLAYBACK_DEBUG > 1)
playback_handle_event_debug.call(this, e); playback_handle_event_debug.call(this, e);
if (p.queue.length > 0) if (p.queue.length > 0)
@ -352,18 +359,18 @@ function playback_handle_event_debug(e)
var p = this.spiceconn; var p = this.spiceconn;
if (p.audio) 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 + 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) if (Utils.PLAYBACK_DEBUG > 1 && p.media_source)
console.log(" media_source " + dump_media_source(p.media_source)); console.log(" media_source " + Utils.dump_media_source(p.media_source));
if (PLAYBACK_DEBUG > 1 && p.source_buffer) if (Utils.PLAYBACK_DEBUG > 1 && p.source_buffer)
console.log(" source_buffer " + dump_source_buffer(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); 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); 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); 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); 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 ** crc logic from rfc2083 ported to Javascript
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
import { SpiceDataView } from './spicedataview.js';
var rfc2083_crc_table = Array(256); var rfc2083_crc_table = Array(256);
var rfc2083_crc_table_computed = 0; var rfc2083_crc_table_computed = 0;
/* Make the table for a fast CRC. */ /* 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; 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/>. 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 ** SpicePortConn
** Drive the Spice Port Channel ** Drive the Spice Port Channel
@ -34,7 +39,7 @@ SpicePortConn.prototype = Object.create(SpiceConn.prototype);
SpicePortConn.prototype.process_channel_message = function(msg) 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) 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.'); 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); DEBUG > 0 && console.log('SPICE port: Port event received for', this.portName, msg);
var event = new CustomEvent('spice-port-event', { var event = new CustomEvent('spice-port-event', {
@ -62,7 +67,7 @@ SpicePortConn.prototype.process_channel_message = function(msg)
window.dispatchEvent(event); window.dispatchEvent(event);
return true; 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); DEBUG > 0 && console.log('SPICE port: Data received in port', this.portName, msg);
var event = new CustomEvent('spice-port-data', { var event = new CustomEvent('spice-port-data', {
@ -83,3 +88,7 @@ SpicePortConn.prototype.process_channel_message = function(msg)
return false; return false;
}; };
export {
SpicePortConn,
};

View file

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

View file

@ -42,6 +42,8 @@ function resize_helper(sc)
var h = window.innerHeight - 20; var h = window.innerHeight - 20;
/* Screen height based on debug console visibility */ /* Screen height based on debug console visibility */
if (m != null)
{
if (window.getComputedStyle(m).getPropertyValue("display") == 'none') if (window.getComputedStyle(m).getPropertyValue("display") == 'none')
{ {
/* Get console height from spice.css .spice-message */ /* Get console height from spice.css .spice-message */
@ -53,15 +55,16 @@ function resize_helper(sc)
/* Show both div elements - spice-area and message-div */ /* Show both div elements - spice-area and message-div */
h = h - m.offsetHeight - m.clientHeight; 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) 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) if (w % 8 > 0)
w += (8 - (w % 8)); w -= (w % 8);
sc.resize_window(0, w, h, 32, 0, 0); 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); 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 ** 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. ** 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 = { var SpiceSimulateCursor = {
cursors : new Array(), cursors : new Array(),
@ -200,3 +204,5 @@ SpiceSimulateCursor.ICONDIRENTRY.prototype =
return 16; return 16;
} }
}; };
export { SpiceSimulateCursor };

View file

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

View file

@ -118,3 +118,7 @@ SpiceDataView.prototype = {
this.setUint32(byteOffset + low, (w & 0x00000000ffffffff), littleEndian); 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 ** a spice server. This file should arguably be generated from
** spice.proto, but it was instead put together by hand. ** 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) function SpiceLinkHeader(a, at)
{ {
this.magic = SPICE_MAGIC; this.magic = Constants.SPICE_MAGIC;
this.major_version = SPICE_VERSION_MAJOR; this.major_version = Constants.SPICE_VERSION_MAJOR;
this.minor_version = SPICE_VERSION_MINOR; this.minor_version = Constants.SPICE_VERSION_MINOR;
this.size = 0; this.size = 0;
if (a !== undefined) if (a !== undefined)
this.from_buffer(a, at); this.from_buffer(a, at);
@ -160,7 +180,7 @@ SpiceLinkReply.prototype =
this.error = dv.getUint32(at, true); at += 4; this.error = dv.getUint32(at, true); at += 4;
this.pub_key = create_rsa_from_mb(a, at); 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_common_caps = dv.getUint32(at, true); at += 4;
var num_channel_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 i;
var dv = new SpiceDataView(a); var dv = new SpiceDataView(a);
dv.setUint32(at, this.auth_mechanism, true); at += 4; 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) if (this.encrypted_data && i < this.encrypted_data.length)
dv.setUint8(at, this.encrypted_data[i], true); dv.setUint8(at, this.encrypted_data[i], true);
@ -206,7 +226,7 @@ SpiceLinkAuthTicket.prototype =
}, },
buffer_size: function() 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) function SpiceMsgcMainAgentData(type, data)
{ {
this.protocol = VD_AGENT_PROTOCOL; this.protocol = Constants.VD_AGENT_PROTOCOL;
this.type = type; this.type = type;
this.opaque = 0; this.opaque = 0;
this.size = data.buffer_size(); this.size = data.buffer_size();
@ -932,13 +952,11 @@ function SpiceMsgcMousePosition(sc, e)
this.buttons_state = sc.buttons_state; this.buttons_state = sc.buttons_state;
if (e) if (e)
{ {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; this.x = e.offsetX;
var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft; this.y = e.offsetY;
this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft + scrollLeft; sc.mousex = e.offsetX;
this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop + scrollTop; sc.mousey = e.offsetY;
sc.mousex = this.x;
sc.mousey = this.y;
} }
else else
{ {
@ -971,16 +989,16 @@ function SpiceMsgcMouseMotion(sc, e)
this.buttons_state = sc.buttons_state; this.buttons_state = sc.buttons_state;
if (e) if (e)
{ {
this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft; this.x = e.offsetX;
this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop; this.y = e.offsetY;
if (sc.mousex !== undefined) if (sc.mousex !== undefined)
{ {
this.x -= sc.mousex; this.x -= sc.mousex;
this.y -= sc.mousey; this.y -= sc.mousey;
} }
sc.mousex = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft; sc.mousex = e.offsetX;
sc.mousey = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop; sc.mousey = e.offsetY;
} }
else else
{ {
@ -1002,8 +1020,8 @@ function SpiceMsgcMousePress(sc, e)
} }
else else
{ {
this.button = SPICE_MOUSE_BUTTON_LEFT; this.button = Constants.SPICE_MOUSE_BUTTON_LEFT;
this.buttons_state = SPICE_MOUSE_BUTTON_MASK_LEFT; this.buttons_state = Constants.SPICE_MOUSE_BUTTON_MASK_LEFT;
} }
} }
@ -1033,7 +1051,7 @@ function SpiceMsgcMouseRelease(sc, e)
} }
else else
{ {
this.button = SPICE_MOUSE_BUTTON_LEFT; this.button = Constants.SPICE_MOUSE_BUTTON_LEFT;
this.buttons_state = 0; this.buttons_state = 0;
} }
} }
@ -1296,3 +1314,58 @@ SpiceMsgPortInit.prototype =
this.name = a.slice(offset, offset + namesize - 1); 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. ** to and from the server.
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
import { Constants } from './enums.js';
import { SpiceQuic } from './quic.js';
function SpiceChannelId() function SpiceChannelId()
{ {
} }
@ -92,7 +95,7 @@ SpiceClip.prototype =
from_dv: function(dv, at, mb) from_dv: function(dv, at, mb)
{ {
this.type = dv.getUint8(at, true); at ++; 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(); this.rects = new SpiceClipRects();
at = this.rects.from_dv(dv, at, mb); at = this.rects.from_dv(dv, at, mb);
@ -151,7 +154,7 @@ SpiceBitmap.prototype =
this.x = dv.getUint32(at, true); at += 4; this.x = dv.getUint32(at, true); at += 4;
this.y = dv.getUint32(at, true); at += 4; this.y = dv.getUint32(at, true); at += 4;
this.stride = 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; this.palette_id = dv.getUint64(at, true); at += 8;
} }
@ -185,7 +188,7 @@ SpiceImage.prototype =
this.descriptor = new SpiceImageDescriptor; this.descriptor = new SpiceImageDescriptor;
at = this.descriptor.from_dv(dv, at, mb); 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 = new Object();
this.lz_rgb.length = dv.getUint32(at, true); at += 4; 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; this.bitmap = new SpiceBitmap;
at = this.bitmap.from_dv(dv, at, mb); 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; 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 = new Object;
this.jpeg.data_size = dv.getUint32(at, true); at += 4; this.jpeg.data_size = dv.getUint32(at, true); at += 4;
@ -229,7 +232,7 @@ SpiceImage.prototype =
at += this.jpeg.data.byteLength; 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 = new Object;
this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1; this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1;
@ -260,7 +263,7 @@ SpiceImage.prototype =
at += this.jpeg_alpha.alpha.data.byteLength; 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; this.quic = new SpiceQuic;
at = this.quic.from_dv(dv, at, mb); at = this.quic.from_dv(dv, at, mb);
@ -327,11 +330,11 @@ SpiceBrush.prototype =
from_dv: function(dv, at, mb) from_dv: function(dv, at, mb)
{ {
this.type = dv.getUint8(at, true); at ++; 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; 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; this.pattern = new SpicePattern;
at = this.pattern.from_dv(dv, at, mb); at = this.pattern.from_dv(dv, at, mb);
@ -439,7 +442,7 @@ SpiceCursor.prototype =
from_dv: function(dv, at, mb) from_dv: function(dv, at, mb)
{ {
this.flags = dv.getUint16(at, true); at += 2; 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; this.header = null;
else else
{ {
@ -471,3 +474,24 @@ SpiceSurface.prototype =
/* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are /* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are
completely unimplemented */ 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" // "constants"
BigInteger.ZERO = nbv(0); BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1); 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. // 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() // An array of bytes the size of the pool will be passed to init()
var rng_psize = 256; 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 // 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 // For best results, put code like
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> // <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
@ -100,3 +101,7 @@ function rng_get_bytes(ba) {
function SecureRandom() {} function SecureRandom() {}
SecureRandom.prototype.nextBytes = rng_get_bytes; 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 // 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 * Copyright (c) 2003-2005 Tom Wu
@ -33,6 +34,8 @@
// Depends on jsbn.js and rng.js // 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 // Version 1.1: support utf-8 encoding in pkcs1pad2
@ -144,3 +147,7 @@ RSAKey.prototype.doPublic = RSADoPublic;
RSAKey.prototype.setPublic = RSASetPublic; RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt; RSAKey.prototype.encrypt = RSAEncrypt;
//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; //RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
export {
RSAKey,
};

View file

@ -344,3 +344,8 @@ function bit_rol(num, cnt)
{ {
return (num << cnt) | (num >>> (32 - 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/>. 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; var SHA_DIGEST_LENGTH = 20;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -248,3 +253,8 @@ function rsa_encrypt(rsa, str)
ret[i / 2] = parseInt(h.substring(i, i + 2), 16); ret[i / 2] = parseInt(h.substring(i, i + 2), 16);
return ret; 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/>. along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { KeyNames } from './atKeynames.js';
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
** Utility settings and functions for Spice ** Utility settings and functions for Spice
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
@ -112,129 +114,142 @@ function arraybuffer_to_str(buf) {
} }
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
** Converting keycodes to AT scancodes is very hard. ** Converting browser keycodes to AT scancodes is very hard.
** luckly there are some resources on the web and in the Xorg driver that help ** Spice transmits keys using the original AT scan codes, often
** us figure out what browser dependent keycodes match to what scancodes. ** described as 'Scan Code Set 1'.
** ** There is a confusion of other scan codes; Xorg synthesizes it's
** This will most likely not work for non US keyboard and browsers other than ** own in the same atKeynames.c file that has the XT codes.
** modern Chrome and FireFox. ** 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 = []; 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 */ /* The following appear to be keycodes that work in most browsers */
common_scanmap[42] = 99; common_scanmap['1'.charCodeAt(0)] = KeyNames.KEY_1;
common_scanmap[19] = 101; // Break common_scanmap['2'.charCodeAt(0)] = KeyNames.KEY_2;
common_scanmap[111] = 0xE035; // KP_Divide common_scanmap['3'.charCodeAt(0)] = KeyNames.KEY_3;
common_scanmap[106] = 0xE037; // KP_Multiply common_scanmap['4'.charCodeAt(0)] = KeyNames.KEY_4;
common_scanmap[36] = 0xE047; // Home common_scanmap['5'.charCodeAt(0)] = KeyNames.KEY_5;
common_scanmap[38] = 0xE048; // Up common_scanmap['6'.charCodeAt(0)] = KeyNames.KEY_6;
common_scanmap[33] = 0xE049; // PgUp common_scanmap['7'.charCodeAt(0)] = KeyNames.KEY_7;
common_scanmap[37] = 0xE04B; // Left common_scanmap['8'.charCodeAt(0)] = KeyNames.KEY_8;
common_scanmap[39] = 0xE04D; // Right common_scanmap['9'.charCodeAt(0)] = KeyNames.KEY_9;
common_scanmap[35] = 0xE04F; // End common_scanmap['0'.charCodeAt(0)] = KeyNames.KEY_0;
common_scanmap[40] = 0xE050; // Down common_scanmap[145] = KeyNames.KEY_ScrollLock;
common_scanmap[34] = 0xE051; // PgDown common_scanmap[103] = KeyNames.KEY_KP_7;
common_scanmap[45] = 0xE052; // Insert common_scanmap[104] = KeyNames.KEY_KP_8;
common_scanmap[46] = 0xE053; // Delete common_scanmap[105] = KeyNames.KEY_KP_9;
common_scanmap[44] = 0x2A37; // Print 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['Q'.charCodeAt(0)] = KeyNames.KEY_Q;
common_scanmap['1'.charCodeAt(0)] = KEY_1; common_scanmap['W'.charCodeAt(0)] = KeyNames.KEY_W;
common_scanmap['2'.charCodeAt(0)] = KEY_2; common_scanmap['E'.charCodeAt(0)] = KeyNames.KEY_E;
common_scanmap['3'.charCodeAt(0)] = KEY_3; common_scanmap['R'.charCodeAt(0)] = KeyNames.KEY_R;
common_scanmap['4'.charCodeAt(0)] = KEY_4; common_scanmap['T'.charCodeAt(0)] = KeyNames.KEY_T;
common_scanmap['5'.charCodeAt(0)] = KEY_5; common_scanmap['Y'.charCodeAt(0)] = KeyNames.KEY_Y;
common_scanmap['6'.charCodeAt(0)] = KEY_6; common_scanmap['U'.charCodeAt(0)] = KeyNames.KEY_U;
common_scanmap['7'.charCodeAt(0)] = KEY_7; common_scanmap['I'.charCodeAt(0)] = KeyNames.KEY_I;
common_scanmap['8'.charCodeAt(0)] = KEY_8; common_scanmap['O'.charCodeAt(0)] = KeyNames.KEY_O;
common_scanmap['9'.charCodeAt(0)] = KEY_9; common_scanmap['P'.charCodeAt(0)] = KeyNames.KEY_P;
common_scanmap['0'.charCodeAt(0)] = KEY_0; common_scanmap['A'.charCodeAt(0)] = KeyNames.KEY_A;
common_scanmap[145] = KEY_ScrollLock; common_scanmap['S'.charCodeAt(0)] = KeyNames.KEY_S;
common_scanmap[103] = KEY_KP_7; common_scanmap['D'.charCodeAt(0)] = KeyNames.KEY_D;
common_scanmap[104] = KEY_KP_8; common_scanmap['F'.charCodeAt(0)] = KeyNames.KEY_F;
common_scanmap[105] = KEY_KP_9; common_scanmap['G'.charCodeAt(0)] = KeyNames.KEY_G;
common_scanmap[100] = KEY_KP_4; common_scanmap['H'.charCodeAt(0)] = KeyNames.KEY_H;
common_scanmap[101] = KEY_KP_5; common_scanmap['J'.charCodeAt(0)] = KeyNames.KEY_J;
common_scanmap[102] = KEY_KP_6; common_scanmap['K'.charCodeAt(0)] = KeyNames.KEY_K;
common_scanmap[107] = KEY_KP_Plus; common_scanmap['L'.charCodeAt(0)] = KeyNames.KEY_L;
common_scanmap[97] = KEY_KP_1; common_scanmap['Z'.charCodeAt(0)] = KeyNames.KEY_Z;
common_scanmap[98] = KEY_KP_2; common_scanmap['X'.charCodeAt(0)] = KeyNames.KEY_X;
common_scanmap[99] = KEY_KP_3; common_scanmap['C'.charCodeAt(0)] = KeyNames.KEY_C;
common_scanmap[96] = KEY_KP_0; common_scanmap['V'.charCodeAt(0)] = KeyNames.KEY_V;
common_scanmap[110] = KEY_KP_Decimal; common_scanmap['B'.charCodeAt(0)] = KeyNames.KEY_B;
common_scanmap[191] = KEY_Slash; common_scanmap['N'.charCodeAt(0)] = KeyNames.KEY_N;
common_scanmap[190] = KEY_Period; common_scanmap['M'.charCodeAt(0)] = KeyNames.KEY_M;
common_scanmap[188] = KEY_Comma; common_scanmap[' '.charCodeAt(0)] = KeyNames.KEY_Space;
common_scanmap[220] = KEY_BSlash; common_scanmap[13] = KeyNames.KEY_Enter;
common_scanmap[192] = KEY_Tilde; common_scanmap[27] = KeyNames.KEY_Escape;
common_scanmap[222] = KEY_Quote; common_scanmap[8] = KeyNames.KEY_BackSpace;
common_scanmap[219] = KEY_LBrace; common_scanmap[9] = KeyNames.KEY_Tab;
common_scanmap[221] = KEY_RBrace; 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 /* TODO: Break and Print are complex scan codes. XSpice cheats and
common_scanmap[92] = 0xE05C; //KEY_RMeta uses Xorg synthesized codes to simplify them. Fixing this will
common_scanmap[93] = 0xE05D; //KEY_Menu 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 */ /* Firefox/Mozilla codes */
var firefox_scanmap = []; var firefox_scanmap = [];
firefox_scanmap[173] = KEY_Minus; firefox_scanmap[173] = KeyNames.KEY_Minus;
firefox_scanmap[109] = KEY_Minus; firefox_scanmap[61] = KeyNames.KEY_Equal;
firefox_scanmap[61] = KEY_Equal; firefox_scanmap[59] = KeyNames.KEY_SemiColon;
firefox_scanmap[59] = KEY_SemiColon;
/* DOM3 codes */ /* DOM3 codes */
var DOM_scanmap = []; var DOM_scanmap = [];
DOM_scanmap[189] = KEY_Minus; DOM_scanmap[189] = KeyNames.KEY_Minus;
DOM_scanmap[187] = KEY_Equal; DOM_scanmap[187] = KeyNames.KEY_Equal;
DOM_scanmap[186] = KEY_SemiColon; DOM_scanmap[186] = KeyNames.KEY_SemiColon;
function get_scancode(code) function get_scancode(code)
{ {
@ -258,11 +273,7 @@ function keycode_to_start_scan(code)
return 0; return 0;
} }
if (scancode < 0x100) {
return scancode; return scancode;
} else {
return 0xe0 | ((scancode - 0x100) << 8);
}
} }
function keycode_to_end_scan(code) function keycode_to_end_scan(code)
@ -274,7 +285,7 @@ function keycode_to_end_scan(code)
if (scancode < 0x100) { if (scancode < 0x100) {
return scancode | 0x80; return scancode | 0x80;
} else { } else {
return 0x80e0 | ((scancode - 0x100) << 8); return scancode | 0x8000;
} }
} }
@ -330,3 +341,20 @@ function dump_timerange(tr)
return ret; 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 ** Various OPUS / Webm constants
**--------------------------------------------------------------------------*/ **--------------------------------------------------------------------------*/
var CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME = 1 << 7; var Constants = {
CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 1 << 7,
var OPUS_FREQUENCY = 48000; OPUS_FREQUENCY : 48000,
var OPUS_CHANNELS = 2; OPUS_CHANNELS : 2,
var SPICE_PLAYBACK_CODEC = 'audio/webm; codecs="opus"'; SPICE_PLAYBACK_CODEC : 'audio/webm; codecs="opus"',
var MAX_CLUSTER_TIME = 1000; MAX_CLUSTER_TIME : 1000,
var EXPECTED_PACKET_DURATION = 10; EXPECTED_PACKET_DURATION : 10,
var GAP_DETECTION_THRESHOLD = 50; GAP_DETECTION_THRESHOLD : 50,
var SPICE_VP8_CODEC = 'video/webm; codecs="vp8"'; SPICE_VP8_CODEC : 'video/webm; codecs="vp8"',
};
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
** EBML utility functions ** EBML utility functions
@ -275,7 +277,7 @@ function webm_Audio(frequency)
{ {
this.id = WEBM_AUDIO; this.id = WEBM_AUDIO;
this.sampling_frequency = frequency; this.sampling_frequency = frequency;
this.channels = OPUS_CHANNELS; this.channels = Constants.OPUS_CHANNELS;
} }
webm_Audio.prototype = webm_Audio.prototype =
@ -407,12 +409,12 @@ function webm_AudioTrackEntry()
this.seek_pre_roll = 0; // 80000000; // fixme - check this.seek_pre_roll = 0; // 80000000; // fixme - check
this.codec_delay = 80000000; // Must match codec_private.preskip this.codec_delay = 80000000; // Must match codec_private.preskip
this.codec_id = "A_OPUS"; 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 // See: http://tools.ietf.org/html/draft-terriberry-oggopus-01
this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead
0x01, // Version 0x01, // Version
OPUS_CHANNELS, Constants.OPUS_CHANNELS,
0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at 48kHz 0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at 48kHz
0x80, 0xbb, 0x00, 0x00, // 48000 0x80, 0xbb, 0x00, 0x00, // 48000
0x00, 0x00, // Output gain 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_u64_data_len(this.data.byteLength + 4, dv, at);
at = EBML_write_u1_data_len(1, dv, at); // Track # at = EBML_write_u1_data_len(1, dv, at); // Track #
dv.setUint16(at, this.timecode); at += 2; // timecode - relative to cluster 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 // FIXME - There should be a better way to copy
var u8 = new Uint8Array(this.data); var u8 = new Uint8Array(this.data);
@ -645,3 +647,15 @@ webm_Header.prototype =
this.info.buffer_size(); 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 ** callback. It will optionally save and pass along a header, useful in processing
** the mini message format. ** the mini message format.
**--------------------------------------------------------------------------------------*/ **--------------------------------------------------------------------------------------*/
import { DEBUG } from './utils.js';
import { combine_array_buffers } from './utils.js';
function SpiceWireReader(sc, callback) function SpiceWireReader(sc, callback)
{ {
this.sc = sc; 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); 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); 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.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.utils.translation import ugettext_lazy as _ 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 django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from storages.forms import AddStgPool, AddImage, CloneImage 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): cache_mode=None, io_mode=None, discard_mode=None, detect_zeroes_mode=None):
additionals = '' 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 additionals += "cache='%s' " % cache_mode
if io_mode is not None and io_mode != 'default': if io_mode is not None and io_mode != 'default':
additionals += "io='%s' " % io_mode 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 += "<driver name='%s' type='%s' %s/>" % (driver_name, driver_type, additionals)
xml_disk += """<source file='%s'/> xml_disk += """<source file='%s'/>
<target dev='%s' bus='%s'/>""" % (source, target_dev, target_bus) <target dev='%s' bus='%s'/>""" % (source, target_dev, target_bus)
if readonly: if readonly or disk_device == 'cdrom':
xml_disk += """<readonly/>""" xml_disk += """<readonly/>"""
if shareable: if shareable:
xml_disk += """<shareable/>""" xml_disk += """<shareable/>"""

View file

@ -12,8 +12,6 @@ urlpatterns = [
url(r'^computes/', include('computes.urls')), url(r'^computes/', include('computes.urls')),
url(r'^logs/', include('logs.urls')), url(r'^logs/', include('logs.urls')),
url(r'^datasource/', include('datasource.urls')), url(r'^datasource/', include('datasource.urls')),
url(r'^console/$', console, name='console'), 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``. It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see 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 import os