Commit be098285 authored by Joel Martin's avatar Joel Martin

Merge branch 'master' of github.com:kanaka/noVNC

parents c3c51ed3 142aa458
...@@ -10,6 +10,7 @@ is not limited to): ...@@ -10,6 +10,7 @@ is not limited to):
include/display.js include/display.js
include/input.js include/input.js
include/jsunzip.js include/jsunzip.js
include/keysym.js
include/logo.js include/logo.js
include/rfb.js include/rfb.js
include/ui.js include/ui.js
......
images/alt.png

339 Bytes

images/esc.png

385 Bytes

images/tab.png

387 Bytes

/* /*
* noVNC base CSS * noVNC base CSS
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed for Cendio AB
* 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).
*/ */
...@@ -51,7 +52,6 @@ html { ...@@ -51,7 +52,6 @@ html {
float:right; float:right;
} }
#noVNC_view_drag_button { #noVNC_view_drag_button {
display: none; display: none;
} }
...@@ -62,34 +62,36 @@ html { ...@@ -62,34 +62,36 @@ html {
display: none; display: none;
} }
#noVNC_extra_keys {
display: inline;
list-style-type: none;
padding: 0px;
margin: 0px;
position: relative;
}
.noVNC-buttons-left { .noVNC-buttons-left {
float: left; float: left;
padding-left:10px; z-index: 1;
padding-top:4px; position: relative;
} }
.noVNC-buttons-right { .noVNC-buttons-right {
float:right; float:right;
right: 0px; right: 0px;
padding-right:10px; z-index: 2;
padding-top:4px; position: absolute;
}
#noVNC_status_bar {
margin-top: 0px;
padding: 0px;
} }
#noVNC_status_bar div { #noVNC_status {
font-size: 12px; font-size: 12px;
padding-top: 4px; padding-top: 4px;
width:100%; height:32px;
}
#noVNC_status {
height:20px;
text-align: center; text-align: center;
font-weight: bold;
color: #fff;
} }
#noVNC_settings_menu { #noVNC_settings_menu {
margin: 3px; margin: 3px;
text-align: left; text-align: left;
...@@ -104,22 +106,12 @@ html { ...@@ -104,22 +106,12 @@ html {
float:right; float:right;
} }
.noVNC_status_normal {
background: #eee;
}
.noVNC_status_error {
background: #f44;
}
.noVNC_status_warn {
background: #ff4;
}
/* Do not set width/height for VNC_screen or VNC_canvas or incorrect /* Do not set width/height for VNC_screen or VNC_canvas or incorrect
* scaling will occur. Canvas resizes to remote VNC settings */ * scaling will occur. Canvas resizes to remote VNC settings */
#noVNC_screen_pad { #noVNC_screen_pad {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
height: 44px; height: 36px;
} }
#noVNC_screen { #noVNC_screen {
text-align: center; text-align: center;
...@@ -154,14 +146,14 @@ html { ...@@ -154,14 +146,14 @@ html {
/*Bubble contents divs*/ /*Bubble contents divs*/
#noVNC_settings { #noVNC_settings {
display:none; display:none;
margin-top:77px; margin-top:73px;
right:20px; right:20px;
position:fixed; position:fixed;
} }
#noVNC_controls { #noVNC_controls {
display:none; display:none;
margin-top:77px; margin-top:73px;
right:12px; right:12px;
position:fixed; position:fixed;
} }
...@@ -173,7 +165,7 @@ html { ...@@ -173,7 +165,7 @@ html {
display:none; display:none;
position:fixed; position:fixed;
margin-top:77px; margin-top:73px;
right:20px; right:20px;
left:20px; left:20px;
padding:15px; padding:15px;
...@@ -186,9 +178,30 @@ html { ...@@ -186,9 +178,30 @@ html {
border-radius:10px; border-radius:10px;
} }
#noVNC_popup_status_panel {
display:none;
position: fixed;
z-index: 1;
margin:15px;
margin-top:60px;
padding:15px;
width:auto;
text-align:center;
font-weight:bold;
word-wrap:break-word;
color:#fff;
background:rgba(0,0,0,0.65);
-webkit-border-radius:10px;
-moz-border-radius:10px;
border-radius:10px;
}
#noVNC_clipboard { #noVNC_clipboard {
display:none; display:none;
margin-top:77px; margin-top:73px;
right:30px; right:30px;
position:fixed; position:fixed;
} }
...@@ -207,17 +220,11 @@ html { ...@@ -207,17 +220,11 @@ html {
z-index: -1; z-index: -1;
} }
.noVNC_status_warn {
background-color:yellow;
}
/* /*
* Advanced Styling * Advanced Styling
*/ */
/* Control bar */ .noVNC_status_normal {
#noVNC-control-bar {
position:fixed;
background: #b2bdcd; /* Old browsers */ background: #b2bdcd; /* Old browsers */
background: -moz-linear-gradient(top, #b2bdcd 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ background: -moz-linear-gradient(top, #b2bdcd 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2bdcd), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2bdcd), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */
...@@ -225,9 +232,32 @@ html { ...@@ -225,9 +232,32 @@ html {
background: -o-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ background: -o-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ background: -ms-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */
background: linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ background: linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */
}
.noVNC_status_error {
background: #f04040; /* Old browsers */
background: -moz-linear-gradient(top, #f04040 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f04040), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */
background: linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */
}
.noVNC_status_warn {
background: #f0f040; /* Old browsers */
background: -moz-linear-gradient(top, #f0f040 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f0f040), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */
background: linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */
}
/* Control bar */
#noVNC-control-bar {
position:fixed;
display:block; display:block;
height:44px; height:36px;
left:0; left:0;
top:0; top:0;
width:100%; width:100%;
...@@ -368,22 +398,85 @@ html { ...@@ -368,22 +398,85 @@ html {
font-size: 180px; font-size: 180px;
} }
@media screen and (min-width: 481px) and (max-width: 640px) { .noVNC-buttons-left {
.noVNC_status_button { padding-left: 10px;
font-size: 10px; }
.noVNC-buttons-right {
padding-right: 10px;
}
#noVNC_status {
z-index: 0;
position: absolute;
width: 100%;
margin-left: 0px;
}
#showExtraKeysButton { display: none; }
#toggleCtrlButton { display: inline; }
#toggleAltButton { display: inline; }
#sendTabButton { display: inline; }
#sendEscButton { display: inline; }
/* left-align the status text on lower resolutions */
@media screen and (max-width: 800px){
#noVNC_status {
z-index: 1;
position: relative;
width: auto;
float: left;
margin-left: 4px;
} }
}
@media screen and (max-width: 640px){
#noVNC_clipboard_text { #noVNC_clipboard_text {
width: 410px; width: 410px;
} }
#noVNC_logo { #noVNC_logo {
font-size: 150px; font-size: 150px;
} }
}
@media screen and (min-width: 321px) and (max-width: 480px) {
.noVNC_status_button { .noVNC_status_button {
font-size: 10px; font-size: 10px;
} }
.noVNC-buttons-left {
padding-left: 0px;
}
.noVNC-buttons-right {
padding-right: 0px;
}
/* collapse the extra keys on lower resolutions */
#showExtraKeysButton {
display: inline;
}
#toggleCtrlButton {
display: none;
position: absolute;
top: 30px;
left: 0px;
}
#toggleAltButton {
display: none;
position: absolute;
top: 65px;
left: 0px;
}
#sendTabButton {
display: none;
position: absolute;
top: 100px;
left: 0px;
}
#sendEscButton {
display: none;
position: absolute;
top: 135px;
left: 0px;
}
}
@media screen and (min-width: 321px) and (max-width: 480px) {
#noVNC_clipboard_text { #noVNC_clipboard_text {
width: 250px; width: 250px;
} }
......
/* /*
* noVNC black CSS * noVNC black CSS
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed for Cendio AB
* 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).
*/ */
...@@ -9,7 +10,7 @@ ...@@ -9,7 +10,7 @@
background-color:#000; background-color:#000;
} }
#noVNC-control-bar { .noVNC_status_normal {
background: #4c4c4c; /* Old browsers */ background: #4c4c4c; /* Old browsers */
background: -moz-linear-gradient(top, #4c4c4c 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ background: -moz-linear-gradient(top, #4c4c4c 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */
...@@ -18,6 +19,24 @@ ...@@ -18,6 +19,24 @@
background: -ms-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ background: -ms-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */
background: linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ background: linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */
} }
.noVNC_status_error {
background: #f04040; /* Old browsers */
background: -moz-linear-gradient(top, #f04040 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f04040), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */
background: linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */
}
.noVNC_status_warn {
background: #f0f040; /* Old browsers */
background: -moz-linear-gradient(top, #f0f040 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f0f040), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */
background: linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */
}
.triangle-right { .triangle-right {
border:2px solid #fff; border:2px solid #fff;
......
/* /*
* noVNC blue CSS * noVNC blue CSS
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed for Cendio AB
* 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).
*/ */
#noVNC-control-bar { .noVNC_status_normal {
background-color:#04073d; background-color:#04073d;
background-image: -webkit-gradient( background-image: -webkit-gradient(
linear, linear,
...@@ -20,6 +21,36 @@ ...@@ -20,6 +21,36 @@
rgb(4,7,61) 50% rgb(4,7,61) 50%
); );
} }
.noVNC_status_error {
background-color:#f04040;
background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.54, rgb(240,64,64)),
color-stop(0.5, rgb(4,7,61))
);
background-image: -moz-linear-gradient(
center bottom,
rgb(4,7,61) 54%,
rgb(249,64,64) 50%
);
}
.noVNC_status_warn {
background-color:#f0f040;
background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.54, rgb(240,240,64)),
color-stop(0.5, rgb(4,7,61))
);
background-image: -moz-linear-gradient(
center bottom,
rgb(4,7,61) 54%,
rgb(240,240,64) 50%
);
}
.triangle-right { .triangle-right {
border:2px solid #fff; border:2px solid #fff;
......
/* /*
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed for Cendio AB
* Licensed under MPL 2.0 or any later version (see LICENSE.txt) * Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/ */
...@@ -489,6 +490,9 @@ var that = {}, // Public API methods ...@@ -489,6 +490,9 @@ var that = {}, // Public API methods
conf = {}, // Configuration attributes conf = {}, // Configuration attributes
mouseCaptured = false; mouseCaptured = false;
var doubleClickTimer = null,
lastTouchPos = null;
// Configuration attributes // Configuration attributes
Util.conf_defaults(conf, that, defaults, [ Util.conf_defaults(conf, that, defaults, [
['target', 'ro', 'dom', document, 'DOM element that captures mouse input'], ['target', 'ro', 'dom', document, 'DOM element that captures mouse input'],
...@@ -521,6 +525,10 @@ function releaseMouse() { ...@@ -521,6 +525,10 @@ function releaseMouse() {
// Private functions // Private functions
// //
function resetDoubleClickTimer() {
doubleClickTimer = null;
}
function onMouseButton(e, down) { function onMouseButton(e, down) {
var evt, pos, bmask; var evt, pos, bmask;
if (! conf.focused) { if (! conf.focused) {
...@@ -528,8 +536,34 @@ function onMouseButton(e, down) { ...@@ -528,8 +536,34 @@ function onMouseButton(e, down) {
} }
evt = (e ? e : window.event); evt = (e ? e : window.event);
pos = Util.getEventPosition(e, conf.target, conf.scale); pos = Util.getEventPosition(e, conf.target, conf.scale);
if (e.touches || e.changedTouches) { if (e.touches || e.changedTouches) {
// Touch device // Touch device
// When two touches occur within 500 ms of each other and are
// closer than 20 pixels together a double click is triggered.
if (down == 1) {
if (doubleClickTimer == null) {
lastTouchPos = pos;
} else {
clearTimeout(doubleClickTimer);
// When the distance between the two touches is small enough
// force the position of the latter touch to the position of
// the first.
var xs = lastTouchPos.x - pos.x;
var ys = lastTouchPos.y - pos.y;
var 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.
if (d < 20 * window.devicePixelRatio) {
pos = lastTouchPos;
}
}
doubleClickTimer = setTimeout(resetDoubleClickTimer, 500);
}
bmask = conf.touchButton; bmask = conf.touchButton;
// If bmask is set // If bmask is set
} else if (evt.which) { } else if (evt.which) {
...@@ -543,7 +577,7 @@ function onMouseButton(e, down) { ...@@ -543,7 +577,7 @@ function onMouseButton(e, down) {
} }
//Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down + //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down +
// " bmask: " + bmask + "(evt.button: " + evt.button + ")"); // " bmask: " + bmask + "(evt.button: " + evt.button + ")");
if (bmask > 0 && conf.onMouseButton) { if (conf.onMouseButton) {
Util.Debug("onMouseButton " + (down ? "down" : "up") + Util.Debug("onMouseButton " + (down ? "down" : "up") +
", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask);
conf.onMouseButton(pos.x, pos.y, down, bmask); conf.onMouseButton(pos.x, pos.y, down, bmask);
...@@ -611,9 +645,9 @@ function onMouseDisable(e) { ...@@ -611,9 +645,9 @@ function onMouseDisable(e) {
evt = (e ? e : window.event); evt = (e ? e : window.event);
pos = Util.getEventPosition(e, conf.target, conf.scale); pos = Util.getEventPosition(e, conf.target, conf.scale);
/* Stop propagation if inside canvas area */ /* Stop propagation if inside canvas area */
if ((pos.x >= 0) && (pos.y >= 0) && if ((pos.realx >= 0) && (pos.realy >= 0) &&
(pos.x < conf.target.offsetWidth) && (pos.realx < conf.target.offsetWidth) &&
(pos.y < conf.target.offsetHeight)) { (pos.realy < conf.target.offsetHeight)) {
//Util.Debug("mouse event disabled"); //Util.Debug("mouse event disabled");
Util.stopEvent(e); Util.stopEvent(e);
return false; return false;
......
var XK_VoidSymbol = 0xffffff, /* Void symbol */
XK_BackSpace = 0xff08, /* Back space, back char */
XK_Tab = 0xff09,
XK_Linefeed = 0xff0a, /* Linefeed, LF */
XK_Clear = 0xff0b,
XK_Return = 0xff0d, /* Return, enter */
XK_Pause = 0xff13, /* Pause, hold */
XK_Scroll_Lock = 0xff14,
XK_Sys_Req = 0xff15,
XK_Escape = 0xff1b,
XK_Delete = 0xffff, /* Delete, rubout */
/* Cursor control & motion */
XK_Home = 0xff50,
XK_Left = 0xff51, /* Move left, left arrow */
XK_Up = 0xff52, /* Move up, up arrow */
XK_Right = 0xff53, /* Move right, right arrow */
XK_Down = 0xff54, /* Move down, down arrow */
XK_Prior = 0xff55, /* Prior, previous */
XK_Page_Up = 0xff55,
XK_Next = 0xff56, /* Next */
XK_Page_Down = 0xff56,
XK_End = 0xff57, /* EOL */
XK_Begin = 0xff58, /* BOL */
/* Misc functions */
XK_Select = 0xff60, /* Select, mark */
XK_Print = 0xff61,
XK_Execute = 0xff62, /* Execute, run, do */
XK_Insert = 0xff63, /* Insert, insert here */
XK_Undo = 0xff65,
XK_Redo = 0xff66, /* Redo, again */
XK_Menu = 0xff67,
XK_Find = 0xff68, /* Find, search */
XK_Cancel = 0xff69, /* Cancel, stop, abort, exit */
XK_Help = 0xff6a, /* Help */
XK_Break = 0xff6b,
XK_Mode_switch = 0xff7e, /* Character set switch */
XK_script_switch = 0xff7e, /* Alias for mode_switch */
XK_Num_Lock = 0xff7f,
/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
XK_KP_Space = 0xff80, /* Space */
XK_KP_Tab = 0xff89,
XK_KP_Enter = 0xff8d, /* Enter */
XK_KP_F1 = 0xff91, /* PF1, KP_A, ... */
XK_KP_F2 = 0xff92,
XK_KP_F3 = 0xff93,
XK_KP_F4 = 0xff94,
XK_KP_Home = 0xff95,
XK_KP_Left = 0xff96,
XK_KP_Up = 0xff97,
XK_KP_Right = 0xff98,
XK_KP_Down = 0xff99,
XK_KP_Prior = 0xff9a,
XK_KP_Page_Up = 0xff9a
XK_KP_Next = 0xff9b,
XK_KP_Page_Down = 0xff9b,
XK_KP_End = 0xff9c,
XK_KP_Begin = 0xff9d,
XK_KP_Insert = 0xff9e,
XK_KP_Delete = 0xff9f,
XK_KP_Equal = 0xffbd, /* Equals */
XK_KP_Multiply = 0xffaa,
XK_KP_Add = 0xffab,
XK_KP_Separator = 0xffac, /* Separator, often comma */
XK_KP_Subtract = 0xffad,
XK_KP_Decimal = 0xffae,
XK_KP_Divide = 0xffaf,
XK_KP_0 = 0xffb0,
XK_KP_1 = 0xffb1,
XK_KP_2 = 0xffb2,
XK_KP_3 = 0xffb3,
XK_KP_4 = 0xffb4,
XK_KP_5 = 0xffb5,
XK_KP_6 = 0xffb6,
XK_KP_7 = 0xffb7,
XK_KP_8 = 0xffb8,
XK_KP_9 = 0xffb9,
/*
* Auxiliary functions; note the duplicate definitions for left and right
* function keys; Sun keyboards and a few other manufacturers have such
* function key groups on the left and/or right sides of the keyboard.
* We've not found a keyboard with more than 35 function keys total.
*/
XK_F1 = 0xffbe,
XK_F2 = 0xffbf,
XK_F3 = 0xffc0,
XK_F4 = 0xffc1,
XK_F5 = 0xffc2,
XK_F6 = 0xffc3,
XK_F7 = 0xffc4,
XK_F8 = 0xffc5,
XK_F9 = 0xffc6,
XK_F10 = 0xffc7,
XK_F11 = 0xffc8,
XK_L1 = 0xffc8,
XK_F12 = 0xffc9,
XK_L2 = 0xffc9,
XK_F13 = 0xffca,
XK_L3 = 0xffca,
XK_F14 = 0xffcb,
XK_L4 = 0xffcb,
XK_F15 = 0xffcc,
XK_L5 = 0xffcc,
XK_F16 = 0xffcd,
XK_L6 = 0xffcd,
XK_F17 = 0xffce,
XK_L7 = 0xffce,
XK_F18 = 0xffcf,
XK_L8 = 0xffcf,
XK_F19 = 0xffd0,
XK_L9 = 0xffd0,
XK_F20 = 0xffd1,
XK_L10 = 0xffd1,
XK_F21 = 0xffd2,
XK_R1 = 0xffd2,
XK_F22 = 0xffd3,
XK_R2 = 0xffd3,
XK_F23 = 0xffd4,
XK_R3 = 0xffd4,
XK_F24 = 0xffd5,
XK_R4 = 0xffd5,
XK_F25 = 0xffd6,
XK_R5 = 0xffd6,
XK_F26 = 0xffd7,
XK_R6 = 0xffd7,
XK_F27 = 0xffd8,
XK_R7 = 0xffd8,
XK_F28 = 0xffd9,
XK_R8 = 0xffd9,
XK_F29 = 0xffda,
XK_R9 = 0xffda,
XK_F30 = 0xffdb,
XK_R10 = 0xffdb,
XK_F31 = 0xffdc,
XK_R11 = 0xffdc,
XK_F32 = 0xffdd,
XK_R12 = 0xffdd,
XK_F33 = 0xffde,
XK_R13 = 0xffde,
XK_F34 = 0xffdf,
XK_R14 = 0xffdf,
XK_F35 = 0xffe0,
XK_R15 = 0xffe0,
/* Modifiers */
XK_Shift_L = 0xffe1, /* Left shift */
XK_Shift_R = 0xffe2, /* Right shift */
XK_Control_L = 0xffe3, /* Left control */
XK_Control_R = 0xffe4, /* Right control */
XK_Caps_Lock = 0xffe5, /* Caps lock */
XK_Shift_Lock = 0xffe6, /* Shift lock */
XK_Meta_L = 0xffe7, /* Left meta */
XK_Meta_R = 0xffe8, /* Right meta */
XK_Alt_L = 0xffe9, /* Left alt */
XK_Alt_R = 0xffea, /* Right alt */
XK_Super_L = 0xffeb, /* Left super */
XK_Super_R = 0xffec, /* Right super */
XK_Hyper_L = 0xffed, /* Left hyper */
XK_Hyper_R = 0xffee, /* Right hyper */
/*
* Latin 1
* (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
* Byte 3 = 0
*/
XK_space = 0x0020, /* U+0020 SPACE */
XK_exclam = 0x0021, /* U+0021 EXCLAMATION MARK */
XK_quotedbl = 0x0022, /* U+0022 QUOTATION MARK */
XK_numbersign = 0x0023, /* U+0023 NUMBER SIGN */
XK_dollar = 0x0024, /* U+0024 DOLLAR SIGN */
XK_percent = 0x0025, /* U+0025 PERCENT SIGN */
XK_ampersand = 0x0026, /* U+0026 AMPERSAND */
XK_apostrophe = 0x0027, /* U+0027 APOSTROPHE */
XK_quoteright = 0x0027, /* deprecated */
XK_parenleft = 0x0028, /* U+0028 LEFT PARENTHESIS */
XK_parenright = 0x0029, /* U+0029 RIGHT PARENTHESIS */
XK_asterisk = 0x002a, /* U+002A ASTERISK */
XK_plus = 0x002b, /* U+002B PLUS SIGN */
XK_comma = 0x002c, /* U+002C COMMA */
XK_minus = 0x002d, /* U+002D HYPHEN-MINUS */
XK_period = 0x002e, /* U+002E FULL STOP */
XK_slash = 0x002f, /* U+002F SOLIDUS */
XK_0 = 0x0030, /* U+0030 DIGIT ZERO */
XK_1 = 0x0031, /* U+0031 DIGIT ONE */
XK_2 = 0x0032, /* U+0032 DIGIT TWO */
XK_3 = 0x0033, /* U+0033 DIGIT THREE */
XK_4 = 0x0034, /* U+0034 DIGIT FOUR */
XK_5 = 0x0035, /* U+0035 DIGIT FIVE */
XK_6 = 0x0036, /* U+0036 DIGIT SIX */
XK_7 = 0x0037, /* U+0037 DIGIT SEVEN */
XK_8 = 0x0038, /* U+0038 DIGIT EIGHT */
XK_9 = 0x0039, /* U+0039 DIGIT NINE */
XK_colon = 0x003a, /* U+003A COLON */
XK_semicolon = 0x003b, /* U+003B SEMICOLON */
XK_less = 0x003c, /* U+003C LESS-THAN SIGN */
XK_equal = 0x003d, /* U+003D EQUALS SIGN */
XK_greater = 0x003e, /* U+003E GREATER-THAN SIGN */
XK_question = 0x003f, /* U+003F QUESTION MARK */
XK_at = 0x0040, /* U+0040 COMMERCIAL AT */
XK_A = 0x0041, /* U+0041 LATIN CAPITAL LETTER A */
XK_B = 0x0042, /* U+0042 LATIN CAPITAL LETTER B */
XK_C = 0x0043, /* U+0043 LATIN CAPITAL LETTER C */
XK_D = 0x0044, /* U+0044 LATIN CAPITAL LETTER D */
XK_E = 0x0045, /* U+0045 LATIN CAPITAL LETTER E */
XK_F = 0x0046, /* U+0046 LATIN CAPITAL LETTER F */
XK_G = 0x0047, /* U+0047 LATIN CAPITAL LETTER G */
XK_H = 0x0048, /* U+0048 LATIN CAPITAL LETTER H */
XK_I = 0x0049, /* U+0049 LATIN CAPITAL LETTER I */
XK_J = 0x004a, /* U+004A LATIN CAPITAL LETTER J */
XK_K = 0x004b, /* U+004B LATIN CAPITAL LETTER K */
XK_L = 0x004c, /* U+004C LATIN CAPITAL LETTER L */
XK_M = 0x004d, /* U+004D LATIN CAPITAL LETTER M */
XK_N = 0x004e, /* U+004E LATIN CAPITAL LETTER N */
XK_O = 0x004f, /* U+004F LATIN CAPITAL LETTER O */
XK_P = 0x0050, /* U+0050 LATIN CAPITAL LETTER P */
XK_Q = 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */
XK_R = 0x0052, /* U+0052 LATIN CAPITAL LETTER R */
XK_S = 0x0053, /* U+0053 LATIN CAPITAL LETTER S */
XK_T = 0x0054, /* U+0054 LATIN CAPITAL LETTER T */
XK_U = 0x0055, /* U+0055 LATIN CAPITAL LETTER U */
XK_V = 0x0056, /* U+0056 LATIN CAPITAL LETTER V */
XK_W = 0x0057, /* U+0057 LATIN CAPITAL LETTER W */
XK_X = 0x0058, /* U+0058 LATIN CAPITAL LETTER X */
XK_Y = 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */
XK_Z = 0x005a, /* U+005A LATIN CAPITAL LETTER Z */
XK_bracketleft = 0x005b, /* U+005B LEFT SQUARE BRACKET */
XK_backslash = 0x005c, /* U+005C REVERSE SOLIDUS */
XK_bracketright = 0x005d, /* U+005D RIGHT SQUARE BRACKET */
XK_asciicircum = 0x005e, /* U+005E CIRCUMFLEX ACCENT */
XK_underscore = 0x005f, /* U+005F LOW LINE */
XK_grave = 0x0060, /* U+0060 GRAVE ACCENT */
XK_quoteleft = 0x0060, /* deprecated */
XK_a = 0x0061, /* U+0061 LATIN SMALL LETTER A */
XK_b = 0x0062, /* U+0062 LATIN SMALL LETTER B */
XK_c = 0x0063, /* U+0063 LATIN SMALL LETTER C */
XK_d = 0x0064, /* U+0064 LATIN SMALL LETTER D */
XK_e = 0x0065, /* U+0065 LATIN SMALL LETTER E */
XK_f = 0x0066, /* U+0066 LATIN SMALL LETTER F */
XK_g = 0x0067, /* U+0067 LATIN SMALL LETTER G */
XK_h = 0x0068, /* U+0068 LATIN SMALL LETTER H */
XK_i = 0x0069, /* U+0069 LATIN SMALL LETTER I */
XK_j = 0x006a, /* U+006A LATIN SMALL LETTER J */
XK_k = 0x006b, /* U+006B LATIN SMALL LETTER K */
XK_l = 0x006c, /* U+006C LATIN SMALL LETTER L */
XK_m = 0x006d, /* U+006D LATIN SMALL LETTER M */
XK_n = 0x006e, /* U+006E LATIN SMALL LETTER N */
XK_o = 0x006f, /* U+006F LATIN SMALL LETTER O */
XK_p = 0x0070, /* U+0070 LATIN SMALL LETTER P */
XK_q = 0x0071, /* U+0071 LATIN SMALL LETTER Q */
XK_r = 0x0072, /* U+0072 LATIN SMALL LETTER R */
XK_s = 0x0073, /* U+0073 LATIN SMALL LETTER S */
XK_t = 0x0074, /* U+0074 LATIN SMALL LETTER T */
XK_u = 0x0075, /* U+0075 LATIN SMALL LETTER U */
XK_v = 0x0076, /* U+0076 LATIN SMALL LETTER V */
XK_w = 0x0077, /* U+0077 LATIN SMALL LETTER W */
XK_x = 0x0078, /* U+0078 LATIN SMALL LETTER X */
XK_y = 0x0079, /* U+0079 LATIN SMALL LETTER Y */
XK_z = 0x007a, /* U+007A LATIN SMALL LETTER Z */
XK_braceleft = 0x007b, /* U+007B LEFT CURLY BRACKET */
XK_bar = 0x007c, /* U+007C VERTICAL LINE */
XK_braceright = 0x007d, /* U+007D RIGHT CURLY BRACKET */
XK_asciitilde = 0x007e, /* U+007E TILDE */
XK_nobreakspace = 0x00a0, /* U+00A0 NO-BREAK SPACE */
XK_exclamdown = 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */
XK_cent = 0x00a2, /* U+00A2 CENT SIGN */
XK_sterling = 0x00a3, /* U+00A3 POUND SIGN */
XK_currency = 0x00a4, /* U+00A4 CURRENCY SIGN */
XK_yen = 0x00a5, /* U+00A5 YEN SIGN */
XK_brokenbar = 0x00a6, /* U+00A6 BROKEN BAR */
XK_section = 0x00a7, /* U+00A7 SECTION SIGN */
XK_diaeresis = 0x00a8, /* U+00A8 DIAERESIS */
XK_copyright = 0x00a9, /* U+00A9 COPYRIGHT SIGN */
XK_ordfeminine = 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */
XK_guillemotleft = 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
XK_notsign = 0x00ac, /* U+00AC NOT SIGN */
XK_hyphen = 0x00ad, /* U+00AD SOFT HYPHEN */
XK_registered = 0x00ae, /* U+00AE REGISTERED SIGN */
XK_macron = 0x00af, /* U+00AF MACRON */
XK_degree = 0x00b0, /* U+00B0 DEGREE SIGN */
XK_plusminus = 0x00b1, /* U+00B1 PLUS-MINUS SIGN */
XK_twosuperior = 0x00b2, /* U+00B2 SUPERSCRIPT TWO */
XK_threesuperior = 0x00b3, /* U+00B3 SUPERSCRIPT THREE */
XK_acute = 0x00b4, /* U+00B4 ACUTE ACCENT */
XK_mu = 0x00b5, /* U+00B5 MICRO SIGN */
XK_paragraph = 0x00b6, /* U+00B6 PILCROW SIGN */
XK_periodcentered = 0x00b7, /* U+00B7 MIDDLE DOT */
XK_cedilla = 0x00b8, /* U+00B8 CEDILLA */
XK_onesuperior = 0x00b9, /* U+00B9 SUPERSCRIPT ONE */
XK_masculine = 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */
XK_guillemotright = 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
XK_onequarter = 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */
XK_onehalf = 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */
XK_threequarters = 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */
XK_questiondown = 0x00bf, /* U+00BF INVERTED QUESTION MARK */
XK_Agrave = 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
XK_Aacute = 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
XK_Acircumflex = 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
XK_Atilde = 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
XK_Adiaeresis = 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
XK_Aring = 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
XK_AE = 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */
XK_Ccedilla = 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
XK_Egrave = 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
XK_Eacute = 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
XK_Ecircumflex = 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
XK_Ediaeresis = 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
XK_Igrave = 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
XK_Iacute = 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
XK_Icircumflex = 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
XK_Idiaeresis = 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
XK_ETH = 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */
XK_Eth = 0x00d0, /* deprecated */
XK_Ntilde = 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
XK_Ograve = 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
XK_Oacute = 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
XK_Ocircumflex = 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
XK_Otilde = 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
XK_Odiaeresis = 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
XK_multiply = 0x00d7, /* U+00D7 MULTIPLICATION SIGN */
XK_Oslash = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
XK_Ooblique = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
XK_Ugrave = 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
XK_Uacute = 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
XK_Ucircumflex = 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
XK_Udiaeresis = 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
XK_Yacute = 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
XK_THORN = 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */
XK_Thorn = 0x00de, /* deprecated */
XK_ssharp = 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */
XK_agrave = 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
XK_aacute = 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
XK_acircumflex = 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
XK_atilde = 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
XK_adiaeresis = 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
XK_aring = 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
XK_ae = 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */
XK_ccedilla = 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
XK_egrave = 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
XK_eacute = 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
XK_ecircumflex = 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
XK_ediaeresis = 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
XK_igrave = 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
XK_iacute = 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
XK_icircumflex = 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
XK_idiaeresis = 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
XK_eth = 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */
XK_ntilde = 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
XK_ograve = 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
XK_oacute = 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
XK_ocircumflex = 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
XK_otilde = 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
XK_odiaeresis = 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
XK_division = 0x00f7, /* U+00F7 DIVISION SIGN */
XK_oslash = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
XK_ooblique = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
XK_ugrave = 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
XK_uacute = 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
XK_ucircumflex = 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
XK_udiaeresis = 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
XK_yacute = 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
XK_thorn = 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */
XK_ydiaeresis = 0x00ff; /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
/* /*
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed 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.
...@@ -102,7 +103,6 @@ var that = {}, // Public API methods ...@@ -102,7 +103,6 @@ var that = {}, // Public API methods
fb_height = 0, fb_height = 0,
fb_name = "", fb_name = "",
last_req_time = 0,
rre_chunk_sz = 100, rre_chunk_sz = 100,
timing = { timing = {
...@@ -147,9 +147,6 @@ Util.conf_defaults(conf, that, defaults, [ ...@@ -147,9 +147,6 @@ Util.conf_defaults(conf, that, defaults, [
['viewportDrag', 'rw', 'bool', false, 'Move the viewport on mouse drags'], ['viewportDrag', 'rw', 'bool', false, 'Move the viewport on mouse drags'],
['check_rate', 'rw', 'int', 217, 'Timing (ms) of send/receive check'],
['fbu_req_rate', 'rw', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests'],
// Callback functions // Callback functions
['onUpdateState', 'rw', 'func', function() { }, ['onUpdateState', 'rw', 'func', function() { },
'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change '], 'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change '],
...@@ -165,6 +162,8 @@ Util.conf_defaults(conf, that, defaults, [ ...@@ -165,6 +162,8 @@ Util.conf_defaults(conf, that, defaults, [
'onFBUComplete(rfb, fbu): RFB FBU received and processed '], 'onFBUComplete(rfb, fbu): RFB FBU received and processed '],
['onFBResize', 'rw', 'func', function() { }, ['onFBResize', 'rw', 'func', function() { },
'onFBResize(rfb, width, height): frame buffer resized'], 'onFBResize(rfb, width, height): frame buffer resized'],
['onDesktopName', 'rw', 'func', function() { },
'onDesktopName(rfb, name): desktop name received'],
// These callback names are deprecated // These callback names are deprecated
['updateState', 'rw', 'func', function() { }, ['updateState', 'rw', 'func', function() { },
...@@ -400,7 +399,7 @@ updateState = function(state, statusMsg) { ...@@ -400,7 +399,7 @@ updateState = function(state, statusMsg) {
} }
if (msgTimer) { if (msgTimer) {
clearInterval(msgTimer); clearTimeout(msgTimer);
msgTimer = null; msgTimer = null;
} }
...@@ -441,13 +440,13 @@ updateState = function(state, statusMsg) { ...@@ -441,13 +440,13 @@ updateState = function(state, statusMsg) {
if (connTimer && (rfb_state !== 'connect')) { if (connTimer && (rfb_state !== 'connect')) {
Util.Debug("Clearing connect timer"); Util.Debug("Clearing connect timer");
clearInterval(connTimer); clearTimeout(connTimer);
connTimer = null; connTimer = null;
} }
if (disconnTimer && (rfb_state !== 'disconnect')) { if (disconnTimer && (rfb_state !== 'disconnect')) {
Util.Debug("Clearing disconnect timer"); Util.Debug("Clearing disconnect timer");
clearInterval(disconnTimer); clearTimeout(disconnTimer);
disconnTimer = null; disconnTimer = null;
} }
...@@ -566,44 +565,18 @@ function genDES(password, challenge) { ...@@ -566,44 +565,18 @@ function genDES(password, challenge) {
return (new DES(passwd)).encrypt(challenge); return (new DES(passwd)).encrypt(challenge);
} }
function flushClient() {
if (mouse_arr.length > 0) {
//send(mouse_arr.concat(fbUpdateRequests()));
ws.send(mouse_arr);
setTimeout(function() {
ws.send(fbUpdateRequests());
}, 50);
mouse_arr = [];
return true;
} else {
return false;
}
}
// overridable for testing // overridable for testing
checkEvents = function() { checkEvents = function() {
var now; if (rfb_state === 'normal' && !viewportDragging && mouse_arr.length > 0) {
if (rfb_state === 'normal' && !viewportDragging) { ws.send(mouse_arr);
if (! flushClient()) { mouse_arr = [];
now = new Date().getTime();
if (now > last_req_time + conf.fbu_req_rate) {
last_req_time = now;
ws.send(fbUpdateRequests());
}
}
} }
setTimeout(checkEvents, conf.check_rate);
}; };
keyPress = function(keysym, down) { keyPress = function(keysym, down) {
var arr;
if (conf.view_only) { return; } // View only, skip keyboard events if (conf.view_only) { return; } // View only, skip keyboard events
arr = keyEvent(keysym, down); ws.send(keyEvent(keysym, down));
arr = arr.concat(fbUpdateRequests());
ws.send(arr);
}; };
mouseButton = function(x, y, down, bmask) { mouseButton = function(x, y, down, bmask) {
...@@ -622,7 +595,6 @@ mouseButton = function(x, y, down, bmask) { ...@@ -622,7 +595,6 @@ mouseButton = function(x, y, down, bmask) {
return; return;
} else { } else {
viewportDragging = false; viewportDragging = false;
ws.send(fbUpdateRequests()); // Force immediate redraw
} }
} }
...@@ -630,7 +602,8 @@ mouseButton = function(x, y, down, bmask) { ...@@ -630,7 +602,8 @@ mouseButton = function(x, y, down, bmask) {
mouse_arr = mouse_arr.concat( mouse_arr = mouse_arr.concat(
pointerEvent(display.absX(x), display.absY(y)) ); pointerEvent(display.absX(x), display.absY(y)) );
flushClient(); ws.send(mouse_arr);
mouse_arr = [];
}; };
mouseMove = function(x, y) { mouseMove = function(x, y) {
...@@ -653,7 +626,9 @@ mouseMove = function(x, y) { ...@@ -653,7 +626,9 @@ mouseMove = function(x, y) {
if (conf.view_only) { return; } // View only, skip mouse events if (conf.view_only) { return; } // View only, skip mouse events
mouse_arr = mouse_arr.concat( mouse_arr = mouse_arr.concat(
pointerEvent(display.absX(x), display.absY(y)) ); pointerEvent(display.absX(x), display.absY(y)));
checkEvents();
}; };
...@@ -873,6 +848,7 @@ init_msg = function() { ...@@ -873,6 +848,7 @@ init_msg = function() {
/* Connection name/title */ /* Connection name/title */
name_length = ws.rQshift32(); name_length = ws.rQshift32();
fb_name = ws.rQshiftStr(name_length); fb_name = ws.rQshiftStr(name_length);
conf.onDesktopName(that, fb_name);
if (conf.true_color && fb_name === "Intel(r) AMT KVM") if (conf.true_color && fb_name === "Intel(r) AMT KVM")
{ {
...@@ -896,13 +872,12 @@ init_msg = function() { ...@@ -896,13 +872,12 @@ init_msg = function() {
response = pixelFormat(); response = pixelFormat();
response = response.concat(clientEncodings()); response = response.concat(clientEncodings());
response = response.concat(fbUpdateRequests()); response = response.concat(fbUpdateRequests()); // initial fbu-request
timing.fbu_rt_start = (new Date()).getTime(); timing.fbu_rt_start = (new Date()).getTime();
timing.pixels = 0; timing.pixels = 0;
ws.send(response); ws.send(response);
/* Start pushing/polling */ checkEvents();
setTimeout(checkEvents, conf.check_rate);
if (conf.encrypt) { if (conf.encrypt) {
updateState('normal', "Connected (encrypted) to: " + fb_name); updateState('normal', "Connected (encrypted) to: " + fb_name);
...@@ -930,6 +905,10 @@ normal_msg = function() { ...@@ -930,6 +905,10 @@ normal_msg = function() {
switch (msg_type) { switch (msg_type) {
case 0: // FramebufferUpdate case 0: // FramebufferUpdate
ret = framebufferUpdate(); // false means need more data ret = framebufferUpdate(); // false means need more data
if (ret) {
// only allow one outstanding fbu-request at a time
ws.send(fbUpdateRequests());
}
break; break;
case 1: // SetColourMapEntries case 1: // SetColourMapEntries
Util.Debug("SetColourMapEntries"); Util.Debug("SetColourMapEntries");
...@@ -1592,8 +1571,6 @@ encHandlers.DesktopSize = function set_desktopsize() { ...@@ -1592,8 +1571,6 @@ encHandlers.DesktopSize = function set_desktopsize() {
conf.onFBResize(that, fb_width, fb_height); conf.onFBResize(that, fb_width, fb_height);
display.resize(fb_width, fb_height); display.resize(fb_width, fb_height);
timing.fbu_rt_start = (new Date()).getTime(); timing.fbu_rt_start = (new Date()).getTime();
// Send a new non-incremental request
ws.send(fbUpdateRequests());
FBU.bytes = 0; FBU.bytes = 0;
FBU.rects -= 1; FBU.rects -= 1;
...@@ -1819,7 +1796,6 @@ that.sendCtrlAltDel = function() { ...@@ -1819,7 +1796,6 @@ that.sendCtrlAltDel = function() {
arr = arr.concat(keyEvent(0xFFFF, 0)); // Delete arr = arr.concat(keyEvent(0xFFFF, 0)); // Delete
arr = arr.concat(keyEvent(0xFFE9, 0)); // Alt arr = arr.concat(keyEvent(0xFFE9, 0)); // Alt
arr = arr.concat(keyEvent(0xFFE3, 0)); // Control arr = arr.concat(keyEvent(0xFFE3, 0)); // Control
arr = arr.concat(fbUpdateRequests());
ws.send(arr); ws.send(arr);
}; };
...@@ -1836,7 +1812,6 @@ that.sendKey = function(code, down) { ...@@ -1836,7 +1812,6 @@ that.sendKey = function(code, down) {
arr = arr.concat(keyEvent(code, 1)); arr = arr.concat(keyEvent(code, 1));
arr = arr.concat(keyEvent(code, 0)); arr = arr.concat(keyEvent(code, 0));
} }
arr = arr.concat(fbUpdateRequests());
ws.send(arr); ws.send(arr);
}; };
......
/* /*
* noVNC: HTML5 VNC client * noVNC: HTML5 VNC client
* Copyright (C) 2012 Joel Martin * Copyright (C) 2012 Joel Martin
* Copyright (C) 2013 Samuel Mannehed 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.
...@@ -13,15 +14,22 @@ ...@@ -13,15 +14,22 @@
// Load supporting scripts // Load supporting scripts
window.onscriptsload = function () { UI.load(); }; window.onscriptsload = function () { UI.load(); };
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js", Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
"input.js", "display.js", "jsunzip.js", "rfb.js"]); "input.js", "display.js", "jsunzip.js", "rfb.js",
"keysym.js"]);
var UI = { var UI = {
rfb_state : 'loaded', rfb_state : 'loaded',
settingsOpen : false, settingsOpen : false,
connSettingsOpen : false, connSettingsOpen : false,
popupStatusOpen : false,
clipboardOpen: false, clipboardOpen: false,
keyboardVisible: false, keyboardVisible: false,
hideKeyboardTimeout: null,
extraKeysVisible: false,
ctrlOn: false,
altOn: false,
isTouchDevice: false,
// Setup rfb object, load settings from browser storage, then call // Setup rfb object, load settings from browser storage, then call
// UI.init to setup the UI/menus // UI.init to setup the UI/menus
...@@ -31,7 +39,9 @@ load: function (callback) { ...@@ -31,7 +39,9 @@ load: function (callback) {
// Render default UI and initialize settings menu // Render default UI and initialize settings menu
start: function(callback) { start: function(callback) {
var html = '', i, sheet, sheets, llevels, port; var html = '', i, sheet, sheets, llevels, port, autoconnect;
UI.isTouchDevice = 'ontouchstart' in document.documentElement;
// Stylesheet selection dropdown // Stylesheet selection dropdown
sheet = WebUtil.selectStylesheet(); sheet = WebUtil.selectStylesheet();
...@@ -73,7 +83,7 @@ start: function(callback) { ...@@ -73,7 +83,7 @@ start: function(callback) {
UI.initSetting('password', ''); UI.initSetting('password', '');
UI.initSetting('encrypt', (window.location.protocol === "https:")); UI.initSetting('encrypt', (window.location.protocol === "https:"));
UI.initSetting('true_color', true); UI.initSetting('true_color', true);
UI.initSetting('cursor', false); UI.initSetting('cursor', !UI.isTouchDevice);
UI.initSetting('shared', true); UI.initSetting('shared', true);
UI.initSetting('view_only', false); UI.initSetting('view_only', false);
UI.initSetting('connectTimeout', 2); UI.initSetting('connectTimeout', 2);
...@@ -82,7 +92,17 @@ start: function(callback) { ...@@ -82,7 +92,17 @@ start: function(callback) {
UI.rfb = RFB({'target': $D('noVNC_canvas'), UI.rfb = RFB({'target': $D('noVNC_canvas'),
'onUpdateState': UI.updateState, 'onUpdateState': UI.updateState,
'onClipboard': UI.clipReceive}); 'onClipboard': UI.clipReceive,
'onDesktopName': UI.updateDocumentTitle});
autoconnect = WebUtil.getQueryVar('autoconnect', false);
if (autoconnect === 'true' || autoconnect == '1') {
autoconnect = true;
UI.connect();
} else {
autoconnect = false;
}
UI.updateVisualState(); UI.updateVisualState();
// Unfocus clipboard when over the VNC area // Unfocus clipboard when over the VNC area
...@@ -94,7 +114,7 @@ start: function(callback) { ...@@ -94,7 +114,7 @@ start: function(callback) {
// }; // };
// Show mouse selector buttons on touch screen devices // Show mouse selector buttons on touch screen devices
if ('ontouchstart' in document.documentElement) { if (UI.isTouchDevice) {
// Show mobile buttons // Show mobile buttons
$D('noVNC_mobile_buttons').style.display = "inline"; $D('noVNC_mobile_buttons').style.display = "inline";
UI.setMouseButton(); UI.setMouseButton();
...@@ -132,8 +152,10 @@ start: function(callback) { ...@@ -132,8 +152,10 @@ start: function(callback) {
// Open the description dialog // Open the description dialog
$D('noVNC_description').style.display = "block"; $D('noVNC_description').style.display = "block";
} else { } else {
// Open the connect panel on first load // Show the connect panel on first load unless autoconnecting
UI.toggleConnectPanel(); if (autoconnect === UI.connSettingsOpen) {
UI.toggleConnectPanel();
}
} }
// Add mouse event click/focus/blur event handlers to the UI // Add mouse event click/focus/blur event handlers to the UI
...@@ -152,10 +174,19 @@ addMouseHandlers: function() { ...@@ -152,10 +174,19 @@ addMouseHandlers: function() {
$D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); }; $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
$D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); }; $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
$D("showKeyboard").onclick = UI.showKeyboard; $D("showKeyboard").onclick = UI.showKeyboard;
//$D("keyboardinput").onkeydown = function (event) { onKeyDown(event); };
$D("keyboardinput").oninput = UI.keyInput;
$D("keyboardinput").onblur = UI.keyInputBlur; $D("keyboardinput").onblur = UI.keyInputBlur;
$D("showExtraKeysButton").onclick = UI.showExtraKeys;
$D("toggleCtrlButton").onclick = UI.toggleCtrl;
$D("toggleAltButton").onclick = UI.toggleAlt;
$D("sendTabButton").onclick = UI.sendTab;
$D("sendEscButton").onclick = UI.sendEsc;
$D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel; $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel;
$D("noVNC_status").onclick = UI.togglePopupStatusPanel;
$D("noVNC_popup_status_panel").onclick = UI.togglePopupStatusPanel;
$D("clipboardButton").onclick = UI.toggleClipboardPanel; $D("clipboardButton").onclick = UI.toggleClipboardPanel;
$D("settingsButton").onclick = UI.toggleSettingsPanel; $D("settingsButton").onclick = UI.toggleSettingsPanel;
$D("connectButton").onclick = UI.toggleConnectPanel; $D("connectButton").onclick = UI.toggleConnectPanel;
...@@ -257,20 +288,39 @@ forceSetting: function(name, val) { ...@@ -257,20 +288,39 @@ forceSetting: function(name, val) {
}, },
// Show the popup status panel
togglePopupStatusPanel: function() {
var psp = $D('noVNC_popup_status_panel');
if (UI.popupStatusOpen === true) {
psp.style.display = "none";
UI.popupStatusOpen = false;
} else {
psp.innerHTML = $D('noVNC_status').innerHTML;
psp.style.display = "block";
psp.style.left = window.innerWidth/2 -
parseInt(window.getComputedStyle(psp, false).width)/2 -30 + "px";
UI.popupStatusOpen = true;
}
},
// Show the clipboard panel // Show the clipboard panel
toggleClipboardPanel: function() { toggleClipboardPanel: function() {
// Close the description panel // Close the description panel
$D('noVNC_description').style.display = "none"; $D('noVNC_description').style.display = "none";
//Close settings if open // Close settings if open
if (UI.settingsOpen === true) { if (UI.settingsOpen === true) {
UI.settingsApply(); UI.settingsApply();
UI.closeSettingsMenu(); UI.closeSettingsMenu();
} }
//Close connection settings if open // Close connection settings if open
if (UI.connSettingsOpen === true) { if (UI.connSettingsOpen === true) {
UI.toggleConnectPanel(); UI.toggleConnectPanel();
} }
//Toggle Clipboard Panel // Close popup status panel if open
if (UI.popupStatusOpen === true) {
UI.togglePopupStatusPanel();
}
// Toggle Clipboard Panel
if (UI.clipboardOpen === true) { if (UI.clipboardOpen === true) {
$D('noVNC_clipboard').style.display = "none"; $D('noVNC_clipboard').style.display = "none";
$D('clipboardButton').className = "noVNC_status_button"; $D('clipboardButton').className = "noVNC_status_button";
...@@ -286,17 +336,22 @@ toggleClipboardPanel: function() { ...@@ -286,17 +336,22 @@ toggleClipboardPanel: function() {
toggleConnectPanel: function() { toggleConnectPanel: function() {
// Close the description panel // Close the description panel
$D('noVNC_description').style.display = "none"; $D('noVNC_description').style.display = "none";
//Close connection settings if open // Close connection settings if open
if (UI.settingsOpen === true) { if (UI.settingsOpen === true) {
UI.settingsApply(); UI.settingsApply();
UI.closeSettingsMenu(); UI.closeSettingsMenu();
$D('connectButton').className = "noVNC_status_button"; $D('connectButton').className = "noVNC_status_button";
} }
// Close clipboard panel if open
if (UI.clipboardOpen === true) { if (UI.clipboardOpen === true) {
UI.toggleClipboardPanel(); UI.toggleClipboardPanel();
} }
// Close popup status panel if open
if (UI.popupStatusOpen === true) {
UI.togglePopupStatusPanel();
}
//Toggle Connection Panel // Toggle Connection Panel
if (UI.connSettingsOpen === true) { if (UI.connSettingsOpen === true) {
$D('noVNC_controls').style.display = "none"; $D('noVNC_controls').style.display = "none";
$D('connectButton').className = "noVNC_status_button"; $D('connectButton').className = "noVNC_status_button";
...@@ -327,7 +382,7 @@ toggleSettingsPanel: function() { ...@@ -327,7 +382,7 @@ toggleSettingsPanel: function() {
if (UI.rfb.get_display().get_cursor_uri()) { if (UI.rfb.get_display().get_cursor_uri()) {
UI.updateSetting('cursor'); UI.updateSetting('cursor');
} else { } else {
UI.updateSetting('cursor', false); UI.updateSetting('cursor', !UI.isTouchDevice);
$D('noVNC_cursor').disabled = true; $D('noVNC_cursor').disabled = true;
} }
UI.updateSetting('clip'); UI.updateSetting('clip');
...@@ -347,13 +402,18 @@ toggleSettingsPanel: function() { ...@@ -347,13 +402,18 @@ toggleSettingsPanel: function() {
openSettingsMenu: function() { openSettingsMenu: function() {
// Close the description panel // Close the description panel
$D('noVNC_description').style.display = "none"; $D('noVNC_description').style.display = "none";
// Close clipboard panel if open
if (UI.clipboardOpen === true) { if (UI.clipboardOpen === true) {
UI.toggleClipboardPanel(); UI.toggleClipboardPanel();
} }
//Close connection settings if open // Close connection settings if open
if (UI.connSettingsOpen === true) { if (UI.connSettingsOpen === true) {
UI.toggleConnectPanel(); UI.toggleConnectPanel();
} }
// Close popup status panel if open
if (UI.popupStatusOpen === true) {
UI.togglePopupStatusPanel();
}
$D('noVNC_settings').style.display = "block"; $D('noVNC_settings').style.display = "block";
$D('settingsButton').className = "noVNC_status_button_selected"; $D('settingsButton').className = "noVNC_status_button_selected";
UI.settingsOpen = true; UI.settingsOpen = true;
...@@ -437,8 +497,6 @@ setMouseButton: function(num) { ...@@ -437,8 +497,6 @@ setMouseButton: function(num) {
updateState: function(rfb, state, oldstate, msg) { updateState: function(rfb, state, oldstate, msg) {
var s, sb, c, d, cad, vd, klass; var s, sb, c, d, cad, vd, klass;
UI.rfb_state = state; UI.rfb_state = state;
s = $D('noVNC_status');
sb = $D('noVNC_status_bar');
switch (state) { switch (state) {
case 'failed': case 'failed':
case 'fatal': case 'fatal':
...@@ -468,9 +526,8 @@ updateState: function(rfb, state, oldstate, msg) { ...@@ -468,9 +526,8 @@ updateState: function(rfb, state, oldstate, msg) {
} }
if (typeof(msg) !== 'undefined') { if (typeof(msg) !== 'undefined') {
s.setAttribute("class", klass); $D('noVNC-control-bar').setAttribute("class", klass);
sb.setAttribute("class", klass); $D('noVNC_status').innerHTML = msg;
s.innerHTML = msg;
} }
UI.updateVisualState(); UI.updateVisualState();
...@@ -487,7 +544,7 @@ updateVisualState: function() { ...@@ -487,7 +544,7 @@ updateVisualState: function() {
UI.rfb.get_display().get_cursor_uri()) { UI.rfb.get_display().get_cursor_uri()) {
$D('noVNC_cursor').disabled = connected; $D('noVNC_cursor').disabled = connected;
} else { } else {
UI.updateSetting('cursor', false); UI.updateSetting('cursor', !UI.isTouchDevice);
$D('noVNC_cursor').disabled = true; $D('noVNC_cursor').disabled = true;
} }
$D('noVNC_shared').disabled = connected; $D('noVNC_shared').disabled = connected;
...@@ -501,13 +558,16 @@ updateVisualState: function() { ...@@ -501,13 +558,16 @@ updateVisualState: function() {
UI.setMouseButton(1); UI.setMouseButton(1);
$D('clipboardButton').style.display = "inline"; $D('clipboardButton').style.display = "inline";
$D('showKeyboard').style.display = "inline"; $D('showKeyboard').style.display = "inline";
$D('noVNC_extra_keys').style.display = "";
$D('sendCtrlAltDelButton').style.display = "inline"; $D('sendCtrlAltDelButton').style.display = "inline";
} else { } else {
UI.setMouseButton(); UI.setMouseButton();
$D('clipboardButton').style.display = "none"; $D('clipboardButton').style.display = "none";
$D('showKeyboard').style.display = "none"; $D('showKeyboard').style.display = "none";
$D('noVNC_extra_keys').style.display = "none";
$D('sendCtrlAltDelButton').style.display = "none"; $D('sendCtrlAltDelButton').style.display = "none";
} }
// State change disables viewport dragging. // State change disables viewport dragging.
// It is enabled (toggled) by direct click on the button // It is enabled (toggled) by direct click on the button
UI.setViewDrag(false); UI.setViewDrag(false);
...@@ -530,6 +590,12 @@ updateVisualState: function() { ...@@ -530,6 +590,12 @@ updateVisualState: function() {
}, },
// Display the desktop name in the document title
updateDocumentTitle: function(rfb, name) {
document.title = name + " - noVNC";
},
clipReceive: function(rfb, text) { clipReceive: function(rfb, text) {
Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
$D('noVNC_clipboard_text').value = text; $D('noVNC_clipboard_text').value = text;
...@@ -664,23 +730,123 @@ setViewDrag: function(drag) { ...@@ -664,23 +730,123 @@ setViewDrag: function(drag) {
// On touch devices, show the OS keyboard // On touch devices, show the OS keyboard
showKeyboard: function() { showKeyboard: function() {
var kbi, skb, l;
kbi = $D('keyboardinput');
skb = $D('showKeyboard');
l = kbi.value.length;
if(UI.keyboardVisible === false) { if(UI.keyboardVisible === false) {
$D('keyboardinput').focus(); kbi.focus();
kbi.setSelectionRange(l, l); // Move the caret to the end
UI.keyboardVisible = true; UI.keyboardVisible = true;
$D('showKeyboard').className = "noVNC_status_button_selected"; skb.className = "noVNC_status_button_selected";
} else if(UI.keyboardVisible === true) { } else if(UI.keyboardVisible === true) {
kbi.blur();
skb.className = "noVNC_status_button";
UI.keyboardVisible = false;
}
},
keepKeyboard: function() {
clearTimeout(UI.hideKeyboardTimeout);
if(UI.keyboardVisible === true) {
$D('keyboardinput').focus();
$D('showKeyboard').className = "noVNC_status_button_selected";
} else if(UI.keyboardVisible === false) {
$D('keyboardinput').blur(); $D('keyboardinput').blur();
$D('showKeyboard').className = "noVNC_status_button"; $D('showKeyboard').className = "noVNC_status_button";
UI.keyboardVisible = false;
} }
}, },
// When keypress events are left uncought, catch the input events from
// the keyboardinput element instead and send the corresponding key events.
keyInput: function(event) {
var elem, input, len;
elem = $D('keyboardinput');
input = event.target.value;
len = (elem.selectionStart > input.length) ? elem.selectionStart : input.length;
if (len < 1) { // something removed?
UI.rfb.sendKey(0xff08); // send BACKSPACE
} else if (len > 1) { // new input?
for (var i = len-1; i > 0; i -= 1) {
// HTML does not consider trailing whitespaces as a part of the string
// and they are therefore undefined.
if (input[len-i] !== undefined) {
UI.rfb.sendKey(input.charCodeAt(len-i)); // send charCode
} else {
UI.rfb.sendKey(0x0020); // send SPACE
}
}
}
// In order to be able to delete text which has been written in
// another session there has to always be text in the
// keyboardinput element with which backspace can interact.
// We also need to reset the input field text to avoid overflow.
elem.value = "x";
},
keyInputBlur: function() { keyInputBlur: function() {
$D('showKeyboard').className = "noVNC_status_button"; $D('showKeyboard').className = "noVNC_status_button";
//Weird bug in iOS if you change keyboardVisible //Weird bug in iOS if you change keyboardVisible
//here it does not actually occur so next time //here it does not actually occur so next time
//you click keyboard icon it doesnt work. //you click keyboard icon it doesnt work.
setTimeout(function() { UI.setKeyboard(); },100); UI.hideKeyboardTimeout = setTimeout(function() { UI.setKeyboard(); },100);
},
showExtraKeys: function() {
UI.keepKeyboard();
if(UI.extraKeysVisible === false) {
$D('toggleCtrlButton').style.display = "inline";
$D('toggleAltButton').style.display = "inline";
$D('sendTabButton').style.display = "inline";
$D('sendEscButton').style.display = "inline";
$D('showExtraKeysButton').className = "noVNC_status_button_selected";
UI.extraKeysVisible = true;
} else if(UI.extraKeysVisible === true) {
$D('toggleCtrlButton').style.display = "";
$D('toggleAltButton').style.display = "";
$D('sendTabButton').style.display = "";
$D('sendEscButton').style.display = "";
$D('showExtraKeysButton').className = "noVNC_status_button";
UI.extraKeysVisible = false;
}
},
toggleCtrl: function() {
UI.keepKeyboard();
if(UI.ctrlOn === false) {
UI.rfb.sendKey(XK_Control_L, true);
$D('toggleCtrlButton').className = "noVNC_status_button_selected";
UI.ctrlOn = true;
} else if(UI.ctrlOn === true) {
UI.rfb.sendKey(XK_Control_L, false);
$D('toggleCtrlButton').className = "noVNC_status_button";
UI.ctrlOn = false;
}
},
toggleAlt: function() {
UI.keepKeyboard();
if(UI.altOn === false) {
UI.rfb.sendKey(XK_Alt_L, true);
$D('toggleAltButton').className = "noVNC_status_button_selected";
UI.altOn = true;
} else if(UI.altOn === true) {
UI.rfb.sendKey(XK_Alt_L, false);
$D('toggleAltButton').className = "noVNC_status_button";
UI.altOn = false;
}
},
sendTab: function() {
UI.keepKeyboard();
UI.rfb.sendKey(XK_Tab);
},
sendEsc: function() {
UI.keepKeyboard();
UI.rfb.sendKey(XK_Escape);
}, },
setKeyboard: function() { setKeyboard: function() {
......
...@@ -298,9 +298,11 @@ Util.getEventPosition = function (e, obj, scale) { ...@@ -298,9 +298,11 @@ Util.getEventPosition = function (e, obj, scale) {
if (typeof scale === "undefined") { if (typeof scale === "undefined") {
scale = 1; scale = 1;
} }
var x = Math.max(Math.min(docX - pos.x, obj.width-1), 0); var realx = docX - pos.x;
var y = Math.max(Math.min(docY - pos.y, obj.height-1), 0); var realy = docY - pos.y;
return {'x': x / scale, 'y': y / scale}; var x = Math.max(Math.min(realx, obj.width-1), 0);
var y = Math.max(Math.min(realy, obj.height-1), 0);
return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale};
}; };
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
<!-- <!--
noVNC example: simple example using default UI noVNC example: simple example using default UI
Copyright (C) 2012 Joel Martin Copyright (C) 2012 Joel Martin
Copyright (C) 2013 Samuel Mannehed for Cendio AB
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).
...@@ -65,12 +66,30 @@ ...@@ -65,12 +66,30 @@
<input type="image" src="images/keyboard.png" <input type="image" src="images/keyboard.png"
id="showKeyboard" class="noVNC_status_button" id="showKeyboard" class="noVNC_status_button"
value="Keyboard" title="Show Keyboard"/> value="Keyboard" title="Show Keyboard"/>
<input type="email" <input type="text" autocapitalize="off" autocorrect="off"
autocapitalize="off" autocorrect="off" id="keyboardinput" class=""/>
id="keyboardinput" class="noVNC_status_button"/> <div id="noVNC_extra_keys">
<input type="image" src="images/showextrakeys.png"
id="showExtraKeysButton"
class="noVNC_status_button">
<input type="image" src="images/ctrl.png"
id="toggleCtrlButton"
class="noVNC_status_button">
<input type="image" src="images/alt.png"
id="toggleAltButton"
class="noVNC_status_button">
<input type="image" src="images/tab.png"
id="sendTabButton"
class="noVNC_status_button">
<input type="image" src="images/esc.png"
id="sendEscButton"
class="noVNC_status_button">
</div>
</div> </div>
</div> </div>
<div id="noVNC_status">Loading</div>
<!--noVNC Buttons--> <!--noVNC Buttons-->
<div class="noVNC-buttons-right"> <div class="noVNC-buttons-right">
<input type="image" src="images/ctrlaltdel.png" <input type="image" src="images/ctrlaltdel.png"
...@@ -106,6 +125,10 @@ ...@@ -106,6 +125,10 @@
<input id="descriptionButton" type="button" value="Close"> <input id="descriptionButton" type="button" value="Close">
</div> </div>
<!-- Popup Status Panel -->
<div id="noVNC_popup_status_panel" class="">
</div>
<!-- Clipboard Panel --> <!-- Clipboard Panel -->
<div id="noVNC_clipboard" class="triangle-right top"> <div id="noVNC_clipboard" class="triangle-right top">
<textarea id="noVNC_clipboard_text" rows=5> <textarea id="noVNC_clipboard_text" rows=5>
...@@ -163,10 +186,6 @@ ...@@ -163,10 +186,6 @@
<div id="noVNC_screen"> <div id="noVNC_screen">
<div id="noVNC_screen_pad"></div> <div id="noVNC_screen_pad"></div>
<div id="noVNC_status_bar" class="noVNC_status_bar">
<div id="noVNC_status">Loading</div>
</div>
<h1 id="noVNC_logo"><span>no</span><br />VNC</h1> <h1 id="noVNC_logo"><span>no</span><br />VNC</h1>
<!-- HTML5 Canvas --> <!-- HTML5 Canvas -->
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
<html> <html>
<head> <head>
<!-- <!--
noVNC example: simple example using default UI noVNC example: simple example using default UI
Copyright (C) 2012 Joel Martin Copyright (C) 2012 Joel Martin
Copyright (C) 2013 Samuel Mannehed for Cendio AB
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).
...@@ -46,7 +47,9 @@ ...@@ -46,7 +47,9 @@
<div id="noVNC_screen"> <div id="noVNC_screen">
<div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;"> <div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;">
<table border=0 width="100%"><tr> <table border=0 width="100%"><tr>
<td><div id="noVNC_status">Loading</div></td> <td><div id="noVNC_status" style="position: relative; height: auto;">
Loading
</div></td>
<td width="1%"><div id="noVNC_buttons"> <td width="1%"><div id="noVNC_buttons">
<input type=button value="Send CtrlAltDel" <input type=button value="Send CtrlAltDel"
id="sendCtrlAltDelButton"> id="sendCtrlAltDelButton">
...@@ -125,12 +128,12 @@ ...@@ -125,12 +128,12 @@
// if port == 80 (or 443) then it won't be present and should be // if port == 80 (or 443) then it won't be present and should be
// set manually // set manually
if (!port) { if (!port) {
if (window.location.protocol.substring(0,4) == 'http') { if (window.location.protocol.substring(0,5) == 'https') {
port = 80;
}
else if (window.location.protocol.substring(0,5) == 'https') {
port = 443; port = 443;
} }
else if (window.location.protocol.substring(0,4) == 'http') {
port = 80;
}
} }
// If a token variable is passed in, set the parameter in a cookie. // If a token variable is passed in, set the parameter in a cookie.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment