]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Make power API generic
authorPierre Ossman <ossman@cendio.se>
Fri, 13 Oct 2017 12:25:26 +0000 (14:25 +0200)
committerPierre Ossman <ossman@cendio.se>
Thu, 9 Nov 2017 11:47:21 +0000 (12:47 +0100)
Decouple it from XVP and make it a generic API.

app/styles/base.css
app/ui.js
core/rfb.js
docs/API.md
tests/test.rfb.js
vnc.html
vnc_lite.html

index 790837a0f2c6b689bef22abace75a726a28878dd..b8ce81bd0f639ba725260a032d38081d109dc242 100644 (file)
@@ -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%;
 }
 
index 6e08172aaf0b3978de38fae8a8f81c7387278366..6f1690ec14a8d206388cc857bc748530c746838e 100644 (file)
--- a/app/ui.js
+++ b/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------*/
index 18380e7e7dced4b70fd3cce857097ebc683dcaef..5b66abb43d8df6839a234244cada1e5289a7d1dd 100644 (file)
@@ -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;
-    },
-
-    xvpShutdown: function () {
-        return this.xvpOp(1, 2);
+    machineShutdown: function () {
+        this._xvpOp(1, 2);
     },
 
-    xvpReboot: function () {
-        return this.xvpOp(1, 3);
+    machineReboot: function () {
+        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) {
index 9052daaf58dd4dfa3e7824c8c2df05d7d0013f26..92222e67c36c417005a6d6e01404ec45241e4d7c 100644 (file)
@@ -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__
index e4336f6f533ea36eb46c320ca04579fea780c6ca..f59a2fe341a79aae068303a11a52ccb846da321e 100644 (file)
@@ -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 () {
index 40d89c7f8ff8576b770043ef5e0e20e169243277..e2799d6eff9e75fc2c4a87b4674c48c9a15bdcc9 100644 (file)
--- a/vnc.html
+++ b/vnc.html
                 </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>
 
index 73aa426f5f6f0ecd491c6fdd8637feaa279d3492..e252aa5c252be1502188ecfe017d56f65d1642a8 100644 (file)
             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) {
                 cad.disabled = false;
             } else {
                 cad.disabled = true;
-                xvpInit(0);
+                updatePowerButtons();
             }
 
         }
             }, 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');
                                'onNotification':  notification,
                                'onUpdateState':  updateState,
                                'onDisconnected': disconnected,
-                               'onXvpInit':    xvpInit,
+                               'onCapabilities': updatePowerButtons,
                                'onCredentialsRequired': credentials,
                                'onFBUComplete': FBUComplete,
                                'onDesktopName': updateDesktopName});
                     <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>