Make power API generic
Decouple it from XVP and make it a generic API.
This commit is contained in:
parent
85b35fc0cc
commit
cd523e8f28
|
@ -591,17 +591,17 @@ select:active {
|
|||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* XVP Shutdown/Reboot */
|
||||
:root:not(.noVNC_connected) #noVNC_xvp_button {
|
||||
/* Shutdown/Reboot */
|
||||
:root:not(.noVNC_connected) #noVNC_power_button {
|
||||
display: none;
|
||||
}
|
||||
#noVNC_xvp {
|
||||
#noVNC_power {
|
||||
}
|
||||
#noVNC_xvp_buttons {
|
||||
#noVNC_power_buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#noVNC_xvp input[type=button] {
|
||||
#noVNC_power input[type=button] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
|
66
app/ui.js
66
app/ui.js
|
@ -91,7 +91,7 @@ var UI = {
|
|||
UI.addControlbarHandlers();
|
||||
UI.addTouchSpecificHandlers();
|
||||
UI.addExtraKeysHandlers();
|
||||
UI.addXvpHandlers();
|
||||
UI.addMachineHandlers();
|
||||
UI.addConnectionControlHandlers();
|
||||
UI.addClipboardHandlers();
|
||||
UI.addSettingsHandlers();
|
||||
|
@ -207,7 +207,7 @@ var UI = {
|
|||
'onUpdateState': UI.updateState,
|
||||
'onDisconnected': UI.disconnectFinished,
|
||||
'onCredentialsRequired': UI.credentials,
|
||||
'onXvpInit': UI.updateXvpButton,
|
||||
'onCapabilities': UI.updatePowerButton,
|
||||
'onClipboard': UI.clipboardReceive,
|
||||
'onBell': UI.bell,
|
||||
'onFBUComplete': UI.initialResize,
|
||||
|
@ -332,15 +332,15 @@ var UI = {
|
|||
.addEventListener('click', UI.sendCtrlAltDel);
|
||||
},
|
||||
|
||||
addXvpHandlers: function() {
|
||||
document.getElementById("noVNC_xvp_shutdown_button")
|
||||
.addEventListener('click', function() { UI.rfb.xvpShutdown(); });
|
||||
document.getElementById("noVNC_xvp_reboot_button")
|
||||
.addEventListener('click', function() { UI.rfb.xvpReboot(); });
|
||||
document.getElementById("noVNC_xvp_reset_button")
|
||||
.addEventListener('click', function() { UI.rfb.xvpReset(); });
|
||||
document.getElementById("noVNC_xvp_button")
|
||||
.addEventListener('click', UI.toggleXvpPanel);
|
||||
addMachineHandlers: function() {
|
||||
document.getElementById("noVNC_shutdown_button")
|
||||
.addEventListener('click', function() { UI.rfb.machineShutdown(); });
|
||||
document.getElementById("noVNC_reboot_button")
|
||||
.addEventListener('click', function() { UI.rfb.machineReboot(); });
|
||||
document.getElementById("noVNC_reset_button")
|
||||
.addEventListener('click', function() { UI.rfb.machineReset(); });
|
||||
document.getElementById("noVNC_power_button")
|
||||
.addEventListener('click', UI.togglePowerPanel);
|
||||
},
|
||||
|
||||
addConnectionControlHandlers: function() {
|
||||
|
@ -489,7 +489,7 @@ var UI = {
|
|||
UI.enableSetting('port');
|
||||
UI.enableSetting('path');
|
||||
UI.enableSetting('repeaterID');
|
||||
UI.updateXvpButton(0);
|
||||
UI.updatePowerButton();
|
||||
UI.keepControlbar();
|
||||
}
|
||||
|
||||
|
@ -868,7 +868,7 @@ var UI = {
|
|||
|
||||
closeAllPanels: function() {
|
||||
UI.closeSettingsPanel();
|
||||
UI.closeXvpPanel();
|
||||
UI.closePowerPanel();
|
||||
UI.closeClipboardPanel();
|
||||
UI.closeExtraKeys();
|
||||
},
|
||||
|
@ -926,50 +926,52 @@ var UI = {
|
|||
/* ------^-------
|
||||
* /SETTINGS
|
||||
* ==============
|
||||
* XVP
|
||||
* POWER
|
||||
* ------v------*/
|
||||
|
||||
openXvpPanel: function() {
|
||||
openPowerPanel: function() {
|
||||
UI.closeAllPanels();
|
||||
UI.openControlbar();
|
||||
|
||||
document.getElementById('noVNC_xvp')
|
||||
document.getElementById('noVNC_power')
|
||||
.classList.add("noVNC_open");
|
||||
document.getElementById('noVNC_xvp_button')
|
||||
document.getElementById('noVNC_power_button')
|
||||
.classList.add("noVNC_selected");
|
||||
},
|
||||
|
||||
closeXvpPanel: function() {
|
||||
document.getElementById('noVNC_xvp')
|
||||
closePowerPanel: function() {
|
||||
document.getElementById('noVNC_power')
|
||||
.classList.remove("noVNC_open");
|
||||
document.getElementById('noVNC_xvp_button')
|
||||
document.getElementById('noVNC_power_button')
|
||||
.classList.remove("noVNC_selected");
|
||||
},
|
||||
|
||||
toggleXvpPanel: function() {
|
||||
if (document.getElementById('noVNC_xvp')
|
||||
togglePowerPanel: function() {
|
||||
if (document.getElementById('noVNC_power')
|
||||
.classList.contains("noVNC_open")) {
|
||||
UI.closeXvpPanel();
|
||||
UI.closePowerPanel();
|
||||
} else {
|
||||
UI.openXvpPanel();
|
||||
UI.openPowerPanel();
|
||||
}
|
||||
},
|
||||
|
||||
// Disable/enable XVP button
|
||||
updateXvpButton: function(ver) {
|
||||
if (ver >= 1 && !UI.rfb.get_view_only()) {
|
||||
document.getElementById('noVNC_xvp_button')
|
||||
// Disable/enable power button
|
||||
updatePowerButton: function() {
|
||||
if (UI.connected &&
|
||||
UI.rfb.get_capabilities().power &&
|
||||
!UI.rfb.get_view_only()) {
|
||||
document.getElementById('noVNC_power_button')
|
||||
.classList.remove("noVNC_hidden");
|
||||
} else {
|
||||
document.getElementById('noVNC_xvp_button')
|
||||
document.getElementById('noVNC_power_button')
|
||||
.classList.add("noVNC_hidden");
|
||||
// Close XVP panel if open
|
||||
UI.closeXvpPanel();
|
||||
// Close power panel if open
|
||||
UI.closePowerPanel();
|
||||
}
|
||||
},
|
||||
|
||||
/* ------^-------
|
||||
* /XVP
|
||||
* /POWER
|
||||
* ==============
|
||||
* CLIPBOARD
|
||||
* ------v------*/
|
||||
|
|
37
core/rfb.js
37
core/rfb.js
|
@ -49,6 +49,8 @@ export default function RFB(defaults) {
|
|||
this._rfb_tightvnc = false;
|
||||
this._rfb_xvp_ver = 0;
|
||||
|
||||
this._capabilities = { power: false };
|
||||
|
||||
this._encHandlers = {};
|
||||
this._encStats = {};
|
||||
|
||||
|
@ -140,7 +142,7 @@ export default function RFB(defaults) {
|
|||
'onFBUComplete': function () { }, // onFBUComplete(rfb): RFB FBU received and processed
|
||||
'onFBResize': function () { }, // onFBResize(rfb, width, height): frame buffer resized
|
||||
'onDesktopName': function () { }, // onDesktopName(rfb, name): desktop name received
|
||||
'onXvpInit': function () { } // onXvpInit(version): XVP extensions active for this connection
|
||||
'onCapabilities': function () { } // onCapabilities(rfb, caps): the supported capabilities has changed
|
||||
});
|
||||
|
||||
// main setup
|
||||
|
@ -282,23 +284,16 @@ RFB.prototype = {
|
|||
return true;
|
||||
},
|
||||
|
||||
xvpOp: function (ver, op) {
|
||||
if (this._rfb_xvp_ver < ver) { return false; }
|
||||
Log.Info("Sending XVP operation " + op + " (version " + ver + ")");
|
||||
RFB.messages.xvpOp(this._sock, ver, op);
|
||||
return true;
|
||||
machineShutdown: function () {
|
||||
this._xvpOp(1, 2);
|
||||
},
|
||||
|
||||
xvpShutdown: function () {
|
||||
return this.xvpOp(1, 2);
|
||||
machineReboot: function () {
|
||||
this._xvpOp(1, 3);
|
||||
},
|
||||
|
||||
xvpReboot: function () {
|
||||
return this.xvpOp(1, 3);
|
||||
},
|
||||
|
||||
xvpReset: function () {
|
||||
return this.xvpOp(1, 4);
|
||||
machineReset: function () {
|
||||
this._xvpOp(1, 4);
|
||||
},
|
||||
|
||||
// Send a key press. If 'down' is not specified then send a down key
|
||||
|
@ -1282,7 +1277,8 @@ RFB.prototype = {
|
|||
case 1: // XVP_INIT
|
||||
this._rfb_xvp_ver = xvp_ver;
|
||||
Log.Info("XVP extensions enabled (version " + this._rfb_xvp_ver + ")");
|
||||
this._onXvpInit(this._rfb_xvp_ver);
|
||||
this._capabilities.power = true;
|
||||
this._onCapabilities(this, this._capabilities)
|
||||
break;
|
||||
default:
|
||||
this._fail("Unexpected server message",
|
||||
|
@ -1480,7 +1476,13 @@ RFB.prototype = {
|
|||
|
||||
this._timing.fbu_rt_start = (new Date()).getTime();
|
||||
this._updateContinuousUpdates();
|
||||
}
|
||||
},
|
||||
|
||||
_xvpOp: function (ver, op) {
|
||||
if (this._rfb_xvp_ver < ver) { return; }
|
||||
Log.Info("Sending XVP operation " + op + " (version " + ver + ")");
|
||||
RFB.messages.xvpOp(this._sock, ver, op);
|
||||
},
|
||||
};
|
||||
|
||||
make_properties(RFB, [
|
||||
|
@ -1496,6 +1498,7 @@ make_properties(RFB, [
|
|||
['wsProtocols', 'rw', 'arr'], // Protocols to use in the WebSocket connection
|
||||
['repeaterID', 'rw', 'str'], // [UltraVNC] RepeaterID to connect to
|
||||
['viewportDrag', 'rw', 'bool'], // Move the viewport on mouse drags
|
||||
['capabilities', 'ro', 'arr'], // Supported capabilities
|
||||
|
||||
// Callback functions
|
||||
['onUpdateState', 'rw', 'func'], // onUpdateState(rfb, state, oldstate): connection state change
|
||||
|
@ -1508,7 +1511,7 @@ make_properties(RFB, [
|
|||
['onFBUComplete', 'rw', 'func'], // onFBUComplete(rfb, fbu): RFB FBU received and processed
|
||||
['onFBResize', 'rw', 'func'], // onFBResize(rfb, width, height): frame buffer resized
|
||||
['onDesktopName', 'rw', 'func'], // onDesktopName(rfb, name): desktop name received
|
||||
['onXvpInit', 'rw', 'func'] // onXvpInit(version): XVP extensions active for this connection
|
||||
['onCapabilities', 'rw', 'func'] // onCapabilities(rfb, caps): the supported capabilities has changed
|
||||
]);
|
||||
|
||||
RFB.prototype.set_local_cursor = function (cursor) {
|
||||
|
|
10
docs/API.md
10
docs/API.md
|
@ -41,6 +41,7 @@ attribute mode is one of the following:
|
|||
| wsProtocols | arr | RW | ['binary'] | Protocols to use in the WebSocket connection
|
||||
| repeaterID | str | RW | '' | UltraVNC RepeaterID to connect to
|
||||
| viewportDrag | bool | RW | false | Move the viewport on mouse drags
|
||||
| capabilities | arr | RO | [] | Supported capabilities (can include: 'power')
|
||||
|
||||
|
||||
## 2 Methods
|
||||
|
@ -55,10 +56,9 @@ object instance.
|
|||
| disconnect | () | Disconnect
|
||||
| sendCredentials | (credentials) | Send credentials after onCredentialsRequired callback
|
||||
| sendCtrlAltDel | () | Send Ctrl-Alt-Del key sequence
|
||||
| xvpOp | (ver, op) | Send a XVP operation (2=shutdown, 3=reboot, 4=reset)
|
||||
| xvpShutdown | () | Send XVP shutdown.
|
||||
| xvpReboot | () | Send XVP reboot.
|
||||
| xvpReset | () | Send XVP reset.
|
||||
| machineShutdown | () | Request a shutdown of the remote machine.
|
||||
| machineReboot | () | Request a reboot of the remote machine.
|
||||
| machineReset | () | Request a reset of the remote machine.
|
||||
| sendKey | (keysym, code, down) | Send a key press event. If down not specified, send a down and up event.
|
||||
| clipboardPasteFrom | (text) | Send a clipboard paste event
|
||||
| autoscale | (width, height, downscaleOnly) | Scale the display
|
||||
|
@ -84,7 +84,7 @@ functions.
|
|||
| onFBUComplete | (rfb, fbu) | RFB FBU received and processed (see details below)
|
||||
| onFBResize | (rfb, width, height) | Frame buffer (remote desktop) size changed
|
||||
| onDesktopName | (rfb, name) | VNC desktop name recieved
|
||||
| onXvpInit | (version) | XVP extensions active for this connection.
|
||||
| onCapabilities | (rfb, capabilities) | The supported capabilities has changed
|
||||
|
||||
|
||||
__RFB onUpdateState callback details__
|
||||
|
|
|
@ -300,28 +300,23 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
|||
client._rfb_xvp_ver = 1;
|
||||
});
|
||||
|
||||
it('should send the shutdown signal on #xvpShutdown', function () {
|
||||
client.xvpShutdown();
|
||||
it('should send the shutdown signal on #machineShutdown', function () {
|
||||
client.machineShutdown();
|
||||
expect(client._sock).to.have.sent(new Uint8Array([0xFA, 0x00, 0x01, 0x02]));
|
||||
});
|
||||
|
||||
it('should send the reboot signal on #xvpReboot', function () {
|
||||
client.xvpReboot();
|
||||
it('should send the reboot signal on #machineReboot', function () {
|
||||
client.machineReboot();
|
||||
expect(client._sock).to.have.sent(new Uint8Array([0xFA, 0x00, 0x01, 0x03]));
|
||||
});
|
||||
|
||||
it('should send the reset signal on #xvpReset', function () {
|
||||
client.xvpReset();
|
||||
it('should send the reset signal on #machineReset', function () {
|
||||
client.machineReset();
|
||||
expect(client._sock).to.have.sent(new Uint8Array([0xFA, 0x00, 0x01, 0x04]));
|
||||
});
|
||||
|
||||
it('should support sending arbitrary XVP operations via #xvpOp', function () {
|
||||
client.xvpOp(1, 7);
|
||||
expect(client._sock).to.have.sent(new Uint8Array([0xFA, 0x00, 0x01, 0x07]));
|
||||
});
|
||||
|
||||
it('should not send XVP operations with higher versions than we support', function () {
|
||||
expect(client.xvpOp(2, 7)).to.be.false;
|
||||
client._xvpOp(2, 7);
|
||||
expect(client._sock.flush).to.not.have.been.called;
|
||||
});
|
||||
});
|
||||
|
@ -1800,11 +1795,11 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
|||
});
|
||||
|
||||
it('should set the XVP version and fire the callback with the version on XVP_INIT', function () {
|
||||
client.set_onXvpInit(sinon.spy());
|
||||
client.set_onCapabilities(sinon.spy());
|
||||
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 1]));
|
||||
expect(client._rfb_xvp_ver).to.equal(10);
|
||||
expect(client.get_onXvpInit()).to.have.been.calledOnce;
|
||||
expect(client.get_onXvpInit()).to.have.been.calledWith(10);
|
||||
expect(client.get_onCapabilities()).to.have.been.calledOnce;
|
||||
expect(client.get_onCapabilities()).to.have.been.calledWith(client, { power: true });
|
||||
});
|
||||
|
||||
it('should fail on unknown XVP message types', function () {
|
||||
|
|
12
vnc.html
12
vnc.html
|
@ -152,18 +152,18 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- XVP Shutdown/Reboot -->
|
||||
<!-- Shutdown/Reboot -->
|
||||
<input type="image" alt="Shutdown/Reboot" src="app/images/power.svg"
|
||||
id="noVNC_xvp_button" class="noVNC_button"
|
||||
id="noVNC_power_button" class="noVNC_button"
|
||||
title="Shutdown/Reboot..." />
|
||||
<div class="noVNC_vcenter">
|
||||
<div id="noVNC_xvp" class="noVNC_panel">
|
||||
<div id="noVNC_power" class="noVNC_panel">
|
||||
<div class="noVNC_heading">
|
||||
<img src="app/images/power.svg"> Power
|
||||
</div>
|
||||
<input type="button" id="noVNC_xvp_shutdown_button" value="Shutdown" />
|
||||
<input type="button" id="noVNC_xvp_reboot_button" value="Reboot" />
|
||||
<input type="button" id="noVNC_xvp_reset_button" value="Reset" />
|
||||
<input type="button" id="noVNC_shutdown_button" value="Shutdown" />
|
||||
<input type="button" id="noVNC_reboot_button" value="Reboot" />
|
||||
<input type="button" id="noVNC_reset_button" value="Reset" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -122,16 +122,16 @@
|
|||
rfb.sendCtrlAltDel();
|
||||
return false;
|
||||
}
|
||||
function xvpShutdown() {
|
||||
rfb.xvpShutdown();
|
||||
function machineShutdown() {
|
||||
rfb.machineShutdown();
|
||||
return false;
|
||||
}
|
||||
function xvpReboot() {
|
||||
rfb.xvpReboot();
|
||||
function machineReboot() {
|
||||
rfb.machineReboot();
|
||||
return false;
|
||||
}
|
||||
function xvpReset() {
|
||||
rfb.xvpReset();
|
||||
function machineReset() {
|
||||
rfb.machineReset();
|
||||
return false;
|
||||
}
|
||||
function status(text, level) {
|
||||
|
@ -176,7 +176,7 @@
|
|||
cad.disabled = false;
|
||||
} else {
|
||||
cad.disabled = true;
|
||||
xvpInit(0);
|
||||
updatePowerButtons();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -199,21 +199,21 @@
|
|||
}, 500);
|
||||
};
|
||||
|
||||
function xvpInit(ver) {
|
||||
var xvpbuttons;
|
||||
xvpbuttons = document.getElementById('noVNC_xvp_buttons');
|
||||
if (ver >= 1) {
|
||||
xvpbuttons.style.display = 'inline';
|
||||
function updatePowerButtons() {
|
||||
var powerbuttons;
|
||||
powerbuttons = document.getElementById('noVNC_power_buttons');
|
||||
if (rfb.get_capabilities().power) {
|
||||
powerbuttons.style.display = 'inline';
|
||||
} else {
|
||||
xvpbuttons.style.display = 'none';
|
||||
powerbuttons.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('sendCtrlAltDelButton').style.display = "inline";
|
||||
document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
|
||||
document.getElementById('xvpShutdownButton').onclick = xvpShutdown;
|
||||
document.getElementById('xvpRebootButton').onclick = xvpReboot;
|
||||
document.getElementById('xvpResetButton').onclick = xvpReset;
|
||||
document.getElementById('machineShutdownButton').onclick = machineShutdown;
|
||||
document.getElementById('machineRebootButton').onclick = machineReboot;
|
||||
document.getElementById('machineResetButton').onclick = machineReset;
|
||||
|
||||
WebUtil.init_logging(WebUtil.getConfigVar('logging', 'warn'));
|
||||
document.title = WebUtil.getConfigVar('title', 'noVNC');
|
||||
|
@ -262,7 +262,7 @@
|
|||
'onNotification': notification,
|
||||
'onUpdateState': updateState,
|
||||
'onDisconnected': disconnected,
|
||||
'onXvpInit': xvpInit,
|
||||
'onCapabilities': updatePowerButtons,
|
||||
'onCredentialsRequired': credentials,
|
||||
'onFBUComplete': FBUComplete,
|
||||
'onDesktopName': updateDesktopName});
|
||||
|
@ -286,13 +286,13 @@
|
|||
<td width="1%"><div id="noVNC_buttons">
|
||||
<input type=button value="Send CtrlAltDel"
|
||||
id="sendCtrlAltDelButton">
|
||||
<span id="noVNC_xvp_buttons">
|
||||
<span id="noVNC_power_buttons">
|
||||
<input type=button value="Shutdown"
|
||||
id="xvpShutdownButton">
|
||||
id="machineShutdownButton">
|
||||
<input type=button value="Reboot"
|
||||
id="xvpRebootButton">
|
||||
id="machineRebootButton">
|
||||
<input type=button value="Reset"
|
||||
id="xvpResetButton">
|
||||
id="machineResetButton">
|
||||
</span>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
|
|
Loading…
Reference in New Issue