Merge e8cc542fa3 into 98c1275d80
This commit is contained in:
commit
9e041e314d
Binary file not shown.
|
After Width: | Height: | Size: 390 B |
|
|
@ -52,12 +52,19 @@ html {
|
|||
float:right;
|
||||
}
|
||||
|
||||
#noVNC_buttons {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#noVNC_view_drag_button {
|
||||
display: none;
|
||||
}
|
||||
#sendCtrlAltDelButton {
|
||||
display: none;
|
||||
}
|
||||
#noVNC_xvp_buttons {
|
||||
display: none;
|
||||
}
|
||||
#noVNC_mobile_buttons {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -199,6 +206,16 @@ html {
|
|||
border-radius:10px;
|
||||
}
|
||||
|
||||
#noVNC_xvp {
|
||||
display:none;
|
||||
margin-top:73px;
|
||||
right:30px;
|
||||
position:fixed;
|
||||
}
|
||||
#noVNC_xvp.top:after {
|
||||
right:125px;
|
||||
}
|
||||
|
||||
#noVNC_clipboard {
|
||||
display:none;
|
||||
margin-top:73px;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ var that = {}, // Public API methods
|
|||
rfb_max_version= 3.8,
|
||||
rfb_auth_scheme= '',
|
||||
|
||||
rfb_xvp_ver = 0,
|
||||
|
||||
|
||||
// In preference order
|
||||
encodings = [
|
||||
|
|
@ -64,7 +66,8 @@ var that = {}, // Public API methods
|
|||
//['JPEG_quality_hi', -23 ],
|
||||
//['compress_lo', -255 ],
|
||||
['compress_hi', -247 ],
|
||||
['last_rect', -224 ]
|
||||
['last_rect', -224 ],
|
||||
['xvp', -309 ]
|
||||
],
|
||||
|
||||
encHandlers = {},
|
||||
|
|
@ -138,6 +141,7 @@ Util.conf_defaults(conf, that, defaults, [
|
|||
['local_cursor', 'rw', 'bool', false, 'Request locally rendered cursor'],
|
||||
['shared', 'rw', 'bool', true, 'Request shared mode'],
|
||||
['view_only', 'rw', 'bool', false, 'Disable client mouse/keyboard'],
|
||||
['xvp_password_sep', 'rw', 'str', '@', 'Separator for XVP password fields'],
|
||||
|
||||
['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'],
|
||||
['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'],
|
||||
|
|
@ -164,6 +168,8 @@ Util.conf_defaults(conf, that, defaults, [
|
|||
'onFBResize(rfb, width, height): frame buffer resized'],
|
||||
['onDesktopName', 'rw', 'func', function() { },
|
||||
'onDesktopName(rfb, name): desktop name received'],
|
||||
['onXvpInit', 'rw', 'func', function() { },
|
||||
'onXvpInit(version): XVP extensions active for this connection'],
|
||||
|
||||
// These callback names are deprecated
|
||||
['updateState', 'rw', 'func', function() { },
|
||||
|
|
@ -644,7 +650,8 @@ init_msg = function() {
|
|||
var strlen, reason, length, sversion, cversion, repeaterID,
|
||||
i, types, num_types, challenge, response, bpp, depth,
|
||||
big_endian, red_max, green_max, blue_max, red_shift,
|
||||
green_shift, blue_shift, true_color, name_length, is_repeater;
|
||||
green_shift, blue_shift, true_color, name_length, is_repeater,
|
||||
xvp_sep, xvp_auth, xvp_auth_str;
|
||||
|
||||
//Util.Debug("ws.rQ (" + ws.rQlen() + ") " + ws.rQslice(0));
|
||||
switch (rfb_state) {
|
||||
|
|
@ -709,7 +716,7 @@ init_msg = function() {
|
|||
types = ws.rQshiftBytes(num_types);
|
||||
Util.Debug("Server security types: " + types);
|
||||
for (i=0; i < types.length; i+=1) {
|
||||
if ((types[i] > rfb_auth_scheme) && (types[i] < 3)) {
|
||||
if ((types[i] > rfb_auth_scheme) && (types[i] < 3 || types[i] == 22)) {
|
||||
rfb_auth_scheme = types[i];
|
||||
}
|
||||
}
|
||||
|
|
@ -744,6 +751,23 @@ init_msg = function() {
|
|||
}
|
||||
// Fall through to ClientInitialisation
|
||||
break;
|
||||
case 22: // XVP authentication
|
||||
xvp_sep = conf.xvp_password_sep;
|
||||
xvp_auth = rfb_password.split(xvp_sep);
|
||||
if (xvp_auth.length < 3) {
|
||||
updateState('password', "XVP credentials required (user" + xvp_sep +
|
||||
"target" + xvp_sep + "password) -- got only " + rfb_password);
|
||||
conf.onPasswordRequired(that);
|
||||
return;
|
||||
}
|
||||
xvp_auth_str = String.fromCharCode(xvp_auth[0].length) +
|
||||
String.fromCharCode(xvp_auth[1].length) +
|
||||
xvp_auth[0] +
|
||||
xvp_auth[1];
|
||||
ws.send_string(xvp_auth_str);
|
||||
rfb_password = xvp_auth.slice(2).join(xvp_sep);
|
||||
rfb_auth_scheme = 2;
|
||||
// Fall through to standard VNC authentication with remaining part of password
|
||||
case 2: // VNC authentication
|
||||
if (rfb_password.length === 0) {
|
||||
// Notify via both callbacks since it is kind of
|
||||
|
|
@ -896,7 +920,8 @@ normal_msg = function() {
|
|||
//Util.Debug(">> normal_msg");
|
||||
|
||||
var ret = true, msg_type, length, text,
|
||||
c, first_colour, num_colours, red, green, blue;
|
||||
c, first_colour, num_colours, red, green, blue,
|
||||
xvp_ver, xvp_msg;
|
||||
|
||||
if (FBU.rects > 0) {
|
||||
msg_type = 0;
|
||||
|
|
@ -946,6 +971,24 @@ normal_msg = function() {
|
|||
conf.clipboardReceive(that, text); // Obsolete
|
||||
conf.onClipboard(that, text);
|
||||
break;
|
||||
case 250: // XVP
|
||||
ws.rQshift8(); // Padding
|
||||
xvp_ver = ws.rQshift8();
|
||||
xvp_msg = ws.rQshift8();
|
||||
switch (xvp_msg) {
|
||||
case 0: // XVP_FAIL
|
||||
updateState(rfb_state, "Operation failed");
|
||||
break;
|
||||
case 1: // XVP_INIT
|
||||
rfb_xvp_ver = xvp_ver;
|
||||
Util.Info("XVP extensions enabled (version " + rfb_xvp_ver + ")");
|
||||
conf.onXvpInit(rfb_xvp_ver);
|
||||
break;
|
||||
default:
|
||||
fail("Disconnected: illegal server XVP message " + xvp_msg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fail("Disconnected: illegal server message type " + msg_type);
|
||||
Util.Debug("ws.rQslice(0,30):" + ws.rQslice(0,30));
|
||||
|
|
@ -1800,6 +1843,25 @@ that.sendCtrlAltDel = function() {
|
|||
ws.send(arr);
|
||||
};
|
||||
|
||||
that.xvpOp = function(ver, op) {
|
||||
if (rfb_xvp_ver < ver) { return false; }
|
||||
Util.Info("Sending XVP operation " + op + " (version " + ver + ")")
|
||||
ws.send_string("\xFA\x00" + String.fromCharCode(ver) + String.fromCharCode(op));
|
||||
return true;
|
||||
};
|
||||
|
||||
that.xvpShutdown = function() {
|
||||
return that.xvpOp(1, 2);
|
||||
};
|
||||
|
||||
that.xvpReboot = function() {
|
||||
return that.xvpOp(1, 3);
|
||||
};
|
||||
|
||||
that.xvpReset = function() {
|
||||
return that.xvpOp(1, 4);
|
||||
};
|
||||
|
||||
// Send a key press. If 'down' is not specified then send a down key
|
||||
// followed by an up key.
|
||||
that.sendKey = function(code, down) {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ start: function(callback) {
|
|||
|
||||
UI.rfb = RFB({'target': $D('noVNC_canvas'),
|
||||
'onUpdateState': UI.updateState,
|
||||
'onXvpInit': UI.updateXvpVisualState,
|
||||
'onClipboard': UI.clipReceive,
|
||||
'onDesktopName': UI.updateDocumentTitle});
|
||||
|
||||
|
|
@ -185,8 +186,12 @@ addMouseHandlers: function() {
|
|||
$D("sendEscButton").onclick = UI.sendEsc;
|
||||
|
||||
$D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel;
|
||||
$D("xvpShutdownButton").onclick = UI.xvpShutdown;
|
||||
$D("xvpRebootButton").onclick = UI.xvpReboot;
|
||||
$D("xvpResetButton").onclick = UI.xvpReset;
|
||||
$D("noVNC_status").onclick = UI.togglePopupStatusPanel;
|
||||
$D("noVNC_popup_status_panel").onclick = UI.togglePopupStatusPanel;
|
||||
$D("xvpButton").onclick = UI.toggleXvpPanel;
|
||||
$D("clipboardButton").onclick = UI.toggleClipboardPanel;
|
||||
$D("settingsButton").onclick = UI.toggleSettingsPanel;
|
||||
$D("connectButton").onclick = UI.toggleConnectPanel;
|
||||
|
|
@ -303,6 +308,39 @@ togglePopupStatusPanel: function() {
|
|||
}
|
||||
},
|
||||
|
||||
// Show the XVP panel
|
||||
toggleXvpPanel: function() {
|
||||
// Close the description panel
|
||||
$D('noVNC_description').style.display = "none";
|
||||
// Close settings if open
|
||||
if (UI.settingsOpen === true) {
|
||||
UI.settingsApply();
|
||||
UI.closeSettingsMenu();
|
||||
}
|
||||
// Close connection settings if open
|
||||
if (UI.connSettingsOpen === true) {
|
||||
UI.toggleConnectPanel();
|
||||
}
|
||||
// Close popup status panel if open
|
||||
if (UI.popupStatusOpen === true) {
|
||||
UI.togglePopupStatusPanel();
|
||||
}
|
||||
// Close clipboard panel if open
|
||||
if (UI.clipboardOpen === true) {
|
||||
UI.toggleClipboardPanel();
|
||||
}
|
||||
// Toggle XVP panel
|
||||
if (UI.xvpOpen === true) {
|
||||
$D('noVNC_xvp').style.display = "none";
|
||||
$D('xvpButton').className = "noVNC_status_button";
|
||||
UI.xvpOpen = false;
|
||||
} else {
|
||||
$D('noVNC_xvp').style.display = "block";
|
||||
$D('xvpButton').className = "noVNC_status_button_selected";
|
||||
UI.xvpOpen = true;
|
||||
}
|
||||
},
|
||||
|
||||
// Show the clipboard panel
|
||||
toggleClipboardPanel: function() {
|
||||
// Close the description panel
|
||||
|
|
@ -320,6 +358,10 @@ toggleClipboardPanel: function() {
|
|||
if (UI.popupStatusOpen === true) {
|
||||
UI.togglePopupStatusPanel();
|
||||
}
|
||||
// Close XVP panel if open
|
||||
if (UI.xvpOpen === true) {
|
||||
UI.toggleXvpPanel();
|
||||
}
|
||||
// Toggle Clipboard Panel
|
||||
if (UI.clipboardOpen === true) {
|
||||
$D('noVNC_clipboard').style.display = "none";
|
||||
|
|
@ -350,6 +392,10 @@ toggleConnectPanel: function() {
|
|||
if (UI.popupStatusOpen === true) {
|
||||
UI.togglePopupStatusPanel();
|
||||
}
|
||||
// Close XVP panel if open
|
||||
if (UI.xvpOpen === true) {
|
||||
UI.toggleXvpPanel();
|
||||
}
|
||||
|
||||
// Toggle Connection Panel
|
||||
if (UI.connSettingsOpen === true) {
|
||||
|
|
@ -414,6 +460,10 @@ openSettingsMenu: function() {
|
|||
if (UI.popupStatusOpen === true) {
|
||||
UI.togglePopupStatusPanel();
|
||||
}
|
||||
// Close XVP panel if open
|
||||
if (UI.xvpOpen === true) {
|
||||
UI.toggleXvpPanel();
|
||||
}
|
||||
$D('noVNC_settings').style.display = "block";
|
||||
$D('settingsButton').className = "noVNC_status_button_selected";
|
||||
UI.settingsOpen = true;
|
||||
|
|
@ -467,6 +517,18 @@ sendCtrlAltDel: function() {
|
|||
UI.rfb.sendCtrlAltDel();
|
||||
},
|
||||
|
||||
xvpShutdown: function() {
|
||||
UI.rfb.xvpShutdown();
|
||||
},
|
||||
|
||||
xvpReboot: function() {
|
||||
UI.rfb.xvpReboot();
|
||||
},
|
||||
|
||||
xvpReset: function() {
|
||||
UI.rfb.xvpReset();
|
||||
},
|
||||
|
||||
setMouseButton: function(num) {
|
||||
var b, blist = [0, 1,2,4], button;
|
||||
|
||||
|
|
@ -566,6 +628,7 @@ updateVisualState: function() {
|
|||
$D('showKeyboard').style.display = "none";
|
||||
$D('noVNC_extra_keys').style.display = "none";
|
||||
$D('sendCtrlAltDelButton').style.display = "none";
|
||||
UI.updateXvpVisualState(0);
|
||||
}
|
||||
|
||||
// State change disables viewport dragging.
|
||||
|
|
@ -589,6 +652,19 @@ updateVisualState: function() {
|
|||
//Util.Debug("<< updateVisualState");
|
||||
},
|
||||
|
||||
// Disable/enable XVP button
|
||||
updateXvpVisualState: function(ver) {
|
||||
if (ver >= 1) {
|
||||
$D('xvpButton').style.display = 'inline';
|
||||
} else {
|
||||
$D('xvpButton').style.display = 'none';
|
||||
// Close XVP panel if open
|
||||
if (UI.xvpOpen === true) {
|
||||
UI.toggleXvpPanel();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Display the desktop name in the document title
|
||||
updateDocumentTitle: function(rfb, name) {
|
||||
|
|
|
|||
12
vnc.html
12
vnc.html
|
|
@ -95,6 +95,9 @@
|
|||
<input type="image" src="images/ctrlaltdel.png"
|
||||
id="sendCtrlAltDelButton" class="noVNC_status_button"
|
||||
title="Send Ctrl-Alt-Del" />
|
||||
<input type="image" src="images/power.png"
|
||||
id="xvpButton" class="noVNC_status_button"
|
||||
title="Shutdown/Reboot..." />
|
||||
<input type="image" src="images/clipboard.png"
|
||||
id="clipboardButton" class="noVNC_status_button"
|
||||
title="Clipboard" />
|
||||
|
|
@ -138,6 +141,15 @@
|
|||
value="Clear">
|
||||
</div>
|
||||
|
||||
<!-- XVP Shutdown/Reboot Panel -->
|
||||
<div id="noVNC_xvp" class="triangle-right top">
|
||||
<span id="noVNC_xvp_menu">
|
||||
<input type="button" id="xvpShutdownButton" value="Shutdown" />
|
||||
<input type="button" id="xvpRebootButton" value="Reboot" />
|
||||
<input type="button" id="xvpResetButton" value="Reset" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Settings Panel -->
|
||||
<div id="noVNC_settings" class="triangle-right top">
|
||||
<span id="noVNC_settings_menu">
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@
|
|||
<td width="1%"><div id="noVNC_buttons">
|
||||
<input type=button value="Send CtrlAltDel"
|
||||
id="sendCtrlAltDelButton">
|
||||
<span id="noVNC_xvp_buttons">
|
||||
<input type=button value="Shutdown"
|
||||
id="xvpShutdownButton">
|
||||
<input type=button value="Reboot"
|
||||
id="xvpRebootButton">
|
||||
<input type=button value="Reset"
|
||||
id="xvpResetButton">
|
||||
</span>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
|
@ -91,6 +99,18 @@
|
|||
rfb.sendCtrlAltDel();
|
||||
return false;
|
||||
}
|
||||
function xvpShutdown() {
|
||||
rfb.xvpShutdown();
|
||||
return false;
|
||||
}
|
||||
function xvpReboot() {
|
||||
rfb.xvpReboot();
|
||||
return false;
|
||||
}
|
||||
function xvpReset() {
|
||||
rfb.xvpReset();
|
||||
return false;
|
||||
}
|
||||
function updateState(rfb, state, oldstate, msg) {
|
||||
var s, sb, cad, level;
|
||||
s = $D('noVNC_status');
|
||||
|
|
@ -105,8 +125,12 @@
|
|||
default: level = "warn"; break;
|
||||
}
|
||||
|
||||
if (state === "normal") { cad.disabled = false; }
|
||||
else { cad.disabled = true; }
|
||||
if (state === "normal") {
|
||||
cad.disabled = false;
|
||||
} else {
|
||||
cad.disabled = true;
|
||||
xvpInit(0);
|
||||
}
|
||||
|
||||
if (typeof(msg) !== 'undefined') {
|
||||
sb.setAttribute("class", "noVNC_status_" + level);
|
||||
|
|
@ -114,11 +138,24 @@
|
|||
}
|
||||
}
|
||||
|
||||
function xvpInit(ver) {
|
||||
var xvpbuttons;
|
||||
xvpbuttons = $D('noVNC_xvp_buttons');
|
||||
if (ver >= 1) {
|
||||
xvpbuttons.style.display = 'inline';
|
||||
} else {
|
||||
xvpbuttons.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
window.onscriptsload = function () {
|
||||
var host, port, password, path, token;
|
||||
|
||||
$D('sendCtrlAltDelButton').style.display = "inline";
|
||||
$D('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
|
||||
$D('xvpShutdownButton').onclick = xvpShutdown;
|
||||
$D('xvpRebootButton').onclick = xvpReboot;
|
||||
$D('xvpResetButton').onclick = xvpReset;
|
||||
|
||||
WebUtil.init_logging(WebUtil.getQueryVar('logging', 'warn'));
|
||||
document.title = unescape(WebUtil.getQueryVar('title', 'noVNC'));
|
||||
|
|
@ -162,6 +199,7 @@
|
|||
'shared': WebUtil.getQueryVar('shared', true),
|
||||
'view_only': WebUtil.getQueryVar('view_only', false),
|
||||
'updateState': updateState,
|
||||
'onXvpInit': xvpInit,
|
||||
'onPasswordRequired': passwordRequired});
|
||||
rfb.connect(host, port, password, path);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue