systemvm: update novnc v1.2.0 (#4323)
Update noVNC v1.2.0, add support for clipboard, explicit button toolbar and resize screensize
@ -484,7 +484,7 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||||||
if (param.getHypervHost() != null || !ConsoleProxyManager.NoVncConsoleDefault.value()) {
|
if (param.getHypervHost() != null || !ConsoleProxyManager.NoVncConsoleDefault.value()) {
|
||||||
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
||||||
} else {
|
} else {
|
||||||
sb.append("/resource/noVNC/vnc_lite.html?port=" + ConsoleProxyManager.DEFAULT_NOVNC_PORT + "&token="
|
sb.append("/resource/noVNC/vnc.html?port=" + ConsoleProxyManager.DEFAULT_NOVNC_PORT + "&token="
|
||||||
+ encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
+ encryptor.encryptObject(ConsoleProxyClientParam.class, param));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
**/xtscancodes.js
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"es6": true
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"rules": {
|
|
||||||
// Unsafe or confusing stuff that we forbid
|
|
||||||
|
|
||||||
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }],
|
|
||||||
"no-constant-condition": ["error", { "checkLoops": false }],
|
|
||||||
"no-var": "error",
|
|
||||||
"no-useless-constructor": "error",
|
|
||||||
"object-shorthand": ["error", "methods", { "avoidQuotes": true }],
|
|
||||||
"prefer-arrow-callback": "error",
|
|
||||||
"arrow-body-style": ["error", "as-needed", { "requireReturnForObjectLiteral": false } ],
|
|
||||||
"arrow-parens": ["error", "as-needed", { "requireForBlockBody": true }],
|
|
||||||
"arrow-spacing": ["error"],
|
|
||||||
"no-confusing-arrow": ["error", { "allowParens": true }],
|
|
||||||
|
|
||||||
// Enforced coding style
|
|
||||||
|
|
||||||
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
|
||||||
"indent": ["error", 4, { "SwitchCase": 1,
|
|
||||||
"CallExpression": { "arguments": "first" },
|
|
||||||
"ArrayExpression": "first",
|
|
||||||
"ObjectExpression": "first",
|
|
||||||
"ignoreComments": true }],
|
|
||||||
"comma-spacing": ["error"],
|
|
||||||
"comma-style": ["error"],
|
|
||||||
"curly": ["error", "multi-line"],
|
|
||||||
"func-call-spacing": ["error"],
|
|
||||||
"func-names": ["error"],
|
|
||||||
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
|
||||||
"key-spacing": ["error"],
|
|
||||||
"keyword-spacing": ["error"],
|
|
||||||
"no-trailing-spaces": ["error"],
|
|
||||||
"semi": ["error"],
|
|
||||||
"space-before-blocks": ["error"],
|
|
||||||
"space-before-function-paren": ["error", { "anonymous": "always",
|
|
||||||
"named": "never",
|
|
||||||
"asyncArrow": "always" }],
|
|
||||||
"switch-colon-spacing": ["error"],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**Client (please complete the following information):**
|
|
||||||
- OS: [e.g. iOS]
|
|
||||||
- Browser: [e.g. chrome, safari]
|
|
||||||
- Browser version: [e.g. 22]
|
|
||||||
|
|
||||||
**Server (please complete the following information):**
|
|
||||||
- noVNC version: [e.g. 1.0.0 or git commit id]
|
|
||||||
- VNC server: [e.g. QEMU, TigerVNC]
|
|
||||||
- WebSocket proxy: [e.g. websockify]
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
12
systemvm/agent/noVNC/.gitignore
vendored
@ -1,12 +0,0 @@
|
|||||||
*.pyc
|
|
||||||
*.o
|
|
||||||
tests/data_*.js
|
|
||||||
utils/rebind.so
|
|
||||||
utils/websockify
|
|
||||||
/node_modules
|
|
||||||
/build
|
|
||||||
/lib
|
|
||||||
recordings
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
noVNC-*.tgz
|
|
||||||
0
systemvm/agent/noVNC/.gitmodules
vendored
@ -1,58 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
sudo: false
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- node_modules
|
|
||||||
node_js:
|
|
||||||
- 6
|
|
||||||
env:
|
|
||||||
matrix:
|
|
||||||
- TEST_BROWSER_NAME=chrome TEST_BROWSER_OS='Windows 10'
|
|
||||||
# FIXME Skip tests in Linux since Sauce Labs browser versions are ancient.
|
|
||||||
# - TEST_BROWSER_NAME=chrome TEST_BROWSER_OS='Linux'
|
|
||||||
- TEST_BROWSER_NAME=chrome TEST_BROWSER_OS='OS X 10.11'
|
|
||||||
- TEST_BROWSER_NAME=firefox TEST_BROWSER_OS='Windows 10'
|
|
||||||
# - TEST_BROWSER_NAME=firefox TEST_BROWSER_OS='Linux'
|
|
||||||
- TEST_BROWSER_NAME=firefox TEST_BROWSER_OS='OS X 10.11'
|
|
||||||
- TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 10'
|
|
||||||
- TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 7'
|
|
||||||
- TEST_BROWSER_NAME=microsoftedge TEST_BROWSER_OS='Windows 10'
|
|
||||||
- TEST_BROWSER_NAME=safari TEST_BROWSER_OS='OS X 10.13'
|
|
||||||
before_script: npm install -g karma-cli
|
|
||||||
addons:
|
|
||||||
sauce_connect:
|
|
||||||
username: "directxman12"
|
|
||||||
jwt:
|
|
||||||
secure: "d3ekMYslpn6R4f0ajtRMt9SUFmNGDiItHpqaXC5T4KI0KMEsxgvEOfJot5PiFFJWg1DSpJZH6oaW2UxGZ3duJLZrXIEd/JePY8a6NtT35BNgiDPgcp+eu2Bu3rhrSNg7/HEsD1ma+JeUTnv18Ai5oMFfCCQJx2J6osIxyl/ZVxA="
|
|
||||||
stages:
|
|
||||||
- lint
|
|
||||||
- test
|
|
||||||
- name: deploy
|
|
||||||
if: tag is PRESENT
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
- stage: lint
|
|
||||||
env:
|
|
||||||
addons:
|
|
||||||
before_script:
|
|
||||||
script: npm run lint
|
|
||||||
-
|
|
||||||
env:
|
|
||||||
addons:
|
|
||||||
before_script:
|
|
||||||
script: git ls-tree --name-only -r HEAD | grep -E "[.](html|css)$" | xargs ./utils/validate
|
|
||||||
- stage: deploy
|
|
||||||
env:
|
|
||||||
addons:
|
|
||||||
script: skip
|
|
||||||
before_script: skip
|
|
||||||
deploy:
|
|
||||||
provider: npm
|
|
||||||
email: ossman@cendio.se
|
|
||||||
api_key:
|
|
||||||
secure: "Qq2Mi9xQawO2zlAigzshzMu2QMHvu1IaN9l0ZIivE99wHJj7eS5f4miJ9wB+/mWRRgb3E8uj9ZRV24+Oc36drlBTU9sz+lHhH0uFMfAIseceK64wZV9sLAZm472fmPp2xdUeTCCqPaRy7g1XBqiJ0LyZvEFLsRijqcLjPBF+b8w="
|
|
||||||
on:
|
|
||||||
tags: true
|
|
||||||
repo: novnc/noVNC
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
maintainers:
|
|
||||||
- Joel Martin (@kanaka)
|
|
||||||
- Solly Ross (@directxman12)
|
|
||||||
- Samuel Mannehed for Cendio AB (@samhed)
|
|
||||||
- Pierre Ossman for Cendio AB (@CendioOssman)
|
|
||||||
maintainersEmeritus:
|
|
||||||
- @astrand
|
|
||||||
contributors:
|
|
||||||
# There are a bunch of people that should be here.
|
|
||||||
# If you want to be on this list, feel free send a PR
|
|
||||||
# to add yourself.
|
|
||||||
- jalf <git@jalf.dk>
|
|
||||||
- NTT corp.
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
noVNC is Copyright (C) 2018 The noVNC Authors
|
|
||||||
(./AUTHORS)
|
|
||||||
|
|
||||||
The noVNC core library files are licensed under the MPL 2.0 (Mozilla
|
|
||||||
Public License 2.0). The noVNC core library is composed of the
|
|
||||||
Javascript code necessary for full noVNC operation. This includes (but
|
|
||||||
is not limited to):
|
|
||||||
|
|
||||||
core/**/*.js
|
|
||||||
app/*.js
|
|
||||||
test/playback.js
|
|
||||||
|
|
||||||
The HTML, CSS, font and images files that included with the noVNC
|
|
||||||
source distibution (or repository) are not considered part of the
|
|
||||||
noVNC core library and are licensed under more permissive licenses.
|
|
||||||
The intent is to allow easy integration of noVNC into existing web
|
|
||||||
sites and web applications.
|
|
||||||
|
|
||||||
The HTML, CSS, font and image files are licensed as follows:
|
|
||||||
|
|
||||||
*.html : 2-Clause BSD license
|
|
||||||
|
|
||||||
app/styles/*.css : 2-Clause BSD license
|
|
||||||
|
|
||||||
app/styles/Orbitron* : SIL Open Font License 1.1
|
|
||||||
(Copyright 2009 Matt McInerney)
|
|
||||||
|
|
||||||
app/images/ : Creative Commons Attribution-ShareAlike
|
|
||||||
http://creativecommons.org/licenses/by-sa/3.0/
|
|
||||||
|
|
||||||
Some portions of noVNC are copyright to their individual authors.
|
|
||||||
Please refer to the individual source files and/or to the noVNC commit
|
|
||||||
history: https://github.com/novnc/noVNC/commits/master
|
|
||||||
|
|
||||||
The are several files and projects that have been incorporated into
|
|
||||||
the noVNC core library. Here is a list of those files and the original
|
|
||||||
licenses (all MPL 2.0 compatible):
|
|
||||||
|
|
||||||
core/base64.js : MPL 2.0
|
|
||||||
|
|
||||||
core/des.js : Various BSD style licenses
|
|
||||||
|
|
||||||
vendor/pako/ : MIT
|
|
||||||
|
|
||||||
vendor/browser-es-module-loader/src/ : MIT
|
|
||||||
|
|
||||||
vendor/browser-es-module-loader/dist/ : Various BSD style licenses
|
|
||||||
|
|
||||||
vendor/promise.js : MIT
|
|
||||||
|
|
||||||
Any other files not mentioned above are typically marked with
|
|
||||||
a copyright/license header at the top of the file. The default noVNC
|
|
||||||
license is MPL-2.0.
|
|
||||||
|
|
||||||
The following license texts are included:
|
|
||||||
|
|
||||||
docs/LICENSE.MPL-2.0
|
|
||||||
docs/LICENSE.OFL-1.1
|
|
||||||
docs/LICENSE.BSD-3-Clause (New BSD)
|
|
||||||
docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD)
|
|
||||||
vendor/pako/LICENSE (MIT)
|
|
||||||
|
|
||||||
Or alternatively the license texts may be found here:
|
|
||||||
|
|
||||||
http://www.mozilla.org/MPL/2.0/
|
|
||||||
http://scripts.sil.org/OFL
|
|
||||||
http://en.wikipedia.org/wiki/BSD_licenses
|
|
||||||
https://opensource.org/licenses/MIT
|
|
||||||
@ -1,152 +0,0 @@
|
|||||||
## noVNC: HTML VNC Client Library and Application
|
|
||||||
|
|
||||||
[](https://travis-ci.org/novnc/noVNC)
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
noVNC is both a HTML VNC client JavaScript library and an application built on
|
|
||||||
top of that library. noVNC runs well in any modern browser including mobile
|
|
||||||
browsers (iOS and Android).
|
|
||||||
|
|
||||||
Many companies, projects and products have integrated noVNC including
|
|
||||||
[OpenStack](http://www.openstack.org),
|
|
||||||
[OpenNebula](http://opennebula.org/),
|
|
||||||
[LibVNCServer](http://libvncserver.sourceforge.net), and
|
|
||||||
[ThinLinc](https://cendio.com/thinlinc). See
|
|
||||||
[the Projects and Companies wiki page](https://github.com/novnc/noVNC/wiki/Projects-and-companies-using-noVNC)
|
|
||||||
for a more complete list with additional info and links.
|
|
||||||
|
|
||||||
### Table of Contents
|
|
||||||
|
|
||||||
- [News/help/contact](#newshelpcontact)
|
|
||||||
- [Features](#features)
|
|
||||||
- [Screenshots](#screenshots)
|
|
||||||
- [Browser Requirements](#browser-requirements)
|
|
||||||
- [Server Requirements](#server-requirements)
|
|
||||||
- [Quick Start](#quick-start)
|
|
||||||
- [Integration and Deployment](#integration-and-deployment)
|
|
||||||
- [Authors/Contributors](#authorscontributors)
|
|
||||||
|
|
||||||
### News/help/contact
|
|
||||||
|
|
||||||
The project website is found at [novnc.com](http://novnc.com).
|
|
||||||
Notable commits, announcements and news are posted to
|
|
||||||
[@noVNC](http://www.twitter.com/noVNC).
|
|
||||||
|
|
||||||
If you are a noVNC developer/integrator/user (or want to be) please join the
|
|
||||||
[noVNC discussion group](https://groups.google.com/forum/?fromgroups#!forum/novnc).
|
|
||||||
|
|
||||||
Bugs and feature requests can be submitted via
|
|
||||||
[github issues](https://github.com/novnc/noVNC/issues). If you have questions
|
|
||||||
about using noVNC then please first use the
|
|
||||||
[discussion group](https://groups.google.com/forum/?fromgroups#!forum/novnc).
|
|
||||||
We also have a [wiki](https://github.com/novnc/noVNC/wiki/) with lots of
|
|
||||||
helpful information.
|
|
||||||
|
|
||||||
If you are looking for a place to start contributing to noVNC, a good place to
|
|
||||||
start would be the issues that are marked as
|
|
||||||
["patchwelcome"](https://github.com/novnc/noVNC/issues?labels=patchwelcome).
|
|
||||||
Please check our
|
|
||||||
[contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) though.
|
|
||||||
|
|
||||||
If you want to show appreciation for noVNC you could donate to a great non-
|
|
||||||
profits such as:
|
|
||||||
[Compassion International](http://www.compassion.com/),
|
|
||||||
[SIL](http://www.sil.org),
|
|
||||||
[Habitat for Humanity](http://www.habitat.org),
|
|
||||||
[Electronic Frontier Foundation](https://www.eff.org/),
|
|
||||||
[Against Malaria Foundation](http://www.againstmalaria.com/),
|
|
||||||
[Nothing But Nets](http://www.nothingbutnets.net/), etc.
|
|
||||||
Please tweet [@noVNC](http://www.twitter.com/noVNC) if you do.
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* Supports all modern browsers including mobile (iOS, Android)
|
|
||||||
* Supported VNC encodings: raw, copyrect, rre, hextile, tight, tightPNG
|
|
||||||
* Supports scaling, clipping and resizing the desktop
|
|
||||||
* Local cursor rendering
|
|
||||||
* Clipboard copy/paste
|
|
||||||
* Translations
|
|
||||||
* Licensed mainly under the [MPL 2.0](http://www.mozilla.org/MPL/2.0/), see
|
|
||||||
[the license document](LICENSE.txt) for details
|
|
||||||
|
|
||||||
### Screenshots
|
|
||||||
|
|
||||||
Running in Firefox before and after connecting:
|
|
||||||
|
|
||||||
<img src="http://novnc.com/img/noVNC-1-login.png" width=400>
|
|
||||||
<img src="http://novnc.com/img/noVNC-3-connected.png" width=400>
|
|
||||||
|
|
||||||
See more screenshots
|
|
||||||
[here](http://novnc.com/screenshots.html).
|
|
||||||
|
|
||||||
|
|
||||||
### Browser Requirements
|
|
||||||
|
|
||||||
noVNC uses many modern web technologies so a formal requirement list is
|
|
||||||
not available. However these are the minimum versions we are currently
|
|
||||||
aware of:
|
|
||||||
|
|
||||||
* Chrome 49, Firefox 44, Safari 10, Opera 36, IE 11, Edge 12
|
|
||||||
|
|
||||||
|
|
||||||
### Server Requirements
|
|
||||||
|
|
||||||
noVNC follows the standard VNC protocol, but unlike other VNC clients it does
|
|
||||||
require WebSockets support. Many servers include support (e.g.
|
|
||||||
[x11vnc/libvncserver](http://libvncserver.sourceforge.net/),
|
|
||||||
[QEMU](http://www.qemu.org/), and
|
|
||||||
[MobileVNC](http://www.smartlab.at/mobilevnc/)), but for the others you need to
|
|
||||||
use a WebSockets to TCP socket proxy. noVNC has a sister project
|
|
||||||
[websockify](https://github.com/novnc/websockify) that provides a simple such
|
|
||||||
proxy.
|
|
||||||
|
|
||||||
|
|
||||||
### Quick Start
|
|
||||||
|
|
||||||
* Use the launch script to automatically download and start websockify, which
|
|
||||||
includes a mini-webserver and the WebSockets proxy. The `--vnc` option is
|
|
||||||
used to specify the location of a running VNC server:
|
|
||||||
|
|
||||||
`./utils/launch.sh --vnc localhost:5901`
|
|
||||||
|
|
||||||
* Point your browser to the cut-and-paste URL that is output by the launch
|
|
||||||
script. Hit the Connect button, enter a password if the VNC server has one
|
|
||||||
configured, and enjoy!
|
|
||||||
|
|
||||||
|
|
||||||
### Integration and Deployment
|
|
||||||
|
|
||||||
Please see our other documents for how to integrate noVNC in your own software,
|
|
||||||
or deploying the noVNC application in production environments:
|
|
||||||
|
|
||||||
* [Embedding](docs/EMBEDDING.md) - For the noVNC application
|
|
||||||
* [Library](docs/LIBRARY.md) - For the noVNC JavaScript library
|
|
||||||
|
|
||||||
|
|
||||||
### Authors/Contributors
|
|
||||||
|
|
||||||
See [AUTHORS](AUTHORS) for a (full-ish) list of authors. If you're not on
|
|
||||||
that list and you think you should be, feel free to send a PR to fix that.
|
|
||||||
|
|
||||||
* Core team:
|
|
||||||
* [Joel Martin](https://github.com/kanaka)
|
|
||||||
* [Samuel Mannehed](https://github.com/samhed) (Cendio)
|
|
||||||
* [Peter Åstrand](https://github.com/astrand) (Cendio)
|
|
||||||
* [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack)
|
|
||||||
* [Pierre Ossman](https://github.com/CendioOssman) (Cendio)
|
|
||||||
|
|
||||||
* Notable contributions:
|
|
||||||
* UI and Icons : Pierre Ossman, Chris Gordon
|
|
||||||
* Original Logo : Michael Sersen
|
|
||||||
* tight encoding : Michael Tinglof (Mercuri.ca)
|
|
||||||
|
|
||||||
* Included libraries:
|
|
||||||
* base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net)
|
|
||||||
* DES : Dave Zimmerman (Widget Workshop), Jef Poskanzer (ACME Labs)
|
|
||||||
* Pako : Vitaly Puzrin (https://github.com/nodeca/pako)
|
|
||||||
|
|
||||||
Do you want to be on this list? Check out our
|
|
||||||
[contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) and
|
|
||||||
start hacking!
|
|
||||||
@ -1 +0,0 @@
|
|||||||
1.1.0
|
|
||||||
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
// NB: this should *not* be included as a module until we have
|
// NB: this should *not* be included as a module until we have
|
||||||
// native support in the browsers, so that our error handler
|
// native support in the browsers, so that our error handler
|
||||||
// can catch script-loading errors.
|
// can catch script-loading errors.
|
||||||
|
|||||||
BIN
systemvm/agent/noVNC/app/images/alt.png
Normal file
|
After Width: | Height: | Size: 335 B |
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="alt.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="18.205425"
|
|
||||||
inkscape:cy="17.531398"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<g
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
id="text5290">
|
|
||||||
<path
|
|
||||||
d="m 9.9560547,1042.3329 -2.9394531,0 -0.4638672,1.3281 -1.8896485,0 2.7001953,-7.29 2.241211,0 2.7001958,7.29 -1.889649,0 -0.4589843,-1.3281 z m -2.4707031,-1.3526 1.9970703,0 -0.9960938,-2.9003 -1.0009765,2.9003 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5340" />
|
|
||||||
<path
|
|
||||||
d="m 13.188477,1036.0634 1.748046,0 0,7.5976 -1.748046,0 0,-7.5976 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5342" />
|
|
||||||
<path
|
|
||||||
d="m 18.535156,1036.6395 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151367,0.5176 0.151368,0.1318 0.600586,0.1318 l 0.898438,0 0,1.25 -1.499024,0 q -1.035156,0 -1.469726,-0.4297 -0.429688,-0.4345 -0.429688,-1.4697 l 0,-2.3193 -0.86914,0 0,-1.25 0.86914,0 0,-1.5528 1.748047,0 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5344" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.5 KiB |
BIN
systemvm/agent/noVNC/app/images/clipboard.png
Normal file
|
After Width: | Height: | Size: 220 B |
@ -1,106 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="clipboard.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="15.366606"
|
|
||||||
inkscape:cy="16.42981"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="M 9,6 6,6 C 5.4459889,6 5,6.4459889 5,7 l 0,13 c 0,0.554011 0.4459889,1 1,1 l 13,0 c 0.554011,0 1,-0.445989 1,-1 L 20,7 C 20,6.4459889 19.554011,6 19,6 l -3,0"
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="rect6083"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cssssssssc" />
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect6085"
|
|
||||||
width="7"
|
|
||||||
height="4"
|
|
||||||
x="9"
|
|
||||||
y="1031.3622"
|
|
||||||
ry="1.00002" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
|
|
||||||
d="m 8.5071212,1038.8622 7.9999998,0"
|
|
||||||
id="path6087"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
|
|
||||||
d="m 8.5071212,1041.8622 3.9999998,0"
|
|
||||||
id="path6089"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081"
|
|
||||||
d="m 8.5071212,1044.8622 5.9999998,0"
|
|
||||||
id="path6091"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.9 KiB |
BIN
systemvm/agent/noVNC/app/images/connect.png
Normal file
|
After Width: | Height: | Size: 424 B |
@ -1,96 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="connect.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="37.14834"
|
|
||||||
inkscape:cy="1.9525926"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<g
|
|
||||||
id="g5103"
|
|
||||||
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-729.15757,315.8823)">
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cssssc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="rect5096"
|
|
||||||
d="m 11,1040.3622 -5,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-4 c 0,-1.108 0.892,-2 2,-2 l 5,0"
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="m 14,1032.3622 5,0 c 1.108,0 2,0.892 2,2 l 0,4 c 0,1.108 -0.892,2 -2,2 l -5,0"
|
|
||||||
id="path5099"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cssssc" />
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path5101"
|
|
||||||
d="m 9,1036.3622 7,0"
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.3 KiB |
BIN
systemvm/agent/noVNC/app/images/ctrl.png
Normal file
|
After Width: | Height: | Size: 399 B |
@ -1,96 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="ctrl.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="18.205425"
|
|
||||||
inkscape:cy="17.531398"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<g
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
id="text5290">
|
|
||||||
<path
|
|
||||||
d="m 9.1210938,1043.1898 q -0.5175782,0.2686 -1.0791016,0.4053 -0.5615235,0.1367 -1.171875,0.1367 -1.8212891,0 -2.8857422,-1.0156 -1.0644531,-1.0205 -1.0644531,-2.7637 0,-1.748 1.0644531,-2.7637 1.0644531,-1.0205 2.8857422,-1.0205 0.6103515,0 1.171875,0.1368 0.5615234,0.1367 1.0791016,0.4052 l 0,1.5088 q -0.522461,-0.3564 -1.0302735,-0.5224 -0.5078125,-0.1661 -1.0693359,-0.1661 -1.0058594,0 -1.5820313,0.6446 -0.5761719,0.6445 -0.5761719,1.7773 0,1.1279 0.5761719,1.7725 0.5761719,0.6445 1.5820313,0.6445 0.5615234,0 1.0693359,-0.166 0.5078125,-0.166 1.0302735,-0.5225 l 0,1.5088 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5370" />
|
|
||||||
<path
|
|
||||||
d="m 12.514648,1036.5687 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151368,0.5176 0.151367,0.1318 0.600586,0.1318 l 0.898437,0 0,1.25 -1.499023,0 q -1.035157,0 -1.469727,-0.4297 -0.429687,-0.4345 -0.429687,-1.4697 l 0,-2.3193 -0.8691411,0 0,-1.25 0.8691411,0 0,-1.5528 1.748046,0 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5372" />
|
|
||||||
<path
|
|
||||||
d="m 19.453125,1039.6107 q -0.229492,-0.1074 -0.458984,-0.1562 -0.22461,-0.054 -0.454102,-0.054 -0.673828,0 -1.040039,0.4345 -0.361328,0.4297 -0.361328,1.2354 l 0,2.5195 -1.748047,0 0,-5.4687 1.748047,0 0,0.8984 q 0.336914,-0.5371 0.771484,-0.7813 0.439453,-0.249 1.049805,-0.249 0.08789,0 0.19043,0.01 0.102539,0 0.297851,0.029 l 0.0049,1.582 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5374" />
|
|
||||||
<path
|
|
||||||
d="m 20.332031,1035.9926 1.748047,0 0,7.5976 -1.748047,0 0,-7.5976 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5376" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB |
BIN
systemvm/agent/noVNC/app/images/ctrlaltdel.png
Normal file
|
After Width: | Height: | Size: 191 B |
@ -1,100 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="ctrlaltdel.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="8"
|
|
||||||
inkscape:cx="11.135667"
|
|
||||||
inkscape:cy="16.407428"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect5253"
|
|
||||||
width="5"
|
|
||||||
height="5.0000172"
|
|
||||||
x="16"
|
|
||||||
y="1031.3622"
|
|
||||||
ry="1.0000174" />
|
|
||||||
<rect
|
|
||||||
y="1043.3622"
|
|
||||||
x="4"
|
|
||||||
height="5.0000172"
|
|
||||||
width="5"
|
|
||||||
id="rect5255"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
ry="1.0000174" />
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect5257"
|
|
||||||
width="5"
|
|
||||||
height="5.0000172"
|
|
||||||
x="13"
|
|
||||||
y="1043.3622"
|
|
||||||
ry="1.0000174" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB |
BIN
systemvm/agent/noVNC/app/images/disconnect.png
Normal file
|
After Width: | Height: | Size: 442 B |
@ -1,94 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="disconnect.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="25.05707"
|
|
||||||
inkscape:cy="11.594858"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="false">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<g
|
|
||||||
id="g5171"
|
|
||||||
transform="translate(-24.062499,-6.15775e-4)">
|
|
||||||
<path
|
|
||||||
id="path5110"
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
d="m 39.744141,3.4960938 c -0.769923,0 -1.539607,0.2915468 -2.121094,0.8730468 l -2.566406,2.5664063 1.414062,1.4140625 2.566406,-2.5664063 c 0.403974,-0.404 1.010089,-0.404 1.414063,0 l 2.828125,2.828125 c 0.40398,0.4039 0.403907,1.0101621 0,1.4140629 l -2.566406,2.566406 1.414062,1.414062 2.566406,-2.566406 c 1.163041,-1.1629 1.162968,-3.0791874 0,-4.2421874 L 41.865234,4.3691406 C 41.283747,3.7876406 40.514063,3.4960937 39.744141,3.4960938 Z M 39.017578,9.015625 a 1.0001,1.0001 0 0 0 -0.6875,0.3027344 l -0.445312,0.4453125 1.414062,1.4140621 0.445313,-0.445312 A 1.0001,1.0001 0 0 0 39.017578,9.015625 Z m -6.363281,0.7070312 a 1.0001,1.0001 0 0 0 -0.6875,0.3027348 L 28.431641,13.5625 c -1.163042,1.163 -1.16297,3.079187 0,4.242188 l 2.828125,2.828124 c 1.162974,1.163101 3.079213,1.163101 4.242187,0 l 3.535156,-3.535156 a 1.0001,1.0001 0 1 0 -1.414062,-1.414062 l -3.535156,3.535156 c -0.403974,0.404 -1.010089,0.404 -1.414063,0 l -2.828125,-2.828125 c -0.403981,-0.404 -0.403908,-1.010162 0,-1.414063 l 3.535156,-3.537109 A 1.0001,1.0001 0 0 0 32.654297,9.7226562 Z m 3.109375,2.1621098 -2.382813,2.384765 a 1.0001,1.0001 0 1 0 1.414063,1.414063 l 2.382812,-2.384766 -1.414062,-1.414062 z"
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<rect
|
|
||||||
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)"
|
|
||||||
y="752.29541"
|
|
||||||
x="-712.31262"
|
|
||||||
height="18.000017"
|
|
||||||
width="3"
|
|
||||||
id="rect5116"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.9 KiB |
BIN
systemvm/agent/noVNC/app/images/drag.png
Normal file
|
After Width: | Height: | Size: 336 B |
@ -1,76 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="drag.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="22.627417"
|
|
||||||
inkscape:cx="9.8789407"
|
|
||||||
inkscape:cy="9.5008608"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="m 7.039733,1049.3037 c -0.4309106,-0.1233 -0.7932634,-0.4631 -0.9705434,-0.9103 -0.04922,-0.1241 -0.057118,-0.2988 -0.071321,-1.5771 l -0.015972,-1.4375 -0.328125,-0.082 c -0.7668138,-0.1927 -1.1897046,-0.4275 -1.7031253,-0.9457 -0.4586773,-0.4629 -0.6804297,-0.8433 -0.867034,-1.4875 -0.067215,-0.232 -0.068001,-0.2642 -0.078682,-3.2188 -0.012078,-3.341 -0.020337,-3.2012 0.2099452,-3.5555 0.2246623,-0.3458 0.5798271,-0.5892 0.9667343,-0.6626 0.092506,-0.017 0.531898,-0.032 0.9764271,-0.032 l 0.8082347,0 1.157e-4,1.336 c 1.125e-4,1.2779 0.00281,1.3403 0.062214,1.4378 0.091785,0.1505 0.2357707,0.226 0.4314082,0.2261 0.285389,2e-4 0.454884,-0.1352 0.5058962,-0.4042 0.019355,-0.102 0.031616,-0.982 0.031616,-2.269 0,-1.9756 0.00357,-2.1138 0.059205,-2.2926 0.1645475,-0.5287 0.6307616,-0.9246 1.19078,-1.0113 0.8000572,-0.1238 1.5711277,0.4446 1.6860387,1.2429 0.01732,0.1203 0.03177,0.8248 0.03211,1.5657 6.19e-4,1.3449 7.22e-4,1.347 0.07093,1.4499 0.108355,0.1587 0.255268,0.2248 0.46917,0.2108 0.204069,-0.013 0.316116,-0.08 0.413642,-0.2453 0.06028,-0.1024 0.06307,-0.1778 0.07862,-2.1218 0.01462,-1.8283 0.02124,-2.0285 0.07121,-2.1549 0.260673,-0.659 0.934894,-1.0527 1.621129,-0.9465 0.640523,0.099 1.152269,0.6104 1.243187,1.2421 0.01827,0.1269 0.03175,0.9943 0.03211,2.0657 l 6.19e-4,1.8469 0.07031,0.103 c 0.108355,0.1587 0.255267,0.2248 0.46917,0.2108 0.204069,-0.013 0.316115,-0.08 0.413642,-0.2453 0.05951,-0.1011 0.06329,-0.1786 0.07907,-1.6218 0.01469,-1.3438 0.02277,-1.5314 0.07121,-1.6549 0.257975,-0.6576 0.934425,-1.0527 1.620676,-0.9465 0.640522,0.099 1.152269,0.6104 1.243186,1.2421 0.0186,0.1292 0.03179,1.0759 0.03222,2.3125 7.15e-4,2.0335 0.0025,2.0966 0.06283,2.1956 0.09178,0.1505 0.235771,0.226 0.431409,0.2261 0.285388,2e-4 0.454884,-0.1352 0.505897,-0.4042 0.01874,-0.099 0.03161,-0.8192 0.03161,-1.769 0,-1.4848 0.0043,-1.6163 0.0592,-1.7926 0.164548,-0.5287 0.630762,-0.9246 1.19078,-1.0113 0.800057,-0.1238 1.571128,0.4446 1.686039,1.2429 0.04318,0.2999 0.04372,9.1764 5.78e-4,9.4531 -0.04431,0.2841 -0.217814,0.6241 -0.420069,0.8232 -0.320102,0.315 -0.63307,0.4268 -1.194973,0.4268 l -0.35281,0 -2.51e-4,1.2734 c -1.25e-4,0.7046 -0.01439,1.3642 -0.03191,1.4766 -0.06665,0.4274 -0.372966,0.8704 -0.740031,1.0702 -0.349999,0.1905 0.01748,0.18 -6.242199,0.1776 -5.3622439,0 -5.7320152,-0.01 -5.9121592,-0.057 l 1.4e-5,0 z"
|
|
||||||
id="path4379"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.6 KiB |
BIN
systemvm/agent/noVNC/app/images/error.png
Normal file
|
After Width: | Height: | Size: 348 B |
@ -1,81 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="error.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="14.00357"
|
|
||||||
inkscape:cy="12.443398"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="M 7 3 C 4.7839905 3 3 4.7839905 3 7 L 3 18 C 3 20.21601 4.7839905 22 7 22 L 18 22 C 20.21601 22 22 20.21601 22 18 L 22 7 C 22 4.7839905 20.21601 3 18 3 L 7 3 z M 7.6992188 6 A 1.6916875 1.6924297 0 0 1 8.9121094 6.5117188 L 12.5 10.101562 L 16.087891 6.5117188 A 1.6916875 1.6924297 0 0 1 17.251953 6 A 1.6916875 1.6924297 0 0 1 18.480469 8.90625 L 14.892578 12.496094 L 18.480469 16.085938 A 1.6916875 1.6924297 0 1 1 16.087891 18.478516 L 12.5 14.888672 L 8.9121094 18.478516 A 1.6916875 1.6924297 0 1 1 6.5214844 16.085938 L 10.109375 12.496094 L 6.5214844 8.90625 A 1.6916875 1.6924297 0 0 1 7.6992188 6 z "
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="rect4135" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB |
BIN
systemvm/agent/noVNC/app/images/esc.png
Normal file
|
After Width: | Height: | Size: 365 B |
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="esc.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="18.205425"
|
|
||||||
inkscape:cy="17.531398"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="text5290"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<g
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
id="text5290">
|
|
||||||
<path
|
|
||||||
d="m 3.9331055,1036.1464 5.0732422,0 0,1.4209 -3.1933594,0 0,1.3574 3.0029297,0 0,1.4209 -3.0029297,0 0,1.6699 3.3007812,0 0,1.4209 -5.180664,0 0,-7.29 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5314" />
|
|
||||||
<path
|
|
||||||
d="m 14.963379,1038.1385 0,1.3282 q -0.561524,-0.2344 -1.083984,-0.3516 -0.522461,-0.1172 -0.986329,-0.1172 -0.498046,0 -0.742187,0.127 -0.239258,0.122 -0.239258,0.3808 0,0.21 0.180664,0.3223 0.185547,0.1123 0.65918,0.166 l 0.307617,0.044 q 1.342773,0.1709 1.806641,0.5615 0.463867,0.3906 0.463867,1.2256 0,0.874 -0.644531,1.3134 -0.644532,0.4395 -1.923829,0.4395 -0.541992,0 -1.123046,-0.088 -0.576172,-0.083 -1.186524,-0.2539 l 0,-1.3281 q 0.522461,0.2539 1.069336,0.3808 0.551758,0.127 1.118164,0.127 0.512695,0 0.771485,-0.1416 0.258789,-0.1416 0.258789,-0.4199 0,-0.2344 -0.180664,-0.3467 -0.175782,-0.1172 -0.708008,-0.1807 l -0.307617,-0.039 q -1.166993,-0.1465 -1.635743,-0.542 -0.46875,-0.3955 -0.46875,-1.2012 0,-0.8691 0.595703,-1.2891 0.595704,-0.4199 1.826172,-0.4199 0.483399,0 1.015625,0.073 0.532227,0.073 1.157227,0.2294 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5316" />
|
|
||||||
<path
|
|
||||||
d="m 21.066895,1038.1385 0,1.4258 q -0.356446,-0.2441 -0.717774,-0.3613 -0.356445,-0.1172 -0.742187,-0.1172 -0.732422,0 -1.142579,0.4297 -0.405273,0.4248 -0.405273,1.1914 0,0.7666 0.405273,1.1963 0.410157,0.4248 1.142579,0.4248 0.410156,0 0.776367,-0.1221 0.371094,-0.122 0.683594,-0.3613 l 0,1.4307 q -0.410157,0.1513 -0.834961,0.2246 -0.419922,0.078 -0.844727,0.078 -1.479492,0 -2.314453,-0.7568 -0.834961,-0.7618 -0.834961,-2.1143 0,-1.3525 0.834961,-2.1094 0.834961,-0.7617 2.314453,-0.7617 0.429688,0 0.844727,0.078 0.419921,0.073 0.834961,0.2246 z"
|
|
||||||
style="font-size:10px;fill:#ffffff;fill-opacity:1"
|
|
||||||
id="path5318" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.4 KiB |
BIN
systemvm/agent/noVNC/app/images/expander.png
Normal file
|
After Width: | Height: | Size: 167 B |
@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="9"
|
|
||||||
height="10"
|
|
||||||
viewBox="0 0 9 10"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="expander.svg">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="45.254834"
|
|
||||||
inkscape:cx="9.8737281"
|
|
||||||
inkscape:cy="6.4583132"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-object-midpoints="false"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1042.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="M 2.0800781,1042.3633 A 2.0002,2.0002 0 0 0 0,1044.3613 l 0,6 a 2.0002,2.0002 0 0 0 3.0292969,1.7168 l 5,-3 a 2.0002,2.0002 0 0 0 0,-3.4316 l -5,-3 a 2.0002,2.0002 0 0 0 -0.9492188,-0.2832 z"
|
|
||||||
id="path4138"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB |
BIN
systemvm/agent/noVNC/app/images/fullscreen.png
Normal file
|
After Width: | Height: | Size: 280 B |
@ -1,93 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="fullscreen.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="16.400723"
|
|
||||||
inkscape:cy="15.083758"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="false">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect5006"
|
|
||||||
width="17"
|
|
||||||
height="17.000017"
|
|
||||||
x="4"
|
|
||||||
y="1031.3622"
|
|
||||||
ry="3.0000174" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="m 7.5,1044.8622 4,0 -1.5,-1.5 1.5,-1.5 -1,-1 -1.5,1.5 -1.5,-1.5 0,4 z"
|
|
||||||
id="path5017"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path5025"
|
|
||||||
d="m 17.5,1034.8622 -4,0 1.5,1.5 -1.5,1.5 1,1 1.5,-1.5 1.5,1.5 0,-4 z"
|
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
BIN
systemvm/agent/noVNC/app/images/handle.png
Normal file
|
After Width: | Height: | Size: 126 B |
@ -1,82 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="5"
|
|
||||||
height="6"
|
|
||||||
viewBox="0 0 5 6"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="handle.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="32"
|
|
||||||
inkscape:cx="1.3551778"
|
|
||||||
inkscape:cy="8.7800329"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1046.3622)">
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 4.0000803,1049.3622 -3,-2 0,4 z"
|
|
||||||
id="path4247"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cccc" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.5 KiB |
BIN
systemvm/agent/noVNC/app/images/handle_bg.png
Normal file
|
After Width: | Height: | Size: 123 B |
@ -1,172 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="15"
|
|
||||||
height="50"
|
|
||||||
viewBox="0 0 15 50"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="handle_bg.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="-10.001409"
|
|
||||||
inkscape:cy="24.512566"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1002.3622)">
|
|
||||||
<rect
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4249"
|
|
||||||
width="1"
|
|
||||||
height="1.0000174"
|
|
||||||
x="9.5"
|
|
||||||
y="1008.8622"
|
|
||||||
ry="1.7382812e-05" />
|
|
||||||
<rect
|
|
||||||
ry="1.7382812e-05"
|
|
||||||
y="1013.8622"
|
|
||||||
x="9.5"
|
|
||||||
height="1.0000174"
|
|
||||||
width="1"
|
|
||||||
id="rect4255"
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
ry="1.7382812e-05"
|
|
||||||
y="1008.8622"
|
|
||||||
x="4.5"
|
|
||||||
height="1.0000174"
|
|
||||||
width="1"
|
|
||||||
id="rect4261"
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4263"
|
|
||||||
width="1"
|
|
||||||
height="1.0000174"
|
|
||||||
x="4.5"
|
|
||||||
y="1013.8622"
|
|
||||||
ry="1.7382812e-05" />
|
|
||||||
<rect
|
|
||||||
ry="1.7382812e-05"
|
|
||||||
y="1039.8622"
|
|
||||||
x="9.5"
|
|
||||||
height="1.0000174"
|
|
||||||
width="1"
|
|
||||||
id="rect4265"
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4267"
|
|
||||||
width="1"
|
|
||||||
height="1.0000174"
|
|
||||||
x="9.5"
|
|
||||||
y="1044.8622"
|
|
||||||
ry="1.7382812e-05" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4269"
|
|
||||||
width="1"
|
|
||||||
height="1.0000174"
|
|
||||||
x="4.5"
|
|
||||||
y="1039.8622"
|
|
||||||
ry="1.7382812e-05" />
|
|
||||||
<rect
|
|
||||||
ry="1.7382812e-05"
|
|
||||||
y="1044.8622"
|
|
||||||
x="4.5"
|
|
||||||
height="1.0000174"
|
|
||||||
width="1"
|
|
||||||
id="rect4271"
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4273"
|
|
||||||
width="1"
|
|
||||||
height="1.0000174"
|
|
||||||
x="9.5"
|
|
||||||
y="1018.8622"
|
|
||||||
ry="1.7382812e-05" />
|
|
||||||
<rect
|
|
||||||
ry="1.7382812e-05"
|
|
||||||
y="1018.8622"
|
|
||||||
x="4.5"
|
|
||||||
height="1.0000174"
|
|
||||||
width="1"
|
|
||||||
id="rect4275"
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4277"
|
|
||||||
width="1"
|
|
||||||
height="1.0000174"
|
|
||||||
x="9.5"
|
|
||||||
y="1034.8622"
|
|
||||||
ry="1.7382812e-05" />
|
|
||||||
<rect
|
|
||||||
ry="1.7382812e-05"
|
|
||||||
y="1034.8622"
|
|
||||||
x="4.5"
|
|
||||||
height="1.0000174"
|
|
||||||
width="1"
|
|
||||||
id="rect4279"
|
|
||||||
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.2 KiB |
BIN
systemvm/agent/noVNC/app/images/info.png
Normal file
|
After Width: | Height: | Size: 448 B |
@ -1,81 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="info.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="15.720838"
|
|
||||||
inkscape:cy="8.9111233"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="M 12.5 3 A 9.5 9.4999914 0 0 0 3 12.5 A 9.5 9.4999914 0 0 0 12.5 22 A 9.5 9.4999914 0 0 0 22 12.5 A 9.5 9.4999914 0 0 0 12.5 3 z M 12.5 5 A 1.5 1.5000087 0 0 1 14 6.5 A 1.5 1.5000087 0 0 1 12.5 8 A 1.5 1.5000087 0 0 1 11 6.5 A 1.5 1.5000087 0 0 1 12.5 5 z M 10.521484 8.9785156 L 12.521484 8.9785156 A 1.50015 1.50015 0 0 1 14.021484 10.478516 L 14.021484 15.972656 A 1.50015 1.50015 0 0 1 14.498047 18.894531 C 14.498047 18.894531 13.74301 19.228309 12.789062 18.912109 C 12.312092 18.754109 11.776235 18.366625 11.458984 17.828125 C 11.141734 17.289525 11.021484 16.668469 11.021484 15.980469 L 11.021484 11.980469 L 10.521484 11.980469 A 1.50015 1.50015 0 1 1 10.521484 8.9804688 L 10.521484 8.9785156 z "
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="path4136" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
BIN
systemvm/agent/noVNC/app/images/keyboard.png
Normal file
|
After Width: | Height: | Size: 308 B |
@ -1,88 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="keyboard.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/keyboard.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#717171"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="31.285341"
|
|
||||||
inkscape:cy="8.8028469"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:snap-bbox-midpoints="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-midpoints="true"
|
|
||||||
inkscape:snap-smooth-nodes="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="M 7,3 C 4.8012876,3 3,4.8013 3,7 3,11.166667 3,15.333333 3,19.5 3,20.8764 4.1236413,22 5.5,22 l 14,0 C 20.876358,22 22,20.8764 22,19.5 22,15.333333 22,11.166667 22,7 22,4.8013 20.198712,3 18,3 Z m 0,2 11,0 c 1.125307,0 2,0.8747 2,2 L 20,12 5,12 5,7 C 5,5.8747 5.8746931,5 7,5 Z M 6.5,14 C 6.777,14 7,14.223 7,14.5 7,14.777 6.777,15 6.5,15 6.223,15 6,14.777 6,14.5 6,14.223 6.223,14 6.5,14 Z m 2,0 C 8.777,14 9,14.223 9,14.5 9,14.777 8.777,15 8.5,15 8.223,15 8,14.777 8,14.5 8,14.223 8.223,14 8.5,14 Z m 2,0 C 10.777,14 11,14.223 11,14.5 11,14.777 10.777,15 10.5,15 10.223,15 10,14.777 10,14.5 10,14.223 10.223,14 10.5,14 Z m 2,0 C 12.777,14 13,14.223 13,14.5 13,14.777 12.777,15 12.5,15 12.223,15 12,14.777 12,14.5 12,14.223 12.223,14 12.5,14 Z m 2,0 C 14.777,14 15,14.223 15,14.5 15,14.777 14.777,15 14.5,15 14.223,15 14,14.777 14,14.5 14,14.223 14.223,14 14.5,14 Z m 2,0 C 16.777,14 17,14.223 17,14.5 17,14.777 16.777,15 16.5,15 16.223,15 16,14.777 16,14.5 16,14.223 16.223,14 16.5,14 Z m 2,0 C 18.777,14 19,14.223 19,14.5 19,14.777 18.777,15 18.5,15 18.223,15 18,14.777 18,14.5 18,14.223 18.223,14 18.5,14 Z m -13,2 C 5.777,16 6,16.223 6,16.5 6,16.777 5.777,17 5.5,17 5.223,17 5,16.777 5,16.5 5,16.223 5.223,16 5.5,16 Z m 2,0 C 7.777,16 8,16.223 8,16.5 8,16.777 7.777,17 7.5,17 7.223,17 7,16.777 7,16.5 7,16.223 7.223,16 7.5,16 Z m 2,0 C 9.777,16 10,16.223 10,16.5 10,16.777 9.777,17 9.5,17 9.223,17 9,16.777 9,16.5 9,16.223 9.223,16 9.5,16 Z m 2,0 C 11.777,16 12,16.223 12,16.5 12,16.777 11.777,17 11.5,17 11.223,17 11,16.777 11,16.5 11,16.223 11.223,16 11.5,16 Z m 2,0 C 13.777,16 14,16.223 14,16.5 14,16.777 13.777,17 13.5,17 13.223,17 13,16.777 13,16.5 13,16.223 13.223,16 13.5,16 Z m 2,0 C 15.777,16 16,16.223 16,16.5 16,16.777 15.777,17 15.5,17 15.223,17 15,16.777 15,16.5 15,16.223 15.223,16 15.5,16 Z m 2,0 C 17.777,16 18,16.223 18,16.5 18,16.777 17.777,17 17.5,17 17.223,17 17,16.777 17,16.5 17,16.223 17.223,16 17.5,16 Z m 2,0 C 19.777,16 20,16.223 20,16.5 20,16.777 19.777,17 19.5,17 19.223,17 19,16.777 19,16.5 19,16.223 19.223,16 19.5,16 Z M 6,18 c 0.554,0 1,0.446 1,1 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 0,-0.554 0.446,-1 1,-1 z m 2.8261719,0 7.3476561,0 C 16.631643,18 17,18.368372 17,18.826172 l 0,0.347656 C 17,19.631628 16.631643,20 16.173828,20 L 8.8261719,20 C 8.3683573,20 8,19.631628 8,19.173828 L 8,18.826172 C 8,18.368372 8.3683573,18 8.8261719,18 Z m 10.1113281,0 0.125,0 C 19.581551,18 20,18.4184 20,18.9375 l 0,0.125 C 20,19.5816 19.581551,20 19.0625,20 l -0.125,0 C 18.418449,20 18,19.5816 18,19.0625 l 0,-0.125 C 18,18.4184 18.418449,18 18.9375,18 Z"
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="rect4160"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="sccssccsssssccssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="m 12.499929,1033.8622 -2,2 1.500071,0 0,2 1,0 0,-2 1.499929,0 z"
|
|
||||||
id="path4150"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cccccccc" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.3 KiB |
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="mouse_left.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="11.313708"
|
|
||||||
inkscape:cx="15.551515"
|
|
||||||
inkscape:cy="12.205592"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0068f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
|
||||||
id="path6219" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
|
||||||
id="path6217" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
|
||||||
id="path6215" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
|
||||||
id="rect6178" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.8 KiB |
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="mouse_middle.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="11.313708"
|
|
||||||
inkscape:cx="15.551515"
|
|
||||||
inkscape:cy="12.205592"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
|
||||||
id="path6219" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
|
||||||
id="path6217" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0068f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
|
||||||
id="path6215" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
|
||||||
id="rect6178" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.8 KiB |
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="mouse_none.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="23.160825"
|
|
||||||
inkscape:cy="13.208262"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
|
||||||
id="path6219" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
|
||||||
id="path6217" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
|
||||||
id="path6215" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
|
||||||
id="rect6178" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.8 KiB |
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="mouse_right.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="11.313708"
|
|
||||||
inkscape:cx="15.551515"
|
|
||||||
inkscape:cy="12.205592"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 8,1030.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,2 5,0 0,-2 c 0,-1.4738 1.090393,-2.7071 2.5,-2.9492 l 0,-1.0508 -3.5,0 z"
|
|
||||||
id="path6219" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0068f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 13.5,1030.3622 0,1.0508 c 1.409607,0.2421 2.5,1.4754 2.5,2.9492 l 0,2 5,0 0,-2 c 0,-2.1987 -1.801288,-4 -4,-4 l -3.5,0 z"
|
|
||||||
id="path6217" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 12,1033.3622 c -0.571311,0 -1,0.4287 -1,1 l 0,5 c 0,0.5713 0.428689,1 1,1 l 1,0 c 0.571311,0 1,-0.4287 1,-1 l 0,-5 c 0,-0.5713 -0.428689,-1 -1,-1 l -1,0 z"
|
|
||||||
id="path6215" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 4,1038.3622 0,3.5 c 0,4.1377 3.362302,7.5 7.5,7.5 l 2,0 c 4.137698,0 7.5,-3.3623 7.5,-7.5 l 0,-3.5 -5,0 0,1 c 0,1.6447 -1.355293,3 -3,3 l -1,0 c -1.644707,0 -3,-1.3553 -3,-3 l 0,-1 -5,0 z"
|
|
||||||
id="rect6178" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.8 KiB |
BIN
systemvm/agent/noVNC/app/images/power.png
Normal file
|
After Width: | Height: | Size: 421 B |
@ -1,87 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="power.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="9.3159849"
|
|
||||||
inkscape:cy="13.436208"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="M 9 6.8183594 C 6.3418164 8.1213032 4.5 10.849161 4.5 14 C 4.5 18.4065 8.0935666 22 12.5 22 C 16.906433 22 20.5 18.4065 20.5 14 C 20.5 10.849161 18.658184 8.1213032 16 6.8183594 L 16 9.125 C 17.514327 10.211757 18.5 11.984508 18.5 14 C 18.5 17.3256 15.825553 20 12.5 20 C 9.1744469 20 6.5 17.3256 6.5 14 C 6.5 11.984508 7.4856727 10.211757 9 9.125 L 9 6.8183594 z "
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="path6140" />
|
|
||||||
<path
|
|
||||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 12.5,1031.8836 0,6.4786"
|
|
||||||
id="path6142"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cc" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.9 KiB |
BIN
systemvm/agent/noVNC/app/images/settings.png
Normal file
|
After Width: | Height: | Size: 379 B |
@ -1,76 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="settings.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="22.627417"
|
|
||||||
inkscape:cx="14.69683"
|
|
||||||
inkscape:cy="8.8039511"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="true"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="M 11 3 L 11 5.1601562 A 7.5 7.5 0 0 0 8.3671875 6.2460938 L 6.84375 4.7226562 L 4.7226562 6.84375 L 6.2480469 8.3691406 A 7.5 7.5 0 0 0 5.1523438 11 L 3 11 L 3 14 L 5.1601562 14 A 7.5 7.5 0 0 0 6.2460938 16.632812 L 4.7226562 18.15625 L 6.84375 20.277344 L 8.3691406 18.751953 A 7.5 7.5 0 0 0 11 19.847656 L 11 22 L 14 22 L 14 19.839844 A 7.5 7.5 0 0 0 16.632812 18.753906 L 18.15625 20.277344 L 20.277344 18.15625 L 18.751953 16.630859 A 7.5 7.5 0 0 0 19.847656 14 L 22 14 L 22 11 L 19.839844 11 A 7.5 7.5 0 0 0 18.753906 8.3671875 L 20.277344 6.84375 L 18.15625 4.7226562 L 16.630859 6.2480469 A 7.5 7.5 0 0 0 14 5.1523438 L 14 3 L 11 3 z M 12.5 10 A 2.5 2.5 0 0 1 15 12.5 A 2.5 2.5 0 0 1 12.5 15 A 2.5 2.5 0 0 1 10 12.5 A 2.5 2.5 0 0 1 12.5 10 z "
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="rect4967" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB |
BIN
systemvm/agent/noVNC/app/images/tab.png
Normal file
|
After Width: | Height: | Size: 190 B |
@ -1,86 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="tab.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="16"
|
|
||||||
inkscape:cx="11.67335"
|
|
||||||
inkscape:cy="17.881696"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="m 3,1031.3622 0,8 2,0 0,-4 0,-4 -2,0 z m 2,4 4,4 0,-3 13,0 0,-2 -13,0 0,-3 -4,4 z"
|
|
||||||
id="rect5194"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
id="path5211"
|
|
||||||
d="m 22,1048.3622 0,-8 -2,0 0,4 0,4 2,0 z m -2,-4 -4,-4 0,3 -13,0 0,2 13,0 0,3 4,-4 z"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.9 KiB |
BIN
systemvm/agent/noVNC/app/images/toggleextrakeys.png
Normal file
|
After Width: | Height: | Size: 353 B |
@ -1,90 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="extrakeys.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="15.234555"
|
|
||||||
inkscape:cy="9.9710826"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="false">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 8,1031.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,8.9996 c 0,2.1987 1.8012876,4 4,4 l 9,0 c 2.198712,0 4,-1.8013 4,-4 l 0,-8.9996 c 0,-2.1987 -1.801288,-4 -4,-4 z m 0,2 9,0 c 1.125307,0 2,0.8747 2,2 l 0,7.0005 c 0,1.1253 -0.874693,2 -2,2 l -9,0 c -1.1253069,0 -2,-0.8747 -2,-2 l 0,-7.0005 c 0,-1.1253 0.8746931,-2 2,-2 z"
|
|
||||||
id="rect5006"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ssssssssssssssssss" />
|
|
||||||
<g
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
id="text4167"
|
|
||||||
transform="matrix(0.96021948,0,0,0.96021948,0.18921715,41.80659)">
|
|
||||||
<path
|
|
||||||
d="m 14.292969,1040.6791 -2.939453,0 -0.463868,1.3281 -1.889648,0 2.700195,-7.29 2.241211,0 2.700196,7.29 -1.889649,0 -0.458984,-1.3281 z m -2.470703,-1.3526 1.99707,0 -0.996094,-2.9004 -1.000976,2.9004 z"
|
|
||||||
id="path4172"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB |
BIN
systemvm/agent/noVNC/app/images/warning.png
Normal file
|
After Width: | Height: | Size: 319 B |
@ -1,81 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25"
|
|
||||||
height="25"
|
|
||||||
viewBox="0 0 25 25"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="warning.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#959595"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1"
|
|
||||||
inkscape:cx="16.457343"
|
|
||||||
inkscape:cy="12.179552"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
inkscape:bbox-nodes="true"
|
|
||||||
inkscape:snap-bbox-edge-midpoints="true"
|
|
||||||
inkscape:object-paths="true"
|
|
||||||
showguides="false"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1136"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:snap-smooth-nodes="true"
|
|
||||||
inkscape:object-nodes="true"
|
|
||||||
inkscape:snap-intersection-paths="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-global="true">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid4136" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(0,-1027.3622)">
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="M 12.513672 3.0019531 C 11.751609 2.9919531 11.052563 3.4242687 10.710938 4.1054688 L 3.2109375 19.105469 C 2.5461937 20.435369 3.5132277 21.9999 5 22 L 20 22 C 21.486772 21.9999 22.453806 20.435369 21.789062 19.105469 L 14.289062 4.1054688 C 13.951849 3.4330688 13.265888 3.0066531 12.513672 3.0019531 z M 12.478516 6.9804688 A 1.50015 1.50015 0 0 1 14 8.5 L 14 14.5 A 1.50015 1.50015 0 1 1 11 14.5 L 11 8.5 A 1.50015 1.50015 0 0 1 12.478516 6.9804688 z M 12.5 17 A 1.5 1.5 0 0 1 14 18.5 A 1.5 1.5 0 0 1 12.5 20 A 1.5 1.5 0 0 1 11 18.5 A 1.5 1.5 0 0 1 12.5 17 z "
|
|
||||||
transform="translate(0,1027.3622)"
|
|
||||||
id="path4208" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
systemvm/agent/noVNC/app/images/windows.png
Normal file
|
After Width: | Height: | Size: 219 B |
@ -1,85 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="svg2"
|
|
||||||
inkscape:export-ydpi="90"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
sodipodi:docname="windows.svg"
|
|
||||||
inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png"
|
|
||||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="-293 384 25 23"
|
|
||||||
xml:space="preserve"
|
|
||||||
width="25"
|
|
||||||
height="23"><metadata
|
|
||||||
id="metadata21"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs19" /><sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
id="namedview17"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:pagecheckerboard="true"
|
|
||||||
inkscape:zoom="9.44"
|
|
||||||
inkscape:cx="-0.84745763"
|
|
||||||
inkscape:cy="12.5"
|
|
||||||
inkscape:window-x="2552"
|
|
||||||
inkscape:window-y="122"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg2" />
|
|
||||||
<style
|
|
||||||
type="text/css"
|
|
||||||
id="style2">
|
|
||||||
.st0{fill:#FFFFFF;}
|
|
||||||
</style>
|
|
||||||
<g
|
|
||||||
id="g14"
|
|
||||||
transform="matrix(1.2624869,0,0,1.3601695,73.614445,-144.84322)">
|
|
||||||
<g
|
|
||||||
id="g12">
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="m -277.4,396 c -0.7,0 -1.3,0 -2,0 -0.4,0 -0.5,-0.1 -0.5,-0.5 0,-1 0,-2 0,-3 0,-0.3 0.2,-0.5 0.5,-0.5 1.3,-0.1 2.6,-0.3 3.9,-0.4 0.4,0 0.7,0.1 0.7,0.6 0,1.1 0,2.2 0,3.3 0,0.4 -0.2,0.6 -0.6,0.6 -0.7,-0.1 -1.4,-0.1 -2,-0.1 z"
|
|
||||||
id="path4"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#ffffff" />
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="m -274.9,399.3 c 0,0.6 0,1.1 0,1.7 0,0.4 -0.1,0.6 -0.6,0.6 -1.4,-0.1 -2.8,-0.3 -4.1,-0.4 -0.3,0 -0.4,-0.3 -0.4,-0.5 0,-1 0,-2 0,-3 0,-0.4 0.2,-0.5 0.6,-0.5 1.3,0 2.6,0 3.9,0 0.5,0 0.6,0.2 0.6,0.6 0,0.4 0,0.9 0,1.5 z"
|
|
||||||
id="path6"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#ffffff" />
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="m -283.5,396 c -0.6,0 -1.3,0 -1.9,0 -0.4,0 -0.6,-0.1 -0.6,-0.6 0,-0.8 0,-1.5 0,-2.3 0,-0.4 0.2,-0.6 0.6,-0.7 1.3,-0.1 2.7,-0.3 4,-0.4 0.4,0 0.5,0.1 0.5,0.5 0,1 0,1.9 0,2.9 0,0.4 -0.2,0.5 -0.5,0.5 -0.8,0.1 -1.5,0.1 -2.1,0.1 z"
|
|
||||||
id="path8"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#ffffff" />
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="m -283.5,397 c 0.6,0 1.3,0 1.9,0 0.4,0 0.6,0.1 0.6,0.5 0,1 0,1.9 0,2.9 0,0.4 -0.2,0.5 -0.5,0.5 -1.3,-0.1 -2.7,-0.3 -4,-0.4 -0.4,0 -0.6,-0.2 -0.6,-0.7 0,-0.7 0,-1.5 0,-2.2 0,-0.5 0.2,-0.7 0.7,-0.7 0.6,0.1 1.2,0.1 1.9,0.1 z"
|
|
||||||
id="path10"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#ffffff" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
1
systemvm/agent/noVNC/app/locale/README
Normal file
@ -0,0 +1 @@
|
|||||||
|
DO NOT MODIFY THE FILES IN THIS FOLDER, THEY ARE AUTOMATICALLY GENERATED FROM THE PO-FILES.
|
||||||
73
systemvm/agent/noVNC/app/locale/ja.json
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"Connecting...": "接続しています...",
|
||||||
|
"Disconnecting...": "切断しています...",
|
||||||
|
"Reconnecting...": "再接続しています...",
|
||||||
|
"Internal error": "内部エラー",
|
||||||
|
"Must set host": "ホストを設定する必要があります",
|
||||||
|
"Connected (encrypted) to ": "接続しました (暗号化済み): ",
|
||||||
|
"Connected (unencrypted) to ": "接続しました (暗号化されていません): ",
|
||||||
|
"Something went wrong, connection is closed": "何かが問題で、接続が閉じられました",
|
||||||
|
"Failed to connect to server": "サーバーへの接続に失敗しました",
|
||||||
|
"Disconnected": "切断しました",
|
||||||
|
"New connection has been rejected with reason: ": "新規接続は次の理由で拒否されました: ",
|
||||||
|
"New connection has been rejected": "新規接続は拒否されました",
|
||||||
|
"Password is required": "パスワードが必要です",
|
||||||
|
"noVNC encountered an error:": "noVNC でエラーが発生しました:",
|
||||||
|
"Hide/Show the control bar": "コントロールバーを隠す/表示する",
|
||||||
|
"Move/Drag Viewport": "ビューポートを移動/ドラッグ",
|
||||||
|
"viewport drag": "ビューポートをドラッグ",
|
||||||
|
"Active Mouse Button": "アクティブなマウスボタン",
|
||||||
|
"No mousebutton": "マウスボタンなし",
|
||||||
|
"Left mousebutton": "左マウスボタン",
|
||||||
|
"Middle mousebutton": "中マウスボタン",
|
||||||
|
"Right mousebutton": "右マウスボタン",
|
||||||
|
"Keyboard": "キーボード",
|
||||||
|
"Show Keyboard": "キーボードを表示",
|
||||||
|
"Extra keys": "追加キー",
|
||||||
|
"Show Extra Keys": "追加キーを表示",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Toggle Ctrl": "Ctrl キーを切り替え",
|
||||||
|
"Alt": "Alt",
|
||||||
|
"Toggle Alt": "Alt キーを切り替え",
|
||||||
|
"Toggle Windows": "Windows キーを切り替え",
|
||||||
|
"Windows": "Windows",
|
||||||
|
"Send Tab": "Tab キーを送信",
|
||||||
|
"Tab": "Tab",
|
||||||
|
"Esc": "Esc",
|
||||||
|
"Send Escape": "Escape キーを送信",
|
||||||
|
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||||
|
"Send Ctrl-Alt-Del": "Ctrl-Alt-Del を送信",
|
||||||
|
"Shutdown/Reboot": "シャットダウン/再起動",
|
||||||
|
"Shutdown/Reboot...": "シャットダウン/再起動...",
|
||||||
|
"Power": "電源",
|
||||||
|
"Shutdown": "シャットダウン",
|
||||||
|
"Reboot": "再起動",
|
||||||
|
"Reset": "リセット",
|
||||||
|
"Clipboard": "クリップボード",
|
||||||
|
"Clear": "クリア",
|
||||||
|
"Fullscreen": "全画面表示",
|
||||||
|
"Settings": "設定",
|
||||||
|
"Shared Mode": "共有モード",
|
||||||
|
"View Only": "表示のみ",
|
||||||
|
"Clip to Window": "ウィンドウにクリップ",
|
||||||
|
"Scaling Mode:": "スケーリングモード:",
|
||||||
|
"None": "なし",
|
||||||
|
"Local Scaling": "ローカルスケーリング",
|
||||||
|
"Remote Resizing": "リモートでリサイズ",
|
||||||
|
"Advanced": "高度",
|
||||||
|
"Repeater ID:": "リピーター ID:",
|
||||||
|
"WebSocket": "WebSocket",
|
||||||
|
"Encrypt": "暗号化",
|
||||||
|
"Host:": "ホスト:",
|
||||||
|
"Port:": "ポート:",
|
||||||
|
"Path:": "パス:",
|
||||||
|
"Automatic Reconnect": "自動再接続",
|
||||||
|
"Reconnect Delay (ms):": "再接続する遅延 (ミリ秒):",
|
||||||
|
"Show Dot when No Cursor": "カーソルがないときにドットを表示",
|
||||||
|
"Logging:": "ロギング:",
|
||||||
|
"Disconnect": "切断",
|
||||||
|
"Connect": "接続",
|
||||||
|
"Password:": "パスワード:",
|
||||||
|
"Send Password": "パスワードを送信",
|
||||||
|
"Cancel": "キャンセル"
|
||||||
|
}
|
||||||
@ -11,16 +11,11 @@
|
|||||||
"Disconnected": "Frånkopplad",
|
"Disconnected": "Frånkopplad",
|
||||||
"New connection has been rejected with reason: ": "Ny anslutning har blivit nekad med följande skäl: ",
|
"New connection has been rejected with reason: ": "Ny anslutning har blivit nekad med följande skäl: ",
|
||||||
"New connection has been rejected": "Ny anslutning har blivit nekad",
|
"New connection has been rejected": "Ny anslutning har blivit nekad",
|
||||||
"Password is required": "Lösenord krävs",
|
"Credentials are required": "Användaruppgifter krävs",
|
||||||
"noVNC encountered an error:": "noVNC stötte på ett problem:",
|
"noVNC encountered an error:": "noVNC stötte på ett problem:",
|
||||||
"Hide/Show the control bar": "Göm/Visa kontrollbaren",
|
"Hide/Show the control bar": "Göm/Visa kontrollbaren",
|
||||||
|
"Drag": "Dra",
|
||||||
"Move/Drag Viewport": "Flytta/Dra Vyn",
|
"Move/Drag Viewport": "Flytta/Dra Vyn",
|
||||||
"viewport drag": "dra vy",
|
|
||||||
"Active Mouse Button": "Aktiv musknapp",
|
|
||||||
"No mousebutton": "Ingen musknapp",
|
|
||||||
"Left mousebutton": "Vänster musknapp",
|
|
||||||
"Middle mousebutton": "Mitten-musknapp",
|
|
||||||
"Right mousebutton": "Höger musknapp",
|
|
||||||
"Keyboard": "Tangentbord",
|
"Keyboard": "Tangentbord",
|
||||||
"Show Keyboard": "Visa Tangentbord",
|
"Show Keyboard": "Visa Tangentbord",
|
||||||
"Extra keys": "Extraknappar",
|
"Extra keys": "Extraknappar",
|
||||||
@ -55,6 +50,8 @@
|
|||||||
"Local Scaling": "Lokal Skalning",
|
"Local Scaling": "Lokal Skalning",
|
||||||
"Remote Resizing": "Ändra Storlek",
|
"Remote Resizing": "Ändra Storlek",
|
||||||
"Advanced": "Avancerat",
|
"Advanced": "Avancerat",
|
||||||
|
"Quality:": "Kvalitet:",
|
||||||
|
"Compression level:": "Kompressionsnivå:",
|
||||||
"Repeater ID:": "Repeater-ID:",
|
"Repeater ID:": "Repeater-ID:",
|
||||||
"WebSocket": "WebSocket",
|
"WebSocket": "WebSocket",
|
||||||
"Encrypt": "Kryptera",
|
"Encrypt": "Kryptera",
|
||||||
@ -65,9 +62,11 @@
|
|||||||
"Reconnect Delay (ms):": "Fördröjning (ms):",
|
"Reconnect Delay (ms):": "Fördröjning (ms):",
|
||||||
"Show Dot when No Cursor": "Visa prick när ingen muspekare finns",
|
"Show Dot when No Cursor": "Visa prick när ingen muspekare finns",
|
||||||
"Logging:": "Loggning:",
|
"Logging:": "Loggning:",
|
||||||
|
"Version:": "Version:",
|
||||||
"Disconnect": "Koppla från",
|
"Disconnect": "Koppla från",
|
||||||
"Connect": "Anslut",
|
"Connect": "Anslut",
|
||||||
|
"Username:": "Användarnamn:",
|
||||||
"Password:": "Lösenord:",
|
"Password:": "Lösenord:",
|
||||||
"Send Password": "Skicka lösenord",
|
"Send Credentials": "Skicka Användaruppgifter",
|
||||||
"Cancel": "Avbryt"
|
"Cancel": "Avbryt"
|
||||||
}
|
}
|
||||||
@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"Connecting...": "链接中...",
|
"Connecting...": "连接中...",
|
||||||
"Disconnecting...": "正在中断连接...",
|
"Disconnecting...": "正在断开连接...",
|
||||||
"Reconnecting...": "重新链接中...",
|
"Reconnecting...": "重新连接中...",
|
||||||
"Internal error": "内部错误",
|
"Internal error": "内部错误",
|
||||||
"Must set host": "请提供主机名",
|
"Must set host": "请提供主机名",
|
||||||
"Connected (encrypted) to ": "已加密链接到",
|
"Connected (encrypted) to ": "已连接到(加密)",
|
||||||
"Connected (unencrypted) to ": "未加密链接到",
|
"Connected (unencrypted) to ": "已连接到(未加密)",
|
||||||
"Something went wrong, connection is closed": "发生错误,链接已关闭",
|
"Something went wrong, connection is closed": "发生错误,连接已关闭",
|
||||||
"Failed to connect to server": "无法链接到服务器",
|
"Failed to connect to server": "无法连接到服务器",
|
||||||
"Disconnected": "链接已中断",
|
"Disconnected": "已断开连接",
|
||||||
"New connection has been rejected with reason: ": "链接被拒绝,原因:",
|
"New connection has been rejected with reason: ": "连接被拒绝,原因:",
|
||||||
"New connection has been rejected": "链接被拒绝",
|
"New connection has been rejected": "连接被拒绝",
|
||||||
"Password is required": "请提供密码",
|
"Password is required": "请提供密码",
|
||||||
"noVNC encountered an error:": "noVNC 遇到一个错误:",
|
"noVNC encountered an error:": "noVNC 遇到一个错误:",
|
||||||
"Hide/Show the control bar": "显示/隐藏控制列",
|
"Hide/Show the control bar": "显示/隐藏控制栏",
|
||||||
"Move/Drag Viewport": "拖放显示范围",
|
"Move/Drag Viewport": "拖放显示范围",
|
||||||
"viewport drag": "显示范围拖放",
|
"viewport drag": "显示范围拖放",
|
||||||
"Active Mouse Button": "启动鼠标按鍵",
|
"Active Mouse Button": "启动鼠标按鍵",
|
||||||
@ -43,10 +43,10 @@
|
|||||||
"Reset": "重置",
|
"Reset": "重置",
|
||||||
"Clipboard": "剪贴板",
|
"Clipboard": "剪贴板",
|
||||||
"Clear": "清除",
|
"Clear": "清除",
|
||||||
"Fullscreen": "全屏幕",
|
"Fullscreen": "全屏",
|
||||||
"Settings": "设置",
|
"Settings": "设置",
|
||||||
"Shared Mode": "分享模式",
|
"Shared Mode": "分享模式",
|
||||||
"View Only": "仅检视",
|
"View Only": "仅查看",
|
||||||
"Clip to Window": "限制/裁切窗口大小",
|
"Clip to Window": "限制/裁切窗口大小",
|
||||||
"Scaling Mode:": "缩放模式:",
|
"Scaling Mode:": "缩放模式:",
|
||||||
"None": "无",
|
"None": "无",
|
||||||
@ -59,11 +59,11 @@
|
|||||||
"Host:": "主机:",
|
"Host:": "主机:",
|
||||||
"Port:": "端口:",
|
"Port:": "端口:",
|
||||||
"Path:": "路径:",
|
"Path:": "路径:",
|
||||||
"Automatic Reconnect": "自动重新链接",
|
"Automatic Reconnect": "自动重新连接",
|
||||||
"Reconnect Delay (ms):": "重新链接间隔 (ms):",
|
"Reconnect Delay (ms):": "重新连接间隔 (ms):",
|
||||||
"Logging:": "日志级别:",
|
"Logging:": "日志级别:",
|
||||||
"Disconnect": "终端链接",
|
"Disconnect": "中断连接",
|
||||||
"Connect": "链接",
|
"Connect": "连接",
|
||||||
"Password:": "密码:",
|
"Password:": "密码:",
|
||||||
"Cancel": "取消"
|
"Cancel": "取消"
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC base CSS
|
* noVNC base CSS
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
|
* noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
|
||||||
* This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
|
* This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
|
||||||
*/
|
*/
|
||||||
@ -83,8 +83,20 @@ html {
|
|||||||
* ----------------------------------------
|
* ----------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
input[type=input], input[type=password], input[type=number],
|
input:not([type]),
|
||||||
input:not([type]), textarea {
|
input[type=date],
|
||||||
|
input[type=datetime-local],
|
||||||
|
input[type=email],
|
||||||
|
input[type=month],
|
||||||
|
input[type=number],
|
||||||
|
input[type=password],
|
||||||
|
input[type=search],
|
||||||
|
input[type=tel],
|
||||||
|
input[type=text],
|
||||||
|
input[type=time],
|
||||||
|
input[type=url],
|
||||||
|
input[type=week],
|
||||||
|
textarea {
|
||||||
/* Disable default rendering */
|
/* Disable default rendering */
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
@ -98,7 +110,11 @@ input:not([type]), textarea {
|
|||||||
background: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240));
|
background: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240));
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=button], input[type=submit], select {
|
input[type=button],
|
||||||
|
input[type=color],
|
||||||
|
input[type=reset],
|
||||||
|
input[type=submit],
|
||||||
|
select {
|
||||||
/* Disable default rendering */
|
/* Disable default rendering */
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
@ -116,7 +132,10 @@ input[type=button], input[type=submit], select {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=button], input[type=submit] {
|
input[type=button],
|
||||||
|
input[type=color],
|
||||||
|
input[type=reset],
|
||||||
|
input[type=submit] {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
@ -126,35 +145,72 @@ option {
|
|||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=input]:focus, input[type=password]:focus,
|
input:not([type]):focus,
|
||||||
input:not([type]):focus, input[type=button]:focus,
|
input[type=button]:focus,
|
||||||
|
input[type=color]:focus,
|
||||||
|
input[type=date]:focus,
|
||||||
|
input[type=datetime-local]:focus,
|
||||||
|
input[type=email]:focus,
|
||||||
|
input[type=month]:focus,
|
||||||
|
input[type=number]:focus,
|
||||||
|
input[type=password]:focus,
|
||||||
|
input[type=reset]:focus,
|
||||||
|
input[type=search]:focus,
|
||||||
input[type=submit]:focus,
|
input[type=submit]:focus,
|
||||||
textarea:focus, select:focus {
|
input[type=tel]:focus,
|
||||||
|
input[type=text]:focus,
|
||||||
|
input[type=time]:focus,
|
||||||
|
input[type=url]:focus,
|
||||||
|
input[type=week]:focus,
|
||||||
|
select:focus,
|
||||||
|
textarea:focus {
|
||||||
box-shadow: 0px 0px 3px rgba(74, 144, 217, 0.5);
|
box-shadow: 0px 0px 3px rgba(74, 144, 217, 0.5);
|
||||||
border-color: rgb(74, 144, 217);
|
border-color: rgb(74, 144, 217);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=button]::-moz-focus-inner,
|
input[type=button]::-moz-focus-inner,
|
||||||
|
input[type=color]::-moz-focus-inner,
|
||||||
|
input[type=reset]::-moz-focus-inner,
|
||||||
input[type=submit]::-moz-focus-inner {
|
input[type=submit]::-moz-focus-inner {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=input]:disabled, input[type=password]:disabled,
|
input:not([type]):disabled,
|
||||||
input:not([type]):disabled, input[type=button]:disabled,
|
input[type=button]:disabled,
|
||||||
input[type=submit]:disabled, input[type=number]:disabled,
|
input[type=color]:disabled,
|
||||||
textarea:disabled, select:disabled {
|
input[type=date]:disabled,
|
||||||
|
input[type=datetime-local]:disabled,
|
||||||
|
input[type=email]:disabled,
|
||||||
|
input[type=month]:disabled,
|
||||||
|
input[type=number]:disabled,
|
||||||
|
input[type=password]:disabled,
|
||||||
|
input[type=reset]:disabled,
|
||||||
|
input[type=search]:disabled,
|
||||||
|
input[type=submit]:disabled,
|
||||||
|
input[type=tel]:disabled,
|
||||||
|
input[type=text]:disabled,
|
||||||
|
input[type=time]:disabled,
|
||||||
|
input[type=url]:disabled,
|
||||||
|
input[type=week]:disabled,
|
||||||
|
select:disabled,
|
||||||
|
textarea:disabled {
|
||||||
color: rgb(128, 128, 128);
|
color: rgb(128, 128, 128);
|
||||||
background: rgb(240, 240, 240);
|
background: rgb(240, 240, 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=button]:active, input[type=submit]:active,
|
input[type=button]:active,
|
||||||
|
input[type=color]:active,
|
||||||
|
input[type=reset]:active,
|
||||||
|
input[type=submit]:active,
|
||||||
select:active {
|
select:active {
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root:not(.noVNC_touch) input[type=button]:hover:not(:disabled),
|
:root:not(.noVNC_touch) input[type=button]:hover:not(:disabled),
|
||||||
|
:root:not(.noVNC_touch) input[type=color]:hover:not(:disabled),
|
||||||
|
:root:not(.noVNC_touch) input[type=reset]:hover:not(:disabled),
|
||||||
:root:not(.noVNC_touch) input[type=submit]:hover:not(:disabled),
|
:root:not(.noVNC_touch) input[type=submit]:hover:not(:disabled),
|
||||||
:root:not(.noVNC_touch) select:hover:not(:disabled) {
|
:root:not(.noVNC_touch) select:hover:not(:disabled) {
|
||||||
background: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
|
background: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
|
||||||
@ -579,7 +635,7 @@ select:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extra manual keys */
|
/* Extra manual keys */
|
||||||
:root:not(.noVNC_connected) #noVNC_extra_keys {
|
:root:not(.noVNC_connected) #noVNC_toggle_extra_keys_button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,6 +687,16 @@ select:active {
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Version */
|
||||||
|
|
||||||
|
.noVNC_version_wrapper {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noVNC_version {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Connection Controls */
|
/* Connection Controls */
|
||||||
:root:not(.noVNC_connected) #noVNC_disconnect_button {
|
:root:not(.noVNC_connected) #noVNC_disconnect_button {
|
||||||
display: none;
|
display: none;
|
||||||
@ -780,19 +846,23 @@ select:active {
|
|||||||
* ----------------------------------------
|
* ----------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#noVNC_password_dlg {
|
#noVNC_credentials_dlg {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
transform: translateY(-50px);
|
transform: translateY(-50px);
|
||||||
}
|
}
|
||||||
#noVNC_password_dlg.noVNC_open {
|
#noVNC_credentials_dlg.noVNC_open {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
#noVNC_password_dlg ul {
|
#noVNC_credentials_dlg ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
.noVNC_hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------
|
/* ----------------------------------------
|
||||||
* Main Area
|
* Main Area
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import * as Log from '../core/util/logging.js';
|
import * as Log from '../core/util/logging.js';
|
||||||
import _, { l10n } from './localization.js';
|
import _, { l10n } from './localization.js';
|
||||||
import { isTouchDevice, isSafari, isIOS, isAndroid, dragThreshold }
|
import { isTouchDevice, isSafari, hasScrollbarGutter, dragThreshold }
|
||||||
from '../core/util/browser.js';
|
from '../core/util/browser.js';
|
||||||
import { setCapture, getPointerEvent } from '../core/util/events.js';
|
import { setCapture, getPointerEvent } from '../core/util/events.js';
|
||||||
import KeyTable from "../core/input/keysym.js";
|
import KeyTable from "../core/input/keysym.js";
|
||||||
@ -17,6 +17,8 @@ import Keyboard from "../core/input/keyboard.js";
|
|||||||
import RFB from "../core/rfb.js";
|
import RFB from "../core/rfb.js";
|
||||||
import * as WebUtil from "./webutil.js";
|
import * as WebUtil from "./webutil.js";
|
||||||
|
|
||||||
|
const PAGE_TITLE = "noVNC";
|
||||||
|
|
||||||
const UI = {
|
const UI = {
|
||||||
|
|
||||||
connected: false,
|
connected: false,
|
||||||
@ -35,9 +37,11 @@ const UI = {
|
|||||||
lastKeyboardinput: null,
|
lastKeyboardinput: null,
|
||||||
defaultKeyboardinputLen: 100,
|
defaultKeyboardinputLen: 100,
|
||||||
|
|
||||||
inhibit_reconnect: true,
|
inhibitReconnect: true,
|
||||||
reconnect_callback: null,
|
reconnectCallback: null,
|
||||||
reconnect_password: null,
|
reconnectPassword: null,
|
||||||
|
|
||||||
|
fullScreen: false,
|
||||||
|
|
||||||
prime() {
|
prime() {
|
||||||
return WebUtil.initSettings().then(() => {
|
return WebUtil.initSettings().then(() => {
|
||||||
@ -59,6 +63,17 @@ const UI = {
|
|||||||
// Translate the DOM
|
// Translate the DOM
|
||||||
l10n.translateDOM();
|
l10n.translateDOM();
|
||||||
|
|
||||||
|
WebUtil.fetchJSON('./package.json')
|
||||||
|
.then((packageInfo) => {
|
||||||
|
Array.from(document.getElementsByClassName('noVNC_version')).forEach(el => el.innerText = packageInfo.version);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
Log.Error("Couldn't fetch package.json: " + err);
|
||||||
|
Array.from(document.getElementsByClassName('noVNC_version_wrapper'))
|
||||||
|
.concat(Array.from(document.getElementsByClassName('noVNC_version_separator')))
|
||||||
|
.forEach(el => el.style.display = 'none');
|
||||||
|
});
|
||||||
|
|
||||||
// Adapt the interface for touch screen devices
|
// Adapt the interface for touch screen devices
|
||||||
if (isTouchDevice) {
|
if (isTouchDevice) {
|
||||||
document.documentElement.classList.add("noVNC_touch");
|
document.documentElement.classList.add("noVNC_touch");
|
||||||
@ -145,10 +160,13 @@ const UI = {
|
|||||||
/* Populate the controls if defaults are provided in the URL */
|
/* Populate the controls if defaults are provided in the URL */
|
||||||
UI.initSetting('host', window.location.hostname);
|
UI.initSetting('host', window.location.hostname);
|
||||||
UI.initSetting('port', port);
|
UI.initSetting('port', port);
|
||||||
|
UI.initSetting('token', window.location.token);
|
||||||
UI.initSetting('encrypt', (window.location.protocol === "https:"));
|
UI.initSetting('encrypt', (window.location.protocol === "https:"));
|
||||||
UI.initSetting('view_clip', false);
|
UI.initSetting('view_clip', false);
|
||||||
UI.initSetting('resize', 'off');
|
UI.initSetting('resize', 'off');
|
||||||
UI.initSetting('shared', false);
|
UI.initSetting('quality', 6);
|
||||||
|
UI.initSetting('compression', 2);
|
||||||
|
UI.initSetting('shared', true);
|
||||||
UI.initSetting('view_only', false);
|
UI.initSetting('view_only', false);
|
||||||
UI.initSetting('show_dot', false);
|
UI.initSetting('show_dot', false);
|
||||||
UI.initSetting('path', 'websockify');
|
UI.initSetting('path', 'websockify');
|
||||||
@ -219,14 +237,6 @@ const UI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
addTouchSpecificHandlers() {
|
addTouchSpecificHandlers() {
|
||||||
document.getElementById("noVNC_mouse_button0")
|
|
||||||
.addEventListener('click', () => UI.setMouseButton(1));
|
|
||||||
document.getElementById("noVNC_mouse_button1")
|
|
||||||
.addEventListener('click', () => UI.setMouseButton(2));
|
|
||||||
document.getElementById("noVNC_mouse_button2")
|
|
||||||
.addEventListener('click', () => UI.setMouseButton(4));
|
|
||||||
document.getElementById("noVNC_mouse_button4")
|
|
||||||
.addEventListener('click', () => UI.setMouseButton(0));
|
|
||||||
document.getElementById("noVNC_keyboard_button")
|
document.getElementById("noVNC_keyboard_button")
|
||||||
.addEventListener('click', UI.toggleVirtualKeyboard);
|
.addEventListener('click', UI.toggleVirtualKeyboard);
|
||||||
|
|
||||||
@ -303,17 +313,17 @@ const UI = {
|
|||||||
document.getElementById("noVNC_cancel_reconnect_button")
|
document.getElementById("noVNC_cancel_reconnect_button")
|
||||||
.addEventListener('click', UI.cancelReconnect);
|
.addEventListener('click', UI.cancelReconnect);
|
||||||
|
|
||||||
document.getElementById("noVNC_password_button")
|
document.getElementById("noVNC_credentials_button")
|
||||||
.addEventListener('click', UI.setPassword);
|
.addEventListener('click', UI.setCredentials);
|
||||||
},
|
},
|
||||||
|
|
||||||
addClipboardHandlers() {
|
addClipboardHandlers() {
|
||||||
document.getElementById("noVNC_clipboard_button")
|
document.getElementById("noVNC_clipboard_button")
|
||||||
.addEventListener('click', UI.toggleClipboardPanel);
|
.addEventListener('click', UI.toggleClipboardPanel);
|
||||||
document.getElementById("noVNC_clipboard_text")
|
|
||||||
.addEventListener('change', UI.clipboardSend);
|
|
||||||
document.getElementById("noVNC_clipboard_clear_button")
|
document.getElementById("noVNC_clipboard_clear_button")
|
||||||
.addEventListener('click', UI.clipboardClear);
|
.addEventListener('click', UI.clipboardClear);
|
||||||
|
document.getElementById("noVNC_clipboard_send_button")
|
||||||
|
.addEventListener('click', UI.clipboardSend);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Add a call to save settings when the element changes,
|
// Add a call to save settings when the element changes,
|
||||||
@ -334,6 +344,10 @@ const UI = {
|
|||||||
UI.addSettingChangeHandler('resize');
|
UI.addSettingChangeHandler('resize');
|
||||||
UI.addSettingChangeHandler('resize', UI.applyResizeMode);
|
UI.addSettingChangeHandler('resize', UI.applyResizeMode);
|
||||||
UI.addSettingChangeHandler('resize', UI.updateViewClip);
|
UI.addSettingChangeHandler('resize', UI.updateViewClip);
|
||||||
|
UI.addSettingChangeHandler('quality');
|
||||||
|
UI.addSettingChangeHandler('quality', UI.updateQuality);
|
||||||
|
UI.addSettingChangeHandler('compression');
|
||||||
|
UI.addSettingChangeHandler('compression', UI.updateCompression);
|
||||||
UI.addSettingChangeHandler('view_clip');
|
UI.addSettingChangeHandler('view_clip');
|
||||||
UI.addSettingChangeHandler('view_clip', UI.updateViewClip);
|
UI.addSettingChangeHandler('view_clip', UI.updateViewClip);
|
||||||
UI.addSettingChangeHandler('shared');
|
UI.addSettingChangeHandler('shared');
|
||||||
@ -375,25 +389,25 @@ const UI = {
|
|||||||
document.documentElement.classList.remove("noVNC_disconnecting");
|
document.documentElement.classList.remove("noVNC_disconnecting");
|
||||||
document.documentElement.classList.remove("noVNC_reconnecting");
|
document.documentElement.classList.remove("noVNC_reconnecting");
|
||||||
|
|
||||||
const transition_elem = document.getElementById("noVNC_transition_text");
|
const transitionElem = document.getElementById("noVNC_transition_text");
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'init':
|
case 'init':
|
||||||
break;
|
break;
|
||||||
case 'connecting':
|
case 'connecting':
|
||||||
transition_elem.textContent = _("Connecting...");
|
transitionElem.textContent = _("Connecting...");
|
||||||
document.documentElement.classList.add("noVNC_connecting");
|
document.documentElement.classList.add("noVNC_connecting");
|
||||||
break;
|
break;
|
||||||
case 'connected':
|
case 'connected':
|
||||||
document.documentElement.classList.add("noVNC_connected");
|
document.documentElement.classList.add("noVNC_connected");
|
||||||
break;
|
break;
|
||||||
case 'disconnecting':
|
case 'disconnecting':
|
||||||
transition_elem.textContent = _("Disconnecting...");
|
transitionElem.textContent = _("Disconnecting...");
|
||||||
document.documentElement.classList.add("noVNC_disconnecting");
|
document.documentElement.classList.add("noVNC_disconnecting");
|
||||||
break;
|
break;
|
||||||
case 'disconnected':
|
case 'disconnected':
|
||||||
break;
|
break;
|
||||||
case 'reconnecting':
|
case 'reconnecting':
|
||||||
transition_elem.textContent = _("Reconnecting...");
|
transitionElem.textContent = _("Reconnecting...");
|
||||||
document.documentElement.classList.add("noVNC_reconnecting");
|
document.documentElement.classList.add("noVNC_reconnecting");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -411,7 +425,6 @@ const UI = {
|
|||||||
UI.disableSetting('port');
|
UI.disableSetting('port');
|
||||||
UI.disableSetting('path');
|
UI.disableSetting('path');
|
||||||
UI.disableSetting('repeaterID');
|
UI.disableSetting('repeaterID');
|
||||||
UI.setMouseButton(1);
|
|
||||||
|
|
||||||
// Hide the controlbar after 2 seconds
|
// Hide the controlbar after 2 seconds
|
||||||
UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000);
|
UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000);
|
||||||
@ -426,38 +439,35 @@ const UI = {
|
|||||||
UI.keepControlbar();
|
UI.keepControlbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// State change closes the password dialog
|
// State change closes dialogs as they may not be relevant
|
||||||
document.getElementById('noVNC_password_dlg')
|
// anymore
|
||||||
|
UI.closeAllPanels();
|
||||||
|
document.getElementById('noVNC_credentials_dlg')
|
||||||
.classList.remove('noVNC_open');
|
.classList.remove('noVNC_open');
|
||||||
},
|
},
|
||||||
|
|
||||||
showStatus(text, status_type, time) {
|
showStatus(text, statusType, time) {
|
||||||
const statusElem = document.getElementById('noVNC_status');
|
const statusElem = document.getElementById('noVNC_status');
|
||||||
|
|
||||||
clearTimeout(UI.statusTimeout);
|
if (typeof statusType === 'undefined') {
|
||||||
|
statusType = 'normal';
|
||||||
if (typeof status_type === 'undefined') {
|
|
||||||
status_type = 'normal';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't overwrite more severe visible statuses and never
|
// Don't overwrite more severe visible statuses and never
|
||||||
// errors. Only shows the first error.
|
// errors. Only shows the first error.
|
||||||
let visible_status_type = 'none';
|
|
||||||
if (statusElem.classList.contains("noVNC_open")) {
|
if (statusElem.classList.contains("noVNC_open")) {
|
||||||
if (statusElem.classList.contains("noVNC_status_error")) {
|
if (statusElem.classList.contains("noVNC_status_error")) {
|
||||||
visible_status_type = 'error';
|
return;
|
||||||
} else if (statusElem.classList.contains("noVNC_status_warn")) {
|
}
|
||||||
visible_status_type = 'warn';
|
if (statusElem.classList.contains("noVNC_status_warn") &&
|
||||||
} else {
|
statusType === 'normal') {
|
||||||
visible_status_type = 'normal';
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (visible_status_type === 'error' ||
|
|
||||||
(visible_status_type === 'warn' && status_type === 'normal')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (status_type) {
|
clearTimeout(UI.statusTimeout);
|
||||||
|
|
||||||
|
switch (statusType) {
|
||||||
case 'error':
|
case 'error':
|
||||||
statusElem.classList.remove("noVNC_status_warn");
|
statusElem.classList.remove("noVNC_status_warn");
|
||||||
statusElem.classList.remove("noVNC_status_normal");
|
statusElem.classList.remove("noVNC_status_normal");
|
||||||
@ -487,7 +497,7 @@ const UI = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Error messages do not timeout
|
// Error messages do not timeout
|
||||||
if (status_type !== 'error') {
|
if (statusType !== 'error') {
|
||||||
UI.statusTimeout = window.setTimeout(UI.hideStatus, time);
|
UI.statusTimeout = window.setTimeout(UI.hideStatus, time);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -507,6 +517,13 @@ const UI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
idleControlbar() {
|
idleControlbar() {
|
||||||
|
// Don't fade if a child of the control bar has focus
|
||||||
|
if (document.getElementById('noVNC_control_bar')
|
||||||
|
.contains(document.activeElement) && document.hasFocus()) {
|
||||||
|
UI.activateControlbar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('noVNC_control_bar_anchor')
|
document.getElementById('noVNC_control_bar_anchor')
|
||||||
.classList.add("noVNC_idle");
|
.classList.add("noVNC_idle");
|
||||||
},
|
},
|
||||||
@ -524,6 +541,7 @@ const UI = {
|
|||||||
UI.closeAllPanels();
|
UI.closeAllPanels();
|
||||||
document.getElementById('noVNC_control_bar')
|
document.getElementById('noVNC_control_bar')
|
||||||
.classList.remove("noVNC_open");
|
.classList.remove("noVNC_open");
|
||||||
|
UI.rfb.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleControlbar() {
|
toggleControlbar() {
|
||||||
@ -821,6 +839,8 @@ const UI = {
|
|||||||
UI.updateSetting('encrypt');
|
UI.updateSetting('encrypt');
|
||||||
UI.updateSetting('view_clip');
|
UI.updateSetting('view_clip');
|
||||||
UI.updateSetting('resize');
|
UI.updateSetting('resize');
|
||||||
|
UI.updateSetting('quality');
|
||||||
|
UI.updateSetting('compression');
|
||||||
UI.updateSetting('shared');
|
UI.updateSetting('shared');
|
||||||
UI.updateSetting('view_only');
|
UI.updateSetting('view_only');
|
||||||
UI.updateSetting('path');
|
UI.updateSetting('path');
|
||||||
@ -927,6 +947,8 @@ const UI = {
|
|||||||
UI.closeClipboardPanel();
|
UI.closeClipboardPanel();
|
||||||
} else {
|
} else {
|
||||||
UI.openClipboardPanel();
|
UI.openClipboardPanel();
|
||||||
|
setTimeout(() => document
|
||||||
|
.getElementById('noVNC_clipboard_text').focus(), 100);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -938,14 +960,13 @@ const UI = {
|
|||||||
|
|
||||||
clipboardClear() {
|
clipboardClear() {
|
||||||
document.getElementById('noVNC_clipboard_text').value = "";
|
document.getElementById('noVNC_clipboard_text').value = "";
|
||||||
UI.rfb.clipboardPasteFrom("");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clipboardSend() {
|
clipboardSend() {
|
||||||
const text = document.getElementById('noVNC_clipboard_text').value;
|
const text = document.getElementById('noVNC_clipboard_text').value;
|
||||||
Log.Debug(">> UI.clipboardSend: " + text.substr(0, 40) + "...");
|
UI.rfb.sendText(text);
|
||||||
UI.rfb.clipboardPasteFrom(text);
|
UI.closeClipboardPanel();
|
||||||
Log.Debug("<< UI.clipboardSend");
|
UI.focusOnConsole();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* ------^-------
|
/* ------^-------
|
||||||
@ -974,10 +995,11 @@ const UI = {
|
|||||||
const host = UI.getSetting('host');
|
const host = UI.getSetting('host');
|
||||||
const port = UI.getSetting('port');
|
const port = UI.getSetting('port');
|
||||||
const path = UI.getSetting('path');
|
const path = UI.getSetting('path');
|
||||||
|
const token = UI.getSetting('token')
|
||||||
|
|
||||||
if (typeof password === 'undefined') {
|
if (typeof password === 'undefined') {
|
||||||
password = WebUtil.getConfigVar('password');
|
password = WebUtil.getConfigVar('password');
|
||||||
UI.reconnect_password = password;
|
UI.reconnectPassword = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password === null) {
|
if (password === null) {
|
||||||
@ -992,7 +1014,6 @@ const UI = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI.closeAllPanels();
|
|
||||||
UI.closeConnectPanel();
|
UI.closeConnectPanel();
|
||||||
|
|
||||||
UI.updateVisualState('connecting');
|
UI.updateVisualState('connecting');
|
||||||
@ -1006,16 +1027,10 @@ const UI = {
|
|||||||
url += ':' + port;
|
url += ':' + port;
|
||||||
}
|
}
|
||||||
url += '/' + path;
|
url += '/' + path;
|
||||||
|
url += '?token=' + token;
|
||||||
var urlParams = new URLSearchParams(window.location.search);
|
|
||||||
var param = urlParams.get('token');
|
|
||||||
if (param) {
|
|
||||||
url += "?token=" + param
|
|
||||||
}
|
|
||||||
|
|
||||||
UI.rfb = new RFB(document.getElementById('noVNC_container'), url,
|
UI.rfb = new RFB(document.getElementById('noVNC_container'), url,
|
||||||
{ shared: UI.getSetting('shared'),
|
{ shared: UI.getSetting('shared'),
|
||||||
showDotCursor: UI.getSetting('show_dot'),
|
|
||||||
repeaterID: UI.getSetting('repeaterID'),
|
repeaterID: UI.getSetting('repeaterID'),
|
||||||
credentials: { password: password } });
|
credentials: { password: password } });
|
||||||
UI.rfb.addEventListener("connect", UI.connectFinished);
|
UI.rfb.addEventListener("connect", UI.connectFinished);
|
||||||
@ -1029,18 +1044,20 @@ const UI = {
|
|||||||
UI.rfb.clipViewport = UI.getSetting('view_clip');
|
UI.rfb.clipViewport = UI.getSetting('view_clip');
|
||||||
UI.rfb.scaleViewport = UI.getSetting('resize') === 'scale';
|
UI.rfb.scaleViewport = UI.getSetting('resize') === 'scale';
|
||||||
UI.rfb.resizeSession = UI.getSetting('resize') === 'remote';
|
UI.rfb.resizeSession = UI.getSetting('resize') === 'remote';
|
||||||
|
UI.rfb.qualityLevel = parseInt(UI.getSetting('quality'));
|
||||||
|
UI.rfb.compressionLevel = parseInt(UI.getSetting('compression'));
|
||||||
|
UI.rfb.showDotCursor = UI.getSetting('show_dot');
|
||||||
|
|
||||||
UI.updateViewOnly(); // requires UI.rfb
|
UI.updateViewOnly(); // requires UI.rfb
|
||||||
},
|
},
|
||||||
|
|
||||||
disconnect() {
|
disconnect() {
|
||||||
UI.closeAllPanels();
|
|
||||||
UI.rfb.disconnect();
|
UI.rfb.disconnect();
|
||||||
|
|
||||||
UI.connected = false;
|
UI.connected = false;
|
||||||
|
|
||||||
// Disable automatic reconnecting
|
// Disable automatic reconnecting
|
||||||
UI.inhibit_reconnect = true;
|
UI.inhibitReconnect = true;
|
||||||
|
|
||||||
UI.updateVisualState('disconnecting');
|
UI.updateVisualState('disconnecting');
|
||||||
|
|
||||||
@ -1048,20 +1065,20 @@ const UI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
reconnect() {
|
reconnect() {
|
||||||
UI.reconnect_callback = null;
|
UI.reconnectCallback = null;
|
||||||
|
|
||||||
// if reconnect has been disabled in the meantime, do nothing.
|
// if reconnect has been disabled in the meantime, do nothing.
|
||||||
if (UI.inhibit_reconnect) {
|
if (UI.inhibitReconnect) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI.connect(null, UI.reconnect_password);
|
UI.connect(null, UI.reconnectPassword);
|
||||||
},
|
},
|
||||||
|
|
||||||
cancelReconnect() {
|
cancelReconnect() {
|
||||||
if (UI.reconnect_callback !== null) {
|
if (UI.reconnectCallback !== null) {
|
||||||
clearTimeout(UI.reconnect_callback);
|
clearTimeout(UI.reconnectCallback);
|
||||||
UI.reconnect_callback = null;
|
UI.reconnectCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI.updateVisualState('disconnected');
|
UI.updateVisualState('disconnected');
|
||||||
@ -1072,13 +1089,13 @@ const UI = {
|
|||||||
|
|
||||||
connectFinished(e) {
|
connectFinished(e) {
|
||||||
UI.connected = true;
|
UI.connected = true;
|
||||||
UI.inhibit_reconnect = false;
|
UI.inhibitReconnect = false;
|
||||||
|
|
||||||
let msg;
|
let msg;
|
||||||
if (UI.getSetting('encrypt')) {
|
if (UI.getSetting('encrypt')) {
|
||||||
msg = _("Connected (encrypted) to ") + UI.desktopName;
|
msg = _("Connected");
|
||||||
} else {
|
} else {
|
||||||
msg = _("Connected (unencrypted) to ") + UI.desktopName;
|
msg = _("Connected")
|
||||||
}
|
}
|
||||||
UI.showStatus(msg);
|
UI.showStatus(msg);
|
||||||
UI.updateVisualState('connected');
|
UI.updateVisualState('connected');
|
||||||
@ -1106,17 +1123,19 @@ const UI = {
|
|||||||
} else {
|
} else {
|
||||||
UI.showStatus(_("Failed to connect to server"), 'error');
|
UI.showStatus(_("Failed to connect to server"), 'error');
|
||||||
}
|
}
|
||||||
} else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) {
|
} else if (UI.getSetting('reconnect', false) === true && !UI.inhibitReconnect) {
|
||||||
UI.updateVisualState('reconnecting');
|
UI.updateVisualState('reconnecting');
|
||||||
|
|
||||||
const delay = parseInt(UI.getSetting('reconnect_delay'));
|
const delay = parseInt(UI.getSetting('reconnect_delay'));
|
||||||
UI.reconnect_callback = setTimeout(UI.reconnect, delay);
|
UI.reconnectCallback = setTimeout(UI.reconnect, delay);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
UI.updateVisualState('disconnected');
|
UI.updateVisualState('disconnected');
|
||||||
UI.showStatus(_("Disconnected"), 'normal');
|
UI.showStatus(_("Disconnected"), 'normal');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.title = PAGE_TITLE;
|
||||||
|
|
||||||
UI.openControlbar();
|
UI.openControlbar();
|
||||||
UI.openConnectPanel();
|
UI.openConnectPanel();
|
||||||
},
|
},
|
||||||
@ -1143,27 +1162,46 @@ const UI = {
|
|||||||
|
|
||||||
credentials(e) {
|
credentials(e) {
|
||||||
// FIXME: handle more types
|
// FIXME: handle more types
|
||||||
document.getElementById('noVNC_password_dlg')
|
|
||||||
|
document.getElementById("noVNC_username_block").classList.remove("noVNC_hidden");
|
||||||
|
document.getElementById("noVNC_password_block").classList.remove("noVNC_hidden");
|
||||||
|
|
||||||
|
let inputFocus = "none";
|
||||||
|
if (e.detail.types.indexOf("username") === -1) {
|
||||||
|
document.getElementById("noVNC_username_block").classList.add("noVNC_hidden");
|
||||||
|
} else {
|
||||||
|
inputFocus = inputFocus === "none" ? "noVNC_username_input" : inputFocus;
|
||||||
|
}
|
||||||
|
if (e.detail.types.indexOf("password") === -1) {
|
||||||
|
document.getElementById("noVNC_password_block").classList.add("noVNC_hidden");
|
||||||
|
} else {
|
||||||
|
inputFocus = inputFocus === "none" ? "noVNC_password_input" : inputFocus;
|
||||||
|
}
|
||||||
|
document.getElementById('noVNC_credentials_dlg')
|
||||||
.classList.add('noVNC_open');
|
.classList.add('noVNC_open');
|
||||||
|
|
||||||
setTimeout(() => document
|
setTimeout(() => document
|
||||||
.getElementById('noVNC_password_input').focus(), 100);
|
.getElementById(inputFocus).focus(), 100);
|
||||||
|
|
||||||
Log.Warn("Server asked for a password");
|
Log.Warn("Server asked for credentials");
|
||||||
UI.showStatus(_("Password is required"), "warning");
|
UI.showStatus(_("Credentials are required"), "warning");
|
||||||
},
|
},
|
||||||
|
|
||||||
setPassword(e) {
|
setCredentials(e) {
|
||||||
// Prevent actually submitting the form
|
// Prevent actually submitting the form
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const inputElem = document.getElementById('noVNC_password_input');
|
let inputElemUsername = document.getElementById('noVNC_username_input');
|
||||||
const password = inputElem.value;
|
const username = inputElemUsername.value;
|
||||||
|
|
||||||
|
let inputElemPassword = document.getElementById('noVNC_password_input');
|
||||||
|
const password = inputElemPassword.value;
|
||||||
// Clear the input after reading the password
|
// Clear the input after reading the password
|
||||||
inputElem.value = "";
|
inputElemPassword.value = "";
|
||||||
UI.rfb.sendCredentials({ password: password });
|
|
||||||
UI.reconnect_password = password;
|
UI.rfb.sendCredentials({ username: username, password: password });
|
||||||
document.getElementById('noVNC_password_dlg')
|
UI.reconnectPassword = password;
|
||||||
|
document.getElementById('noVNC_credentials_dlg')
|
||||||
.classList.remove('noVNC_open');
|
.classList.remove('noVNC_open');
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1174,38 +1212,14 @@ const UI = {
|
|||||||
* ------v------*/
|
* ------v------*/
|
||||||
|
|
||||||
toggleFullscreen() {
|
toggleFullscreen() {
|
||||||
if (document.fullscreenElement || // alternative standard method
|
this.fullScreen = !this.fullScreen
|
||||||
document.mozFullScreenElement || // currently working methods
|
UI.rfb.scaleViewport = this.fullScreen
|
||||||
document.webkitFullscreenElement ||
|
UI.updateFullscreenButton(this.fullScreen);
|
||||||
document.msFullscreenElement) {
|
UI.focusOnConsole();
|
||||||
if (document.exitFullscreen) {
|
|
||||||
document.exitFullscreen();
|
|
||||||
} else if (document.mozCancelFullScreen) {
|
|
||||||
document.mozCancelFullScreen();
|
|
||||||
} else if (document.webkitExitFullscreen) {
|
|
||||||
document.webkitExitFullscreen();
|
|
||||||
} else if (document.msExitFullscreen) {
|
|
||||||
document.msExitFullscreen();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (document.documentElement.requestFullscreen) {
|
|
||||||
document.documentElement.requestFullscreen();
|
|
||||||
} else if (document.documentElement.mozRequestFullScreen) {
|
|
||||||
document.documentElement.mozRequestFullScreen();
|
|
||||||
} else if (document.documentElement.webkitRequestFullscreen) {
|
|
||||||
document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
|
|
||||||
} else if (document.body.msRequestFullscreen) {
|
|
||||||
document.body.msRequestFullscreen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UI.updateFullscreenButton();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateFullscreenButton() {
|
updateFullscreenButton(fullScreen) {
|
||||||
if (document.fullscreenElement || // alternative standard method
|
if (fullScreen) {
|
||||||
document.mozFullScreenElement || // currently working methods
|
|
||||||
document.webkitFullscreenElement ||
|
|
||||||
document.msFullscreenElement ) {
|
|
||||||
document.getElementById('noVNC_fullscreen_button')
|
document.getElementById('noVNC_fullscreen_button')
|
||||||
.classList.add("noVNC_selected");
|
.classList.add("noVNC_selected");
|
||||||
} else {
|
} else {
|
||||||
@ -1246,8 +1260,9 @@ const UI = {
|
|||||||
// Can't be clipping if viewport is scaled to fit
|
// Can't be clipping if viewport is scaled to fit
|
||||||
UI.forceSetting('view_clip', false);
|
UI.forceSetting('view_clip', false);
|
||||||
UI.rfb.clipViewport = false;
|
UI.rfb.clipViewport = false;
|
||||||
} else if (isIOS() || isAndroid()) {
|
} else if (!hasScrollbarGutter) {
|
||||||
// iOS and Android usually have shit scrollbars
|
// Some platforms have scrollbars that are difficult
|
||||||
|
// to use in our case, so we always use our own panning
|
||||||
UI.forceSetting('view_clip', true);
|
UI.forceSetting('view_clip', true);
|
||||||
UI.rfb.clipViewport = true;
|
UI.rfb.clipViewport = true;
|
||||||
} else {
|
} else {
|
||||||
@ -1290,30 +1305,40 @@ const UI = {
|
|||||||
viewDragButton.classList.remove("noVNC_selected");
|
viewDragButton.classList.remove("noVNC_selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Different behaviour for touch vs non-touch
|
if (UI.rfb.clipViewport) {
|
||||||
// The button is disabled instead of hidden on touch devices
|
|
||||||
if (isTouchDevice) {
|
|
||||||
viewDragButton.classList.remove("noVNC_hidden");
|
viewDragButton.classList.remove("noVNC_hidden");
|
||||||
|
|
||||||
if (UI.rfb.clipViewport) {
|
|
||||||
viewDragButton.disabled = false;
|
|
||||||
} else {
|
|
||||||
viewDragButton.disabled = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
viewDragButton.disabled = false;
|
viewDragButton.classList.add("noVNC_hidden");
|
||||||
|
|
||||||
if (UI.rfb.clipViewport) {
|
|
||||||
viewDragButton.classList.remove("noVNC_hidden");
|
|
||||||
} else {
|
|
||||||
viewDragButton.classList.add("noVNC_hidden");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/* ------^-------
|
/* ------^-------
|
||||||
* /VIEWDRAG
|
* /VIEWDRAG
|
||||||
* ==============
|
* ==============
|
||||||
|
* QUALITY
|
||||||
|
* ------v------*/
|
||||||
|
|
||||||
|
updateQuality() {
|
||||||
|
if (!UI.rfb) return;
|
||||||
|
|
||||||
|
UI.rfb.qualityLevel = parseInt(UI.getSetting('quality'));
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ------^-------
|
||||||
|
* /QUALITY
|
||||||
|
* ==============
|
||||||
|
* COMPRESSION
|
||||||
|
* ------v------*/
|
||||||
|
|
||||||
|
updateCompression() {
|
||||||
|
if (!UI.rfb) return;
|
||||||
|
|
||||||
|
UI.rfb.compressionLevel = parseInt(UI.getSetting('compression'));
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ------^-------
|
||||||
|
* /COMPRESSION
|
||||||
|
* ==============
|
||||||
* KEYBOARD
|
* KEYBOARD
|
||||||
* ------v------*/
|
* ------v------*/
|
||||||
|
|
||||||
@ -1508,20 +1533,20 @@ const UI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
sendEsc() {
|
sendEsc() {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Escape, "Escape");
|
UI.sendKey(KeyTable.XK_Escape, "Escape");
|
||||||
},
|
},
|
||||||
|
|
||||||
sendTab() {
|
sendTab() {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Tab);
|
UI.sendKey(KeyTable.XK_Tab, "Tab");
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleCtrl() {
|
toggleCtrl() {
|
||||||
const btn = document.getElementById('noVNC_toggle_ctrl_button');
|
const btn = document.getElementById('noVNC_toggle_ctrl_button');
|
||||||
if (btn.classList.contains("noVNC_selected")) {
|
if (btn.classList.contains("noVNC_selected")) {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
|
UI.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
|
||||||
btn.classList.remove("noVNC_selected");
|
btn.classList.remove("noVNC_selected");
|
||||||
} else {
|
} else {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", true);
|
UI.sendKey(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||||
btn.classList.add("noVNC_selected");
|
btn.classList.add("noVNC_selected");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1529,10 +1554,10 @@ const UI = {
|
|||||||
toggleWindows() {
|
toggleWindows() {
|
||||||
const btn = document.getElementById('noVNC_toggle_windows_button');
|
const btn = document.getElementById('noVNC_toggle_windows_button');
|
||||||
if (btn.classList.contains("noVNC_selected")) {
|
if (btn.classList.contains("noVNC_selected")) {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Super_L, "MetaLeft", false);
|
UI.sendKey(KeyTable.XK_Super_L, "MetaLeft", false);
|
||||||
btn.classList.remove("noVNC_selected");
|
btn.classList.remove("noVNC_selected");
|
||||||
} else {
|
} else {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Super_L, "MetaLeft", true);
|
UI.sendKey(KeyTable.XK_Super_L, "MetaLeft", true);
|
||||||
btn.classList.add("noVNC_selected");
|
btn.classList.add("noVNC_selected");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1540,16 +1565,42 @@ const UI = {
|
|||||||
toggleAlt() {
|
toggleAlt() {
|
||||||
const btn = document.getElementById('noVNC_toggle_alt_button');
|
const btn = document.getElementById('noVNC_toggle_alt_button');
|
||||||
if (btn.classList.contains("noVNC_selected")) {
|
if (btn.classList.contains("noVNC_selected")) {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
|
UI.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
|
||||||
btn.classList.remove("noVNC_selected");
|
btn.classList.remove("noVNC_selected");
|
||||||
} else {
|
} else {
|
||||||
UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", true);
|
UI.sendKey(KeyTable.XK_Alt_L, "AltLeft", true);
|
||||||
btn.classList.add("noVNC_selected");
|
btn.classList.add("noVNC_selected");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sendCtrlAltDel() {
|
sendCtrlAltDel() {
|
||||||
UI.rfb.sendCtrlAltDel();
|
UI.rfb.sendCtrlAltDel();
|
||||||
|
// See below
|
||||||
|
UI.rfb.focus();
|
||||||
|
UI.idleControlbar();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Move focus to the screen in order to be able to use the
|
||||||
|
// keyboard right after these extra keys.
|
||||||
|
// The exception is when a virtual keyboard is used, because
|
||||||
|
// if we focus the screen the virtual keyboard would be closed.
|
||||||
|
// In this case we focus our special virtual keyboard input
|
||||||
|
// element instead.
|
||||||
|
focusOnConsole() {
|
||||||
|
if (document.getElementById('noVNC_keyboard_button')
|
||||||
|
.classList.contains("noVNC_selected")) {
|
||||||
|
document.getElementById('noVNC_keyboardinput').focus();
|
||||||
|
} else {
|
||||||
|
UI.rfb.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sendKey(keysym, code, down) {
|
||||||
|
UI.rfb.sendKey(keysym, code, down);
|
||||||
|
UI.focusOnConsole()
|
||||||
|
// fade out the controlbar to highlight that
|
||||||
|
// the focus has been moved to the screen
|
||||||
|
UI.idleControlbar();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* ------^-------
|
/* ------^-------
|
||||||
@ -1558,24 +1609,6 @@ const UI = {
|
|||||||
* MISC
|
* MISC
|
||||||
* ------v------*/
|
* ------v------*/
|
||||||
|
|
||||||
setMouseButton(num) {
|
|
||||||
const view_only = UI.rfb.viewOnly;
|
|
||||||
if (UI.rfb && !view_only) {
|
|
||||||
UI.rfb.touchButton = num;
|
|
||||||
}
|
|
||||||
|
|
||||||
const blist = [0, 1, 2, 4];
|
|
||||||
for (let b = 0; b < blist.length; b++) {
|
|
||||||
const button = document.getElementById('noVNC_mouse_button' +
|
|
||||||
blist[b]);
|
|
||||||
if (blist[b] === num && !view_only) {
|
|
||||||
button.classList.remove("noVNC_hidden");
|
|
||||||
} else {
|
|
||||||
button.classList.add("noVNC_hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateViewOnly() {
|
updateViewOnly() {
|
||||||
if (!UI.rfb) return;
|
if (!UI.rfb) return;
|
||||||
UI.rfb.viewOnly = UI.getSetting('view_only');
|
UI.rfb.viewOnly = UI.getSetting('view_only');
|
||||||
@ -1586,14 +1619,14 @@ const UI = {
|
|||||||
.classList.add('noVNC_hidden');
|
.classList.add('noVNC_hidden');
|
||||||
document.getElementById('noVNC_toggle_extra_keys_button')
|
document.getElementById('noVNC_toggle_extra_keys_button')
|
||||||
.classList.add('noVNC_hidden');
|
.classList.add('noVNC_hidden');
|
||||||
document.getElementById('noVNC_mouse_button' + UI.rfb.touchButton)
|
document.getElementById('noVNC_clipboard_button')
|
||||||
.classList.add('noVNC_hidden');
|
.classList.add('noVNC_hidden');
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('noVNC_keyboard_button')
|
document.getElementById('noVNC_keyboard_button')
|
||||||
.classList.remove('noVNC_hidden');
|
.classList.remove('noVNC_hidden');
|
||||||
document.getElementById('noVNC_toggle_extra_keys_button')
|
document.getElementById('noVNC_toggle_extra_keys_button')
|
||||||
.classList.remove('noVNC_hidden');
|
.classList.remove('noVNC_hidden');
|
||||||
document.getElementById('noVNC_mouse_button' + UI.rfb.touchButton)
|
document.getElementById('noVNC_clipboard_button')
|
||||||
.classList.remove('noVNC_hidden');
|
.classList.remove('noVNC_hidden');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1604,13 +1637,13 @@ const UI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateLogging() {
|
updateLogging() {
|
||||||
WebUtil.init_logging(UI.getSetting('logging'));
|
WebUtil.initLogging(UI.getSetting('logging'));
|
||||||
},
|
},
|
||||||
|
|
||||||
updateDesktopName(e) {
|
updateDesktopName(e) {
|
||||||
UI.desktopName = e.detail.name;
|
UI.desktopName = e.detail.name;
|
||||||
// Display the desktop name in the document title
|
// Display the desktop name in the document title
|
||||||
document.title = e.detail.name + " - noVNC";
|
document.title = e.detail.name + " - " + PAGE_TITLE;
|
||||||
},
|
},
|
||||||
|
|
||||||
bell(e) {
|
bell(e) {
|
||||||
@ -1646,7 +1679,7 @@ const UI = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Set up translations
|
// Set up translations
|
||||||
const LINGUAS = ["cs", "de", "el", "es", "ko", "nl", "pl", "ru", "sv", "tr", "zh_CN", "zh_TW"];
|
const LINGUAS = ["cs", "de", "el", "es", "ja", "ko", "nl", "pl", "ru", "sv", "tr", "zh_CN", "zh_TW"];
|
||||||
l10n.setup(LINGUAS);
|
l10n.setup(LINGUAS);
|
||||||
if (l10n.language === "en" || l10n.dictionary !== undefined) {
|
if (l10n.language === "en" || l10n.dictionary !== undefined) {
|
||||||
UI.prime();
|
UI.prime();
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { init_logging as main_init_logging } from '../core/util/logging.js';
|
import { initLogging as mainInitLogging } from '../core/util/logging.js';
|
||||||
|
|
||||||
// init log level reading the logging HTTP param
|
// init log level reading the logging HTTP param
|
||||||
export function init_logging(level) {
|
export function initLogging(level) {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof level !== "undefined") {
|
if (typeof level !== "undefined") {
|
||||||
main_init_logging(level);
|
mainInitLogging(level);
|
||||||
} else {
|
} else {
|
||||||
const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/);
|
const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/);
|
||||||
main_init_logging(param || undefined);
|
mainInitLogging(param || undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,13 +115,8 @@ export function eraseCookie(name) {
|
|||||||
let settings = {};
|
let settings = {};
|
||||||
|
|
||||||
export function initSettings() {
|
export function initSettings() {
|
||||||
if (!window.chrome || !window.chrome.storage) {
|
settings = {};
|
||||||
settings = {};
|
return Promise.resolve();
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise(resolve => window.chrome.storage.sync.get(resolve))
|
|
||||||
.then((cfg) => { settings = cfg; });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the settings cache, but do not write to permanent storage
|
// Update the settings cache, but do not write to permanent storage
|
||||||
@ -134,22 +129,13 @@ export function writeSetting(name, value) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
if (settings[name] === value) return;
|
if (settings[name] === value) return;
|
||||||
settings[name] = value;
|
settings[name] = value;
|
||||||
if (window.chrome && window.chrome.storage) {
|
|
||||||
window.chrome.storage.sync.set(settings);
|
|
||||||
} else {
|
|
||||||
localStorage.setItem(name, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readSetting(name, defaultValue) {
|
export function readSetting(name, defaultValue) {
|
||||||
"use strict";
|
"use strict";
|
||||||
let value;
|
let value;
|
||||||
if ((name in settings) || (window.chrome && window.chrome.storage)) {
|
value = settings[name];
|
||||||
value = settings[name];
|
|
||||||
} else {
|
|
||||||
value = localStorage.getItem(name);
|
|
||||||
settings[name] = value;
|
|
||||||
}
|
|
||||||
if (typeof value === "undefined") {
|
if (typeof value === "undefined") {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
@ -169,11 +155,6 @@ export function eraseSetting(name) {
|
|||||||
// between this delete and the next read, it could lead to an unexpected
|
// between this delete and the next read, it could lead to an unexpected
|
||||||
// value change.
|
// value change.
|
||||||
delete settings[name];
|
delete settings[name];
|
||||||
if (window.chrome && window.chrome.storage) {
|
|
||||||
window.chrome.storage.sync.remove(name);
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function injectParamIfMissing(path, param, value) {
|
export function injectParamIfMissing(path, param, value) {
|
||||||
@ -184,7 +165,7 @@ export function injectParamIfMissing(path, param, value) {
|
|||||||
const elem = document.createElement('a');
|
const elem = document.createElement('a');
|
||||||
elem.href = path;
|
elem.href = path;
|
||||||
|
|
||||||
const param_eq = encodeURIComponent(param) + "=";
|
const paramEq = encodeURIComponent(param) + "=";
|
||||||
let query;
|
let query;
|
||||||
if (elem.search) {
|
if (elem.search) {
|
||||||
query = elem.search.slice(1).split('&');
|
query = elem.search.slice(1).split('&');
|
||||||
@ -192,8 +173,8 @@ export function injectParamIfMissing(path, param, value) {
|
|||||||
query = [];
|
query = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query.some(v => v.startsWith(param_eq))) {
|
if (!query.some(v => v.startsWith(paramEq))) {
|
||||||
query.push(param_eq + encodeURIComponent(value));
|
query.push(paramEq + encodeURIComponent(value));
|
||||||
elem.search = "?" + query.join("&");
|
elem.search = "?" + query.join("&");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,12 +57,12 @@ export default {
|
|||||||
/* eslint-enable comma-spacing */
|
/* eslint-enable comma-spacing */
|
||||||
|
|
||||||
decode(data, offset = 0) {
|
decode(data, offset = 0) {
|
||||||
let data_length = data.indexOf('=') - offset;
|
let dataLength = data.indexOf('=') - offset;
|
||||||
if (data_length < 0) { data_length = data.length - offset; }
|
if (dataLength < 0) { dataLength = data.length - offset; }
|
||||||
|
|
||||||
/* Every four characters is 3 resulting numbers */
|
/* Every four characters is 3 resulting numbers */
|
||||||
const result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
|
const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5);
|
||||||
const result = new Array(result_length);
|
const result = new Array(resultLength);
|
||||||
|
|
||||||
// Convert one by one.
|
// Convert one by one.
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2012 Joel Martin
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
|
||||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -17,6 +15,11 @@ export default class CopyRectDecoder {
|
|||||||
|
|
||||||
let deltaX = sock.rQshift16();
|
let deltaX = sock.rQshift16();
|
||||||
let deltaY = sock.rQshift16();
|
let deltaY = sock.rQshift16();
|
||||||
|
|
||||||
|
if ((width === 0) || (height === 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
display.copyImage(deltaX, deltaY, x, y, width, height);
|
display.copyImage(deltaX, deltaY, x, y, width, height);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2012 Joel Martin
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
|
||||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -15,14 +13,15 @@ export default class HextileDecoder {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this._tiles = 0;
|
this._tiles = 0;
|
||||||
this._lastsubencoding = 0;
|
this._lastsubencoding = 0;
|
||||||
|
this._tileBuffer = new Uint8Array(16 * 16 * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeRect(x, y, width, height, sock, display, depth) {
|
decodeRect(x, y, width, height, sock, display, depth) {
|
||||||
if (this._tiles === 0) {
|
if (this._tiles === 0) {
|
||||||
this._tiles_x = Math.ceil(width / 16);
|
this._tilesX = Math.ceil(width / 16);
|
||||||
this._tiles_y = Math.ceil(height / 16);
|
this._tilesY = Math.ceil(height / 16);
|
||||||
this._total_tiles = this._tiles_x * this._tiles_y;
|
this._totalTiles = this._tilesX * this._tilesY;
|
||||||
this._tiles = this._total_tiles;
|
this._tiles = this._totalTiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (this._tiles > 0) {
|
while (this._tiles > 0) {
|
||||||
@ -41,11 +40,11 @@ export default class HextileDecoder {
|
|||||||
subencoding + ")");
|
subencoding + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
const curr_tile = this._total_tiles - this._tiles;
|
const currTile = this._totalTiles - this._tiles;
|
||||||
const tile_x = curr_tile % this._tiles_x;
|
const tileX = currTile % this._tilesX;
|
||||||
const tile_y = Math.floor(curr_tile / this._tiles_x);
|
const tileY = Math.floor(currTile / this._tilesX);
|
||||||
const tx = x + tile_x * 16;
|
const tx = x + tileX * 16;
|
||||||
const ty = y + tile_y * 16;
|
const ty = y + tileY * 16;
|
||||||
const tw = Math.min(16, (x + width) - tx);
|
const tw = Math.min(16, (x + width) - tx);
|
||||||
const th = Math.min(16, (y + height) - ty);
|
const th = Math.min(16, (y + height) - ty);
|
||||||
|
|
||||||
@ -89,6 +88,11 @@ export default class HextileDecoder {
|
|||||||
display.fillRect(tx, ty, tw, th, this._background);
|
display.fillRect(tx, ty, tw, th, this._background);
|
||||||
}
|
}
|
||||||
} else if (subencoding & 0x01) { // Raw
|
} else if (subencoding & 0x01) { // Raw
|
||||||
|
let pixels = tw * th;
|
||||||
|
// Max sure the image is fully opaque
|
||||||
|
for (let i = 0;i < pixels;i++) {
|
||||||
|
rQ[rQi + i * 4 + 3] = 255;
|
||||||
|
}
|
||||||
display.blitImage(tx, ty, tw, th, rQ, rQi);
|
display.blitImage(tx, ty, tw, th, rQ, rQi);
|
||||||
rQi += bytes - 1;
|
rQi += bytes - 1;
|
||||||
} else {
|
} else {
|
||||||
@ -101,7 +105,7 @@ export default class HextileDecoder {
|
|||||||
rQi += 4;
|
rQi += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
display.startTile(tx, ty, tw, th, this._background);
|
this._startTile(tx, ty, tw, th, this._background);
|
||||||
if (subencoding & 0x08) { // AnySubrects
|
if (subencoding & 0x08) { // AnySubrects
|
||||||
let subrects = rQ[rQi];
|
let subrects = rQ[rQi];
|
||||||
rQi++;
|
rQi++;
|
||||||
@ -124,10 +128,10 @@ export default class HextileDecoder {
|
|||||||
const sw = (wh >> 4) + 1;
|
const sw = (wh >> 4) + 1;
|
||||||
const sh = (wh & 0x0f) + 1;
|
const sh = (wh & 0x0f) + 1;
|
||||||
|
|
||||||
display.subTile(sx, sy, sw, sh, color);
|
this._subTile(sx, sy, sw, sh, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
display.finishTile();
|
this._finishTile(display);
|
||||||
}
|
}
|
||||||
sock.rQi = rQi;
|
sock.rQi = rQi;
|
||||||
this._lastsubencoding = subencoding;
|
this._lastsubencoding = subencoding;
|
||||||
@ -136,4 +140,52 @@ export default class HextileDecoder {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start updating a tile
|
||||||
|
_startTile(x, y, width, height, color) {
|
||||||
|
this._tileX = x;
|
||||||
|
this._tileY = y;
|
||||||
|
this._tileW = width;
|
||||||
|
this._tileH = height;
|
||||||
|
|
||||||
|
const red = color[0];
|
||||||
|
const green = color[1];
|
||||||
|
const blue = color[2];
|
||||||
|
|
||||||
|
const data = this._tileBuffer;
|
||||||
|
for (let i = 0; i < width * height * 4; i += 4) {
|
||||||
|
data[i] = red;
|
||||||
|
data[i + 1] = green;
|
||||||
|
data[i + 2] = blue;
|
||||||
|
data[i + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update sub-rectangle of the current tile
|
||||||
|
_subTile(x, y, w, h, color) {
|
||||||
|
const red = color[0];
|
||||||
|
const green = color[1];
|
||||||
|
const blue = color[2];
|
||||||
|
const xend = x + w;
|
||||||
|
const yend = y + h;
|
||||||
|
|
||||||
|
const data = this._tileBuffer;
|
||||||
|
const width = this._tileW;
|
||||||
|
for (let j = y; j < yend; j++) {
|
||||||
|
for (let i = x; i < xend; i++) {
|
||||||
|
const p = (i + (j * width)) * 4;
|
||||||
|
data[p] = red;
|
||||||
|
data[p + 1] = green;
|
||||||
|
data[p + 2] = blue;
|
||||||
|
data[p + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the current tile to the screen
|
||||||
|
_finishTile(display) {
|
||||||
|
display.blitImage(this._tileX, this._tileY,
|
||||||
|
this._tileW, this._tileH,
|
||||||
|
this._tileBuffer, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2012 Joel Martin
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
|
||||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -15,6 +13,10 @@ export default class RawDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
decodeRect(x, y, width, height, sock, display, depth) {
|
decodeRect(x, y, width, height, sock, display, depth) {
|
||||||
|
if ((width === 0) || (height === 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (this._lines === 0) {
|
if (this._lines === 0) {
|
||||||
this._lines = height;
|
this._lines = height;
|
||||||
}
|
}
|
||||||
@ -26,29 +28,35 @@ export default class RawDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cur_y = y + (height - this._lines);
|
const curY = y + (height - this._lines);
|
||||||
const curr_height = Math.min(this._lines,
|
const currHeight = Math.min(this._lines,
|
||||||
Math.floor(sock.rQlen / bytesPerLine));
|
Math.floor(sock.rQlen / bytesPerLine));
|
||||||
|
const pixels = width * currHeight;
|
||||||
|
|
||||||
let data = sock.rQ;
|
let data = sock.rQ;
|
||||||
let index = sock.rQi;
|
let index = sock.rQi;
|
||||||
|
|
||||||
// Convert data if needed
|
// Convert data if needed
|
||||||
if (depth == 8) {
|
if (depth == 8) {
|
||||||
const pixels = width * curr_height;
|
|
||||||
const newdata = new Uint8Array(pixels * 4);
|
const newdata = new Uint8Array(pixels * 4);
|
||||||
for (let i = 0; i < pixels; i++) {
|
for (let i = 0; i < pixels; i++) {
|
||||||
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3;
|
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3;
|
||||||
newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3;
|
newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3;
|
||||||
newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3;
|
newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3;
|
||||||
newdata[i * 4 + 4] = 0;
|
newdata[i * 4 + 3] = 255;
|
||||||
}
|
}
|
||||||
data = newdata;
|
data = newdata;
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
display.blitImage(x, cur_y, width, curr_height, data, index);
|
// Max sure the image is fully opaque
|
||||||
sock.rQskipBytes(curr_height * bytesPerLine);
|
for (let i = 0; i < pixels; i++) {
|
||||||
this._lines -= curr_height;
|
data[i * 4 + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
display.blitImage(x, curY, width, currHeight, data, index);
|
||||||
|
sock.rQskipBytes(currHeight * bytesPerLine);
|
||||||
|
this._lines -= currHeight;
|
||||||
if (this._lines > 0) {
|
if (this._lines > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2012 Joel Martin
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
|
||||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2012 Joel Martin
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
|
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
|
||||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
|
||||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -58,7 +56,7 @@ export default class TightDecoder {
|
|||||||
} else if (this._ctl === 0x0A) {
|
} else if (this._ctl === 0x0A) {
|
||||||
ret = this._pngRect(x, y, width, height,
|
ret = this._pngRect(x, y, width, height,
|
||||||
sock, display, depth);
|
sock, display, depth);
|
||||||
} else if ((this._ctl & 0x80) == 0) {
|
} else if ((this._ctl & 0x08) == 0) {
|
||||||
ret = this._basicRect(this._ctl, x, y, width, height,
|
ret = this._basicRect(this._ctl, x, y, width, height,
|
||||||
sock, display, depth);
|
sock, display, depth);
|
||||||
} else {
|
} else {
|
||||||
@ -82,7 +80,7 @@ export default class TightDecoder {
|
|||||||
const rQ = sock.rQ;
|
const rQ = sock.rQ;
|
||||||
|
|
||||||
display.fillRect(x, y, width, height,
|
display.fillRect(x, y, width, height,
|
||||||
[rQ[rQi + 2], rQ[rQi + 1], rQ[rQi]], false);
|
[rQ[rQi], rQ[rQi + 1], rQ[rQi + 2]], false);
|
||||||
sock.rQskipBytes(3);
|
sock.rQskipBytes(3);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -94,7 +92,7 @@ export default class TightDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
display.imageRect(x, y, "image/jpeg", data);
|
display.imageRect(x, y, width, height, "image/jpeg", data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -150,6 +148,10 @@ export default class TightDecoder {
|
|||||||
const uncompressedSize = width * height * 3;
|
const uncompressedSize = width * height * 3;
|
||||||
let data;
|
let data;
|
||||||
|
|
||||||
|
if (uncompressedSize === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (uncompressedSize < 12) {
|
if (uncompressedSize < 12) {
|
||||||
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
||||||
return false;
|
return false;
|
||||||
@ -162,13 +164,20 @@ export default class TightDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = this._zlibs[streamId].inflate(data, true, uncompressedSize);
|
this._zlibs[streamId].setInput(data);
|
||||||
if (data.length != uncompressedSize) {
|
data = this._zlibs[streamId].inflate(uncompressedSize);
|
||||||
throw new Error("Incomplete zlib block");
|
this._zlibs[streamId].setInput(null);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
display.blitRgbImage(x, y, width, height, data, 0, false);
|
let rgbx = new Uint8Array(width * height * 4);
|
||||||
|
for (let i = 0, j = 0; i < width * height * 4; i += 4, j += 3) {
|
||||||
|
rgbx[i] = data[j];
|
||||||
|
rgbx[i + 1] = data[j + 1];
|
||||||
|
rgbx[i + 2] = data[j + 2];
|
||||||
|
rgbx[i + 3] = 255; // Alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
display.blitImage(x, y, width, height, rgbx, 0, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -198,6 +207,10 @@ export default class TightDecoder {
|
|||||||
|
|
||||||
let data;
|
let data;
|
||||||
|
|
||||||
|
if (uncompressedSize === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (uncompressedSize < 12) {
|
if (uncompressedSize < 12) {
|
||||||
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
||||||
return false;
|
return false;
|
||||||
@ -210,10 +223,9 @@ export default class TightDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = this._zlibs[streamId].inflate(data, true, uncompressedSize);
|
this._zlibs[streamId].setInput(data);
|
||||||
if (data.length != uncompressedSize) {
|
data = this._zlibs[streamId].inflate(uncompressedSize);
|
||||||
throw new Error("Incomplete zlib block");
|
this._zlibs[streamId].setInput(null);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert indexed (palette based) image data to RGB
|
// Convert indexed (palette based) image data to RGB
|
||||||
@ -241,7 +253,7 @@ export default class TightDecoder {
|
|||||||
for (let b = 7; b >= 0; b--) {
|
for (let b = 7; b >= 0; b--) {
|
||||||
dp = (y * width + x * 8 + 7 - b) * 4;
|
dp = (y * width + x * 8 + 7 - b) * 4;
|
||||||
sp = (data[y * w + x] >> b & 1) * 3;
|
sp = (data[y * w + x] >> b & 1) * 3;
|
||||||
dest[dp] = palette[sp];
|
dest[dp] = palette[sp];
|
||||||
dest[dp + 1] = palette[sp + 1];
|
dest[dp + 1] = palette[sp + 1];
|
||||||
dest[dp + 2] = palette[sp + 2];
|
dest[dp + 2] = palette[sp + 2];
|
||||||
dest[dp + 3] = 255;
|
dest[dp + 3] = 255;
|
||||||
@ -251,14 +263,14 @@ export default class TightDecoder {
|
|||||||
for (let b = 7; b >= 8 - width % 8; b--) {
|
for (let b = 7; b >= 8 - width % 8; b--) {
|
||||||
dp = (y * width + x * 8 + 7 - b) * 4;
|
dp = (y * width + x * 8 + 7 - b) * 4;
|
||||||
sp = (data[y * w + x] >> b & 1) * 3;
|
sp = (data[y * w + x] >> b & 1) * 3;
|
||||||
dest[dp] = palette[sp];
|
dest[dp] = palette[sp];
|
||||||
dest[dp + 1] = palette[sp + 1];
|
dest[dp + 1] = palette[sp + 1];
|
||||||
dest[dp + 2] = palette[sp + 2];
|
dest[dp + 2] = palette[sp + 2];
|
||||||
dest[dp + 3] = 255;
|
dest[dp + 3] = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display.blitRgbxImage(x, y, width, height, dest, 0, false);
|
display.blitImage(x, y, width, height, dest, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_paletteRect(x, y, width, height, data, palette, display) {
|
_paletteRect(x, y, width, height, data, palette, display) {
|
||||||
@ -267,13 +279,13 @@ export default class TightDecoder {
|
|||||||
const total = width * height * 4;
|
const total = width * height * 4;
|
||||||
for (let i = 0, j = 0; i < total; i += 4, j++) {
|
for (let i = 0, j = 0; i < total; i += 4, j++) {
|
||||||
const sp = data[j] * 3;
|
const sp = data[j] * 3;
|
||||||
dest[i] = palette[sp];
|
dest[i] = palette[sp];
|
||||||
dest[i + 1] = palette[sp + 1];
|
dest[i + 1] = palette[sp + 1];
|
||||||
dest[i + 2] = palette[sp + 2];
|
dest[i + 2] = palette[sp + 2];
|
||||||
dest[i + 3] = 255;
|
dest[i + 3] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
display.blitRgbxImage(x, y, width, height, dest, 0, false);
|
display.blitImage(x, y, width, height, dest, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_gradientFilter(streamId, x, y, width, height, sock, display, depth) {
|
_gradientFilter(streamId, x, y, width, height, sock, display, depth) {
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2012 Joel Martin
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Copyright (C) 2018 Samuel Mannehed for Cendio AB
|
|
||||||
* Copyright (C) 2018 Pierre Ossman for Cendio AB
|
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -18,7 +16,7 @@ export default class TightPNGDecoder extends TightDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
display.imageRect(x, y, "image/png", data);
|
display.imageRect(x, y, width, height, "image/png", data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
85
systemvm/agent/noVNC/core/deflator.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2020 The noVNC Authors
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { deflateInit, deflate } from "../vendor/pako/lib/zlib/deflate.js";
|
||||||
|
import { Z_FULL_FLUSH } from "../vendor/pako/lib/zlib/deflate.js";
|
||||||
|
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
|
||||||
|
|
||||||
|
export default class Deflator {
|
||||||
|
constructor() {
|
||||||
|
this.strm = new ZStream();
|
||||||
|
this.chunkSize = 1024 * 10 * 10;
|
||||||
|
this.outputBuffer = new Uint8Array(this.chunkSize);
|
||||||
|
this.windowBits = 5;
|
||||||
|
|
||||||
|
deflateInit(this.strm, this.windowBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
deflate(inData) {
|
||||||
|
/* eslint-disable camelcase */
|
||||||
|
this.strm.input = inData;
|
||||||
|
this.strm.avail_in = this.strm.input.length;
|
||||||
|
this.strm.next_in = 0;
|
||||||
|
this.strm.output = this.outputBuffer;
|
||||||
|
this.strm.avail_out = this.chunkSize;
|
||||||
|
this.strm.next_out = 0;
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
|
let lastRet = deflate(this.strm, Z_FULL_FLUSH);
|
||||||
|
let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
|
||||||
|
|
||||||
|
if (lastRet < 0) {
|
||||||
|
throw new Error("zlib deflate failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.strm.avail_in > 0) {
|
||||||
|
// Read chunks until done
|
||||||
|
|
||||||
|
let chunks = [outData];
|
||||||
|
let totalLen = outData.length;
|
||||||
|
do {
|
||||||
|
/* eslint-disable camelcase */
|
||||||
|
this.strm.output = new Uint8Array(this.chunkSize);
|
||||||
|
this.strm.next_out = 0;
|
||||||
|
this.strm.avail_out = this.chunkSize;
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
|
lastRet = deflate(this.strm, Z_FULL_FLUSH);
|
||||||
|
|
||||||
|
if (lastRet < 0) {
|
||||||
|
throw new Error("zlib deflate failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
let chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
|
||||||
|
totalLen += chunk.length;
|
||||||
|
chunks.push(chunk);
|
||||||
|
} while (this.strm.avail_in > 0);
|
||||||
|
|
||||||
|
// Combine chunks into a single data
|
||||||
|
|
||||||
|
let newData = new Uint8Array(totalLen);
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < chunks.length; i++) {
|
||||||
|
newData.set(chunks[i], offset);
|
||||||
|
offset += chunks[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
outData = newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable camelcase */
|
||||||
|
this.strm.input = null;
|
||||||
|
this.strm.avail_in = 0;
|
||||||
|
this.strm.next_in = 0;
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
|
return outData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -9,24 +9,20 @@
|
|||||||
import * as Log from './util/logging.js';
|
import * as Log from './util/logging.js';
|
||||||
import Base64 from "./base64.js";
|
import Base64 from "./base64.js";
|
||||||
import { supportsImageMetadata } from './util/browser.js';
|
import { supportsImageMetadata } from './util/browser.js';
|
||||||
|
import { toSigned32bit } from './util/int.js';
|
||||||
|
|
||||||
export default class Display {
|
export default class Display {
|
||||||
constructor(target) {
|
constructor(target) {
|
||||||
this._drawCtx = null;
|
this._drawCtx = null;
|
||||||
this._c_forceCanvas = false;
|
|
||||||
|
|
||||||
this._renderQ = []; // queue drawing actions for in-oder rendering
|
this._renderQ = []; // queue drawing actions for in-oder rendering
|
||||||
this._flushing = false;
|
this._flushing = false;
|
||||||
|
|
||||||
// the full frame buffer (logical canvas) size
|
// the full frame buffer (logical canvas) size
|
||||||
this._fb_width = 0;
|
this._fbWidth = 0;
|
||||||
this._fb_height = 0;
|
this._fbHeight = 0;
|
||||||
|
|
||||||
this._prevDrawStyle = "";
|
this._prevDrawStyle = "";
|
||||||
this._tile = null;
|
|
||||||
this._tile16x16 = null;
|
|
||||||
this._tile_x = 0;
|
|
||||||
this._tile_y = 0;
|
|
||||||
|
|
||||||
Log.Debug(">> Display.constructor");
|
Log.Debug(">> Display.constructor");
|
||||||
|
|
||||||
@ -60,21 +56,17 @@ export default class Display {
|
|||||||
|
|
||||||
Log.Debug("User Agent: " + navigator.userAgent);
|
Log.Debug("User Agent: " + navigator.userAgent);
|
||||||
|
|
||||||
this.clear();
|
|
||||||
|
|
||||||
// Check canvas features
|
// Check canvas features
|
||||||
if (!('createImageData' in this._drawCtx)) {
|
if (!('createImageData' in this._drawCtx)) {
|
||||||
throw new Error("Canvas does not support createImageData");
|
throw new Error("Canvas does not support createImageData");
|
||||||
}
|
}
|
||||||
|
|
||||||
this._tile16x16 = this._drawCtx.createImageData(16, 16);
|
|
||||||
Log.Debug("<< Display.constructor");
|
Log.Debug("<< Display.constructor");
|
||||||
|
|
||||||
// ===== PROPERTIES =====
|
// ===== PROPERTIES =====
|
||||||
|
|
||||||
this._scale = 1.0;
|
this._scale = 1.0;
|
||||||
this._clipViewport = false;
|
this._clipViewport = false;
|
||||||
this.logo = null;
|
|
||||||
|
|
||||||
// ===== EVENT HANDLERS =====
|
// ===== EVENT HANDLERS =====
|
||||||
|
|
||||||
@ -98,11 +90,11 @@ export default class Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get width() {
|
get width() {
|
||||||
return this._fb_width;
|
return this._fbWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
get height() {
|
get height() {
|
||||||
return this._fb_height;
|
return this._fbHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== PUBLIC METHODS =====
|
// ===== PUBLIC METHODS =====
|
||||||
@ -125,15 +117,15 @@ export default class Display {
|
|||||||
if (deltaX < 0 && vp.x + deltaX < 0) {
|
if (deltaX < 0 && vp.x + deltaX < 0) {
|
||||||
deltaX = -vp.x;
|
deltaX = -vp.x;
|
||||||
}
|
}
|
||||||
if (vx2 + deltaX >= this._fb_width) {
|
if (vx2 + deltaX >= this._fbWidth) {
|
||||||
deltaX -= vx2 + deltaX - this._fb_width + 1;
|
deltaX -= vx2 + deltaX - this._fbWidth + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vp.y + deltaY < 0) {
|
if (vp.y + deltaY < 0) {
|
||||||
deltaY = -vp.y;
|
deltaY = -vp.y;
|
||||||
}
|
}
|
||||||
if (vy2 + deltaY >= this._fb_height) {
|
if (vy2 + deltaY >= this._fbHeight) {
|
||||||
deltaY -= (vy2 + deltaY - this._fb_height + 1);
|
deltaY -= (vy2 + deltaY - this._fbHeight + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deltaX === 0 && deltaY === 0) {
|
if (deltaX === 0 && deltaY === 0) {
|
||||||
@ -156,18 +148,18 @@ export default class Display {
|
|||||||
typeof(height) === "undefined") {
|
typeof(height) === "undefined") {
|
||||||
|
|
||||||
Log.Debug("Setting viewport to full display region");
|
Log.Debug("Setting viewport to full display region");
|
||||||
width = this._fb_width;
|
width = this._fbWidth;
|
||||||
height = this._fb_height;
|
height = this._fbHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = Math.floor(width);
|
width = Math.floor(width);
|
||||||
height = Math.floor(height);
|
height = Math.floor(height);
|
||||||
|
|
||||||
if (width > this._fb_width) {
|
if (width > this._fbWidth) {
|
||||||
width = this._fb_width;
|
width = this._fbWidth;
|
||||||
}
|
}
|
||||||
if (height > this._fb_height) {
|
if (height > this._fbHeight) {
|
||||||
height = this._fb_height;
|
height = this._fbHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vp = this._viewportLoc;
|
const vp = this._viewportLoc;
|
||||||
@ -194,21 +186,21 @@ export default class Display {
|
|||||||
if (this._scale === 0) {
|
if (this._scale === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return x / this._scale + this._viewportLoc.x;
|
return toSigned32bit(x / this._scale + this._viewportLoc.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
absY(y) {
|
absY(y) {
|
||||||
if (this._scale === 0) {
|
if (this._scale === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return y / this._scale + this._viewportLoc.y;
|
return toSigned32bit(y / this._scale + this._viewportLoc.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
resize(width, height) {
|
resize(width, height) {
|
||||||
this._prevDrawStyle = "";
|
this._prevDrawStyle = "";
|
||||||
|
|
||||||
this._fb_width = width;
|
this._fbWidth = width;
|
||||||
this._fb_height = height;
|
this._fbHeight = height;
|
||||||
|
|
||||||
const canvas = this._backbuffer;
|
const canvas = this._backbuffer;
|
||||||
if (canvas.width !== width || canvas.height !== height) {
|
if (canvas.width !== width || canvas.height !== height) {
|
||||||
@ -256,9 +248,9 @@ export default class Display {
|
|||||||
|
|
||||||
// Update the visible canvas with the contents of the
|
// Update the visible canvas with the contents of the
|
||||||
// rendering canvas
|
// rendering canvas
|
||||||
flip(from_queue) {
|
flip(fromQueue) {
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
if (this._renderQ.length !== 0 && !fromQueue) {
|
||||||
this._renderQ_push({
|
this._renderQPush({
|
||||||
'type': 'flip'
|
'type': 'flip'
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -302,17 +294,6 @@ export default class Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
|
||||||
if (this._logo) {
|
|
||||||
this.resize(this._logo.width, this._logo.height);
|
|
||||||
this.imageRect(0, 0, this._logo.type, this._logo.data);
|
|
||||||
} else {
|
|
||||||
this.resize(240, 20);
|
|
||||||
this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height);
|
|
||||||
}
|
|
||||||
this.flip();
|
|
||||||
}
|
|
||||||
|
|
||||||
pending() {
|
pending() {
|
||||||
return this._renderQ.length > 0;
|
return this._renderQ.length > 0;
|
||||||
}
|
}
|
||||||
@ -325,9 +306,9 @@ export default class Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fillRect(x, y, width, height, color, from_queue) {
|
fillRect(x, y, width, height, color, fromQueue) {
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
if (this._renderQ.length !== 0 && !fromQueue) {
|
||||||
this._renderQ_push({
|
this._renderQPush({
|
||||||
'type': 'fill',
|
'type': 'fill',
|
||||||
'x': x,
|
'x': x,
|
||||||
'y': y,
|
'y': y,
|
||||||
@ -342,14 +323,14 @@ export default class Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
copyImage(old_x, old_y, new_x, new_y, w, h, from_queue) {
|
copyImage(oldX, oldY, newX, newY, w, h, fromQueue) {
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
if (this._renderQ.length !== 0 && !fromQueue) {
|
||||||
this._renderQ_push({
|
this._renderQPush({
|
||||||
'type': 'copy',
|
'type': 'copy',
|
||||||
'old_x': old_x,
|
'oldX': oldX,
|
||||||
'old_y': old_y,
|
'oldY': oldY,
|
||||||
'x': new_x,
|
'x': newX,
|
||||||
'y': new_y,
|
'y': newY,
|
||||||
'width': w,
|
'width': w,
|
||||||
'height': h,
|
'height': h,
|
||||||
});
|
});
|
||||||
@ -367,131 +348,60 @@ export default class Display {
|
|||||||
this._drawCtx.imageSmoothingEnabled = false;
|
this._drawCtx.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
this._drawCtx.drawImage(this._backbuffer,
|
this._drawCtx.drawImage(this._backbuffer,
|
||||||
old_x, old_y, w, h,
|
oldX, oldY, w, h,
|
||||||
new_x, new_y, w, h);
|
newX, newY, w, h);
|
||||||
this._damage(new_x, new_y, w, h);
|
this._damage(newX, newY, w, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imageRect(x, y, mime, arr) {
|
imageRect(x, y, width, height, mime, arr) {
|
||||||
|
/* The internal logic cannot handle empty images, so bail early */
|
||||||
|
if ((width === 0) || (height === 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.src = "data: " + mime + ";base64," + Base64.encode(arr);
|
img.src = "data: " + mime + ";base64," + Base64.encode(arr);
|
||||||
this._renderQ_push({
|
|
||||||
|
this._renderQPush({
|
||||||
'type': 'img',
|
'type': 'img',
|
||||||
'img': img,
|
'img': img,
|
||||||
'x': x,
|
'x': x,
|
||||||
'y': y
|
'y': y,
|
||||||
|
'width': width,
|
||||||
|
'height': height
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// start updating a tile
|
blitImage(x, y, width, height, arr, offset, fromQueue) {
|
||||||
startTile(x, y, width, height, color) {
|
if (this._renderQ.length !== 0 && !fromQueue) {
|
||||||
this._tile_x = x;
|
|
||||||
this._tile_y = y;
|
|
||||||
if (width === 16 && height === 16) {
|
|
||||||
this._tile = this._tile16x16;
|
|
||||||
} else {
|
|
||||||
this._tile = this._drawCtx.createImageData(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
const red = color[2];
|
|
||||||
const green = color[1];
|
|
||||||
const blue = color[0];
|
|
||||||
|
|
||||||
const data = this._tile.data;
|
|
||||||
for (let i = 0; i < width * height * 4; i += 4) {
|
|
||||||
data[i] = red;
|
|
||||||
data[i + 1] = green;
|
|
||||||
data[i + 2] = blue;
|
|
||||||
data[i + 3] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update sub-rectangle of the current tile
|
|
||||||
subTile(x, y, w, h, color) {
|
|
||||||
const red = color[2];
|
|
||||||
const green = color[1];
|
|
||||||
const blue = color[0];
|
|
||||||
const xend = x + w;
|
|
||||||
const yend = y + h;
|
|
||||||
|
|
||||||
const data = this._tile.data;
|
|
||||||
const width = this._tile.width;
|
|
||||||
for (let j = y; j < yend; j++) {
|
|
||||||
for (let i = x; i < xend; i++) {
|
|
||||||
const p = (i + (j * width)) * 4;
|
|
||||||
data[p] = red;
|
|
||||||
data[p + 1] = green;
|
|
||||||
data[p + 2] = blue;
|
|
||||||
data[p + 3] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the current tile to the screen
|
|
||||||
finishTile() {
|
|
||||||
this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y);
|
|
||||||
this._damage(this._tile_x, this._tile_y,
|
|
||||||
this._tile.width, this._tile.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
blitImage(x, y, width, height, arr, offset, from_queue) {
|
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
|
||||||
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
||||||
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
||||||
// this probably isn't getting called *nearly* as much
|
// this probably isn't getting called *nearly* as much
|
||||||
const new_arr = new Uint8Array(width * height * 4);
|
const newArr = new Uint8Array(width * height * 4);
|
||||||
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
|
newArr.set(new Uint8Array(arr.buffer, 0, newArr.length));
|
||||||
this._renderQ_push({
|
this._renderQPush({
|
||||||
'type': 'blit',
|
'type': 'blit',
|
||||||
'data': new_arr,
|
'data': newArr,
|
||||||
'x': x,
|
'x': x,
|
||||||
'y': y,
|
'y': y,
|
||||||
'width': width,
|
'width': width,
|
||||||
'height': height,
|
'height': height,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this._bgrxImageData(x, y, width, height, arr, offset);
|
// NB(directxman12): arr must be an Type Array view
|
||||||
}
|
let data = new Uint8ClampedArray(arr.buffer,
|
||||||
}
|
arr.byteOffset + offset,
|
||||||
|
width * height * 4);
|
||||||
blitRgbImage(x, y, width, height, arr, offset, from_queue) {
|
let img;
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
if (supportsImageMetadata) {
|
||||||
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
img = new ImageData(data, width, height);
|
||||||
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
} else {
|
||||||
// this probably isn't getting called *nearly* as much
|
img = this._drawCtx.createImageData(width, height);
|
||||||
const new_arr = new Uint8Array(width * height * 3);
|
img.data.set(data);
|
||||||
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
|
}
|
||||||
this._renderQ_push({
|
this._drawCtx.putImageData(img, x, y);
|
||||||
'type': 'blitRgb',
|
this._damage(x, y, width, height);
|
||||||
'data': new_arr,
|
|
||||||
'x': x,
|
|
||||||
'y': y,
|
|
||||||
'width': width,
|
|
||||||
'height': height,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this._rgbImageData(x, y, width, height, arr, offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blitRgbxImage(x, y, width, height, arr, offset, from_queue) {
|
|
||||||
if (this._renderQ.length !== 0 && !from_queue) {
|
|
||||||
// NB(directxman12): it's technically more performant here to use preallocated arrays,
|
|
||||||
// but it's a lot of extra work for not a lot of payoff -- if we're using the render queue,
|
|
||||||
// this probably isn't getting called *nearly* as much
|
|
||||||
const new_arr = new Uint8Array(width * height * 4);
|
|
||||||
new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length));
|
|
||||||
this._renderQ_push({
|
|
||||||
'type': 'blitRgbx',
|
|
||||||
'data': new_arr,
|
|
||||||
'x': x,
|
|
||||||
'y': y,
|
|
||||||
'width': width,
|
|
||||||
'height': height,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this._rgbxImageData(x, y, width, height, arr, offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,69 +453,30 @@ export default class Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_setFillColor(color) {
|
_setFillColor(color) {
|
||||||
const newStyle = 'rgb(' + color[2] + ',' + color[1] + ',' + color[0] + ')';
|
const newStyle = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')';
|
||||||
if (newStyle !== this._prevDrawStyle) {
|
if (newStyle !== this._prevDrawStyle) {
|
||||||
this._drawCtx.fillStyle = newStyle;
|
this._drawCtx.fillStyle = newStyle;
|
||||||
this._prevDrawStyle = newStyle;
|
this._prevDrawStyle = newStyle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_rgbImageData(x, y, width, height, arr, offset) {
|
_renderQPush(action) {
|
||||||
const img = this._drawCtx.createImageData(width, height);
|
|
||||||
const data = img.data;
|
|
||||||
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 3) {
|
|
||||||
data[i] = arr[j];
|
|
||||||
data[i + 1] = arr[j + 1];
|
|
||||||
data[i + 2] = arr[j + 2];
|
|
||||||
data[i + 3] = 255; // Alpha
|
|
||||||
}
|
|
||||||
this._drawCtx.putImageData(img, x, y);
|
|
||||||
this._damage(x, y, img.width, img.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
_bgrxImageData(x, y, width, height, arr, offset) {
|
|
||||||
const img = this._drawCtx.createImageData(width, height);
|
|
||||||
const data = img.data;
|
|
||||||
for (let i = 0, j = offset; i < width * height * 4; i += 4, j += 4) {
|
|
||||||
data[i] = arr[j + 2];
|
|
||||||
data[i + 1] = arr[j + 1];
|
|
||||||
data[i + 2] = arr[j];
|
|
||||||
data[i + 3] = 255; // Alpha
|
|
||||||
}
|
|
||||||
this._drawCtx.putImageData(img, x, y);
|
|
||||||
this._damage(x, y, img.width, img.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
_rgbxImageData(x, y, width, height, arr, offset) {
|
|
||||||
// NB(directxman12): arr must be an Type Array view
|
|
||||||
let img;
|
|
||||||
if (supportsImageMetadata) {
|
|
||||||
img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height);
|
|
||||||
} else {
|
|
||||||
img = this._drawCtx.createImageData(width, height);
|
|
||||||
img.data.set(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4));
|
|
||||||
}
|
|
||||||
this._drawCtx.putImageData(img, x, y);
|
|
||||||
this._damage(x, y, img.width, img.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderQ_push(action) {
|
|
||||||
this._renderQ.push(action);
|
this._renderQ.push(action);
|
||||||
if (this._renderQ.length === 1) {
|
if (this._renderQ.length === 1) {
|
||||||
// If this can be rendered immediately it will be, otherwise
|
// If this can be rendered immediately it will be, otherwise
|
||||||
// the scanner will wait for the relevant event
|
// the scanner will wait for the relevant event
|
||||||
this._scan_renderQ();
|
this._scanRenderQ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_resume_renderQ() {
|
_resumeRenderQ() {
|
||||||
// "this" is the object that is ready, not the
|
// "this" is the object that is ready, not the
|
||||||
// display object
|
// display object
|
||||||
this.removeEventListener('load', this._noVNC_display._resume_renderQ);
|
this.removeEventListener('load', this._noVNCDisplay._resumeRenderQ);
|
||||||
this._noVNC_display._scan_renderQ();
|
this._noVNCDisplay._scanRenderQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
_scan_renderQ() {
|
_scanRenderQ() {
|
||||||
let ready = true;
|
let ready = true;
|
||||||
while (ready && this._renderQ.length > 0) {
|
while (ready && this._renderQ.length > 0) {
|
||||||
const a = this._renderQ[0];
|
const a = this._renderQ[0];
|
||||||
@ -614,7 +485,7 @@ export default class Display {
|
|||||||
this.flip(true);
|
this.flip(true);
|
||||||
break;
|
break;
|
||||||
case 'copy':
|
case 'copy':
|
||||||
this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true);
|
this.copyImage(a.oldX, a.oldY, a.x, a.y, a.width, a.height, true);
|
||||||
break;
|
break;
|
||||||
case 'fill':
|
case 'fill':
|
||||||
this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
|
this.fillRect(a.x, a.y, a.width, a.height, a.color, true);
|
||||||
@ -622,18 +493,19 @@ export default class Display {
|
|||||||
case 'blit':
|
case 'blit':
|
||||||
this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
||||||
break;
|
break;
|
||||||
case 'blitRgb':
|
|
||||||
this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
|
||||||
break;
|
|
||||||
case 'blitRgbx':
|
|
||||||
this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true);
|
|
||||||
break;
|
|
||||||
case 'img':
|
case 'img':
|
||||||
if (a.img.complete) {
|
/* IE tends to set "complete" prematurely, so check dimensions */
|
||||||
|
if (a.img.complete && (a.img.width !== 0) && (a.img.height !== 0)) {
|
||||||
|
if (a.img.width !== a.width || a.img.height !== a.height) {
|
||||||
|
Log.Error("Decoded image has incorrect dimensions. Got " +
|
||||||
|
a.img.width + "x" + a.img.height + ". Expected " +
|
||||||
|
a.width + "x" + a.height + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.drawImage(a.img, a.x, a.y);
|
this.drawImage(a.img, a.x, a.y);
|
||||||
} else {
|
} else {
|
||||||
a.img._noVNC_display = this;
|
a.img._noVNCDisplay = this;
|
||||||
a.img.addEventListener('load', this._resume_renderQ);
|
a.img.addEventListener('load', this._resumeRenderQ);
|
||||||
// We need to wait for this image to 'load'
|
// We need to wait for this image to 'load'
|
||||||
// to keep things in-order
|
// to keep things in-order
|
||||||
ready = false;
|
ready = false;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -20,12 +20,15 @@ export const encodings = {
|
|||||||
pseudoEncodingLastRect: -224,
|
pseudoEncodingLastRect: -224,
|
||||||
pseudoEncodingCursor: -239,
|
pseudoEncodingCursor: -239,
|
||||||
pseudoEncodingQEMUExtendedKeyEvent: -258,
|
pseudoEncodingQEMUExtendedKeyEvent: -258,
|
||||||
|
pseudoEncodingDesktopName: -307,
|
||||||
pseudoEncodingExtendedDesktopSize: -308,
|
pseudoEncodingExtendedDesktopSize: -308,
|
||||||
pseudoEncodingXvp: -309,
|
pseudoEncodingXvp: -309,
|
||||||
pseudoEncodingFence: -312,
|
pseudoEncodingFence: -312,
|
||||||
pseudoEncodingContinuousUpdates: -313,
|
pseudoEncodingContinuousUpdates: -313,
|
||||||
pseudoEncodingCompressLevel9: -247,
|
pseudoEncodingCompressLevel9: -247,
|
||||||
pseudoEncodingCompressLevel0: -256,
|
pseudoEncodingCompressLevel0: -256,
|
||||||
|
pseudoEncodingVMwareCursor: 0x574d5664,
|
||||||
|
pseudoEncodingExtendedClipboard: 0xc0a1e5ce
|
||||||
};
|
};
|
||||||
|
|
||||||
export function encodingName(num) {
|
export function encodingName(num) {
|
||||||
|
|||||||
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2020 The noVNC Authors
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js";
|
import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js";
|
||||||
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
|
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
|
||||||
|
|
||||||
@ -11,12 +19,22 @@ export default class Inflate {
|
|||||||
inflateInit(this.strm, this.windowBits);
|
inflateInit(this.strm, this.windowBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
inflate(data, flush, expected) {
|
setInput(data) {
|
||||||
this.strm.input = data;
|
if (!data) {
|
||||||
this.strm.avail_in = this.strm.input.length;
|
//FIXME: flush remaining data.
|
||||||
this.strm.next_in = 0;
|
/* eslint-disable camelcase */
|
||||||
this.strm.next_out = 0;
|
this.strm.input = null;
|
||||||
|
this.strm.avail_in = 0;
|
||||||
|
this.strm.next_in = 0;
|
||||||
|
} else {
|
||||||
|
this.strm.input = data;
|
||||||
|
this.strm.avail_in = this.strm.input.length;
|
||||||
|
this.strm.next_in = 0;
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inflate(expected) {
|
||||||
// resize our output buffer if it's too small
|
// resize our output buffer if it's too small
|
||||||
// (we could just use multiple chunks, but that would cause an extra
|
// (we could just use multiple chunks, but that would cause an extra
|
||||||
// allocation each time to flatten the chunks)
|
// allocation each time to flatten the chunks)
|
||||||
@ -25,9 +43,19 @@ export default class Inflate {
|
|||||||
this.strm.output = new Uint8Array(this.chunkSize);
|
this.strm.output = new Uint8Array(this.chunkSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.strm.avail_out = this.chunkSize;
|
/* eslint-disable camelcase */
|
||||||
|
this.strm.next_out = 0;
|
||||||
|
this.strm.avail_out = expected;
|
||||||
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
inflate(this.strm, flush);
|
let ret = inflate(this.strm, 0); // Flush argument not used.
|
||||||
|
if (ret < 0) {
|
||||||
|
throw new Error("zlib inflate failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.strm.next_out != expected) {
|
||||||
|
throw new Error("Incomplete zlib block");
|
||||||
|
}
|
||||||
|
|
||||||
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
|
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,12 +43,10 @@ addStandard("CapsLock", KeyTable.XK_Caps_Lock);
|
|||||||
addLeftRight("Control", KeyTable.XK_Control_L, KeyTable.XK_Control_R);
|
addLeftRight("Control", KeyTable.XK_Control_L, KeyTable.XK_Control_R);
|
||||||
// - Fn
|
// - Fn
|
||||||
// - FnLock
|
// - FnLock
|
||||||
addLeftRight("Hyper", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
|
||||||
addLeftRight("Meta", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
addLeftRight("Meta", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
||||||
addStandard("NumLock", KeyTable.XK_Num_Lock);
|
addStandard("NumLock", KeyTable.XK_Num_Lock);
|
||||||
addStandard("ScrollLock", KeyTable.XK_Scroll_Lock);
|
addStandard("ScrollLock", KeyTable.XK_Scroll_Lock);
|
||||||
addLeftRight("Shift", KeyTable.XK_Shift_L, KeyTable.XK_Shift_R);
|
addLeftRight("Shift", KeyTable.XK_Shift_L, KeyTable.XK_Shift_R);
|
||||||
addLeftRight("Super", KeyTable.XK_Super_L, KeyTable.XK_Super_R);
|
|
||||||
// - Symbol
|
// - Symbol
|
||||||
// - SymbolLock
|
// - SymbolLock
|
||||||
|
|
||||||
@ -72,6 +70,9 @@ addNumpad("PageUp", KeyTable.XK_Prior, KeyTable.XK_KP_Prior);
|
|||||||
// 2.5. Editing Keys
|
// 2.5. Editing Keys
|
||||||
|
|
||||||
addStandard("Backspace", KeyTable.XK_BackSpace);
|
addStandard("Backspace", KeyTable.XK_BackSpace);
|
||||||
|
// Browsers send "Clear" for the numpad 5 without NumLock because
|
||||||
|
// Windows uses VK_Clear for that key. But Unix expects KP_Begin for
|
||||||
|
// that scenario.
|
||||||
addNumpad("Clear", KeyTable.XK_Clear, KeyTable.XK_KP_Begin);
|
addNumpad("Clear", KeyTable.XK_Clear, KeyTable.XK_KP_Begin);
|
||||||
addStandard("Copy", KeyTable.XF86XK_Copy);
|
addStandard("Copy", KeyTable.XF86XK_Copy);
|
||||||
// - CrSel
|
// - CrSel
|
||||||
@ -194,7 +195,8 @@ addStandard("F35", KeyTable.XK_F35);
|
|||||||
addStandard("Close", KeyTable.XF86XK_Close);
|
addStandard("Close", KeyTable.XF86XK_Close);
|
||||||
addStandard("MailForward", KeyTable.XF86XK_MailForward);
|
addStandard("MailForward", KeyTable.XF86XK_MailForward);
|
||||||
addStandard("MailReply", KeyTable.XF86XK_Reply);
|
addStandard("MailReply", KeyTable.XF86XK_Reply);
|
||||||
addStandard("MainSend", KeyTable.XF86XK_Send);
|
addStandard("MailSend", KeyTable.XF86XK_Send);
|
||||||
|
// - MediaClose
|
||||||
addStandard("MediaFastForward", KeyTable.XF86XK_AudioForward);
|
addStandard("MediaFastForward", KeyTable.XF86XK_AudioForward);
|
||||||
addStandard("MediaPause", KeyTable.XF86XK_AudioPause);
|
addStandard("MediaPause", KeyTable.XF86XK_AudioPause);
|
||||||
addStandard("MediaPlay", KeyTable.XF86XK_AudioPlay);
|
addStandard("MediaPlay", KeyTable.XF86XK_AudioPlay);
|
||||||
@ -218,11 +220,9 @@ addStandard("SpellCheck", KeyTable.XF86XK_Spell);
|
|||||||
|
|
||||||
// - AudioBalanceLeft
|
// - AudioBalanceLeft
|
||||||
// - AudioBalanceRight
|
// - AudioBalanceRight
|
||||||
// - AudioBassDown
|
|
||||||
// - AudioBassBoostDown
|
// - AudioBassBoostDown
|
||||||
// - AudioBassBoostToggle
|
// - AudioBassBoostToggle
|
||||||
// - AudioBassBoostUp
|
// - AudioBassBoostUp
|
||||||
// - AudioBassUp
|
|
||||||
// - AudioFaderFront
|
// - AudioFaderFront
|
||||||
// - AudioFaderRear
|
// - AudioFaderRear
|
||||||
// - AudioSurroundModeNext
|
// - AudioSurroundModeNext
|
||||||
@ -243,12 +243,12 @@ addStandard("MicrophoneVolumeMute", KeyTable.XF86XK_AudioMicMute);
|
|||||||
|
|
||||||
// 2.14. Application Keys
|
// 2.14. Application Keys
|
||||||
|
|
||||||
addStandard("LaunchCalculator", KeyTable.XF86XK_Calculator);
|
addStandard("LaunchApplication1", KeyTable.XF86XK_MyComputer);
|
||||||
|
addStandard("LaunchApplication2", KeyTable.XF86XK_Calculator);
|
||||||
addStandard("LaunchCalendar", KeyTable.XF86XK_Calendar);
|
addStandard("LaunchCalendar", KeyTable.XF86XK_Calendar);
|
||||||
addStandard("LaunchMail", KeyTable.XF86XK_Mail);
|
addStandard("LaunchMail", KeyTable.XF86XK_Mail);
|
||||||
addStandard("LaunchMediaPlayer", KeyTable.XF86XK_AudioMedia);
|
addStandard("LaunchMediaPlayer", KeyTable.XF86XK_AudioMedia);
|
||||||
addStandard("LaunchMusicPlayer", KeyTable.XF86XK_Music);
|
addStandard("LaunchMusicPlayer", KeyTable.XF86XK_Music);
|
||||||
addStandard("LaunchMyComputer", KeyTable.XF86XK_MyComputer);
|
|
||||||
addStandard("LaunchPhone", KeyTable.XF86XK_Phone);
|
addStandard("LaunchPhone", KeyTable.XF86XK_Phone);
|
||||||
addStandard("LaunchScreenSaver", KeyTable.XF86XK_ScreenSaver);
|
addStandard("LaunchScreenSaver", KeyTable.XF86XK_ScreenSaver);
|
||||||
addStandard("LaunchSpreadsheet", KeyTable.XF86XK_Excel);
|
addStandard("LaunchSpreadsheet", KeyTable.XF86XK_Excel);
|
||||||
|
|||||||
567
systemvm/agent/noVNC/core/input/gesturehandler.js
Normal file
@ -0,0 +1,567 @@
|
|||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2020 The noVNC Authors
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const GH_NOGESTURE = 0;
|
||||||
|
const GH_ONETAP = 1;
|
||||||
|
const GH_TWOTAP = 2;
|
||||||
|
const GH_THREETAP = 4;
|
||||||
|
const GH_DRAG = 8;
|
||||||
|
const GH_LONGPRESS = 16;
|
||||||
|
const GH_TWODRAG = 32;
|
||||||
|
const GH_PINCH = 64;
|
||||||
|
|
||||||
|
const GH_INITSTATE = 127;
|
||||||
|
|
||||||
|
const GH_MOVE_THRESHOLD = 50;
|
||||||
|
const GH_ANGLE_THRESHOLD = 90; // Degrees
|
||||||
|
|
||||||
|
// Timeout when waiting for gestures (ms)
|
||||||
|
const GH_MULTITOUCH_TIMEOUT = 250;
|
||||||
|
|
||||||
|
// Maximum time between press and release for a tap (ms)
|
||||||
|
const GH_TAP_TIMEOUT = 1000;
|
||||||
|
|
||||||
|
// Timeout when waiting for longpress (ms)
|
||||||
|
const GH_LONGPRESS_TIMEOUT = 1000;
|
||||||
|
|
||||||
|
// Timeout when waiting to decide between PINCH and TWODRAG (ms)
|
||||||
|
const GH_TWOTOUCH_TIMEOUT = 50;
|
||||||
|
|
||||||
|
export default class GestureHandler {
|
||||||
|
constructor() {
|
||||||
|
this._target = null;
|
||||||
|
|
||||||
|
this._state = GH_INITSTATE;
|
||||||
|
|
||||||
|
this._tracked = [];
|
||||||
|
this._ignored = [];
|
||||||
|
|
||||||
|
this._waitingRelease = false;
|
||||||
|
this._releaseStart = 0.0;
|
||||||
|
|
||||||
|
this._longpressTimeoutId = null;
|
||||||
|
this._twoTouchTimeoutId = null;
|
||||||
|
|
||||||
|
this._boundEventHandler = this._eventHandler.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
attach(target) {
|
||||||
|
this.detach();
|
||||||
|
|
||||||
|
this._target = target;
|
||||||
|
this._target.addEventListener('touchstart',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target.addEventListener('touchmove',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target.addEventListener('touchend',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target.addEventListener('touchcancel',
|
||||||
|
this._boundEventHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
detach() {
|
||||||
|
if (!this._target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._stopLongpressTimeout();
|
||||||
|
this._stopTwoTouchTimeout();
|
||||||
|
|
||||||
|
this._target.removeEventListener('touchstart',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target.removeEventListener('touchmove',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target.removeEventListener('touchend',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target.removeEventListener('touchcancel',
|
||||||
|
this._boundEventHandler);
|
||||||
|
this._target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_eventHandler(e) {
|
||||||
|
let fn;
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
switch (e.type) {
|
||||||
|
case 'touchstart':
|
||||||
|
fn = this._touchStart;
|
||||||
|
break;
|
||||||
|
case 'touchmove':
|
||||||
|
fn = this._touchMove;
|
||||||
|
break;
|
||||||
|
case 'touchend':
|
||||||
|
case 'touchcancel':
|
||||||
|
fn = this._touchEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < e.changedTouches.length; i++) {
|
||||||
|
let touch = e.changedTouches[i];
|
||||||
|
fn.call(this, touch.identifier, touch.clientX, touch.clientY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_touchStart(id, x, y) {
|
||||||
|
// Ignore any new touches if there is already an active gesture,
|
||||||
|
// or we're in a cleanup state
|
||||||
|
if (this._hasDetectedGesture() || (this._state === GH_NOGESTURE)) {
|
||||||
|
this._ignored.push(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did it take too long between touches that we should no longer
|
||||||
|
// consider this a single gesture?
|
||||||
|
if ((this._tracked.length > 0) &&
|
||||||
|
((Date.now() - this._tracked[0].started) > GH_MULTITOUCH_TIMEOUT)) {
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
this._ignored.push(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're waiting for fingers to release then we should no longer
|
||||||
|
// recognize new touches
|
||||||
|
if (this._waitingRelease) {
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
this._ignored.push(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._tracked.push({
|
||||||
|
id: id,
|
||||||
|
started: Date.now(),
|
||||||
|
active: true,
|
||||||
|
firstX: x,
|
||||||
|
firstY: y,
|
||||||
|
lastX: x,
|
||||||
|
lastY: y,
|
||||||
|
angle: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (this._tracked.length) {
|
||||||
|
case 1:
|
||||||
|
this._startLongpressTimeout();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
this._state &= ~(GH_ONETAP | GH_DRAG | GH_LONGPRESS);
|
||||||
|
this._stopLongpressTimeout();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
this._state &= ~(GH_TWOTAP | GH_TWODRAG | GH_PINCH);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_touchMove(id, x, y) {
|
||||||
|
let touch = this._tracked.find(t => t.id === id);
|
||||||
|
|
||||||
|
// If this is an update for a touch we're not tracking, ignore it
|
||||||
|
if (touch === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the touches last position with the event coordinates
|
||||||
|
touch.lastX = x;
|
||||||
|
touch.lastY = y;
|
||||||
|
|
||||||
|
let deltaX = x - touch.firstX;
|
||||||
|
let deltaY = y - touch.firstY;
|
||||||
|
|
||||||
|
// Update angle when the touch has moved
|
||||||
|
if ((touch.firstX !== touch.lastX) ||
|
||||||
|
(touch.firstY !== touch.lastY)) {
|
||||||
|
touch.angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._hasDetectedGesture()) {
|
||||||
|
// Ignore moves smaller than the minimum threshold
|
||||||
|
if (Math.hypot(deltaX, deltaY) < GH_MOVE_THRESHOLD) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't be a tap or long press as we've seen movement
|
||||||
|
this._state &= ~(GH_ONETAP | GH_TWOTAP | GH_THREETAP | GH_LONGPRESS);
|
||||||
|
this._stopLongpressTimeout();
|
||||||
|
|
||||||
|
if (this._tracked.length !== 1) {
|
||||||
|
this._state &= ~(GH_DRAG);
|
||||||
|
}
|
||||||
|
if (this._tracked.length !== 2) {
|
||||||
|
this._state &= ~(GH_TWODRAG | GH_PINCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to figure out which of our different two touch gestures
|
||||||
|
// this might be
|
||||||
|
if (this._tracked.length === 2) {
|
||||||
|
|
||||||
|
// The other touch is the one where the id doesn't match
|
||||||
|
let prevTouch = this._tracked.find(t => t.id !== id);
|
||||||
|
|
||||||
|
// How far the previous touch point has moved since start
|
||||||
|
let prevDeltaMove = Math.hypot(prevTouch.firstX - prevTouch.lastX,
|
||||||
|
prevTouch.firstY - prevTouch.lastY);
|
||||||
|
|
||||||
|
// We know that the current touch moved far enough,
|
||||||
|
// but unless both touches moved further than their
|
||||||
|
// threshold we don't want to disqualify any gestures
|
||||||
|
if (prevDeltaMove > GH_MOVE_THRESHOLD) {
|
||||||
|
|
||||||
|
// The angle difference between the direction of the touch points
|
||||||
|
let deltaAngle = Math.abs(touch.angle - prevTouch.angle);
|
||||||
|
deltaAngle = Math.abs(((deltaAngle + 180) % 360) - 180);
|
||||||
|
|
||||||
|
// PINCH or TWODRAG can be eliminated depending on the angle
|
||||||
|
if (deltaAngle > GH_ANGLE_THRESHOLD) {
|
||||||
|
this._state &= ~GH_TWODRAG;
|
||||||
|
} else {
|
||||||
|
this._state &= ~GH_PINCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._isTwoTouchTimeoutRunning()) {
|
||||||
|
this._stopTwoTouchTimeout();
|
||||||
|
}
|
||||||
|
} else if (!this._isTwoTouchTimeoutRunning()) {
|
||||||
|
// We can't determine the gesture right now, let's
|
||||||
|
// wait and see if more events are on their way
|
||||||
|
this._startTwoTouchTimeout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._hasDetectedGesture()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pushEvent('gesturestart');
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pushEvent('gesturemove');
|
||||||
|
}
|
||||||
|
|
||||||
|
_touchEnd(id, x, y) {
|
||||||
|
// Check if this is an ignored touch
|
||||||
|
if (this._ignored.indexOf(id) !== -1) {
|
||||||
|
// Remove this touch from ignored
|
||||||
|
this._ignored.splice(this._ignored.indexOf(id), 1);
|
||||||
|
|
||||||
|
// And reset the state if there are no more touches
|
||||||
|
if ((this._ignored.length === 0) &&
|
||||||
|
(this._tracked.length === 0)) {
|
||||||
|
this._state = GH_INITSTATE;
|
||||||
|
this._waitingRelease = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got a touchend before the timer triggered,
|
||||||
|
// this cannot result in a gesture anymore.
|
||||||
|
if (!this._hasDetectedGesture() &&
|
||||||
|
this._isTwoTouchTimeoutRunning()) {
|
||||||
|
this._stopTwoTouchTimeout();
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some gestures don't trigger until a touch is released
|
||||||
|
if (!this._hasDetectedGesture()) {
|
||||||
|
// Can't be a gesture that relies on movement
|
||||||
|
this._state &= ~(GH_DRAG | GH_TWODRAG | GH_PINCH);
|
||||||
|
// Or something that relies on more time
|
||||||
|
this._state &= ~GH_LONGPRESS;
|
||||||
|
this._stopLongpressTimeout();
|
||||||
|
|
||||||
|
if (!this._waitingRelease) {
|
||||||
|
this._releaseStart = Date.now();
|
||||||
|
this._waitingRelease = true;
|
||||||
|
|
||||||
|
// Can't be a tap that requires more touches than we current have
|
||||||
|
switch (this._tracked.length) {
|
||||||
|
case 1:
|
||||||
|
this._state &= ~(GH_TWOTAP | GH_THREETAP);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
this._state &= ~(GH_ONETAP | GH_THREETAP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Waiting for all touches to release? (i.e. some tap)
|
||||||
|
if (this._waitingRelease) {
|
||||||
|
// Were all touches released at roughly the same time?
|
||||||
|
if ((Date.now() - this._releaseStart) > GH_MULTITOUCH_TIMEOUT) {
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did too long time pass between press and release?
|
||||||
|
if (this._tracked.some(t => (Date.now() - t.started) > GH_TAP_TIMEOUT)) {
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
let touch = this._tracked.find(t => t.id === id);
|
||||||
|
touch.active = false;
|
||||||
|
|
||||||
|
// Are we still waiting for more releases?
|
||||||
|
if (this._hasDetectedGesture()) {
|
||||||
|
this._pushEvent('gesturestart');
|
||||||
|
} else {
|
||||||
|
// Have we reached a dead end?
|
||||||
|
if (this._state !== GH_NOGESTURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._hasDetectedGesture()) {
|
||||||
|
this._pushEvent('gestureend');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore any remaining touches until they are ended
|
||||||
|
for (let i = 0; i < this._tracked.length; i++) {
|
||||||
|
if (this._tracked[i].active) {
|
||||||
|
this._ignored.push(this._tracked[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._tracked = [];
|
||||||
|
|
||||||
|
this._state = GH_NOGESTURE;
|
||||||
|
|
||||||
|
// Remove this touch from ignored if it's in there
|
||||||
|
if (this._ignored.indexOf(id) !== -1) {
|
||||||
|
this._ignored.splice(this._ignored.indexOf(id), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We reset the state if ignored is empty
|
||||||
|
if ((this._ignored.length === 0)) {
|
||||||
|
this._state = GH_INITSTATE;
|
||||||
|
this._waitingRelease = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasDetectedGesture() {
|
||||||
|
if (this._state === GH_NOGESTURE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check to see if the bitmask value is a power of 2
|
||||||
|
// (i.e. only one bit set). If it is, we have a state.
|
||||||
|
if (this._state & (this._state - 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For taps we also need to have all touches released
|
||||||
|
// before we've fully detected the gesture
|
||||||
|
if (this._state & (GH_ONETAP | GH_TWOTAP | GH_THREETAP)) {
|
||||||
|
if (this._tracked.some(t => t.active)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_startLongpressTimeout() {
|
||||||
|
this._stopLongpressTimeout();
|
||||||
|
this._longpressTimeoutId = setTimeout(() => this._longpressTimeout(),
|
||||||
|
GH_LONGPRESS_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopLongpressTimeout() {
|
||||||
|
clearTimeout(this._longpressTimeoutId);
|
||||||
|
this._longpressTimeoutId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_longpressTimeout() {
|
||||||
|
if (this._hasDetectedGesture()) {
|
||||||
|
throw new Error("A longpress gesture failed, conflict with a different gesture");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._state = GH_LONGPRESS;
|
||||||
|
this._pushEvent('gesturestart');
|
||||||
|
}
|
||||||
|
|
||||||
|
_startTwoTouchTimeout() {
|
||||||
|
this._stopTwoTouchTimeout();
|
||||||
|
this._twoTouchTimeoutId = setTimeout(() => this._twoTouchTimeout(),
|
||||||
|
GH_TWOTOUCH_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopTwoTouchTimeout() {
|
||||||
|
clearTimeout(this._twoTouchTimeoutId);
|
||||||
|
this._twoTouchTimeoutId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isTwoTouchTimeoutRunning() {
|
||||||
|
return this._twoTouchTimeoutId !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_twoTouchTimeout() {
|
||||||
|
if (this._tracked.length === 0) {
|
||||||
|
throw new Error("A pinch or two drag gesture failed, no tracked touches");
|
||||||
|
}
|
||||||
|
|
||||||
|
// How far each touch point has moved since start
|
||||||
|
let avgM = this._getAverageMovement();
|
||||||
|
let avgMoveH = Math.abs(avgM.x);
|
||||||
|
let avgMoveV = Math.abs(avgM.y);
|
||||||
|
|
||||||
|
// The difference in the distance between where
|
||||||
|
// the touch points started and where they are now
|
||||||
|
let avgD = this._getAverageDistance();
|
||||||
|
let deltaTouchDistance = Math.abs(Math.hypot(avgD.first.x, avgD.first.y) -
|
||||||
|
Math.hypot(avgD.last.x, avgD.last.y));
|
||||||
|
|
||||||
|
if ((avgMoveV < deltaTouchDistance) &&
|
||||||
|
(avgMoveH < deltaTouchDistance)) {
|
||||||
|
this._state = GH_PINCH;
|
||||||
|
} else {
|
||||||
|
this._state = GH_TWODRAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pushEvent('gesturestart');
|
||||||
|
this._pushEvent('gesturemove');
|
||||||
|
}
|
||||||
|
|
||||||
|
_pushEvent(type) {
|
||||||
|
let detail = { type: this._stateToGesture(this._state) };
|
||||||
|
|
||||||
|
// For most gesture events the current (average) position is the
|
||||||
|
// most useful
|
||||||
|
let avg = this._getPosition();
|
||||||
|
let pos = avg.last;
|
||||||
|
|
||||||
|
// However we have a slight distance to detect gestures, so for the
|
||||||
|
// first gesture event we want to use the first positions we saw
|
||||||
|
if (type === 'gesturestart') {
|
||||||
|
pos = avg.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For these gestures, we always want the event coordinates
|
||||||
|
// to be where the gesture began, not the current touch location.
|
||||||
|
switch (this._state) {
|
||||||
|
case GH_TWODRAG:
|
||||||
|
case GH_PINCH:
|
||||||
|
pos = avg.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
detail['clientX'] = pos.x;
|
||||||
|
detail['clientY'] = pos.y;
|
||||||
|
|
||||||
|
// FIXME: other coordinates?
|
||||||
|
|
||||||
|
// Some gestures also have a magnitude
|
||||||
|
if (this._state === GH_PINCH) {
|
||||||
|
let distance = this._getAverageDistance();
|
||||||
|
if (type === 'gesturestart') {
|
||||||
|
detail['magnitudeX'] = distance.first.x;
|
||||||
|
detail['magnitudeY'] = distance.first.y;
|
||||||
|
} else {
|
||||||
|
detail['magnitudeX'] = distance.last.x;
|
||||||
|
detail['magnitudeY'] = distance.last.y;
|
||||||
|
}
|
||||||
|
} else if (this._state === GH_TWODRAG) {
|
||||||
|
if (type === 'gesturestart') {
|
||||||
|
detail['magnitudeX'] = 0.0;
|
||||||
|
detail['magnitudeY'] = 0.0;
|
||||||
|
} else {
|
||||||
|
let movement = this._getAverageMovement();
|
||||||
|
detail['magnitudeX'] = movement.x;
|
||||||
|
detail['magnitudeY'] = movement.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gev = new CustomEvent(type, { detail: detail });
|
||||||
|
this._target.dispatchEvent(gev);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateToGesture(state) {
|
||||||
|
switch (state) {
|
||||||
|
case GH_ONETAP:
|
||||||
|
return 'onetap';
|
||||||
|
case GH_TWOTAP:
|
||||||
|
return 'twotap';
|
||||||
|
case GH_THREETAP:
|
||||||
|
return 'threetap';
|
||||||
|
case GH_DRAG:
|
||||||
|
return 'drag';
|
||||||
|
case GH_LONGPRESS:
|
||||||
|
return 'longpress';
|
||||||
|
case GH_TWODRAG:
|
||||||
|
return 'twodrag';
|
||||||
|
case GH_PINCH:
|
||||||
|
return 'pinch';
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Unknown gesture state: " + state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getPosition() {
|
||||||
|
if (this._tracked.length === 0) {
|
||||||
|
throw new Error("Failed to get gesture position, no tracked touches");
|
||||||
|
}
|
||||||
|
|
||||||
|
let size = this._tracked.length;
|
||||||
|
let fx = 0, fy = 0, lx = 0, ly = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._tracked.length; i++) {
|
||||||
|
fx += this._tracked[i].firstX;
|
||||||
|
fy += this._tracked[i].firstY;
|
||||||
|
lx += this._tracked[i].lastX;
|
||||||
|
ly += this._tracked[i].lastY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { first: { x: fx / size,
|
||||||
|
y: fy / size },
|
||||||
|
last: { x: lx / size,
|
||||||
|
y: ly / size } };
|
||||||
|
}
|
||||||
|
|
||||||
|
_getAverageMovement() {
|
||||||
|
if (this._tracked.length === 0) {
|
||||||
|
throw new Error("Failed to get gesture movement, no tracked touches");
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalH, totalV;
|
||||||
|
totalH = totalV = 0;
|
||||||
|
let size = this._tracked.length;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._tracked.length; i++) {
|
||||||
|
totalH += this._tracked[i].lastX - this._tracked[i].firstX;
|
||||||
|
totalV += this._tracked[i].lastY - this._tracked[i].firstY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { x: totalH / size,
|
||||||
|
y: totalV / size };
|
||||||
|
}
|
||||||
|
|
||||||
|
_getAverageDistance() {
|
||||||
|
if (this._tracked.length === 0) {
|
||||||
|
throw new Error("Failed to get gesture distance, no tracked touches");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distance between the first and last tracked touches
|
||||||
|
|
||||||
|
let first = this._tracked[0];
|
||||||
|
let last = this._tracked[this._tracked.length - 1];
|
||||||
|
|
||||||
|
let fdx = Math.abs(last.firstX - first.firstX);
|
||||||
|
let fdy = Math.abs(last.firstY - first.firstY);
|
||||||
|
|
||||||
|
let ldx = Math.abs(last.lastX - first.lastX);
|
||||||
|
let ldy = Math.abs(last.lastY - first.lastY);
|
||||||
|
|
||||||
|
return { first: { x: fdx, y: fdy },
|
||||||
|
last: { x: ldx, y: ldy } };
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -118,9 +118,7 @@ export default class Keyboard {
|
|||||||
|
|
||||||
// We cannot handle keys we cannot track, but we also need
|
// We cannot handle keys we cannot track, but we also need
|
||||||
// to deal with virtual keyboards which omit key info
|
// to deal with virtual keyboards which omit key info
|
||||||
// (iOS omits tracking info on keyup events, which forces us to
|
if (code === 'Unidentified') {
|
||||||
// special treat that platform here)
|
|
||||||
if ((code === 'Unidentified') || browser.isIOS()) {
|
|
||||||
if (keysym) {
|
if (keysym) {
|
||||||
// If it's a virtual keyboard then it should be
|
// If it's a virtual keyboard then it should be
|
||||||
// sufficient to just send press and release right
|
// sufficient to just send press and release right
|
||||||
@ -137,7 +135,7 @@ export default class Keyboard {
|
|||||||
// keys around a bit to make things more sane for the remote
|
// keys around a bit to make things more sane for the remote
|
||||||
// server. This method is used by RealVNC and TigerVNC (and
|
// server. This method is used by RealVNC and TigerVNC (and
|
||||||
// possibly others).
|
// possibly others).
|
||||||
if (browser.isMac()) {
|
if (browser.isMac() || browser.isIOS()) {
|
||||||
switch (keysym) {
|
switch (keysym) {
|
||||||
case KeyTable.XK_Super_L:
|
case KeyTable.XK_Super_L:
|
||||||
keysym = KeyTable.XK_Alt_L;
|
keysym = KeyTable.XK_Alt_L;
|
||||||
@ -164,7 +162,7 @@ export default class Keyboard {
|
|||||||
// state change events. That gets extra confusing for CapsLock
|
// state change events. That gets extra confusing for CapsLock
|
||||||
// which toggles on each press, but not on release. So pretend
|
// which toggles on each press, but not on release. So pretend
|
||||||
// it was a quick press and release of the button.
|
// it was a quick press and release of the button.
|
||||||
if (browser.isMac() && (code === 'CapsLock')) {
|
if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
|
||||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
|
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
|
||||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
|
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
|
||||||
stopEvent(e);
|
stopEvent(e);
|
||||||
@ -276,13 +274,28 @@ export default class Keyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See comment in _handleKeyDown()
|
// See comment in _handleKeyDown()
|
||||||
if (browser.isMac() && (code === 'CapsLock')) {
|
if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
|
||||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
|
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
|
||||||
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
|
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._sendKeyEvent(this._keyDownList[code], code, false);
|
this._sendKeyEvent(this._keyDownList[code], code, false);
|
||||||
|
|
||||||
|
// Windows has a rather nasty bug where it won't send key
|
||||||
|
// release events for a Shift button if the other Shift is still
|
||||||
|
// pressed
|
||||||
|
if (browser.isWindows() && ((code === 'ShiftLeft') ||
|
||||||
|
(code === 'ShiftRight'))) {
|
||||||
|
if ('ShiftRight' in this._keyDownList) {
|
||||||
|
this._sendKeyEvent(this._keyDownList['ShiftRight'],
|
||||||
|
'ShiftRight', false);
|
||||||
|
}
|
||||||
|
if ('ShiftLeft' in this._keyDownList) {
|
||||||
|
this._sendKeyEvent(this._keyDownList['ShiftLeft'],
|
||||||
|
'ShiftLeft', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleAltGrTimeout() {
|
_handleAltGrTimeout() {
|
||||||
@ -299,8 +312,11 @@ export default class Keyboard {
|
|||||||
Log.Debug("<< Keyboard.allKeysUp");
|
Log.Debug("<< Keyboard.allKeysUp");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Firefox Alt workaround, see below
|
// Alt workaround for Firefox on Windows, see below
|
||||||
_checkAlt(e) {
|
_checkAlt(e) {
|
||||||
|
if (e.skipCheckAlt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (e.altKey) {
|
if (e.altKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -315,6 +331,7 @@ export default class Keyboard {
|
|||||||
const event = new KeyboardEvent('keyup',
|
const event = new KeyboardEvent('keyup',
|
||||||
{ key: downList[code],
|
{ key: downList[code],
|
||||||
code: code });
|
code: code });
|
||||||
|
event.skipCheckAlt = true;
|
||||||
target.dispatchEvent(event);
|
target.dispatchEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -331,9 +348,10 @@ export default class Keyboard {
|
|||||||
// Release (key up) if window loses focus
|
// Release (key up) if window loses focus
|
||||||
window.addEventListener('blur', this._eventHandlers.blur);
|
window.addEventListener('blur', this._eventHandlers.blur);
|
||||||
|
|
||||||
// Firefox has broken handling of Alt, so we need to poll as
|
// Firefox on Windows has broken handling of Alt, so we need to
|
||||||
// best we can for releases (still doesn't prevent the menu
|
// poll as best we can for releases (still doesn't prevent the
|
||||||
// from popping up though as we can't call preventDefault())
|
// menu from popping up though as we can't call
|
||||||
|
// preventDefault())
|
||||||
if (browser.isWindows() && browser.isFirefox()) {
|
if (browser.isWindows() && browser.isFirefox()) {
|
||||||
const handler = this._eventHandlers.checkalt;
|
const handler = this._eventHandlers.checkalt;
|
||||||
['mousedown', 'mouseup', 'mousemove', 'wheel',
|
['mousedown', 'mouseup', 'mousemove', 'wheel',
|
||||||
|
|||||||
@ -1,276 +0,0 @@
|
|||||||
/*
|
|
||||||
* noVNC: HTML5 VNC client
|
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
|
||||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as Log from '../util/logging.js';
|
|
||||||
import { isTouchDevice } from '../util/browser.js';
|
|
||||||
import { setCapture, stopEvent, getPointerEvent } from '../util/events.js';
|
|
||||||
|
|
||||||
const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
|
|
||||||
const WHEEL_STEP_TIMEOUT = 50; // ms
|
|
||||||
const WHEEL_LINE_HEIGHT = 19;
|
|
||||||
|
|
||||||
export default class Mouse {
|
|
||||||
constructor(target) {
|
|
||||||
this._target = target || document;
|
|
||||||
|
|
||||||
this._doubleClickTimer = null;
|
|
||||||
this._lastTouchPos = null;
|
|
||||||
|
|
||||||
this._pos = null;
|
|
||||||
this._wheelStepXTimer = null;
|
|
||||||
this._wheelStepYTimer = null;
|
|
||||||
this._accumulatedWheelDeltaX = 0;
|
|
||||||
this._accumulatedWheelDeltaY = 0;
|
|
||||||
|
|
||||||
this._eventHandlers = {
|
|
||||||
'mousedown': this._handleMouseDown.bind(this),
|
|
||||||
'mouseup': this._handleMouseUp.bind(this),
|
|
||||||
'mousemove': this._handleMouseMove.bind(this),
|
|
||||||
'mousewheel': this._handleMouseWheel.bind(this),
|
|
||||||
'mousedisable': this._handleMouseDisable.bind(this)
|
|
||||||
};
|
|
||||||
|
|
||||||
// ===== PROPERTIES =====
|
|
||||||
|
|
||||||
this.touchButton = 1; // Button mask (1, 2, 4) for touch devices (0 means ignore clicks)
|
|
||||||
|
|
||||||
// ===== EVENT HANDLERS =====
|
|
||||||
|
|
||||||
this.onmousebutton = () => {}; // Handler for mouse button click/release
|
|
||||||
this.onmousemove = () => {}; // Handler for mouse movement
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== PRIVATE METHODS =====
|
|
||||||
|
|
||||||
_resetDoubleClickTimer() {
|
|
||||||
this._doubleClickTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleMouseButton(e, down) {
|
|
||||||
this._updateMousePosition(e);
|
|
||||||
let pos = this._pos;
|
|
||||||
|
|
||||||
let bmask;
|
|
||||||
if (e.touches || e.changedTouches) {
|
|
||||||
// Touch device
|
|
||||||
|
|
||||||
// When two touches occur within 500 ms of each other and are
|
|
||||||
// close enough together a double click is triggered.
|
|
||||||
if (down == 1) {
|
|
||||||
if (this._doubleClickTimer === null) {
|
|
||||||
this._lastTouchPos = pos;
|
|
||||||
} else {
|
|
||||||
clearTimeout(this._doubleClickTimer);
|
|
||||||
|
|
||||||
// When the distance between the two touches is small enough
|
|
||||||
// force the position of the latter touch to the position of
|
|
||||||
// the first.
|
|
||||||
|
|
||||||
const xs = this._lastTouchPos.x - pos.x;
|
|
||||||
const ys = this._lastTouchPos.y - pos.y;
|
|
||||||
const d = Math.sqrt((xs * xs) + (ys * ys));
|
|
||||||
|
|
||||||
// The goal is to trigger on a certain physical width, the
|
|
||||||
// devicePixelRatio brings us a bit closer but is not optimal.
|
|
||||||
const threshold = 20 * (window.devicePixelRatio || 1);
|
|
||||||
if (d < threshold) {
|
|
||||||
pos = this._lastTouchPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._doubleClickTimer = setTimeout(this._resetDoubleClickTimer.bind(this), 500);
|
|
||||||
}
|
|
||||||
bmask = this.touchButton;
|
|
||||||
// If bmask is set
|
|
||||||
} else if (e.which) {
|
|
||||||
/* everything except IE */
|
|
||||||
bmask = 1 << e.button;
|
|
||||||
} else {
|
|
||||||
/* IE including 9 */
|
|
||||||
bmask = (e.button & 0x1) + // Left
|
|
||||||
(e.button & 0x2) * 2 + // Right
|
|
||||||
(e.button & 0x4) / 2; // Middle
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Debug("onmousebutton " + (down ? "down" : "up") +
|
|
||||||
", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask);
|
|
||||||
this.onmousebutton(pos.x, pos.y, down, bmask);
|
|
||||||
|
|
||||||
stopEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleMouseDown(e) {
|
|
||||||
// Touch events have implicit capture
|
|
||||||
if (e.type === "mousedown") {
|
|
||||||
setCapture(this._target);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._handleMouseButton(e, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleMouseUp(e) {
|
|
||||||
this._handleMouseButton(e, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse wheel events are sent in steps over VNC. This means that the VNC
|
|
||||||
// protocol can't handle a wheel event with specific distance or speed.
|
|
||||||
// Therefor, if we get a lot of small mouse wheel events we combine them.
|
|
||||||
_generateWheelStepX() {
|
|
||||||
|
|
||||||
if (this._accumulatedWheelDeltaX < 0) {
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 5);
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 5);
|
|
||||||
} else if (this._accumulatedWheelDeltaX > 0) {
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 6);
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._accumulatedWheelDeltaX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_generateWheelStepY() {
|
|
||||||
|
|
||||||
if (this._accumulatedWheelDeltaY < 0) {
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 3);
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 3);
|
|
||||||
} else if (this._accumulatedWheelDeltaY > 0) {
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 4);
|
|
||||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._accumulatedWheelDeltaY = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_resetWheelStepTimers() {
|
|
||||||
window.clearTimeout(this._wheelStepXTimer);
|
|
||||||
window.clearTimeout(this._wheelStepYTimer);
|
|
||||||
this._wheelStepXTimer = null;
|
|
||||||
this._wheelStepYTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleMouseWheel(e) {
|
|
||||||
this._resetWheelStepTimers();
|
|
||||||
|
|
||||||
this._updateMousePosition(e);
|
|
||||||
|
|
||||||
let dX = e.deltaX;
|
|
||||||
let dY = e.deltaY;
|
|
||||||
|
|
||||||
// Pixel units unless it's non-zero.
|
|
||||||
// Note that if deltamode is line or page won't matter since we aren't
|
|
||||||
// sending the mouse wheel delta to the server anyway.
|
|
||||||
// The difference between pixel and line can be important however since
|
|
||||||
// we have a threshold that can be smaller than the line height.
|
|
||||||
if (e.deltaMode !== 0) {
|
|
||||||
dX *= WHEEL_LINE_HEIGHT;
|
|
||||||
dY *= WHEEL_LINE_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._accumulatedWheelDeltaX += dX;
|
|
||||||
this._accumulatedWheelDeltaY += dY;
|
|
||||||
|
|
||||||
// Generate a mouse wheel step event when the accumulated delta
|
|
||||||
// for one of the axes is large enough.
|
|
||||||
// Small delta events that do not pass the threshold get sent
|
|
||||||
// after a timeout.
|
|
||||||
if (Math.abs(this._accumulatedWheelDeltaX) > WHEEL_STEP) {
|
|
||||||
this._generateWheelStepX();
|
|
||||||
} else {
|
|
||||||
this._wheelStepXTimer =
|
|
||||||
window.setTimeout(this._generateWheelStepX.bind(this),
|
|
||||||
WHEEL_STEP_TIMEOUT);
|
|
||||||
}
|
|
||||||
if (Math.abs(this._accumulatedWheelDeltaY) > WHEEL_STEP) {
|
|
||||||
this._generateWheelStepY();
|
|
||||||
} else {
|
|
||||||
this._wheelStepYTimer =
|
|
||||||
window.setTimeout(this._generateWheelStepY.bind(this),
|
|
||||||
WHEEL_STEP_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
stopEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleMouseMove(e) {
|
|
||||||
this._updateMousePosition(e);
|
|
||||||
this.onmousemove(this._pos.x, this._pos.y);
|
|
||||||
stopEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleMouseDisable(e) {
|
|
||||||
/*
|
|
||||||
* Stop propagation if inside canvas area
|
|
||||||
* Note: This is only needed for the 'click' event as it fails
|
|
||||||
* to fire properly for the target element so we have
|
|
||||||
* to listen on the document element instead.
|
|
||||||
*/
|
|
||||||
if (e.target == this._target) {
|
|
||||||
stopEvent(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update coordinates relative to target
|
|
||||||
_updateMousePosition(e) {
|
|
||||||
e = getPointerEvent(e);
|
|
||||||
const bounds = this._target.getBoundingClientRect();
|
|
||||||
let x;
|
|
||||||
let y;
|
|
||||||
// Clip to target bounds
|
|
||||||
if (e.clientX < bounds.left) {
|
|
||||||
x = 0;
|
|
||||||
} else if (e.clientX >= bounds.right) {
|
|
||||||
x = bounds.width - 1;
|
|
||||||
} else {
|
|
||||||
x = e.clientX - bounds.left;
|
|
||||||
}
|
|
||||||
if (e.clientY < bounds.top) {
|
|
||||||
y = 0;
|
|
||||||
} else if (e.clientY >= bounds.bottom) {
|
|
||||||
y = bounds.height - 1;
|
|
||||||
} else {
|
|
||||||
y = e.clientY - bounds.top;
|
|
||||||
}
|
|
||||||
this._pos = {x: x, y: y};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== PUBLIC METHODS =====
|
|
||||||
|
|
||||||
grab() {
|
|
||||||
if (isTouchDevice) {
|
|
||||||
this._target.addEventListener('touchstart', this._eventHandlers.mousedown);
|
|
||||||
this._target.addEventListener('touchend', this._eventHandlers.mouseup);
|
|
||||||
this._target.addEventListener('touchmove', this._eventHandlers.mousemove);
|
|
||||||
}
|
|
||||||
this._target.addEventListener('mousedown', this._eventHandlers.mousedown);
|
|
||||||
this._target.addEventListener('mouseup', this._eventHandlers.mouseup);
|
|
||||||
this._target.addEventListener('mousemove', this._eventHandlers.mousemove);
|
|
||||||
this._target.addEventListener('wheel', this._eventHandlers.mousewheel);
|
|
||||||
|
|
||||||
/* Prevent middle-click pasting (see above for why we bind to document) */
|
|
||||||
document.addEventListener('click', this._eventHandlers.mousedisable);
|
|
||||||
|
|
||||||
/* preventDefault() on mousedown doesn't stop this event for some
|
|
||||||
reason so we have to explicitly block it */
|
|
||||||
this._target.addEventListener('contextmenu', this._eventHandlers.mousedisable);
|
|
||||||
}
|
|
||||||
|
|
||||||
ungrab() {
|
|
||||||
this._resetWheelStepTimers();
|
|
||||||
|
|
||||||
if (isTouchDevice) {
|
|
||||||
this._target.removeEventListener('touchstart', this._eventHandlers.mousedown);
|
|
||||||
this._target.removeEventListener('touchend', this._eventHandlers.mouseup);
|
|
||||||
this._target.removeEventListener('touchmove', this._eventHandlers.mousemove);
|
|
||||||
}
|
|
||||||
this._target.removeEventListener('mousedown', this._eventHandlers.mousedown);
|
|
||||||
this._target.removeEventListener('mouseup', this._eventHandlers.mouseup);
|
|
||||||
this._target.removeEventListener('mousemove', this._eventHandlers.mousemove);
|
|
||||||
this._target.removeEventListener('wheel', this._eventHandlers.mousewheel);
|
|
||||||
|
|
||||||
document.removeEventListener('click', this._eventHandlers.mousedisable);
|
|
||||||
|
|
||||||
this._target.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
57
systemvm/agent/noVNC/core/input/uskeysym.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
export default {
|
||||||
|
'1': 0x0031, /* U+0031 DIGIT ONE */
|
||||||
|
'2': 0x0032, /* U+0032 DIGIT TWO */
|
||||||
|
'3': 0x0033, /* U+0033 DIGIT THREE */
|
||||||
|
'4': 0x0034, /* U+0034 DIGIT FOUR */
|
||||||
|
'5': 0x0035, /* U+0035 DIGIT FIVE */
|
||||||
|
'6': 0x0036, /* U+0036 DIGIT SIX */
|
||||||
|
'7': 0x0037, /* U+0037 DIGIT SEVEN */
|
||||||
|
'8': 0x0038, /* U+0038 DIGIT EIGHT */
|
||||||
|
'9': 0x0039, /* U+0039 DIGIT NINE */
|
||||||
|
'0': 0x0030, /* U+0030 DIGIT ZERO */
|
||||||
|
|
||||||
|
'a': 0x0061, /* U+0061 LATIN SMALL LETTER A */
|
||||||
|
'b': 0x0062, /* U+0062 LATIN SMALL LETTER B */
|
||||||
|
'c': 0x0063, /* U+0063 LATIN SMALL LETTER C */
|
||||||
|
'd': 0x0064, /* U+0064 LATIN SMALL LETTER D */
|
||||||
|
'e': 0x0065, /* U+0065 LATIN SMALL LETTER E */
|
||||||
|
'f': 0x0066, /* U+0066 LATIN SMALL LETTER F */
|
||||||
|
'g': 0x0067, /* U+0067 LATIN SMALL LETTER G */
|
||||||
|
'h': 0x0068, /* U+0068 LATIN SMALL LETTER H */
|
||||||
|
'i': 0x0069, /* U+0069 LATIN SMALL LETTER I */
|
||||||
|
'j': 0x006a, /* U+006A LATIN SMALL LETTER J */
|
||||||
|
'k': 0x006b, /* U+006B LATIN SMALL LETTER K */
|
||||||
|
'l': 0x006c, /* U+006C LATIN SMALL LETTER L */
|
||||||
|
'm': 0x006d, /* U+006D LATIN SMALL LETTER M */
|
||||||
|
'n': 0x006e, /* U+006E LATIN SMALL LETTER N */
|
||||||
|
'o': 0x006f, /* U+006F LATIN SMALL LETTER O */
|
||||||
|
'p': 0x0070, /* U+0070 LATIN SMALL LETTER P */
|
||||||
|
'q': 0x0071, /* U+0071 LATIN SMALL LETTER Q */
|
||||||
|
'r': 0x0072, /* U+0072 LATIN SMALL LETTER R */
|
||||||
|
's': 0x0073, /* U+0073 LATIN SMALL LETTER S */
|
||||||
|
't': 0x0074, /* U+0074 LATIN SMALL LETTER T */
|
||||||
|
'u': 0x0075, /* U+0075 LATIN SMALL LETTER U */
|
||||||
|
'v': 0x0076, /* U+0076 LATIN SMALL LETTER V */
|
||||||
|
'w': 0x0077, /* U+0077 LATIN SMALL LETTER W */
|
||||||
|
'x': 0x0078, /* U+0078 LATIN SMALL LETTER X */
|
||||||
|
'y': 0x0079, /* U+0079 LATIN SMALL LETTER Y */
|
||||||
|
'z': 0x007a, /* U+007A LATIN SMALL LETTER Z */
|
||||||
|
|
||||||
|
'`': 0x0060, /* U+0060 GRAVE ACCENT */
|
||||||
|
'-': 0x002d, /* U+002D HYPHEN-MINUS */
|
||||||
|
'=': 0x003d, /* U+003D EQUALS SIGN */
|
||||||
|
|
||||||
|
'[': 0x005b, /* U+005B LEFT SQUARE BRACKET */
|
||||||
|
']': 0x005d, /* U+005D RIGHT SQUARE BRACKET */
|
||||||
|
'\\': 0x005c, /* U+005C REVERSE SOLIDUS */
|
||||||
|
|
||||||
|
';': 0x003b, /* U+003B SEMICOLON */
|
||||||
|
'\'': 0x0027, /* U+0027 APOSTROPHE */
|
||||||
|
|
||||||
|
',': 0x002c, /* U+002C COMMA */
|
||||||
|
'.': 0x002e, /* U+002E FULL STOP */
|
||||||
|
'/': 0x002f, /* U+002F SOLIDUS */
|
||||||
|
|
||||||
|
' ': 0x0020, /* U+0020 SPACE */
|
||||||
|
'\n': 0xff0d
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import KeyTable from "./keysym.js";
|
||||||
import keysyms from "./keysymdef.js";
|
import keysyms from "./keysymdef.js";
|
||||||
import vkeys from "./vkeys.js";
|
import vkeys from "./vkeys.js";
|
||||||
import fixedkeys from "./fixedkeys.js";
|
import fixedkeys from "./fixedkeys.js";
|
||||||
@ -91,6 +92,8 @@ export function getKey(evt) {
|
|||||||
// Mozilla isn't fully in sync with the spec yet
|
// Mozilla isn't fully in sync with the spec yet
|
||||||
switch (evt.key) {
|
switch (evt.key) {
|
||||||
case 'OS': return 'Meta';
|
case 'OS': return 'Meta';
|
||||||
|
case 'LaunchMyComputer': return 'LaunchApplication1';
|
||||||
|
case 'LaunchCalculator': return 'LaunchApplication2';
|
||||||
}
|
}
|
||||||
|
|
||||||
// iOS leaks some OS names
|
// iOS leaks some OS names
|
||||||
@ -102,9 +105,21 @@ export function getKey(evt) {
|
|||||||
case 'UIKeyInputEscape': return 'Escape';
|
case 'UIKeyInputEscape': return 'Escape';
|
||||||
}
|
}
|
||||||
|
|
||||||
// IE and Edge have broken handling of AltGraph so we cannot
|
// Broken behaviour in Chrome
|
||||||
// trust them for printable characters
|
if ((evt.key === '\x00') && (evt.code === 'NumpadDecimal')) {
|
||||||
if ((evt.key.length !== 1) || (!browser.isIE() && !browser.isEdge())) {
|
return 'Delete';
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE and Edge need special handling, but for everyone else we
|
||||||
|
// can trust the value provided
|
||||||
|
if (!browser.isIE() && !browser.isEdge()) {
|
||||||
|
return evt.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE and Edge have broken handling of AltGraph so we can only
|
||||||
|
// trust them for non-printable characters (and unfortunately
|
||||||
|
// they also specify 'Unidentified' for some problem keys)
|
||||||
|
if ((evt.key.length !== 1) && (evt.key !== 'Unidentified')) {
|
||||||
return evt.key;
|
return evt.key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,10 +156,39 @@ export function getKeysym(evt) {
|
|||||||
location = 2;
|
location = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// And for Clear
|
||||||
|
if ((key === 'Clear') && (location === 3)) {
|
||||||
|
let code = getKeycode(evt);
|
||||||
|
if (code === 'NumLock') {
|
||||||
|
location = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((location === undefined) || (location > 3)) {
|
if ((location === undefined) || (location > 3)) {
|
||||||
location = 0;
|
location = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The original Meta key now gets confused with the Windows key
|
||||||
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1020141
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1232918
|
||||||
|
if (key === 'Meta') {
|
||||||
|
let code = getKeycode(evt);
|
||||||
|
if (code === 'AltLeft') {
|
||||||
|
return KeyTable.XK_Meta_L;
|
||||||
|
} else if (code === 'AltRight') {
|
||||||
|
return KeyTable.XK_Meta_R;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// macOS has Clear instead of NumLock, but the remote system is
|
||||||
|
// probably not macOS, so lying here is probably best...
|
||||||
|
if (key === 'Clear') {
|
||||||
|
let code = getKeycode(evt);
|
||||||
|
if (code === 'NumLock') {
|
||||||
|
return KeyTable.XK_Num_Lock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return DOMKeyTable[key][location];
|
return DOMKeyTable[key][location];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
|
*
|
||||||
|
* Browser feature support detection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as Log from './logging.js';
|
import * as Log from './logging.js';
|
||||||
@ -31,7 +33,7 @@ try {
|
|||||||
const target = document.createElement('canvas');
|
const target = document.createElement('canvas');
|
||||||
target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
|
target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default';
|
||||||
|
|
||||||
if (target.style.cursor) {
|
if (target.style.cursor.indexOf("url") === 0) {
|
||||||
Log.Info("Data URI scheme cursor supported");
|
Log.Info("Data URI scheme cursor supported");
|
||||||
_supportsCursorURIs = true;
|
_supportsCursorURIs = true;
|
||||||
} else {
|
} else {
|
||||||
@ -52,6 +54,38 @@ try {
|
|||||||
}
|
}
|
||||||
export const supportsImageMetadata = _supportsImageMetadata;
|
export const supportsImageMetadata = _supportsImageMetadata;
|
||||||
|
|
||||||
|
let _hasScrollbarGutter = true;
|
||||||
|
try {
|
||||||
|
// Create invisible container
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.style.visibility = 'hidden';
|
||||||
|
container.style.overflow = 'scroll'; // forcing scrollbars
|
||||||
|
document.body.appendChild(container);
|
||||||
|
|
||||||
|
// Create a div and place it in the container
|
||||||
|
const child = document.createElement('div');
|
||||||
|
container.appendChild(child);
|
||||||
|
|
||||||
|
// Calculate the difference between the container's full width
|
||||||
|
// and the child's width - the difference is the scrollbars
|
||||||
|
const scrollbarWidth = (container.offsetWidth - child.offsetWidth);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
container.parentNode.removeChild(container);
|
||||||
|
|
||||||
|
_hasScrollbarGutter = scrollbarWidth != 0;
|
||||||
|
} catch (exc) {
|
||||||
|
Log.Error("Scrollbar test exception: " + exc);
|
||||||
|
}
|
||||||
|
export const hasScrollbarGutter = _hasScrollbarGutter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The functions for detection of platforms and browsers below are exported
|
||||||
|
* but the use of these should be minimized as much as possible.
|
||||||
|
*
|
||||||
|
* It's better to use feature detection than platform detection.
|
||||||
|
*/
|
||||||
|
|
||||||
export function isMac() {
|
export function isMac() {
|
||||||
return navigator && !!(/mac/i).exec(navigator.platform);
|
return navigator && !!(/mac/i).exec(navigator.platform);
|
||||||
}
|
}
|
||||||
@ -67,10 +101,6 @@ export function isIOS() {
|
|||||||
!!(/ipod/i).exec(navigator.platform));
|
!!(/ipod/i).exec(navigator.platform));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isAndroid() {
|
|
||||||
return navigator && !!(/android/i).exec(navigator.userAgent);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isSafari() {
|
export function isSafari() {
|
||||||
return navigator && (navigator.userAgent.indexOf('Safari') !== -1 &&
|
return navigator && (navigator.userAgent.indexOf('Safari') !== -1 &&
|
||||||
navigator.userAgent.indexOf('Chrome') === -1);
|
navigator.userAgent.indexOf('Chrome') === -1);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -20,7 +20,6 @@ export default class Cursor {
|
|||||||
this._canvas.style.pointerEvents = 'none';
|
this._canvas.style.pointerEvents = 'none';
|
||||||
// Can't use "display" because of Firefox bug #1445997
|
// Can't use "display" because of Firefox bug #1445997
|
||||||
this._canvas.style.visibility = 'hidden';
|
this._canvas.style.visibility = 'hidden';
|
||||||
document.body.appendChild(this._canvas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._position = { x: 0, y: 0 };
|
this._position = { x: 0, y: 0 };
|
||||||
@ -31,9 +30,6 @@ export default class Cursor {
|
|||||||
'mouseleave': this._handleMouseLeave.bind(this),
|
'mouseleave': this._handleMouseLeave.bind(this),
|
||||||
'mousemove': this._handleMouseMove.bind(this),
|
'mousemove': this._handleMouseMove.bind(this),
|
||||||
'mouseup': this._handleMouseUp.bind(this),
|
'mouseup': this._handleMouseUp.bind(this),
|
||||||
'touchstart': this._handleTouchStart.bind(this),
|
|
||||||
'touchmove': this._handleTouchMove.bind(this),
|
|
||||||
'touchend': this._handleTouchEnd.bind(this),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +41,8 @@ export default class Cursor {
|
|||||||
this._target = target;
|
this._target = target;
|
||||||
|
|
||||||
if (useFallback) {
|
if (useFallback) {
|
||||||
|
document.body.appendChild(this._canvas);
|
||||||
|
|
||||||
// FIXME: These don't fire properly except for mouse
|
// FIXME: These don't fire properly except for mouse
|
||||||
/// movement in IE. We want to also capture element
|
/// movement in IE. We want to also capture element
|
||||||
// movement, size changes, visibility, etc.
|
// movement, size changes, visibility, etc.
|
||||||
@ -53,17 +51,16 @@ export default class Cursor {
|
|||||||
this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options);
|
this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options);
|
||||||
this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options);
|
this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options);
|
||||||
this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options);
|
this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options);
|
||||||
|
|
||||||
// There is no "touchleave" so we monitor touchstart globally
|
|
||||||
window.addEventListener('touchstart', this._eventHandlers.touchstart, options);
|
|
||||||
this._target.addEventListener('touchmove', this._eventHandlers.touchmove, options);
|
|
||||||
this._target.addEventListener('touchend', this._eventHandlers.touchend, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
detach() {
|
detach() {
|
||||||
|
if (!this._target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (useFallback) {
|
if (useFallback) {
|
||||||
const options = { capture: true, passive: true };
|
const options = { capture: true, passive: true };
|
||||||
this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options);
|
this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options);
|
||||||
@ -71,9 +68,7 @@ export default class Cursor {
|
|||||||
this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options);
|
this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options);
|
||||||
this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options);
|
this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options);
|
||||||
|
|
||||||
window.removeEventListener('touchstart', this._eventHandlers.touchstart, options);
|
document.body.removeChild(this._canvas);
|
||||||
this._target.removeEventListener('touchmove', this._eventHandlers.touchmove, options);
|
|
||||||
this._target.removeEventListener('touchend', this._eventHandlers.touchend, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._target = null;
|
this._target = null;
|
||||||
@ -124,6 +119,27 @@ export default class Cursor {
|
|||||||
this._hotSpot.y = 0;
|
this._hotSpot.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mouse events might be emulated, this allows
|
||||||
|
// moving the cursor in such cases
|
||||||
|
move(clientX, clientY) {
|
||||||
|
if (!useFallback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// clientX/clientY are relative the _visual viewport_,
|
||||||
|
// but our position is relative the _layout viewport_,
|
||||||
|
// so try to compensate when we can
|
||||||
|
if (window.visualViewport) {
|
||||||
|
this._position.x = clientX + window.visualViewport.offsetLeft;
|
||||||
|
this._position.y = clientY + window.visualViewport.offsetTop;
|
||||||
|
} else {
|
||||||
|
this._position.x = clientX;
|
||||||
|
this._position.y = clientY;
|
||||||
|
}
|
||||||
|
this._updatePosition();
|
||||||
|
let target = document.elementFromPoint(clientX, clientY);
|
||||||
|
this._updateVisibility(target);
|
||||||
|
}
|
||||||
|
|
||||||
_handleMouseOver(event) {
|
_handleMouseOver(event) {
|
||||||
// This event could be because we're entering the target, or
|
// This event could be because we're entering the target, or
|
||||||
// moving around amongst its sub elements. Let the move handler
|
// moving around amongst its sub elements. Let the move handler
|
||||||
@ -132,7 +148,8 @@ export default class Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_handleMouseLeave(event) {
|
_handleMouseLeave(event) {
|
||||||
this._hideCursor();
|
// Check if we should show the cursor on the element we are leaving to
|
||||||
|
this._updateVisibility(event.relatedTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleMouseMove(event) {
|
_handleMouseMove(event) {
|
||||||
@ -150,27 +167,29 @@ export default class Cursor {
|
|||||||
// now and adjust visibility based on that.
|
// now and adjust visibility based on that.
|
||||||
let target = document.elementFromPoint(event.clientX, event.clientY);
|
let target = document.elementFromPoint(event.clientX, event.clientY);
|
||||||
this._updateVisibility(target);
|
this._updateVisibility(target);
|
||||||
}
|
|
||||||
|
|
||||||
_handleTouchStart(event) {
|
// Captures end with a mouseup but we can't know the event order of
|
||||||
// Just as for mouseover, we let the move handler deal with it
|
// mouseup vs releaseCapture.
|
||||||
this._handleTouchMove(event);
|
//
|
||||||
}
|
// In the cases when releaseCapture comes first, the code above is
|
||||||
|
// enough.
|
||||||
_handleTouchMove(event) {
|
//
|
||||||
this._updateVisibility(event.target);
|
// In the cases when the mouseup comes first, we need wait for the
|
||||||
|
// browser to flush all events and then check again if the cursor
|
||||||
this._position.x = event.changedTouches[0].clientX - this._hotSpot.x;
|
// should be visible.
|
||||||
this._position.y = event.changedTouches[0].clientY - this._hotSpot.y;
|
if (this._captureIsActive()) {
|
||||||
|
window.setTimeout(() => {
|
||||||
this._updatePosition();
|
// We might have detached at this point
|
||||||
}
|
if (!this._target) {
|
||||||
|
return;
|
||||||
_handleTouchEnd(event) {
|
}
|
||||||
// Same principle as for mouseup
|
// Refresh the target from elementFromPoint since queued events
|
||||||
let target = document.elementFromPoint(event.changedTouches[0].clientX,
|
// might have altered the DOM
|
||||||
event.changedTouches[0].clientY);
|
target = document.elementFromPoint(event.clientX,
|
||||||
this._updateVisibility(target);
|
event.clientY);
|
||||||
|
this._updateVisibility(target);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_showCursor() {
|
_showCursor() {
|
||||||
@ -189,6 +208,9 @@ export default class Cursor {
|
|||||||
// (i.e. are we over the target, or a child of the target without a
|
// (i.e. are we over the target, or a child of the target without a
|
||||||
// different cursor set)
|
// different cursor set)
|
||||||
_shouldShowCursor(target) {
|
_shouldShowCursor(target) {
|
||||||
|
if (!target) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Easy case
|
// Easy case
|
||||||
if (target === this._target) {
|
if (target === this._target) {
|
||||||
return true;
|
return true;
|
||||||
@ -207,6 +229,11 @@ export default class Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_updateVisibility(target) {
|
_updateVisibility(target) {
|
||||||
|
// When the cursor target has capture we want to show the cursor.
|
||||||
|
// So, if a capture is active - look at the captured element instead.
|
||||||
|
if (this._captureIsActive()) {
|
||||||
|
target = document.captureElement;
|
||||||
|
}
|
||||||
if (this._shouldShowCursor(target)) {
|
if (this._shouldShowCursor(target)) {
|
||||||
this._showCursor();
|
this._showCursor();
|
||||||
} else {
|
} else {
|
||||||
@ -218,4 +245,9 @@ export default class Cursor {
|
|||||||
this._canvas.style.left = this._position.x + "px";
|
this._canvas.style.left = this._position.x + "px";
|
||||||
this._canvas.style.top = this._position.y + "px";
|
this._canvas.style.top = this._position.y + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_captureIsActive() {
|
||||||
|
return document.captureElement &&
|
||||||
|
document.documentElement.contains(document.captureElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
systemvm/agent/noVNC/core/util/element.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2020 The noVNC Authors
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HTML element utility functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function clientToElement(x, y, elem) {
|
||||||
|
const bounds = elem.getBoundingClientRect();
|
||||||
|
let pos = { x: 0, y: 0 };
|
||||||
|
// Clip to target bounds
|
||||||
|
if (x < bounds.left) {
|
||||||
|
pos.x = 0;
|
||||||
|
} else if (x >= bounds.right) {
|
||||||
|
pos.x = bounds.width - 1;
|
||||||
|
} else {
|
||||||
|
pos.x = x - bounds.left;
|
||||||
|
}
|
||||||
|
if (y < bounds.top) {
|
||||||
|
pos.y = 0;
|
||||||
|
} else if (y >= bounds.bottom) {
|
||||||
|
pos.y = bounds.height - 1;
|
||||||
|
} else {
|
||||||
|
pos.y = y - bounds.top;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
@ -21,7 +21,8 @@ export function stopEvent(e) {
|
|||||||
|
|
||||||
// Emulate Element.setCapture() when not supported
|
// Emulate Element.setCapture() when not supported
|
||||||
let _captureRecursion = false;
|
let _captureRecursion = false;
|
||||||
let _captureElem = null;
|
let _elementForUnflushedEvents = null;
|
||||||
|
document.captureElement = null;
|
||||||
function _captureProxy(e) {
|
function _captureProxy(e) {
|
||||||
// Recursion protection as we'll see our own event
|
// Recursion protection as we'll see our own event
|
||||||
if (_captureRecursion) return;
|
if (_captureRecursion) return;
|
||||||
@ -30,7 +31,11 @@ function _captureProxy(e) {
|
|||||||
const newEv = new e.constructor(e.type, e);
|
const newEv = new e.constructor(e.type, e);
|
||||||
|
|
||||||
_captureRecursion = true;
|
_captureRecursion = true;
|
||||||
_captureElem.dispatchEvent(newEv);
|
if (document.captureElement) {
|
||||||
|
document.captureElement.dispatchEvent(newEv);
|
||||||
|
} else {
|
||||||
|
_elementForUnflushedEvents.dispatchEvent(newEv);
|
||||||
|
}
|
||||||
_captureRecursion = false;
|
_captureRecursion = false;
|
||||||
|
|
||||||
// Avoid double events
|
// Avoid double events
|
||||||
@ -48,58 +53,56 @@ function _captureProxy(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Follow cursor style of target element
|
// Follow cursor style of target element
|
||||||
function _captureElemChanged() {
|
function _capturedElemChanged() {
|
||||||
const captureElem = document.getElementById("noVNC_mouse_capture_elem");
|
const proxyElem = document.getElementById("noVNC_mouse_capture_elem");
|
||||||
captureElem.style.cursor = window.getComputedStyle(_captureElem).cursor;
|
proxyElem.style.cursor = window.getComputedStyle(document.captureElement).cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _captureObserver = new MutationObserver(_captureElemChanged);
|
const _captureObserver = new MutationObserver(_capturedElemChanged);
|
||||||
|
|
||||||
let _captureIndex = 0;
|
export function setCapture(target) {
|
||||||
|
if (target.setCapture) {
|
||||||
|
|
||||||
export function setCapture(elem) {
|
target.setCapture();
|
||||||
if (elem.setCapture) {
|
document.captureElement = target;
|
||||||
|
|
||||||
elem.setCapture();
|
|
||||||
|
|
||||||
// IE releases capture on 'click' events which might not trigger
|
// IE releases capture on 'click' events which might not trigger
|
||||||
elem.addEventListener('mouseup', releaseCapture);
|
target.addEventListener('mouseup', releaseCapture);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Release any existing capture in case this method is
|
// Release any existing capture in case this method is
|
||||||
// called multiple times without coordination
|
// called multiple times without coordination
|
||||||
releaseCapture();
|
releaseCapture();
|
||||||
|
|
||||||
let captureElem = document.getElementById("noVNC_mouse_capture_elem");
|
let proxyElem = document.getElementById("noVNC_mouse_capture_elem");
|
||||||
|
|
||||||
if (captureElem === null) {
|
if (proxyElem === null) {
|
||||||
captureElem = document.createElement("div");
|
proxyElem = document.createElement("div");
|
||||||
captureElem.id = "noVNC_mouse_capture_elem";
|
proxyElem.id = "noVNC_mouse_capture_elem";
|
||||||
captureElem.style.position = "fixed";
|
proxyElem.style.position = "fixed";
|
||||||
captureElem.style.top = "0px";
|
proxyElem.style.top = "0px";
|
||||||
captureElem.style.left = "0px";
|
proxyElem.style.left = "0px";
|
||||||
captureElem.style.width = "100%";
|
proxyElem.style.width = "100%";
|
||||||
captureElem.style.height = "100%";
|
proxyElem.style.height = "100%";
|
||||||
captureElem.style.zIndex = 10000;
|
proxyElem.style.zIndex = 10000;
|
||||||
captureElem.style.display = "none";
|
proxyElem.style.display = "none";
|
||||||
document.body.appendChild(captureElem);
|
document.body.appendChild(proxyElem);
|
||||||
|
|
||||||
// This is to make sure callers don't get confused by having
|
// This is to make sure callers don't get confused by having
|
||||||
// our blocking element as the target
|
// our blocking element as the target
|
||||||
captureElem.addEventListener('contextmenu', _captureProxy);
|
proxyElem.addEventListener('contextmenu', _captureProxy);
|
||||||
|
|
||||||
captureElem.addEventListener('mousemove', _captureProxy);
|
proxyElem.addEventListener('mousemove', _captureProxy);
|
||||||
captureElem.addEventListener('mouseup', _captureProxy);
|
proxyElem.addEventListener('mouseup', _captureProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
_captureElem = elem;
|
document.captureElement = target;
|
||||||
_captureIndex++;
|
|
||||||
|
|
||||||
// Track cursor and get initial cursor
|
// Track cursor and get initial cursor
|
||||||
_captureObserver.observe(elem, {attributes: true});
|
_captureObserver.observe(target, {attributes: true});
|
||||||
_captureElemChanged();
|
_capturedElemChanged();
|
||||||
|
|
||||||
captureElem.style.display = "";
|
proxyElem.style.display = "";
|
||||||
|
|
||||||
// We listen to events on window in order to keep tracking if it
|
// We listen to events on window in order to keep tracking if it
|
||||||
// happens to leave the viewport
|
// happens to leave the viewport
|
||||||
@ -112,26 +115,26 @@ export function releaseCapture() {
|
|||||||
if (document.releaseCapture) {
|
if (document.releaseCapture) {
|
||||||
|
|
||||||
document.releaseCapture();
|
document.releaseCapture();
|
||||||
|
document.captureElement = null;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!_captureElem) {
|
if (!document.captureElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There might be events already queued, so we need to wait for
|
// There might be events already queued. The event proxy needs
|
||||||
// them to flush. E.g. contextmenu in Microsoft Edge
|
// access to the captured element for these queued events.
|
||||||
window.setTimeout((expected) => {
|
// E.g. contextmenu (right-click) in Microsoft Edge
|
||||||
// Only clear it if it's the expected grab (i.e. no one
|
//
|
||||||
// else has initiated a new grab)
|
// Before removing the capturedElem pointer we save it to a
|
||||||
if (_captureIndex === expected) {
|
// temporary variable that the unflushed events can use.
|
||||||
_captureElem = null;
|
_elementForUnflushedEvents = document.captureElement;
|
||||||
}
|
document.captureElement = null;
|
||||||
}, 0, _captureIndex);
|
|
||||||
|
|
||||||
_captureObserver.disconnect();
|
_captureObserver.disconnect();
|
||||||
|
|
||||||
const captureElem = document.getElementById("noVNC_mouse_capture_elem");
|
const proxyElem = document.getElementById("noVNC_mouse_capture_elem");
|
||||||
captureElem.style.display = "none";
|
proxyElem.style.display = "none";
|
||||||
|
|
||||||
window.removeEventListener('mousemove', _captureProxy);
|
window.removeEventListener('mousemove', _captureProxy);
|
||||||
window.removeEventListener('mouseup', _captureProxy);
|
window.removeEventListener('mouseup', _captureProxy);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
|
|||||||
15
systemvm/agent/noVNC/core/util/int.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2020 The noVNC Authors
|
||||||
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
|
*
|
||||||
|
* See README.md for usage and integration instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function toUnsigned32bit(toConvert) {
|
||||||
|
return toConvert >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toSigned32bit(toConvert) {
|
||||||
|
return toConvert | 0;
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
@ -10,18 +10,18 @@
|
|||||||
* Logging/debug routines
|
* Logging/debug routines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let _log_level = 'warn';
|
let _logLevel = 'warn';
|
||||||
|
|
||||||
let Debug = () => {};
|
let Debug = () => {};
|
||||||
let Info = () => {};
|
let Info = () => {};
|
||||||
let Warn = () => {};
|
let Warn = () => {};
|
||||||
let Error = () => {};
|
let Error = () => {};
|
||||||
|
|
||||||
export function init_logging(level) {
|
export function initLogging(level) {
|
||||||
if (typeof level === 'undefined') {
|
if (typeof level === 'undefined') {
|
||||||
level = _log_level;
|
level = _logLevel;
|
||||||
} else {
|
} else {
|
||||||
_log_level = level;
|
_logLevel = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug = Info = Warn = Error = () => {};
|
Debug = Info = Warn = Error = () => {};
|
||||||
@ -46,11 +46,11 @@ export function init_logging(level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get_logging() {
|
export function getLogging() {
|
||||||
return _log_level;
|
return _logLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Debug, Info, Warn, Error };
|
export { Debug, Info, Warn, Error };
|
||||||
|
|
||||||
// Initialize logging level
|
// Initialize logging level
|
||||||
init_logging();
|
initLogging();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2020 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -52,3 +52,10 @@ if (typeof Object.assign != 'function') {
|
|||||||
window.CustomEvent = CustomEvent;
|
window.CustomEvent = CustomEvent;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* Number.isInteger() (taken from MDN) */
|
||||||
|
Number.isInteger = Number.isInteger || function isInteger(value) {
|
||||||
|
return typeof value === 'number' &&
|
||||||
|
isFinite(value) &&
|
||||||
|
Math.floor(value) === value;
|
||||||
|
};
|
||||||
|
|||||||
@ -1,14 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* noVNC: HTML5 VNC client
|
* noVNC: HTML5 VNC client
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* See README.md for usage and integration instructions.
|
* See README.md for usage and integration instructions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
// Decode from UTF-8
|
||||||
* Decode from UTF-8
|
export function decodeUTF8(utf8string, allowLatin1=false) {
|
||||||
*/
|
try {
|
||||||
export function decodeUTF8(utf8string) {
|
return decodeURIComponent(escape(utf8string));
|
||||||
return decodeURIComponent(escape(utf8string));
|
} catch (e) {
|
||||||
|
if (e instanceof URIError) {
|
||||||
|
if (allowLatin1) {
|
||||||
|
// If we allow Latin1 we can ignore any decoding fails
|
||||||
|
// and in these cases return the original string
|
||||||
|
return utf8string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode to UTF-8
|
||||||
|
export function encodeUTF8(DOMString) {
|
||||||
|
return unescape(encodeURIComponent(DOMString));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Websock: high-performance binary WebSockets
|
* Websock: high-performance binary WebSockets
|
||||||
* Copyright (C) 2018 The noVNC Authors
|
* Copyright (C) 2019 The noVNC Authors
|
||||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||||
*
|
*
|
||||||
* Websock is similar to the standard WebSocket object but with extra
|
* Websock is similar to the standard WebSocket object but with extra
|
||||||
@ -17,6 +17,8 @@ import * as Log from './util/logging.js';
|
|||||||
// this has performance issues in some versions Chromium, and
|
// this has performance issues in some versions Chromium, and
|
||||||
// doesn't gain a tremendous amount of performance increase in Firefox
|
// doesn't gain a tremendous amount of performance increase in Firefox
|
||||||
// at the moment. It may be valuable to turn it on in the future.
|
// at the moment. It may be valuable to turn it on in the future.
|
||||||
|
// Also copyWithin() for TypedArrays is not supported in IE 11 or
|
||||||
|
// Safari 13 (at the moment we want to support Safari 11).
|
||||||
const ENABLE_COPYWITHIN = false;
|
const ENABLE_COPYWITHIN = false;
|
||||||
const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
|
const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
|
||||||
|
|
||||||
@ -27,7 +29,6 @@ export default class Websock {
|
|||||||
this._rQi = 0; // Receive queue index
|
this._rQi = 0; // Receive queue index
|
||||||
this._rQlen = 0; // Next write position in the receive queue
|
this._rQlen = 0; // Next write position in the receive queue
|
||||||
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
|
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
|
||||||
this._rQmax = this._rQbufferSize / 8;
|
|
||||||
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
|
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
|
||||||
this._rQ = null; // Receive queue
|
this._rQ = null; // Receive queue
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ export default class Websock {
|
|||||||
|
|
||||||
flush() {
|
flush() {
|
||||||
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
|
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
|
||||||
this._websocket.send(this._encode_message());
|
this._websocket.send(this._encodeMessage());
|
||||||
this._sQlen = 0;
|
this._sQlen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +155,7 @@ export default class Websock {
|
|||||||
this.flush();
|
this.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
send_string(str) {
|
sendString(str) {
|
||||||
this.send(str.split('').map(chr => chr.charCodeAt(0)));
|
this.send(str.split('').map(chr => chr.charCodeAt(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,13 +168,13 @@ export default class Websock {
|
|||||||
this._eventHandlers[evt] = handler;
|
this._eventHandlers[evt] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
_allocate_buffers() {
|
_allocateBuffers() {
|
||||||
this._rQ = new Uint8Array(this._rQbufferSize);
|
this._rQ = new Uint8Array(this._rQbufferSize);
|
||||||
this._sQ = new Uint8Array(this._sQbufferSize);
|
this._sQ = new Uint8Array(this._sQbufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._allocate_buffers();
|
this._allocateBuffers();
|
||||||
this._rQi = 0;
|
this._rQi = 0;
|
||||||
this._websocket = null;
|
this._websocket = null;
|
||||||
}
|
}
|
||||||
@ -184,7 +185,7 @@ export default class Websock {
|
|||||||
this._websocket = new WebSocket(uri, protocols);
|
this._websocket = new WebSocket(uri, protocols);
|
||||||
this._websocket.binaryType = 'arraybuffer';
|
this._websocket.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
this._websocket.onmessage = this._recv_message.bind(this);
|
this._websocket.onmessage = this._recvMessage.bind(this);
|
||||||
this._websocket.onopen = () => {
|
this._websocket.onopen = () => {
|
||||||
Log.Debug('>> WebSock.onopen');
|
Log.Debug('>> WebSock.onopen');
|
||||||
if (this._websocket.protocol) {
|
if (this._websocket.protocol) {
|
||||||
@ -219,42 +220,46 @@ export default class Websock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
_encode_message() {
|
_encodeMessage() {
|
||||||
// Put in a binary arraybuffer
|
// Put in a binary arraybuffer
|
||||||
// according to the spec, you can send ArrayBufferViews with the send method
|
// according to the spec, you can send ArrayBufferViews with the send method
|
||||||
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
|
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
_expand_compact_rQ(min_fit) {
|
// We want to move all the unread data to the start of the queue,
|
||||||
const resizeNeeded = min_fit || this.rQlen > this._rQbufferSize / 2;
|
// e.g. compacting.
|
||||||
|
// The function also expands the receive que if needed, and for
|
||||||
|
// performance reasons we combine these two actions to avoid
|
||||||
|
// unneccessary copying.
|
||||||
|
_expandCompactRQ(minFit) {
|
||||||
|
// if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place
|
||||||
|
// instead of resizing
|
||||||
|
const requiredBufferSize = (this._rQlen - this._rQi + minFit) * 8;
|
||||||
|
const resizeNeeded = this._rQbufferSize < requiredBufferSize;
|
||||||
|
|
||||||
if (resizeNeeded) {
|
if (resizeNeeded) {
|
||||||
if (!min_fit) {
|
// Make sure we always *at least* double the buffer size, and have at least space for 8x
|
||||||
// just double the size if we need to do compaction
|
// the current amount of data
|
||||||
this._rQbufferSize *= 2;
|
this._rQbufferSize = Math.max(this._rQbufferSize * 2, requiredBufferSize);
|
||||||
} else {
|
|
||||||
// otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
|
|
||||||
this._rQbufferSize = (this.rQlen + min_fit) * 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't want to grow unboundedly
|
// we don't want to grow unboundedly
|
||||||
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
|
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
|
||||||
this._rQbufferSize = MAX_RQ_GROW_SIZE;
|
this._rQbufferSize = MAX_RQ_GROW_SIZE;
|
||||||
if (this._rQbufferSize - this.rQlen < min_fit) {
|
if (this._rQbufferSize - this.rQlen < minFit) {
|
||||||
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resizeNeeded) {
|
if (resizeNeeded) {
|
||||||
const old_rQbuffer = this._rQ.buffer;
|
const oldRQbuffer = this._rQ.buffer;
|
||||||
this._rQmax = this._rQbufferSize / 8;
|
|
||||||
this._rQ = new Uint8Array(this._rQbufferSize);
|
this._rQ = new Uint8Array(this._rQbufferSize);
|
||||||
this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi));
|
this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi));
|
||||||
} else {
|
} else {
|
||||||
if (ENABLE_COPYWITHIN) {
|
if (ENABLE_COPYWITHIN) {
|
||||||
this._rQ.copyWithin(0, this._rQi);
|
this._rQ.copyWithin(0, this._rQi, this._rQlen);
|
||||||
} else {
|
} else {
|
||||||
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
|
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi, this._rQlen - this._rQi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,26 +267,25 @@ export default class Websock {
|
|||||||
this._rQi = 0;
|
this._rQi = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_decode_message(data) {
|
// push arraybuffer values onto the end of the receive que
|
||||||
// push arraybuffer values onto the end
|
_DecodeMessage(data) {
|
||||||
const u8 = new Uint8Array(data);
|
const u8 = new Uint8Array(data);
|
||||||
if (u8.length > this._rQbufferSize - this._rQlen) {
|
if (u8.length > this._rQbufferSize - this._rQlen) {
|
||||||
this._expand_compact_rQ(u8.length);
|
this._expandCompactRQ(u8.length);
|
||||||
}
|
}
|
||||||
this._rQ.set(u8, this._rQlen);
|
this._rQ.set(u8, this._rQlen);
|
||||||
this._rQlen += u8.length;
|
this._rQlen += u8.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
_recv_message(e) {
|
_recvMessage(e) {
|
||||||
this._decode_message(e.data);
|
this._DecodeMessage(e.data);
|
||||||
if (this.rQlen > 0) {
|
if (this.rQlen > 0) {
|
||||||
this._eventHandlers.message();
|
this._eventHandlers.message();
|
||||||
// Compact the receive queue
|
|
||||||
if (this._rQlen == this._rQi) {
|
if (this._rQlen == this._rQi) {
|
||||||
|
// All data has now been processed, this means we
|
||||||
|
// can reset the receive queue.
|
||||||
this._rQlen = 0;
|
this._rQlen = 0;
|
||||||
this._rQi = 0;
|
this._rQi = 0;
|
||||||
} else if (this._rQlen > this._rQmax) {
|
|
||||||
this._expand_compact_rQ();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.Debug("Ignoring empty message");
|
Log.Debug("Ignoring empty message");
|
||||||
|
|||||||
@ -1,122 +0,0 @@
|
|||||||
# 1. Internal Modules
|
|
||||||
|
|
||||||
The noVNC client is composed of several internal modules that handle
|
|
||||||
rendering, input, networking, etc. Each of the modules is designed to
|
|
||||||
be cross-browser and independent from each other.
|
|
||||||
|
|
||||||
Note however that the API of these modules is not guaranteed to be
|
|
||||||
stable, and this documentation is not maintained as well as the
|
|
||||||
official external API.
|
|
||||||
|
|
||||||
|
|
||||||
## 1.1 Module List
|
|
||||||
|
|
||||||
* __Mouse__ (core/input/mouse.js): Mouse input event handler with
|
|
||||||
limited touch support.
|
|
||||||
|
|
||||||
* __Keyboard__ (core/input/keyboard.js): Keyboard input event handler with
|
|
||||||
non-US keyboard support. Translates keyDown and keyUp events to X11
|
|
||||||
keysym values.
|
|
||||||
|
|
||||||
* __Display__ (core/display.js): Efficient 2D rendering abstraction
|
|
||||||
layered on the HTML5 canvas element.
|
|
||||||
|
|
||||||
* __Websock__ (core/websock.js): Websock client from websockify
|
|
||||||
with transparent binary data support.
|
|
||||||
[Websock API](https://github.com/novnc/websockify/wiki/websock.js) wiki page.
|
|
||||||
|
|
||||||
|
|
||||||
## 1.2 Callbacks
|
|
||||||
|
|
||||||
For the Mouse, Keyboard and Display objects the callback functions are
|
|
||||||
assigned to configuration attributes, just as for the RFB object. The
|
|
||||||
WebSock module has a method named 'on' that takes two parameters: the
|
|
||||||
callback event name, and the callback function.
|
|
||||||
|
|
||||||
## 2. Modules
|
|
||||||
|
|
||||||
## 2.1 Mouse Module
|
|
||||||
|
|
||||||
### 2.1.1 Configuration Attributes
|
|
||||||
|
|
||||||
| name | type | mode | default | description
|
|
||||||
| ----------- | ---- | ---- | -------- | ------------
|
|
||||||
| touchButton | int | RW | 1 | Button mask (1, 2, 4) for which click to send on touch devices. 0 means ignore clicks.
|
|
||||||
|
|
||||||
### 2.1.2 Methods
|
|
||||||
|
|
||||||
| name | parameters | description
|
|
||||||
| ------ | ---------- | ------------
|
|
||||||
| grab | () | Begin capturing mouse events
|
|
||||||
| ungrab | () | Stop capturing mouse events
|
|
||||||
|
|
||||||
### 2.1.2 Callbacks
|
|
||||||
|
|
||||||
| name | parameters | description
|
|
||||||
| ------------- | ------------------- | ------------
|
|
||||||
| onmousebutton | (x, y, down, bmask) | Handler for mouse button click/release
|
|
||||||
| onmousemove | (x, y) | Handler for mouse movement
|
|
||||||
|
|
||||||
|
|
||||||
## 2.2 Keyboard Module
|
|
||||||
|
|
||||||
### 2.2.1 Configuration Attributes
|
|
||||||
|
|
||||||
None
|
|
||||||
|
|
||||||
### 2.2.2 Methods
|
|
||||||
|
|
||||||
| name | parameters | description
|
|
||||||
| ------ | ---------- | ------------
|
|
||||||
| grab | () | Begin capturing keyboard events
|
|
||||||
| ungrab | () | Stop capturing keyboard events
|
|
||||||
|
|
||||||
### 2.2.3 Callbacks
|
|
||||||
|
|
||||||
| name | parameters | description
|
|
||||||
| ---------- | -------------------- | ------------
|
|
||||||
| onkeypress | (keysym, code, down) | Handler for key press/release
|
|
||||||
|
|
||||||
|
|
||||||
## 2.3 Display Module
|
|
||||||
|
|
||||||
### 2.3.1 Configuration Attributes
|
|
||||||
|
|
||||||
| name | type | mode | default | description
|
|
||||||
| ------------ | ----- | ---- | ------- | ------------
|
|
||||||
| logo | raw | RW | | Logo to display when cleared: {"width": width, "height": height, "type": mime-type, "data": data}
|
|
||||||
| scale | float | RW | 1.0 | Display area scale factor 0.0 - 1.0
|
|
||||||
| clipViewport | bool | RW | false | Use viewport clipping
|
|
||||||
| width | int | RO | | Display area width
|
|
||||||
| height | int | RO | | Display area height
|
|
||||||
|
|
||||||
### 2.3.2 Methods
|
|
||||||
|
|
||||||
| name | parameters | description
|
|
||||||
| ------------------ | ------------------------------------------------------- | ------------
|
|
||||||
| viewportChangePos | (deltaX, deltaY) | Move the viewport relative to the current location
|
|
||||||
| viewportChangeSize | (width, height) | Change size of the viewport
|
|
||||||
| absX | (x) | Return X relative to the remote display
|
|
||||||
| absY | (y) | Return Y relative to the remote display
|
|
||||||
| resize | (width, height) | Set width and height
|
|
||||||
| flip | (from_queue) | Update the visible canvas with the contents of the rendering canvas
|
|
||||||
| clear | () | Clear the display (show logo if set)
|
|
||||||
| pending | () | Check if there are waiting items in the render queue
|
|
||||||
| flush | () | Resume processing the render queue unless it's empty
|
|
||||||
| fillRect | (x, y, width, height, color, from_queue) | Draw a filled in rectangle
|
|
||||||
| copyImage | (old_x, old_y, new_x, new_y, width, height, from_queue) | Copy a rectangular area
|
|
||||||
| imageRect | (x, y, mime, arr) | Draw a rectangle with an image
|
|
||||||
| startTile | (x, y, width, height, color) | Begin updating a tile
|
|
||||||
| subTile | (tile, x, y, w, h, color) | Update a sub-rectangle within the given tile
|
|
||||||
| finishTile | () | Draw the current tile to the display
|
|
||||||
| blitImage | (x, y, width, height, arr, offset, from_queue) | Blit pixels (of R,G,B,A) to the display
|
|
||||||
| blitRgbImage | (x, y, width, height, arr, offset, from_queue) | Blit RGB encoded image to display
|
|
||||||
| blitRgbxImage | (x, y, width, height, arr, offset, from_queue) | Blit RGBX encoded image to display
|
|
||||||
| drawImage | (img, x, y) | Draw image and track damage
|
|
||||||
| autoscale | (containerWidth, containerHeight) | Scale the display
|
|
||||||
|
|
||||||
### 2.3.3 Callbacks
|
|
||||||
|
|
||||||
| name | parameters | description
|
|
||||||
| ------- | ---------- | ------------
|
|
||||||
| onflush | () | A display flush has been requested and we are now ready to resume FBU processing
|
|
||||||
@ -1,375 +0,0 @@
|
|||||||
# noVNC API
|
|
||||||
|
|
||||||
The interface of the noVNC client consists of a single RFB object that
|
|
||||||
is instantiated once per connection.
|
|
||||||
|
|
||||||
## RFB
|
|
||||||
|
|
||||||
The `RFB` object represents a single connection to a VNC server. It
|
|
||||||
communicates using a WebSocket that must provide a standard RFB
|
|
||||||
protocol stream.
|
|
||||||
|
|
||||||
### Constructor
|
|
||||||
|
|
||||||
[`RFB()`](#rfb-1)
|
|
||||||
- Creates and returns a new `RFB` object.
|
|
||||||
|
|
||||||
### Properties
|
|
||||||
|
|
||||||
`viewOnly`
|
|
||||||
- Is a `boolean` indicating if any events (e.g. key presses or mouse
|
|
||||||
movement) should be prevented from being sent to the server.
|
|
||||||
Disabled by default.
|
|
||||||
|
|
||||||
`focusOnClick`
|
|
||||||
- Is a `boolean` indicating if keyboard focus should automatically be
|
|
||||||
moved to the remote session when a `mousedown` or `touchstart`
|
|
||||||
event is received.
|
|
||||||
|
|
||||||
`touchButton`
|
|
||||||
- Is a `long` controlling the button mask that should be simulated
|
|
||||||
when a touch event is recieved. Uses the same values as
|
|
||||||
[`MouseEvent.button`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button).
|
|
||||||
Is set to `1` by default.
|
|
||||||
|
|
||||||
`clipViewport`
|
|
||||||
- Is a `boolean` indicating if the remote session should be clipped
|
|
||||||
to its container. When disabled scrollbars will be shown to handle
|
|
||||||
the resulting overflow. Disabled by default.
|
|
||||||
|
|
||||||
`dragViewport`
|
|
||||||
- Is a `boolean` indicating if mouse events should control the
|
|
||||||
relative position of a clipped remote session. Only relevant if
|
|
||||||
`clipViewport` is enabled. Disabled by default.
|
|
||||||
|
|
||||||
`scaleViewport`
|
|
||||||
- Is a `boolean` indicating if the remote session should be scaled
|
|
||||||
locally so it fits its container. When disabled it will be centered
|
|
||||||
if the remote session is smaller than its container, or handled
|
|
||||||
according to `clipViewport` if it is larger. Disabled by default.
|
|
||||||
|
|
||||||
`resizeSession`
|
|
||||||
- Is a `boolean` indicating if a request to resize the remote session
|
|
||||||
should be sent whenever the container changes dimensions. Disabled
|
|
||||||
by default.
|
|
||||||
|
|
||||||
`showDotCursor`
|
|
||||||
- Is a `boolean` indicating whether a dot cursor should be shown
|
|
||||||
instead of a zero-sized or fully-transparent cursor if the server
|
|
||||||
sets such invisible cursor. Disabled by default.
|
|
||||||
|
|
||||||
`background`
|
|
||||||
- Is a valid CSS [background](https://developer.mozilla.org/en-US/docs/Web/CSS/background)
|
|
||||||
style value indicating which background style should be applied
|
|
||||||
to the element containing the remote session screen. The default value is `rgb(40, 40, 40)`
|
|
||||||
(solid gray color).
|
|
||||||
|
|
||||||
`capabilities` *Read only*
|
|
||||||
- Is an `Object` indicating which optional extensions are available
|
|
||||||
on the server. Some methods may only be called if the corresponding
|
|
||||||
capability is set. The following capabilities are defined:
|
|
||||||
|
|
||||||
| name | type | description
|
|
||||||
| -------- | --------- | -----------
|
|
||||||
| `power` | `boolean` | Machine power control is available
|
|
||||||
|
|
||||||
### Events
|
|
||||||
|
|
||||||
[`connect`](#connect)
|
|
||||||
- The `connect` event is fired when the `RFB` object has completed
|
|
||||||
the connection and handshaking with the server.
|
|
||||||
|
|
||||||
[`disconnect`](#disconnected)
|
|
||||||
- The `disconnect` event is fired when the `RFB` object disconnects.
|
|
||||||
|
|
||||||
[`credentialsrequired`](#credentialsrequired)
|
|
||||||
- The `credentialsrequired` event is fired when more credentials must
|
|
||||||
be given to continue.
|
|
||||||
|
|
||||||
[`securityfailure`](#securityfailure)
|
|
||||||
- The `securityfailure` event is fired when the security negotiation
|
|
||||||
with the server fails.
|
|
||||||
|
|
||||||
[`clipboard`](#clipboard)
|
|
||||||
- The `clipboard` event is fired when clipboard data is received from
|
|
||||||
the server.
|
|
||||||
|
|
||||||
[`bell`](#bell)
|
|
||||||
- The `bell` event is fired when a audible bell request is received
|
|
||||||
from the server.
|
|
||||||
|
|
||||||
[`desktopname`](#desktopname)
|
|
||||||
- The `desktopname` event is fired when the remote desktop name
|
|
||||||
changes.
|
|
||||||
|
|
||||||
[`capabilities`](#capabilities)
|
|
||||||
- The `capabilities` event is fired when `RFB.capabilities` is
|
|
||||||
updated.
|
|
||||||
|
|
||||||
### Methods
|
|
||||||
|
|
||||||
[`RFB.disconnect()`](#rfbdisconnect)
|
|
||||||
- Disconnect from the server.
|
|
||||||
|
|
||||||
[`RFB.sendCredentials()`](#rfbsendcredentials)
|
|
||||||
- Send credentials to server. Should be called after the
|
|
||||||
[`credentialsrequired`](#credentialsrequired) event has fired.
|
|
||||||
|
|
||||||
[`RFB.sendKey()`](#rfbsendKey)
|
|
||||||
- Send a key event.
|
|
||||||
|
|
||||||
[`RFB.sendCtrlAltDel()`](#rfbsendctrlaltdel)
|
|
||||||
- Send Ctrl-Alt-Del key sequence.
|
|
||||||
|
|
||||||
[`RFB.focus()`](#rfbfocus)
|
|
||||||
- Move keyboard focus to the remote session.
|
|
||||||
|
|
||||||
[`RFB.blur()`](#rfbblur)
|
|
||||||
- Remove keyboard focus from the remote session.
|
|
||||||
|
|
||||||
[`RFB.machineShutdown()`](#rfbmachineshutdown)
|
|
||||||
- Request a shutdown of the remote machine.
|
|
||||||
|
|
||||||
[`RFB.machineReboot()`](#rfbmachinereboot)
|
|
||||||
- Request a reboot of the remote machine.
|
|
||||||
|
|
||||||
[`RFB.machineReset()`](#rfbmachinereset)
|
|
||||||
- Request a reset of the remote machine.
|
|
||||||
|
|
||||||
[`RFB.clipboardPasteFrom()`](#rfbclipboardPasteFrom)
|
|
||||||
- Send clipboard contents to server.
|
|
||||||
|
|
||||||
### Details
|
|
||||||
|
|
||||||
#### RFB()
|
|
||||||
|
|
||||||
The `RFB()` constructor returns a new `RFB` object and initiates a new
|
|
||||||
connection to a specified VNC server.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
let rfb = new RFB( target, url [, options] );
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
**`target`**
|
|
||||||
- A block [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)
|
|
||||||
that specifies where the `RFB` object should attach itself. The
|
|
||||||
existing contents of the `HTMLElement` will be untouched, but new
|
|
||||||
elements will be added during the lifetime of the `RFB` object.
|
|
||||||
|
|
||||||
**`url`**
|
|
||||||
- A `DOMString` specifying the VNC server to connect to. This must be
|
|
||||||
a valid WebSocket URL.
|
|
||||||
|
|
||||||
**`options`** *Optional*
|
|
||||||
- An `Object` specifying extra details about how the connection
|
|
||||||
should be made.
|
|
||||||
|
|
||||||
Possible options:
|
|
||||||
|
|
||||||
`shared`
|
|
||||||
- A `boolean` indicating if the remote server should be shared or
|
|
||||||
if any other connected clients should be disconnected. Enabled
|
|
||||||
by default.
|
|
||||||
|
|
||||||
`credentials`
|
|
||||||
- An `Object` specifying the credentials to provide to the server
|
|
||||||
when authenticating. The following credentials are possible:
|
|
||||||
|
|
||||||
| name | type | description
|
|
||||||
| ------------ | ----------- | -----------
|
|
||||||
| `"username"` | `DOMString` | The user that authenticates
|
|
||||||
| `"password"` | `DOMString` | Password for the user
|
|
||||||
| `"target"` | `DOMString` | Target machine or session
|
|
||||||
|
|
||||||
`repeaterID`
|
|
||||||
- A `DOMString` specifying the ID to provide to any VNC repeater
|
|
||||||
encountered.
|
|
||||||
|
|
||||||
#### connect
|
|
||||||
|
|
||||||
The `connect` event is fired after all the handshaking with the server
|
|
||||||
is completed and the connection is fully established. After this event
|
|
||||||
the `RFB` object is ready to recieve graphics updates and to send input.
|
|
||||||
|
|
||||||
#### disconnect
|
|
||||||
|
|
||||||
The `disconnect` event is fired when the connection has been
|
|
||||||
terminated. The `detail` property is an `Object` that contains the
|
|
||||||
property `clean`. `clean` is a `boolean` indicating if the termination
|
|
||||||
was clean or not. In the event of an unexpected termination or an error
|
|
||||||
`clean` will be set to false.
|
|
||||||
|
|
||||||
#### credentialsrequired
|
|
||||||
|
|
||||||
The `credentialsrequired` event is fired when the server requests more
|
|
||||||
credentials than were specified to [`RFB()`](#rfb-1). The `detail`
|
|
||||||
property is an `Object` containing the property `types` which is an
|
|
||||||
`Array` of `DOMString` listing the credentials that are required.
|
|
||||||
|
|
||||||
#### securityfailure
|
|
||||||
|
|
||||||
The `securityfailure` event is fired when the handshaking process with
|
|
||||||
the server fails during the security negotiation step. The `detail`
|
|
||||||
property is an `Object` containing the following properties:
|
|
||||||
|
|
||||||
| Property | Type | Description
|
|
||||||
| -------- | ----------- | -----------
|
|
||||||
| `status` | `long` | The failure status code
|
|
||||||
| `reason` | `DOMString` | The **optional** reason for the failure
|
|
||||||
|
|
||||||
The property `status` corresponds to the
|
|
||||||
[SecurityResult](https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#securityresult)
|
|
||||||
status code in cases of failure. A status of zero will not be sent in
|
|
||||||
this event since that indicates a successful security handshaking
|
|
||||||
process. The optional property `reason` is provided by the server and
|
|
||||||
thus the language of the string is not known. However most servers will
|
|
||||||
probably send English strings. The server can choose to not send a
|
|
||||||
reason and in these cases the `reason` property will be omitted.
|
|
||||||
|
|
||||||
#### clipboard
|
|
||||||
|
|
||||||
The `clipboard` event is fired when the server has sent clipboard data.
|
|
||||||
The `detail` property is an `Object` containing the property `text`
|
|
||||||
which is a `DOMString` with the clipboard data.
|
|
||||||
|
|
||||||
#### bell
|
|
||||||
|
|
||||||
The `bell` event is fired when the server has requested an audible
|
|
||||||
bell.
|
|
||||||
|
|
||||||
#### desktopname
|
|
||||||
|
|
||||||
The `desktopname` event is fired when the name of the remote desktop
|
|
||||||
changes. The `detail` property is an `Object` with the property `name`
|
|
||||||
which is a `DOMString` specifying the new name.
|
|
||||||
|
|
||||||
#### capabilities
|
|
||||||
|
|
||||||
The `capabilities` event is fired whenever an entry is added or removed
|
|
||||||
from `RFB.capabilities`. The `detail` property is an `Object` with the
|
|
||||||
property `capabilities` containing the new value of `RFB.capabilities`.
|
|
||||||
|
|
||||||
#### RFB.disconnect()
|
|
||||||
|
|
||||||
The `RFB.disconnect()` method is used to disconnect from the currently
|
|
||||||
connected server.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.disconnect( );
|
|
||||||
|
|
||||||
#### RFB.sendCredentials()
|
|
||||||
|
|
||||||
The `RFB.sendCredentials()` method is used to provide the missing
|
|
||||||
credentials after a `credentialsrequired` event has been fired.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.sendCredentials( credentials );
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
**`credentials`**
|
|
||||||
- An `Object` specifying the credentials to provide to the server
|
|
||||||
when authenticating. See [`RFB()`](#rfb-1) for details.
|
|
||||||
|
|
||||||
#### RFB.sendKey()
|
|
||||||
|
|
||||||
The `RFB.sendKey()` method is used to send a key event to the server.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.sendKey( keysym, code [, down] );
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
**`keysym`**
|
|
||||||
- A `long` specifying the RFB keysym to send. Can be `0` if a valid
|
|
||||||
**`code`** is specified.
|
|
||||||
|
|
||||||
**`code`**
|
|
||||||
- A `DOMString` specifying the physical key to send. Valid values are
|
|
||||||
those that can be specified to
|
|
||||||
[`KeyboardEvent.code`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code).
|
|
||||||
If the physical key cannot be determined then `null` shall be
|
|
||||||
specified.
|
|
||||||
|
|
||||||
**`down`** *Optional*
|
|
||||||
- A `boolean` specifying if a press or a release event should be
|
|
||||||
sent. If omitted then both a press and release event are sent.
|
|
||||||
|
|
||||||
#### RFB.sendCtrlAltDel()
|
|
||||||
|
|
||||||
The `RFB.sendCtrlAltDel()` method is used to send the key sequence
|
|
||||||
*left Control*, *left Alt*, *Delete*. This is a convenience wrapper
|
|
||||||
around [`RFB.sendKey()`](#rfbsendkey).
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.sendCtrlAltDel( );
|
|
||||||
|
|
||||||
#### RFB.focus()
|
|
||||||
|
|
||||||
The `RFB.focus()` method sets the keyboard focus on the remote session.
|
|
||||||
Keyboard events will be sent to the remote server after this point.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.focus( );
|
|
||||||
|
|
||||||
#### RFB.blur()
|
|
||||||
|
|
||||||
The `RFB.blur()` method remove keyboard focus on the remote session.
|
|
||||||
Keyboard events will no longer be sent to the remote server after this
|
|
||||||
point.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.blur( );
|
|
||||||
|
|
||||||
#### RFB.machineShutdown()
|
|
||||||
|
|
||||||
The `RFB.machineShutdown()` method is used to request to shut down the
|
|
||||||
remote machine. The capability `power` must be set for this method to
|
|
||||||
have any effect.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.machineShutdown( );
|
|
||||||
|
|
||||||
#### RFB.machineReboot()
|
|
||||||
|
|
||||||
The `RFB.machineReboot()` method is used to request a clean reboot of
|
|
||||||
the remote machine. The capability `power` must be set for this method
|
|
||||||
to have any effect.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.machineReboot( );
|
|
||||||
|
|
||||||
#### RFB.machineReset()
|
|
||||||
|
|
||||||
The `RFB.machineReset()` method is used to request a forced reset of
|
|
||||||
the remote machine. The capability `power` must be set for this method
|
|
||||||
to have any effect.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.machineReset( );
|
|
||||||
|
|
||||||
#### RFB.clipboardPasteFrom()
|
|
||||||
|
|
||||||
The `RFB.clipboardPasteFrom()` method is used to send clipboard data
|
|
||||||
to the remote server.
|
|
||||||
|
|
||||||
##### Syntax
|
|
||||||
|
|
||||||
RFB.clipboardPasteFrom( text );
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
**`text`**
|
|
||||||
- A `DOMString` specifying the clipboard data to send. Currently only
|
|
||||||
characters from ISO 8859-1 are supported.
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
# Embedding and Deploying noVNC Application
|
|
||||||
|
|
||||||
This document describes how to embed and deploy the noVNC application, which
|
|
||||||
includes settings and a full user interface. If you are looking for
|
|
||||||
documentation on how to use the core noVNC library in your own application,
|
|
||||||
then please see our [library documentation](LIBRARY.md).
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
The noVNC application consists of the following files and directories:
|
|
||||||
|
|
||||||
* `vnc.html` - The main page for the application and where users should go. It
|
|
||||||
is possible to rename this file.
|
|
||||||
|
|
||||||
* `app/` - Support files for the application. Contains code, images, styles and
|
|
||||||
translations.
|
|
||||||
|
|
||||||
* `core/` - The core noVNC library.
|
|
||||||
|
|
||||||
* `vendor/` - Third party support libraries used by the application and the
|
|
||||||
core library.
|
|
||||||
|
|
||||||
The most basic deployment consists of simply serving these files from a web
|
|
||||||
server and setting up a WebSocket proxy to the VNC server.
|
|
||||||
|
|
||||||
## Parameters
|
|
||||||
|
|
||||||
The noVNC application can be controlled by including certain settings in the
|
|
||||||
query string. Currently the following options are available:
|
|
||||||
|
|
||||||
* `autoconnect` - Automatically connect as soon as the page has finished
|
|
||||||
loading.
|
|
||||||
|
|
||||||
* `reconnect` - If noVNC should automatically reconnect if the connection is
|
|
||||||
dropped.
|
|
||||||
|
|
||||||
* `reconnect_delay` - How long to wait in milliseconds before attempting to
|
|
||||||
reconnect.
|
|
||||||
|
|
||||||
* `host` - The WebSocket host to connect to.
|
|
||||||
|
|
||||||
* `port` - The WebSocket port to connect to.
|
|
||||||
|
|
||||||
* `encrypt` - If TLS should be used for the WebSocket connection.
|
|
||||||
|
|
||||||
* `path` - The WebSocket path to use.
|
|
||||||
|
|
||||||
* `password` - The password sent to the server, if required.
|
|
||||||
|
|
||||||
* `repeaterID` - The repeater ID to use if a VNC repeater is detected.
|
|
||||||
|
|
||||||
* `shared` - If other VNC clients should be disconnected when noVNC connects.
|
|
||||||
|
|
||||||
* `bell` - If the keyboard bell should be enabled or not.
|
|
||||||
|
|
||||||
* `view_only` - If the remote session should be in non-interactive mode.
|
|
||||||
|
|
||||||
* `view_clip` - If the remote session should be clipped or use scrollbars if
|
|
||||||
it cannot fit in the browser.
|
|
||||||
|
|
||||||
* `resize` - How to resize the remote session if it is not the same size as
|
|
||||||
the browser window. Can be one of `off`, `scale` and `remote`.
|
|
||||||
|
|
||||||
* `show_dot` - If a dot cursor should be shown when the remote server provides
|
|
||||||
no local cursor, or provides a fully-transparent (invisible) cursor.
|
|
||||||
|
|
||||||
* `logging` - The console log level. Can be one of `error`, `warn`, `info` or
|
|
||||||
`debug`.
|
|
||||||
|
|
||||||
## Pre-conversion of Modules
|
|
||||||
|
|
||||||
noVNC is written using ECMAScript 6 modules. Many of the major browsers support
|
|
||||||
these modules natively, but not all. By default the noVNC application includes
|
|
||||||
a script that can convert these modules to an older format as they are being
|
|
||||||
loaded. However this process can be slow and severely increases the load time
|
|
||||||
for the application.
|
|
||||||
|
|
||||||
It is possible to perform this conversion ahead of time, avoiding the extra
|
|
||||||
load times. To do this please follow these steps:
|
|
||||||
|
|
||||||
1. Install Node.js
|
|
||||||
2. Run `npm install` in the noVNC directory
|
|
||||||
3. Run `./utils/use_require.js --with-app --as commonjs`
|
|
||||||
|
|
||||||
This will produce a `build/` directory that includes everything needed to run
|
|
||||||
the noVNC application.
|
|
||||||
|
|
||||||
## HTTP Serving Considerations
|
|
||||||
### Browser Cache Issue
|
|
||||||
|
|
||||||
If you serve noVNC files using a web server that provides an ETag header, and
|
|
||||||
include any options in the query string, a nasty browser cache issue can bite
|
|
||||||
you on upgrade, resulting in a red error box. The issue is caused by a mismatch
|
|
||||||
between the new vnc.html (which is reloaded because the user has used it with
|
|
||||||
new query string after the upgrade) and the old javascript files (that the
|
|
||||||
browser reuses from its cache). To avoid this issue, the browser must be told
|
|
||||||
to always revalidate cached files using conditional requests. The correct
|
|
||||||
semantics are achieved via the (confusingly named) `Cache-Control: no-cache`
|
|
||||||
header that needs to be provided in the web server responses.
|
|
||||||
|
|
||||||
### Example Server Configurations
|
|
||||||
|
|
||||||
Apache:
|
|
||||||
|
|
||||||
```
|
|
||||||
# In the main configuration file
|
|
||||||
# (Debian/Ubuntu users: use "a2enmod headers" instead)
|
|
||||||
LoadModule headers_module modules/mod_headers.so
|
|
||||||
|
|
||||||
# In the <Directory> or <Location> block related to noVNC
|
|
||||||
Header set Cache-Control "no-cache"
|
|
||||||
```
|
|
||||||
|
|
||||||
Nginx:
|
|
||||||
|
|
||||||
```
|
|
||||||
# In the location block related to noVNC
|
|
||||||
add_header Cache-Control no-cache;
|
|
||||||
```
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
# Using the noVNC JavaScript library
|
|
||||||
|
|
||||||
This document describes how to make use of the noVNC JavaScript library for
|
|
||||||
integration in your own VNC client application. If you wish to embed the more
|
|
||||||
complete noVNC application with its included user interface then please see
|
|
||||||
our [embedding documentation](EMBEDDING.md).
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
The API of noVNC consists of a single object called `RFB`. The formal
|
|
||||||
documentation for that object can be found in our [API documentation](API.md).
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
noVNC includes a small example application called `vnc_lite.html`. This does
|
|
||||||
not make use of all the features of noVNC, but is a good start to see how to
|
|
||||||
do things.
|
|
||||||
|
|
||||||
## Conversion of Modules
|
|
||||||
|
|
||||||
noVNC is written using ECMAScript 6 modules. Many of the major browsers support
|
|
||||||
these modules natively, but not all. They are also not supported by Node.js. To
|
|
||||||
use noVNC in these places the library must first be converted.
|
|
||||||
|
|
||||||
Fortunately noVNC includes a script to handle this conversion. Please follow
|
|
||||||
the following steps:
|
|
||||||
|
|
||||||
1. Install Node.js
|
|
||||||
2. Run `npm install` in the noVNC directory
|
|
||||||
3. Run `./utils/use_require.js --as <module format>`
|
|
||||||
|
|
||||||
Several module formats are available. Please run
|
|
||||||
`./utils/use_require.js --help` to see them all.
|
|
||||||
|
|
||||||
The result of the conversion is available in the `lib/` directory.
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) <year>, <copyright holder>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
Copyright (c) <year>, <copyright holder>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the <organization> nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||