From 2b738be8e672721efae06841dfd3badd4aa72a28 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Tue, 28 May 2024 14:41:15 +0200 Subject: [PATCH 01/19] Add UltraVNC touch gestures support --- app/ui.js | 7 +- core/encodings.js | 1 + core/input/touchhandlerultravnc.js | 112 ++++++++++++++++++ core/rfb.js | 184 +++++++++++++++++++++++++++-- vnc.html | 1 + 5 files changed, 297 insertions(+), 8 deletions(-) create mode 100644 core/input/touchhandlerultravnc.js diff --git a/app/ui.js b/app/ui.js index f27dfe28e..8c1098e4e 100644 --- a/app/ui.js +++ b/app/ui.js @@ -180,6 +180,7 @@ const UI = { UI.initSetting('shared', true); UI.initSetting('view_only', false); UI.initSetting('show_dot', false); + UI.initSetting('ultravnc_gestures', false); UI.initSetting('path', 'websockify'); UI.initSetting('repeaterID', ''); UI.initSetting('reconnect', false); @@ -368,6 +369,7 @@ const UI = { UI.addSettingChangeHandler('view_only', UI.updateViewOnly); UI.addSettingChangeHandler('show_dot'); UI.addSettingChangeHandler('show_dot', UI.updateShowDotCursor); + UI.addSettingChangeHandler('ultravnc_gestures'); UI.addSettingChangeHandler('host'); UI.addSettingChangeHandler('port'); UI.addSettingChangeHandler('path'); @@ -438,6 +440,7 @@ const UI = { UI.disableSetting('port'); UI.disableSetting('path'); UI.disableSetting('repeaterID'); + UI.disableSetting('ultravnc_gestures'); // Hide the controlbar after 2 seconds UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000); @@ -448,6 +451,7 @@ const UI = { UI.enableSetting('port'); UI.enableSetting('path'); UI.enableSetting('repeaterID'); + UI.enableSetting('ultravnc_gestures'); UI.updatePowerButton(); UI.keepControlbar(); } @@ -1045,7 +1049,8 @@ const UI = { UI.rfb = new RFB(document.getElementById('noVNC_container'), url, { shared: UI.getSetting('shared'), repeaterID: UI.getSetting('repeaterID'), - credentials: { password: password } }); + credentials: { password: password }, + useUltraVNCGestures: UI.getSetting('ultravnc_gestures') }); } catch (exc) { Log.Error("Failed to connect to server: " + exc); UI.updateVisualState('disconnected'); diff --git a/core/encodings.js b/core/encodings.js index 1a79989d1..1e43738b6 100644 --- a/core/encodings.js +++ b/core/encodings.js @@ -23,6 +23,7 @@ export const encodings = { pseudoEncodingCursor: -239, pseudoEncodingQEMUExtendedKeyEvent: -258, pseudoEncodingQEMULedEvent: -261, + pseudoEncodingGii: -305, pseudoEncodingDesktopName: -307, pseudoEncodingExtendedDesktopSize: -308, pseudoEncodingXvp: -309, diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js new file mode 100644 index 000000000..c9ccac919 --- /dev/null +++ b/core/input/touchhandlerultravnc.js @@ -0,0 +1,112 @@ +import * as Log from '../util/logging.js'; + +export default class TouchHandlerUltraVNC { + static PF_flag = 0x80000000; // Pressed Flag : active if the touch event is pressed, inactive if it's being released. + static R1_flag = 0x40000000; // Reserved 1 + static IF_flag = 0x20000000; // Primary Flag : active if the touch event is the primary touch event. + static S1_flag = 0x10000000; // Size Flag : active if the message contains information about the size of the touch event. The events are currently all sent as symetrical ellipses. + static S2_flag = 0x8000000; // Reserved for asymetrical ellipses. Not supported yet and should be 0. + static RT_flag = 0x4000000; // Rectangle : the touch event is a rectangle instead of an ellipse. + static PR_flag = 0x2000000; // Pressure Flag : pressure of the touch. Currently unused. + static TI_flag = 0x1000000; // Timestamp : the timestamp of the touch event. + static HC_flag = 0x800000; // High Performance Counter + + static LENGTH_16_flag = 0x10; // 16 bits signed for x touch coordinate followed by 16 bits signed for y together in a 32 bits word + static IDFORMAT_32 = 0x1; // 32 bits ID + static IDFORMAT_CLEAR = 0xF; // No more touch points + + constructor() { + this._target = null; + + this._currentTouches = []; + this._sendTouchesIntervalId = -1; + this._giiDeviceOrigin = 0; + this._isUltraVNCTouchActivated = false; + + this._boundEventHandler = this._handleTouch.bind(this); + } + + attach(target) { + this.detach(); + + this._target = target; + this._target.addEventListener('touchstart', + this._boundEventHandler); + this._target.addEventListener('touchmove', + this._boundEventHandler); + this._target.addEventListener('touchend', + this._boundEventHandler); + this._target.addEventListener('touchcancel', + this._boundEventHandler); + } + + detach() { + if (!this._target) { + return; + } + + this._target.removeEventListener('touchstart', + this._boundEventHandler); + this._target.removeEventListener('touchmove', + this._boundEventHandler); + this._target.removeEventListener('touchend', + this._boundEventHandler); + this._target.removeEventListener('touchcancel', + this._boundEventHandler); + + clearInterval(this._sendTouchesIntervalId); + this._sendTouchesIntervalId = -1; + + this._target = null; + } + + _handleTouch(ev) { + Log.Debug("Gesture: " + ev.type); + + if (!this._isUltraVNCTouchActivated) { + return; + } + + if (ev.type === "touchstart") { + for (let i = 0; i < ev.changedTouches.length; i++) { + this._currentTouches.push({ event: ev.changedTouches[i], status: "POINTER_DOWN" }); + } + + if (this._sendTouchesIntervalId === -1 && this._target) { + this._dispatchTouchEvent(ev); + this._sendTouchesIntervalId = setInterval(() => { + this._dispatchTouchEvent(ev); + }, 200); + } + } else if (ev.type === "touchmove") { + for (let i = 0; i < ev.changedTouches.length; i++) { + const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); + if (index !== -1) { + this._currentTouches[index].event = ev.changedTouches[i]; + this._currentTouches[index].status = "POINTER_UPDATE"; + } + } + } else if (ev.type === "touchend" || ev.type === "touchcancel") { + for (let i = 0; i < ev.changedTouches.length; i++) { + const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); + if (index !== -1) { + this._currentTouches[index].status = "POINTER_UP"; + } + } + } + } + + _dispatchTouchEvent(ev) { + let tev = new CustomEvent('ultravnctouch', { event: ev, detail: { currentTouches: this._currentTouches, giiDeviceOrigin: this._giiDeviceOrigin } }); + this._target.dispatchEvent(tev); + } + + _removeTouch(index) { + this._currentTouches.splice(index, 1); + } + + _interruptTouches() { + clearInterval(this._sendTouchesIntervalId); + this._sendTouchesIntervalId = -1; + } +} \ No newline at end of file diff --git a/core/rfb.js b/core/rfb.js index f2deb0e7b..b45b51727 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -19,6 +19,7 @@ import Inflator from "./inflator.js"; import Deflator from "./deflator.js"; import Keyboard from "./input/keyboard.js"; import GestureHandler from "./input/gesturehandler.js"; +import TouchHandlerUltraVNC from "./input/touchhandlerultravnc.js"; import Cursor from "./util/cursor.js"; import Websock from "./websock.js"; import KeyTable from "./input/keysym.js"; @@ -117,6 +118,7 @@ export default class RFB extends EventTargetMixin { this._shared = 'shared' in options ? !!options.shared : true; this._repeaterID = options.repeaterID || ''; this._wsProtocols = options.wsProtocols || []; + this._useUltraVNCGestures = options.useUltraVNCGestures || false; // Internal state this._rfbConnectionState = ''; @@ -202,6 +204,7 @@ export default class RFB extends EventTargetMixin { handleMouse: this._handleMouse.bind(this), handleWheel: this._handleWheel.bind(this), handleGesture: this._handleGesture.bind(this), + handleUltraVNCTouch: this._handleUltraVNCTouch.bind(this), handleRSAAESCredentialsRequired: this._handleRSAAESCredentialsRequired.bind(this), handleRSAAESServerVerification: this._handleRSAAESServerVerification.bind(this), }; @@ -263,7 +266,11 @@ export default class RFB extends EventTargetMixin { this._remoteCapsLock = null; // Null indicates unknown or irrelevant this._remoteNumLock = null; - this._gestures = new GestureHandler(); + if (this._useUltraVNCGestures) { + this._gestures = new TouchHandlerUltraVNC(); + } else { + this._gestures = new GestureHandler(); + } this._sock = new Websock(); this._sock.on('open', this._socketOpen.bind(this)); @@ -594,9 +601,13 @@ export default class RFB extends EventTargetMixin { this._canvas.addEventListener("wheel", this._eventHandlers.handleWheel); // Gesture events - this._canvas.addEventListener("gesturestart", this._eventHandlers.handleGesture); - this._canvas.addEventListener("gesturemove", this._eventHandlers.handleGesture); - this._canvas.addEventListener("gestureend", this._eventHandlers.handleGesture); + if (this._useUltraVNCGestures) { + this._canvas.addEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); + } else { + this._canvas.addEventListener('gesturestart', this._eventHandlers.handleGesture); + this._canvas.addEventListener('gesturemove', this._eventHandlers.handleGesture); + this._canvas.addEventListener('gestureend', this._eventHandlers.handleGesture); + } Log.Debug("<< RFB.connect"); } @@ -604,9 +615,13 @@ export default class RFB extends EventTargetMixin { _disconnect() { Log.Debug(">> RFB.disconnect"); this._cursor.detach(); - this._canvas.removeEventListener("gesturestart", this._eventHandlers.handleGesture); - this._canvas.removeEventListener("gesturemove", this._eventHandlers.handleGesture); - this._canvas.removeEventListener("gestureend", this._eventHandlers.handleGesture); + if (this._useUltraVNCGestures) { + this._canvas.removeEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); + } else { + this._canvas.removeEventListener('gesturestart', this._eventHandlers.handleGesture); + this._canvas.removeEventListener('gesturemove', this._eventHandlers.handleGesture); + this._canvas.removeEventListener('gestureend', this._eventHandlers.handleGesture); + } this._canvas.removeEventListener("wheel", this._eventHandlers.handleWheel); this._canvas.removeEventListener('mousedown', this._eventHandlers.handleMouse); this._canvas.removeEventListener('mouseup', this._eventHandlers.handleMouse); @@ -1374,6 +1389,87 @@ export default class RFB extends EventTargetMixin { } } + _handleUltraVNCTouch(ev) { + Log.Debug("SENDING " + ev.detail.currentTouches.length + " TOUCH(ES)"); + this._sock.sQpush8(253); // GII message type + this._sock.sQpush8(128); // GII event + this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length + this._sock.sQpush8(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // eventSize + this._sock.sQpush8(12); // eventType + this._sock.sQpush16(0); // padding + this._sock.sQpush32(ev.detail.giiDeviceOrigin); // deviceOrigin + this._sock.sQpush32(ev.detail.currentTouches.length); // first + this._sock.sQpush32(6 * ev.detail.currentTouches.length); // count + + let pointerUpIds = []; + + // Send all current touches + for (let i = 0; i < ev.detail.currentTouches.length; i++) { + Log.Debug("Touch Id: " + ev.detail.currentTouches[i].event.identifier); + let valuatorFlag = 0x00000000; + valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; + valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; + if (ev.detail.currentTouches[i].status !== "POINTER_UP") valuatorFlag |= TouchHandlerUltraVNC.PF_flag; + if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag + + this._sock.sQpush32(valuatorFlag); + this._sock.sQpush32(ev.detail.currentTouches[i].event.identifier); + + let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, + this._canvas); + + if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { + let scaledX16 = Math.floor(scaledPosition.x) & 0xFFFF; + let scaledY16 = Math.floor(scaledPosition.y) & 0xFFFF; + let coordinates = (Math.floor(scaledX16) << 16) | (Math.floor(scaledY16)); + this._sock.sQpush32(coordinates); + } + + // Keep track of last released touches + if (ev.detail.currentTouches[i].status === "POINTER_UP") { + pointerUpIds.push(ev.detail.currentTouches[i].event.identifier); + } + } + + this._sock.flush(); + + // Remove released touches from current touches in handler + for (let i = 0; i < pointerUpIds.length; i++) { + const index = ev.detail.currentTouches.findIndex(t => t.event.identifier === pointerUpIds[i]); + if (index !== -1) { + this._gestures._removeTouch(index); + } + } + + // Interrupt touch sending interval + if (ev.detail.currentTouches.length === 0 && this._sendTouchesIntervalId !== -1) { + Log.Debug("NO MORE TOUCHES\n"); + this._gestures._interruptTouches(); + this._sendEmptyTouch(ev.detail.giiDeviceOrigin); + return; + } + } + + _sendEmptyTouch(giiDeviceOrigin) { + let valuatorFlag = 0x00000000; + valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; + valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_CLEAR; + + this._sock.sQpush8(253); // GII message type + this._sock.sQpush8(128); // GII event + this._sock.sQpush16(24); // Header length + this._sock.sQpush8(24); // Event size + this._sock.sQpush8(12); // eventType + this._sock.sQpush16(0); // padding + this._sock.sQpush32(giiDeviceOrigin); // deviceOrigin + this._sock.sQpush32(1); // first + this._sock.sQpush32(4); // Count + this._sock.sQpush32(valuatorFlag); // Flag + this._sock.sQpush32(0); // Empty Id + this._sock.sQpush32(0); // Empty coordinates + this._sock.flush(); + } + // Message Handlers _negotiateProtocolVersion() { @@ -2139,6 +2235,10 @@ export default class RFB extends EventTargetMixin { encs.push(encodings.pseudoEncodingDesktopName); encs.push(encodings.pseudoEncodingExtendedClipboard); + if (this._useUltraVNCGestures) { + encs.push(encodings.pseudoEncodingGii); + } + if (this._fbDepth == 24) { encs.push(encodings.pseudoEncodingVMwareCursor); encs.push(encodings.pseudoEncodingCursor); @@ -2434,6 +2534,25 @@ export default class RFB extends EventTargetMixin { return true; } + _handleGiiMsg() { + let giiMsgSubtype = this._sock.rQshift8(); + + switch (giiMsgSubtype) { + case 129: // GII Version Message + this._sock.rQskipBytes(34); + RFB.messages.giiVersionMessage(this._sock); + RFB.messages.giiDeviceCreation(this._sock); + break; + case 130: // GII Device Creation + this._sock.rQshiftBytes(2); + this._gestures._giiDeviceOrigin = this._sock.rQshift32(); + if (this._gestures._giiDeviceOrigin) this._gestures._isUltraVNCTouchActivated = true; + break; + } + + return true; + } + _normalMsg() { let msgType; if (this._FBU.rects > 0) { @@ -2485,6 +2604,9 @@ export default class RFB extends EventTargetMixin { case 250: // XVP return this._handleXvpMsg(); + case 253: // GII + return this._handleGiiMsg(); + default: this._fail("Unexpected server message (type " + msgType + ")"); Log.Debug("sock.rQpeekBytes(30): " + this._sock.rQpeekBytes(30)); @@ -2933,6 +3055,16 @@ export default class RFB extends EventTargetMixin { "raw", passwordChars, { name: "DES-ECB" }, false, ["encrypt"]); return legacyCrypto.encrypt({ name: "DES-ECB" }, key, challenge); } + + static stringAsByteArrayWithPadding(str, size) { + let full = new Uint8Array(size); + let utf8Encode = new TextEncoder(); + let strArray = utf8Encode.encode(str); + for (let i = 0; i < strArray.length; i++) { + full[i] = strArray[i]; + } + return full; + } } // Class Methods @@ -3224,6 +3356,44 @@ RFB.messages = { sock.sQpush8(ver); sock.sQpush8(op); + sock.flush(); + }, + + giiVersionMessage(sock) { + sock.sQpush8(253); // gii msg-type + sock.sQpush8(129); // gii version sub-msg-type + sock.sQpush16(2); // length + sock.sQpush16(1); // version + + sock.flush(); + }, + + giiDeviceCreation(sock) { + sock.sQpush8(253); // gii msg-type + sock.sQpush8(130); // gii device creation sub-msg-type + sock.sQpush16(172); // length + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NOVNC-MT", 31)); // device name + sock.sQpush8(0); // DNTerm + sock.sQpush32(0x0908); // vendorID + sock.sQpush32(0x000b); // productID + sock.sQpush32(0x00002000); // eventMask + sock.sQpush32(0); // numRegisters + sock.sQpush32(1); // numValuators + sock.sQpush32(5); // numButtons + sock.sQpush32(0); // index + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NOVNC Multitouch Device", 74)); // longName + sock.sQpush8(0); // LNTerm + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NMD", 4)); // shortName + sock.sQpush8(0); // SNTerm + sock.sQpush32(0); // rangeMin + sock.sQpush32(0); // rangeCenter + sock.sQpush32(0); // rangeMax + sock.sQpush32(0); // SIUnit + sock.sQpush32(0); // SIAdd + sock.sQpush32(0); // SIMul + sock.sQpush32(0); // SIDiv + sock.sQpush32(0); // SIShift + sock.flush(); } }; diff --git a/vnc.html b/vnc.html index 24a118dbd..6209aa659 100644 --- a/vnc.html +++ b/vnc.html @@ -220,6 +220,7 @@

no
VNC


  • +

  • From c1efe1f9871d1c1f9bad342cbde1f170958e7ade Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Wed, 31 Jul 2024 15:44:55 +0200 Subject: [PATCH 02/19] Fix local scaling touch position --- core/rfb.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/rfb.js b/core/rfb.js index b45b51727..2c58471d9 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -1419,9 +1419,9 @@ export default class RFB extends EventTargetMixin { this._canvas); if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { - let scaledX16 = Math.floor(scaledPosition.x) & 0xFFFF; - let scaledY16 = Math.floor(scaledPosition.y) & 0xFFFF; - let coordinates = (Math.floor(scaledX16) << 16) | (Math.floor(scaledY16)); + let scaledX16 = this._display.absX(scaledPosition.x) & 0xFFFF; + let scaledY16 = this._display.absY(scaledPosition.y) & 0xFFFF; + let coordinates = (scaledX16 << 16) | scaledY16; this._sock.sQpush32(coordinates); } @@ -2535,15 +2535,20 @@ export default class RFB extends EventTargetMixin { } _handleGiiMsg() { + if (this._sock.rQwait("GII message subtype", 1, 1)) { + return false; + } let giiMsgSubtype = this._sock.rQshift8(); switch (giiMsgSubtype) { case 129: // GII Version Message + if (this._sock.rQwait("GII version message", 34, 1)) { return false; } this._sock.rQskipBytes(34); RFB.messages.giiVersionMessage(this._sock); RFB.messages.giiDeviceCreation(this._sock); break; case 130: // GII Device Creation + if (this._sock.rQwait("GII device creation", 6, 1)) { return false; } this._sock.rQshiftBytes(2); this._gestures._giiDeviceOrigin = this._sock.rQshift32(); if (this._gestures._giiDeviceOrigin) this._gestures._isUltraVNCTouchActivated = true; From 6b770c9da26e47454416e5d49a16e2365c8d9f23 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Wed, 31 Jul 2024 15:45:33 +0200 Subject: [PATCH 03/19] Fix touches with same id not being removed properly --- core/input/touchhandlerultravnc.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js index c9ccac919..05fba0efa 100644 --- a/core/input/touchhandlerultravnc.js +++ b/core/input/touchhandlerultravnc.js @@ -88,14 +88,20 @@ export default class TouchHandlerUltraVNC { } } else if (ev.type === "touchend" || ev.type === "touchcancel") { for (let i = 0; i < ev.changedTouches.length; i++) { - const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); - if (index !== -1) { - this._currentTouches[index].status = "POINTER_UP"; - } + const indexes = this._getAllIndexes(this._currentTouches, (t) => t.event.identifier === ev.changedTouches[i].identifier) + indexes.forEach((index) => this._currentTouches[index].status = "POINTER_UP"); } } } + _getAllIndexes(arr, func) { + var indexes = [], i; + for (i = 0; i < arr.length; i++) + if (func(arr[i])) + indexes.push(i); + return indexes; + } + _dispatchTouchEvent(ev) { let tev = new CustomEvent('ultravnctouch', { event: ev, detail: { currentTouches: this._currentTouches, giiDeviceOrigin: this._giiDeviceOrigin } }); this._target.dispatchEvent(tev); From 43ddc6c982114dbe1299539f908aa3783b19d4a0 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Tue, 24 Sep 2024 09:23:45 +0200 Subject: [PATCH 04/19] Add preventDefault in UltraVNC touch and manage touch ids manually --- core/input/touchhandlerultravnc.js | 12 +++++++++++- core/rfb.js | 4 +--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js index 05fba0efa..48bb0015c 100644 --- a/core/input/touchhandlerultravnc.js +++ b/core/input/touchhandlerultravnc.js @@ -61,7 +61,8 @@ export default class TouchHandlerUltraVNC { } _handleTouch(ev) { - Log.Debug("Gesture: " + ev.type); + ev.preventDefault(); + ev.stopImmediatePropagation(); if (!this._isUltraVNCTouchActivated) { return; @@ -69,6 +70,7 @@ export default class TouchHandlerUltraVNC { if (ev.type === "touchstart") { for (let i = 0; i < ev.changedTouches.length; i++) { + ev.changedTouches[i].touchIdentifier = this._getTouchIdentifier(); this._currentTouches.push({ event: ev.changedTouches[i], status: "POINTER_DOWN" }); } @@ -82,6 +84,7 @@ export default class TouchHandlerUltraVNC { for (let i = 0; i < ev.changedTouches.length; i++) { const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); if (index !== -1) { + ev.changedTouches[i].touchIdentifier = this._currentTouches[index].event.touchIdentifier; this._currentTouches[index].event = ev.changedTouches[i]; this._currentTouches[index].status = "POINTER_UPDATE"; } @@ -102,6 +105,13 @@ export default class TouchHandlerUltraVNC { return indexes; } + _getTouchIdentifier() { + const ids = this._currentTouches.map((ev) => ev.event.touchIdentifier); + let i = 0; + while (ids.includes(i)) { i++; } + return i; + } + _dispatchTouchEvent(ev) { let tev = new CustomEvent('ultravnctouch', { event: ev, detail: { currentTouches: this._currentTouches, giiDeviceOrigin: this._giiDeviceOrigin } }); this._target.dispatchEvent(tev); diff --git a/core/rfb.js b/core/rfb.js index 2c58471d9..8129ecf63 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -1390,7 +1390,6 @@ export default class RFB extends EventTargetMixin { } _handleUltraVNCTouch(ev) { - Log.Debug("SENDING " + ev.detail.currentTouches.length + " TOUCH(ES)"); this._sock.sQpush8(253); // GII message type this._sock.sQpush8(128); // GII event this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length @@ -1405,7 +1404,6 @@ export default class RFB extends EventTargetMixin { // Send all current touches for (let i = 0; i < ev.detail.currentTouches.length; i++) { - Log.Debug("Touch Id: " + ev.detail.currentTouches[i].event.identifier); let valuatorFlag = 0x00000000; valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; @@ -1413,7 +1411,7 @@ export default class RFB extends EventTargetMixin { if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag this._sock.sQpush32(valuatorFlag); - this._sock.sQpush32(ev.detail.currentTouches[i].event.identifier); + this._sock.sQpush32(ev.detail.currentTouches[i].event.touchIdentifier); let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, this._canvas); From 88a5a59629bdf948e5416a6f4e0c702b9bd78195 Mon Sep 17 00:00:00 2001 From: dim5x Date: Sat, 2 Nov 2024 04:38:57 +0300 Subject: [PATCH 05/19] Fix typos in Russian translation --- app/locale/ru.json | 8 ++++---- po/ru.po | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/locale/ru.json b/app/locale/ru.json index cab97396e..5a1a1b9ba 100644 --- a/app/locale/ru.json +++ b/app/locale/ru.json @@ -21,10 +21,10 @@ "Extra keys": "Дополнительные Кнопки", "Show Extra Keys": "Показать Дополнительные Кнопки", "Ctrl": "Ctrl", - "Toggle Ctrl": "Переключение нажатия Ctrl", + "Toggle Ctrl": "Зажать Ctrl", "Alt": "Alt", - "Toggle Alt": "Переключение нажатия Alt", - "Toggle Windows": "Переключение вкладок", + "Toggle Alt": "Зажать Alt", + "Toggle Windows": "Зажать Windows", "Windows": "Вкладка", "Send Tab": "Передать нажатие Tab", "Tab": "Tab", @@ -47,7 +47,7 @@ "Clip to Window": "В окно", "Scaling Mode:": "Масштаб:", "None": "Нет", - "Local Scaling": "Локльный масштаб", + "Local Scaling": "Локальный масштаб", "Remote Resizing": "Удаленная перенастройка размера", "Advanced": "Дополнительно", "Quality:": "Качество", diff --git a/po/ru.po b/po/ru.po index 5a81bb069..dbc1d840f 100644 --- a/po/ru.po +++ b/po/ru.po @@ -6,11 +6,11 @@ # msgid "" msgstr "" -"Project-Id-Version: noVNC 1.3.0\n" +"Project-Id-Version: noVNC 1.5.0\n" "Report-Msgid-Bugs-To: novnc@googlegroups.com\n" "POT-Creation-Date: 2021-08-27 16:03+0200\n" -"PO-Revision-Date: 2021-09-09 10:29+0400\n" -"Last-Translator: Nia Remez \n" +"PO-Revision-Date: 2024-02-11 03:58+0300\n" +"Last-Translator: Dim5x \n" "Language-Team: Russian\n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -111,7 +111,7 @@ msgstr "Ctrl" #: ../vnc.html:94 msgid "Toggle Ctrl" -msgstr "Переключение нажатия Ctrl" +msgstr "Зажать Ctrl" #: ../vnc.html:97 msgid "Alt" @@ -119,11 +119,11 @@ msgstr "Alt" #: ../vnc.html:97 msgid "Toggle Alt" -msgstr "Переключение нажатия Alt" +msgstr "Зажать Alt" #: ../vnc.html:100 msgid "Toggle Windows" -msgstr "Переключение вкладок" +msgstr "Зажать Windows" #: ../vnc.html:100 msgid "Windows" @@ -215,7 +215,7 @@ msgstr "Нет" #: ../vnc.html:175 msgid "Local Scaling" -msgstr "Локльный масштаб" +msgstr "Локальный масштаб" #: ../vnc.html:176 msgid "Remote Resizing" From 43326eb67b1a77bed7ea90766101aecf1158024e Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 20 Nov 2024 10:46:52 +0100 Subject: [PATCH 06/19] Fix handling of VideoDecoder.isConfigSupported() It returns an object with details, not just a simple boolean. --- tests/test.h264.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test.h264.js b/tests/test.h264.js index 42273e7ce..2f67391c3 100644 --- a/tests/test.h264.js +++ b/tests/test.h264.js @@ -49,7 +49,9 @@ async function haveH264Decode() { optimizeForLatency: true, }; - _haveH264Decode = await VideoDecoder.isConfigSupported(config); + let support = await VideoDecoder.isConfigSupported(config); + _haveH264Decode = support.supported; + return _haveH264Decode; } From 89e0591aab3dbf0f119cc8ab4b901b194506d9fa Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 20 Nov 2024 12:49:36 +0100 Subject: [PATCH 07/19] Use common H.264 check in tests Avoid duplicating this logic in multiple places. --- tests/test.h264.js | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/tests/test.h264.js b/tests/test.h264.js index 2f67391c3..e6fbacb8c 100644 --- a/tests/test.h264.js +++ b/tests/test.h264.js @@ -4,6 +4,7 @@ import Display from '../core/display.js'; import { H264Parser } from '../core/decoders/h264.js'; import H264Decoder from '../core/decoders/h264.js'; import Base64 from '../core/base64.js'; +import { supportsWebCodecsH264Decode } from '../core/util/browser.js'; import FakeWebSocket from './fake.websocket.js'; @@ -29,32 +30,6 @@ const redGreenBlue16x16Video = new Uint8Array(Base64.decode( '4AA5DRJMnkycJk4TPwAAAAFBiIga8RigADVVHAAGaGOAANtuAAAAAUGIkBr///wRRQABVf8c' + 'AAcho4AAiD4=')); -let _haveH264Decode = null; - -async function haveH264Decode() { - if (_haveH264Decode !== null) { - return _haveH264Decode; - } - - if (!('VideoDecoder' in window)) { - _haveH264Decode = false; - return false; - } - - // We'll need to make do with some placeholders here - const config = { - codec: 'avc1.42401f', - codedWidth: 1920, - codedHeight: 1080, - optimizeForLatency: true, - }; - - let support = await VideoDecoder.isConfigSupported(config); - _haveH264Decode = support.supported; - - return _haveH264Decode; -} - function createSolidColorFrameBuffer(color, width, height) { const r = (color >> 24) & 0xff; const g = (color >> 16) & 0xff; @@ -158,8 +133,8 @@ describe('H.264 Parser', function () { describe('H.264 Decoder Unit Test', function () { let decoder; - beforeEach(async function () { - if (!await haveH264Decode()) { + beforeEach(function () { + if (!supportsWebCodecsH264Decode) { this.skip(); return; } @@ -213,8 +188,8 @@ describe('H.264 Decoder Functional Test', function () { before(FakeWebSocket.replace); after(FakeWebSocket.restore); - beforeEach(async function () { - if (!await haveH264Decode()) { + beforeEach(function () { + if (!supportsWebCodecsH264Decode) { this.skip(); return; } From 69750c74a65041764c99302cf2e80c8771b2990d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 21 Nov 2024 13:30:57 +0100 Subject: [PATCH 08/19] Raise JavaScript version requirement So that we can use await at module top level. --- README.md | 2 +- eslint.config.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 305108588..794ff60fd 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ noVNC uses many modern web technologies so a formal requirement list is not available. However these are the minimum versions we are currently aware of: -* Chrome 64, Firefox 79, Safari 13.4, Opera 51, Edge 79 +* Chrome 89, Firefox 89, Safari 15, Opera 75, Edge 89 ### Server Requirements diff --git a/eslint.config.mjs b/eslint.config.mjs index 13b1a32a4..10a99ce13 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,11 +5,11 @@ export default [ js.configs.recommended, { languageOptions: { - ecmaVersion: 2020, + ecmaVersion: 2022, sourceType: "module", globals: { ...globals.browser, - ...globals.es2020, + ...globals.es2022, } }, ignores: ["**/xtscancodes.js"], From 3677afe30514fb3c678e35bb9b6bde924820be8d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 21 Nov 2024 12:44:32 +0100 Subject: [PATCH 09/19] Do a real H.264 test decode to determine support Firefox is buggy and reports support for H.264 but then throws errors once we actually try to decode things. Detect this early by doing a quick test decode of a single frame. --- core/util/browser.js | 55 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/core/util/browser.js b/core/util/browser.js index 1ecded662..23f3d3e93 100644 --- a/core/util/browser.js +++ b/core/util/browser.js @@ -9,6 +9,7 @@ */ import * as Log from './logging.js'; +import Base64 from '../base64.js'; // Touch detection export let isTouchDevice = ('ontouchstart' in document.documentElement) || @@ -74,7 +75,7 @@ export let supportsWebCodecsH264Decode = false; async function _checkWebCodecsH264DecodeSupport() { if (!('VideoDecoder' in window)) { - return; + return false; } // We'll need to make do with some placeholders here @@ -85,10 +86,56 @@ async function _checkWebCodecsH264DecodeSupport() { optimizeForLatency: true, }; - const result = await VideoDecoder.isConfigSupported(config); - supportsWebCodecsH264Decode = result.supported; + let support = await VideoDecoder.isConfigSupported(config); + if (!support.supported) { + return false; + } + + // Firefox incorrectly reports supports for H.264 under some + // circumstances, so we need to actually test a real frame + // https://bugzilla.mozilla.org/show_bug.cgi?id=1932392 + + const data = new Uint8Array(Base64.decode( + 'AAAAAWdCwBTZnpuAgICgAAADACAAAAZB4oVNAAAAAWjJYyyAAAABBgX//4Hc' + + 'Rem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTY0IHIzMTA4IDMxZTE5Zjkg' + + 'LSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDIz' + + 'IC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9u' + + 'czogY2FiYWM9MCByZWY9NSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjB4' + + 'MTExIG1lPWhleCBzdWJtZT04IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4' + + 'ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0yIDh4' + + 'OGRjdD0wIGNxbT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJv' + + 'bWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9MSBsb29rYWhlYWRfdGhyZWFkcz0x' + + 'IHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9' + + 'MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVz' + + 'PTAgd2VpZ2h0cD0wIGtleWludD1pbmZpbml0ZSBrZXlpbnRfbWluPTI1IHNj' + + 'ZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NTAgcmM9' + + 'YWJyIG1idHJlZT0xIGJpdHJhdGU9NDAwIHJhdGV0b2w9MS4wIHFjb21wPTAu' + + 'NjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFx' + + 'PTE6MS4wMACAAAABZYiEBrxmKAAPVccAAS044AA5DRJMnkycJk4TPw==')); + + let error = null; + + let decoder = new VideoDecoder({ + output: (frame) => {}, + error: (e) => { error = e; }, + }); + let chunk = new EncodedVideoChunk({ + timestamp: 0, + type: 'key', + data: data, + }); + + decoder.configure(config); + decoder.decode(chunk); + await decoder.flush(); + + if (error !== null) { + return false; + } + + return true; } -_checkWebCodecsH264DecodeSupport(); +supportsWebCodecsH264Decode = await _checkWebCodecsH264DecodeSupport(); /* * The functions for detection of platforms and browsers below are exported From a89dfd61415afd8137f22fdde8d863346fee1ade Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 21 Nov 2024 13:16:17 +0100 Subject: [PATCH 10/19] Handle exceptions from VideoDecoder.flush() These are not supposed to happen according to the specification, but Firefox has some bug and throws them anyway. --- core/util/browser.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/util/browser.js b/core/util/browser.js index 23f3d3e93..b55264fec 100644 --- a/core/util/browser.js +++ b/core/util/browser.js @@ -127,7 +127,13 @@ async function _checkWebCodecsH264DecodeSupport() { decoder.configure(config); decoder.decode(chunk); - await decoder.flush(); + try { + await decoder.flush(); + } catch (e) { + // Firefox incorrectly throws an exception here + // https://bugzilla.mozilla.org/show_bug.cgi?id=1932566 + error = e; + } if (error !== null) { return false; From 2463ccd08fabdd3a5c8b628d9afe5f539f9168b2 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 21 Nov 2024 13:16:56 +0100 Subject: [PATCH 11/19] Detect broken Firefox H.264 decoder The Firefox H.264 decoder on Windows might simply just refuse to deliver any finished frames. It also doesn't deliver any errors. Detect this early by expecting a frame after flush() has completed. --- core/util/browser.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/util/browser.js b/core/util/browser.js index b55264fec..407cad9cb 100644 --- a/core/util/browser.js +++ b/core/util/browser.js @@ -113,10 +113,11 @@ async function _checkWebCodecsH264DecodeSupport() { 'NjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFx' + 'PTE6MS4wMACAAAABZYiEBrxmKAAPVccAAS044AA5DRJMnkycJk4TPw==')); + let gotframe = false; let error = null; let decoder = new VideoDecoder({ - output: (frame) => {}, + output: (frame) => { gotframe = true; }, error: (e) => { error = e; }, }); let chunk = new EncodedVideoChunk({ @@ -135,6 +136,13 @@ async function _checkWebCodecsH264DecodeSupport() { error = e; } + // Firefox fails to deliver the error on Windows, so we need to + // check if we got a frame instead + // https://bugzilla.mozilla.org/show_bug.cgi?id=1932579 + if (!gotframe) { + return false; + } + if (error !== null) { return false; } From 90a6c7bbb6ec0bc378410b9e091a1a002147e6e0 Mon Sep 17 00:00:00 2001 From: wxtewx <181315147@qq.com> Date: Sat, 23 Nov 2024 15:36:12 +0800 Subject: [PATCH 12/19] Update zh_CN.po --- po/zh_CN.po | 317 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 203 insertions(+), 114 deletions(-) diff --git a/po/zh_CN.po b/po/zh_CN.po index caae28504..23294a662 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,278 +7,367 @@ msgid "" msgstr "" "Project-Id-Version: noVNC 1.1.0\n" "Report-Msgid-Bugs-To: novnc@googlegroups.com\n" -"POT-Creation-Date: 2018-01-10 00:53+0800\n" -"PO-Revision-Date: 2020-01-02 13:19+0800\n" -"Last-Translator: CUI Wei \n" +"POT-Creation-Date: 2024-06-03 14:10+0200\n" +"PO-Revision-Date: 2024-11-23 15:29+0800\n" +"Last-Translator: wxtewx \n" +"Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.5\n" -#: ../app/ui.js:430 +#: ../app/ui.js:69 +msgid "" +"Running without HTTPS is not recommended, crashes or other issues are likely." +msgstr "不建议在没有 HTTPS 的情况下运行,可能会出现崩溃或出现其他问题。" + +#: ../app/ui.js:410 msgid "Connecting..." msgstr "连接中..." -#: ../app/ui.js:438 +#: ../app/ui.js:417 +msgid "Disconnecting..." +msgstr "正在断开连接..." + +#: ../app/ui.js:423 +msgid "Reconnecting..." +msgstr "重新连接中..." + +#: ../app/ui.js:428 +msgid "Internal error" +msgstr "内部错误" + +#: ../app/ui.js:1026 +msgid "Must set host" +msgstr "必须设置主机" + +#: ../app/ui.js:1052 +msgid "Failed to connect to server: " +msgstr "无法连接到服务器:" + +#: ../app/ui.js:1118 msgid "Connected (encrypted) to " msgstr "已连接(已加密)到" -#: ../app/ui.js:440 +#: ../app/ui.js:1120 msgid "Connected (unencrypted) to " msgstr "已连接(未加密)到" -#: ../app/ui.js:446 -msgid "Disconnecting..." -msgstr "正在断开连接..." +#: ../app/ui.js:1143 +msgid "Something went wrong, connection is closed" +msgstr "出了点问题,连接已关闭" + +#: ../app/ui.js:1146 +msgid "Failed to connect to server" +msgstr "无法连接到服务器" -#: ../app/ui.js:450 +#: ../app/ui.js:1158 msgid "Disconnected" msgstr "已断开连接" -#: ../app/ui.js:1052 ../core/rfb.js:248 -msgid "Must set host" -msgstr "必须设置主机" - -#: ../app/ui.js:1101 -msgid "Reconnecting..." -msgstr "重新连接中..." +#: ../app/ui.js:1173 +msgid "New connection has been rejected with reason: " +msgstr "新连接被拒绝,原因如下:" -#: ../app/ui.js:1140 -msgid "Password is required" -msgstr "请提供密码" +#: ../app/ui.js:1176 +msgid "New connection has been rejected" +msgstr "新连接已被拒绝" -#: ../core/rfb.js:548 -msgid "Disconnect timeout" -msgstr "超时断开" +#: ../app/ui.js:1242 +msgid "Credentials are required" +msgstr "需要凭证" -#: ../vnc.html:89 +#: ../vnc.html:55 msgid "noVNC encountered an error:" msgstr "noVNC 遇到一个错误:" -#: ../vnc.html:99 +#: ../vnc.html:65 msgid "Hide/Show the control bar" msgstr "显示/隐藏控制栏" -#: ../vnc.html:106 +#: ../vnc.html:74 +msgid "Drag" +msgstr "拖动" + +#: ../vnc.html:74 msgid "Move/Drag Viewport" msgstr "移动/拖动窗口" -#: ../vnc.html:106 -msgid "viewport drag" -msgstr "窗口拖动" - -#: ../vnc.html:112 ../vnc.html:115 ../vnc.html:118 ../vnc.html:121 -msgid "Active Mouse Button" -msgstr "启动鼠标按键" - -#: ../vnc.html:112 -msgid "No mousebutton" -msgstr "禁用鼠标按键" - -#: ../vnc.html:115 -msgid "Left mousebutton" -msgstr "鼠标左键" - -#: ../vnc.html:118 -msgid "Middle mousebutton" -msgstr "鼠标中键" - -#: ../vnc.html:121 -msgid "Right mousebutton" -msgstr "鼠标右键" - -#: ../vnc.html:124 +#: ../vnc.html:80 msgid "Keyboard" msgstr "键盘" -#: ../vnc.html:124 +#: ../vnc.html:80 msgid "Show Keyboard" msgstr "显示键盘" -#: ../vnc.html:131 +#: ../vnc.html:85 msgid "Extra keys" msgstr "额外按键" -#: ../vnc.html:131 +#: ../vnc.html:85 msgid "Show Extra Keys" msgstr "显示额外按键" -#: ../vnc.html:136 +#: ../vnc.html:90 msgid "Ctrl" msgstr "Ctrl" -#: ../vnc.html:136 +#: ../vnc.html:90 msgid "Toggle Ctrl" msgstr "切换 Ctrl" -#: ../vnc.html:136 -msgid "Edit clipboard content in the textarea below." -msgstr "在下面的文本区域中编辑剪贴板内容。" - -#: ../vnc.html:139 +#: ../vnc.html:93 msgid "Alt" msgstr "Alt" -#: ../vnc.html:139 +#: ../vnc.html:93 msgid "Toggle Alt" msgstr "切换 Alt" -#: ../vnc.html:142 +#: ../vnc.html:96 +msgid "Toggle Windows" +msgstr "切换窗口" + +#: ../vnc.html:96 +msgid "Windows" +msgstr "窗口" + +#: ../vnc.html:99 msgid "Send Tab" msgstr "发送 Tab 键" -#: ../vnc.html:142 +#: ../vnc.html:99 msgid "Tab" msgstr "Tab" -#: ../vnc.html:145 +#: ../vnc.html:102 msgid "Esc" msgstr "Esc" -#: ../vnc.html:145 +#: ../vnc.html:102 msgid "Send Escape" msgstr "发送 Escape 键" -#: ../vnc.html:148 +#: ../vnc.html:105 msgid "Ctrl+Alt+Del" msgstr "Ctrl+Alt+Del" -#: ../vnc.html:148 +#: ../vnc.html:105 msgid "Send Ctrl-Alt-Del" msgstr "发送 Ctrl+Alt+Del 键" -#: ../vnc.html:156 +#: ../vnc.html:112 msgid "Shutdown/Reboot" msgstr "关机/重启" -#: ../vnc.html:156 +#: ../vnc.html:112 msgid "Shutdown/Reboot..." msgstr "关机/重启..." -#: ../vnc.html:162 +#: ../vnc.html:118 msgid "Power" msgstr "电源" -#: ../vnc.html:164 +#: ../vnc.html:120 msgid "Shutdown" msgstr "关机" -#: ../vnc.html:165 +#: ../vnc.html:121 msgid "Reboot" msgstr "重启" -#: ../vnc.html:166 +#: ../vnc.html:122 msgid "Reset" msgstr "重置" -#: ../vnc.html:171 ../vnc.html:177 +#: ../vnc.html:127 ../vnc.html:133 msgid "Clipboard" msgstr "剪贴板" -#: ../vnc.html:181 -msgid "Clear" -msgstr "清除" +#: ../vnc.html:135 +msgid "Edit clipboard content in the textarea below." +msgstr "在下面的文本区域中编辑剪贴板内容。" -#: ../vnc.html:187 -msgid "Fullscreen" +#: ../vnc.html:143 +msgid "Full Screen" msgstr "全屏" -#: ../vnc.html:192 ../vnc.html:199 +#: ../vnc.html:148 ../vnc.html:154 msgid "Settings" msgstr "设置" -#: ../vnc.html:200 -msgid "Encrypt" -msgstr "加密" - -#: ../vnc.html:202 +#: ../vnc.html:158 msgid "Shared Mode" msgstr "分享模式" -#: ../vnc.html:205 +#: ../vnc.html:161 msgid "View Only" msgstr "仅查看" -#: ../vnc.html:209 +#: ../vnc.html:165 msgid "Clip to Window" msgstr "限制/裁切窗口大小" -#: ../vnc.html:212 +#: ../vnc.html:168 msgid "Scaling Mode:" msgstr "缩放模式:" -#: ../vnc.html:214 +#: ../vnc.html:170 msgid "None" msgstr "无" -#: ../vnc.html:215 +#: ../vnc.html:171 msgid "Local Scaling" msgstr "本地缩放" -#: ../vnc.html:216 -msgid "Local Downscaling" -msgstr "降低本地尺寸" - -#: ../vnc.html:217 +#: ../vnc.html:172 msgid "Remote Resizing" msgstr "远程调整大小" -#: ../vnc.html:222 +#: ../vnc.html:177 msgid "Advanced" msgstr "高级" -#: ../vnc.html:225 -msgid "Local Cursor" -msgstr "本地光标" +#: ../vnc.html:180 +msgid "Quality:" +msgstr "品质:" + +#: ../vnc.html:184 +msgid "Compression level:" +msgstr "压缩级别:" -#: ../vnc.html:229 +#: ../vnc.html:189 msgid "Repeater ID:" msgstr "中继站 ID" -#: ../vnc.html:233 +#: ../vnc.html:193 msgid "WebSocket" msgstr "WebSocket" -#: ../vnc.html:239 +#: ../vnc.html:196 +msgid "Encrypt" +msgstr "加密" + +#: ../vnc.html:199 msgid "Host:" msgstr "主机:" -#: ../vnc.html:243 +#: ../vnc.html:203 msgid "Port:" msgstr "端口:" -#: ../vnc.html:247 +#: ../vnc.html:207 msgid "Path:" msgstr "路径:" -#: ../vnc.html:254 +#: ../vnc.html:214 msgid "Automatic Reconnect" msgstr "自动重新连接" -#: ../vnc.html:257 +#: ../vnc.html:217 msgid "Reconnect Delay (ms):" msgstr "重新连接间隔 (ms):" -#: ../vnc.html:263 +#: ../vnc.html:222 +msgid "Show Dot when No Cursor" +msgstr "无光标时显示点" + +#: ../vnc.html:227 msgid "Logging:" msgstr "日志级别:" -#: ../vnc.html:275 +#: ../vnc.html:236 +msgid "Version:" +msgstr "版本:" + +#: ../vnc.html:244 msgid "Disconnect" msgstr "断开连接" -#: ../vnc.html:294 +#: ../vnc.html:267 msgid "Connect" msgstr "连接" +#: ../vnc.html:276 +msgid "Server identity" +msgstr "服务器身份" + +#: ../vnc.html:279 +msgid "The server has provided the following identifying information:" +msgstr "服务器提供了以下识别信息:" + +#: ../vnc.html:283 +msgid "Fingerprint:" +msgstr "指纹:" + +#: ../vnc.html:286 +msgid "" +"Please verify that the information is correct and press \"Approve\". " +"Otherwise press \"Reject\"." +msgstr "请核实信息是否正确,并按 “同意”,否则按 “拒绝”。" + +#: ../vnc.html:291 +msgid "Approve" +msgstr "同意" + +#: ../vnc.html:292 +msgid "Reject" +msgstr "拒绝" + +#: ../vnc.html:300 +msgid "Credentials" +msgstr "凭证" + #: ../vnc.html:304 +msgid "Username:" +msgstr "用户名:" + +#: ../vnc.html:308 msgid "Password:" msgstr "密码:" -#: ../vnc.html:318 +#: ../vnc.html:312 +msgid "Send Credentials" +msgstr "发送凭证" + +#: ../vnc.html:321 msgid "Cancel" msgstr "取消" -#: ../vnc.html:334 -msgid "Canvas not supported." -msgstr "不支持 Canvas。" \ No newline at end of file +#~ msgid "Password is required" +#~ msgstr "请提供密码" + +#~ msgid "Disconnect timeout" +#~ msgstr "超时断开" + +#~ msgid "viewport drag" +#~ msgstr "窗口拖动" + +#~ msgid "Active Mouse Button" +#~ msgstr "启动鼠标按键" + +#~ msgid "No mousebutton" +#~ msgstr "禁用鼠标按键" + +#~ msgid "Left mousebutton" +#~ msgstr "鼠标左键" + +#~ msgid "Middle mousebutton" +#~ msgstr "鼠标中键" + +#~ msgid "Right mousebutton" +#~ msgstr "鼠标右键" + +#~ msgid "Clear" +#~ msgstr "清除" + +#~ msgid "Local Downscaling" +#~ msgstr "降低本地尺寸" + +#~ msgid "Local Cursor" +#~ msgstr "本地光标" + +#~ msgid "Canvas not supported." +#~ msgstr "不支持 Canvas。" From 7f5b51acf35963d125992bb05d32aa1b68cf87bf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 27 Nov 2024 13:58:26 +0100 Subject: [PATCH 13/19] Consistently use "sentence case" style Try to be more consistent in how we capitalize things. Both the "Title Case" and "Sentence case" styles are popular, so either would work. Google and Mozilla both prefer "Sentence case", so let's follow them. --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- LICENSE.txt | 2 +- README.md | 44 +++++++++--------- app/error-handler.js | 2 +- app/localization.js | 4 +- app/styles/base.css | 16 +++---- app/styles/input.css | 2 +- app/ui.js | 2 +- app/webutil.js | 4 +- core/crypto/md5.js | 2 +- core/decoders/copyrect.js | 2 +- core/decoders/h264.js | 2 +- core/decoders/hextile.js | 2 +- core/decoders/jpeg.js | 2 +- core/decoders/raw.js | 2 +- core/decoders/rre.js | 2 +- core/decoders/tight.js | 2 +- core/decoders/tightpng.js | 2 +- core/decoders/zlib.js | 2 +- core/decoders/zrle.js | 2 +- core/deflator.js | 2 +- core/display.js | 2 +- core/encodings.js | 2 +- core/inflator.js | 2 +- core/input/domkeytable.js | 2 +- core/input/fixedkeys.js | 2 +- core/input/gesturehandler.js | 2 +- core/input/keyboard.js | 2 +- core/input/vkeys.js | 2 +- core/rfb.js | 8 ++-- core/util/browser.js | 2 +- core/util/cursor.js | 2 +- core/util/element.js | 2 +- core/util/events.js | 2 +- core/util/eventtarget.js | 2 +- core/util/int.js | 2 +- core/util/logging.js | 2 +- core/util/strings.js | 2 +- core/websock.js | 12 ++--- docs/API-internal.md | 12 ++--- docs/EMBEDDING.md | 8 ++-- docs/LIBRARY.md | 2 +- docs/novnc_proxy.1 | 2 +- po/Makefile | 2 +- po/po2js | 2 +- po/xgettext-html | 2 +- tests/playback.js | 2 +- tests/test.base64.js | 2 +- tests/test.copyrect.js | 2 +- tests/test.display.js | 2 +- tests/test.h264.js | 6 +-- tests/test.hextile.js | 2 +- tests/test.jpeg.js | 2 +- tests/test.keyboard.js | 8 ++-- tests/test.raw.js | 2 +- tests/test.rfb.js | 68 ++++++++++++++-------------- tests/test.rre.js | 2 +- tests/test.tight.js | 2 +- tests/test.tightpng.js | 2 +- tests/test.websock.js | 2 +- tests/test.zlib.js | 2 +- tests/test.zrle.js | 2 +- tests/vnc_playback.html | 2 +- utils/genkeysymdef.js | 2 +- utils/novnc_proxy | 4 +- vnc.html | 46 +++++++++---------- vnc_lite.html | 4 +- 67 files changed, 175 insertions(+), 175 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 94ac6f8dc..1b377d569 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,7 +7,7 @@ about: Create a report to help us improve **Describe the bug** A clear and concise description of what the bug is. -**To Reproduce** +**To reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' diff --git a/LICENSE.txt b/LICENSE.txt index 37efdcdba..0581c11ed 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -noVNC is Copyright (C) 2022 The noVNC Authors +noVNC is Copyright (C) 2022 The noVNC authors (./AUTHORS) The noVNC core library files are licensed under the MPL 2.0 (Mozilla diff --git a/README.md b/README.md index 794ff60fd..c497ad220 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## noVNC: HTML VNC Client Library and Application +## noVNC: HTML VNC client library and application [![Test Status](https://github.com/novnc/noVNC/workflows/Test/badge.svg)](https://github.com/novnc/noVNC/actions?query=workflow%3ATest) [![Lint Status](https://github.com/novnc/noVNC/workflows/Lint/badge.svg)](https://github.com/novnc/noVNC/actions?query=workflow%3ALint) @@ -14,19 +14,19 @@ Many companies, projects and products have integrated noVNC including [OpenNebula](http://opennebula.org/), [LibVNCServer](http://libvncserver.sourceforge.net), and [ThinLinc](https://cendio.com/thinlinc). See -[the Projects and Companies wiki page](https://github.com/novnc/noVNC/wiki/Projects-and-companies-using-noVNC) +[the Projects and companies wiki page](https://github.com/novnc/noVNC/wiki/Projects-and-companies-using-noVNC) for a more complete list with additional info and links. -### Table of Contents +### Table of contents - [News/help/contact](#newshelpcontact) - [Features](#features) - [Screenshots](#screenshots) -- [Browser Requirements](#browser-requirements) -- [Server Requirements](#server-requirements) -- [Quick Start](#quick-start) -- [Installation from Snap Package](#installation-from-snap-package) -- [Integration and Deployment](#integration-and-deployment) +- [Browser requirements](#browser-requirements) +- [Server requirements](#server-requirements) +- [Quick start](#quick-start) +- [Installation from snap package](#installation-from-snap-package) +- [Integration and deployment](#integration-and-deployment) - [Authors/Contributors](#authorscontributors) ### News/help/contact @@ -86,7 +86,7 @@ See more screenshots [here](http://novnc.com/screenshots.html). -### Browser Requirements +### Browser requirements noVNC uses many modern web technologies so a formal requirement list is not available. However these are the minimum versions we are currently @@ -95,7 +95,7 @@ aware of: * Chrome 89, Firefox 89, Safari 15, Opera 75, Edge 89 -### Server Requirements +### Server requirements noVNC follows the standard VNC protocol, but unlike other VNC clients it does require WebSockets support. Many servers include support (e.g. @@ -107,7 +107,7 @@ use a WebSockets to TCP socket proxy. noVNC has a sister project proxy. -### Quick Start +### Quick start * Use the `novnc_proxy` script to automatically download and start websockify, which includes a mini-webserver and the WebSockets proxy. The `--vnc` option is @@ -124,23 +124,23 @@ proxy. script. Hit the Connect button, enter a password if the VNC server has one configured, and enjoy! -### Installation from Snap Package -Running the command below will install the latest release of noVNC from Snap: +### Installation from snap package +Running the command below will install the latest release of noVNC from snap: `sudo snap install novnc` -#### Running noVNC from Snap Directly +#### Running noVNC from snap directly -You can run the Snap-package installed novnc directly with, for example: +You can run the snap package installed novnc directly with, for example: `novnc --listen 6081 --vnc localhost:5901 # /snap/bin/novnc if /snap/bin is not in your PATH` -If you want to use certificate files, due to standard Snap confinement restrictions you need to have them in the /home/\/snap/novnc/current/ directory. If your username is jsmith an example command would be: +If you want to use certificate files, due to standard snap confinement restrictions you need to have them in the /home/\/snap/novnc/current/ directory. If your username is jsmith an example command would be: `novnc --listen 8443 --cert ~jsmith/snap/novnc/current/self.crt --key ~jsmith/snap/novnc/current/self.key --vnc ubuntu.example.com:5901` -#### Running noVNC from Snap as a Service (Daemon) -The Snap package also has the capability to run a 'novnc' service which can be +#### Running noVNC from snap as a service (daemon) +The snap package also has the capability to run a 'novnc' service which can be configured to listen on multiple ports connecting to multiple VNC servers (effectively a service runing multiple instances of novnc). Instructions (with example values): @@ -172,7 +172,7 @@ services.n6082.listen 6082 services.n6082.vnc localhost:5902 ``` -Disable a service (note that because of a limitation in Snap it's currently not +Disable a service (note that because of a limitation in snap it's currently not possible to unset config variables, setting them to blank values is the way to disable a service): @@ -189,7 +189,7 @@ services.n6082.listen services.n6082.vnc ``` -### Integration and Deployment +### Integration and deployment Please see our other documents for how to integrate noVNC in your own software, or deploying the noVNC application in production environments: @@ -212,8 +212,8 @@ that list and you think you should be, feel free to send a PR to fix that. * [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack) * Notable contributions: - * UI and Icons : Pierre Ossman, Chris Gordon - * Original Logo : Michael Sersen + * UI and icons : Pierre Ossman, Chris Gordon + * Original logo : Michael Sersen * tight encoding : Michael Tinglof (Mercuri.ca) * RealVNC RSA AES authentication : USTC Vlab Team diff --git a/app/error-handler.js b/app/error-handler.js index 67b63720c..5f6ffb674 100644 --- a/app/error-handler.js +++ b/app/error-handler.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/app/localization.js b/app/localization.js index 7d7e6e6af..c8257fdbe 100644 --- a/app/localization.js +++ b/app/localization.js @@ -1,13 +1,13 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. */ /* - * Localization Utilities + * Localization utilities */ export class Localizer { diff --git a/app/styles/base.css b/app/styles/base.css index f83ad4b93..395c18e62 100644 --- a/app/styles/base.css +++ b/app/styles/base.css @@ -1,6 +1,6 @@ /* * noVNC base CSS - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). */ @@ -213,7 +213,7 @@ html { } /* ---------------------------------------- - * Control Bar + * Control bar * ---------------------------------------- */ @@ -629,13 +629,13 @@ html { margin-left: 1rem; } -/* Connection Controls */ +/* Connection controls */ :root:not(.noVNC_connected) #noVNC_disconnect_button { display: none; } /* ---------------------------------------- - * Status Dialog + * Status dialog * ---------------------------------------- */ @@ -701,7 +701,7 @@ html { } /* ---------------------------------------- - * Connect Dialog + * Connect dialog * ---------------------------------------- */ @@ -770,7 +770,7 @@ html { } /* ---------------------------------------- - * Server verification Dialog + * Server verification dialog * ---------------------------------------- */ @@ -787,7 +787,7 @@ html { } /* ---------------------------------------- - * Password Dialog + * Password dialog * ---------------------------------------- */ @@ -806,7 +806,7 @@ html { /* ---------------------------------------- - * Main Area + * Main area * ---------------------------------------- */ diff --git a/app/styles/input.css b/app/styles/input.css index dc345aabc..911cf20cf 100644 --- a/app/styles/input.css +++ b/app/styles/input.css @@ -1,6 +1,6 @@ /* * noVNC general input element CSS - * Copyright (C) 2022 The noVNC Authors + * Copyright (C) 2022 The noVNC authors * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). */ diff --git a/app/ui.js b/app/ui.js index 39d28a33d..fd23c8007 100644 --- a/app/ui.js +++ b/app/ui.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/app/webutil.js b/app/webutil.js index 6011442cb..1ecdc1282 100644 --- a/app/webutil.js +++ b/app/webutil.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. @@ -27,7 +27,7 @@ export function initLogging(level) { // the url can be requested in the following way: // https://www.example.com#myqueryparam=myvalue&password=secretvalue // -// Even Mixing public and non public parameters will work: +// Even mixing public and non public parameters will work: // https://www.example.com?nonsecretparam=example.com#password=secretvalue export function getQueryVar(name, defVal) { "use strict"; diff --git a/core/crypto/md5.js b/core/crypto/md5.js index fcfefff06..b01ba6fd0 100644 --- a/core/crypto/md5.js +++ b/core/crypto/md5.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2021 The noVNC Authors + * Copyright (C) 2021 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/copyrect.js b/core/decoders/copyrect.js index 9e6391a17..3c7e0d5dc 100644 --- a/core/decoders/copyrect.js +++ b/core/decoders/copyrect.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/h264.js b/core/decoders/h264.js index 2587d61be..a508b6741 100644 --- a/core/decoders/h264.js +++ b/core/decoders/h264.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2024 The noVNC Authors + * Copyright (C) 2024 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/hextile.js b/core/decoders/hextile.js index cc33e0e10..db0792bd4 100644 --- a/core/decoders/hextile.js +++ b/core/decoders/hextile.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/jpeg.js b/core/decoders/jpeg.js index feb2aeb6c..5fd1e0564 100644 --- a/core/decoders/jpeg.js +++ b/core/decoders/jpeg.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/raw.js b/core/decoders/raw.js index 3c1661425..bd5d20445 100644 --- a/core/decoders/raw.js +++ b/core/decoders/raw.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/rre.js b/core/decoders/rre.js index 6219369d6..a5fea7c46 100644 --- a/core/decoders/rre.js +++ b/core/decoders/rre.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/tight.js b/core/decoders/tight.js index 8bc977a79..1a145d4e5 100644 --- a/core/decoders/tight.js +++ b/core/decoders/tight.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) * Licensed under MPL 2.0 (see LICENSE.txt) * diff --git a/core/decoders/tightpng.js b/core/decoders/tightpng.js index 82f492de8..cf1df6ba1 100644 --- a/core/decoders/tightpng.js +++ b/core/decoders/tightpng.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/zlib.js b/core/decoders/zlib.js index d1e5d5c98..a876908b6 100644 --- a/core/decoders/zlib.js +++ b/core/decoders/zlib.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2024 The noVNC Authors + * Copyright (C) 2024 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/decoders/zrle.js b/core/decoders/zrle.js index 49128e798..ef1726f69 100644 --- a/core/decoders/zrle.js +++ b/core/decoders/zrle.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2021 The noVNC Authors + * Copyright (C) 2021 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/deflator.js b/core/deflator.js index 22f6770b3..af24009e1 100644 --- a/core/deflator.js +++ b/core/deflator.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors + * Copyright (C) 2020 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/display.js b/core/display.js index bc0bf2190..ef42ac666 100644 --- a/core/display.js +++ b/core/display.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/encodings.js b/core/encodings.js index f037510b8..bf25ac917 100644 --- a/core/encodings.js +++ b/core/encodings.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/inflator.js b/core/inflator.js index f851f2a7d..7ef47f13f 100644 --- a/core/inflator.js +++ b/core/inflator.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors + * Copyright (C) 2020 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/input/domkeytable.js b/core/input/domkeytable.js index f79aeadfa..9e599f748 100644 --- a/core/input/domkeytable.js +++ b/core/input/domkeytable.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 or any later version (see LICENSE.txt) */ diff --git a/core/input/fixedkeys.js b/core/input/fixedkeys.js index 4d09f2f7e..6a9221580 100644 --- a/core/input/fixedkeys.js +++ b/core/input/fixedkeys.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 or any later version (see LICENSE.txt) */ diff --git a/core/input/gesturehandler.js b/core/input/gesturehandler.js index 6fa72d2aa..b072e01db 100644 --- a/core/input/gesturehandler.js +++ b/core/input/gesturehandler.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors + * Copyright (C) 2020 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/input/keyboard.js b/core/input/keyboard.js index ff14de849..3cc89174d 100644 --- a/core/input/keyboard.js +++ b/core/input/keyboard.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 or any later version (see LICENSE.txt) */ diff --git a/core/input/vkeys.js b/core/input/vkeys.js index dacc35809..d848337a7 100644 --- a/core/input/vkeys.js +++ b/core/input/vkeys.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 or any later version (see LICENSE.txt) */ diff --git a/core/rfb.js b/core/rfb.js index 0007bed86..9559e487d 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors + * Copyright (C) 2020 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. @@ -1378,7 +1378,7 @@ export default class RFB extends EventTargetMixin { } } - // Message Handlers + // Message handlers _negotiateProtocolVersion() { if (this._sock.rQwait("version", 12)) { @@ -2427,7 +2427,7 @@ export default class RFB extends EventTargetMixin { switch (xvpMsg) { case 0: // XVP_FAIL - Log.Error("XVP Operation Failed"); + Log.Error("XVP operation failed"); break; case 1: // XVP_INIT this._rfbXvpVer = xvpVer; @@ -2756,7 +2756,7 @@ export default class RFB extends EventTargetMixin { } _handleLedEvent() { - if (this._sock.rQwait("LED Status", 1)) { + if (this._sock.rQwait("LED status", 1)) { return false; } diff --git a/core/util/browser.js b/core/util/browser.js index 407cad9cb..2c3667650 100644 --- a/core/util/browser.js +++ b/core/util/browser.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/util/cursor.js b/core/util/cursor.js index 20e75f1b2..6d689e7d5 100644 --- a/core/util/cursor.js +++ b/core/util/cursor.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 or any later version (see LICENSE.txt) */ diff --git a/core/util/element.js b/core/util/element.js index 466a7453e..17d82d58f 100644 --- a/core/util/element.js +++ b/core/util/element.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors + * Copyright (C) 2020 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/util/events.js b/core/util/events.js index eb09fe1e2..26aa97908 100644 --- a/core/util/events.js +++ b/core/util/events.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/util/eventtarget.js b/core/util/eventtarget.js index a21aa5494..547bf5fa2 100644 --- a/core/util/eventtarget.js +++ b/core/util/eventtarget.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/util/int.js b/core/util/int.js index 001f40f2a..303ddc5fd 100644 --- a/core/util/int.js +++ b/core/util/int.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2020 The noVNC Authors + * Copyright (C) 2020 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/util/logging.js b/core/util/logging.js index fe449e935..0db083856 100644 --- a/core/util/logging.js +++ b/core/util/logging.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/util/strings.js b/core/util/strings.js index 3dd4b29fb..432b0a9d2 100644 --- a/core/util/strings.js +++ b/core/util/strings.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. diff --git a/core/websock.js b/core/websock.js index 61a3091a3..ae17a4409 100644 --- a/core/websock.js +++ b/core/websock.js @@ -1,6 +1,6 @@ /* * Websock: high-performance buffering wrapper - * Copyright (C) 2019 The noVNC Authors + * Copyright (C) 2019 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) * * Websock is similar to the standard WebSocket / RTCDataChannel object @@ -70,7 +70,7 @@ export default class Websock { }; } - // Getters and Setters + // Getters and setters get readyState() { let subState; @@ -94,7 +94,7 @@ export default class Websock { return "unknown"; } - // Receive Queue + // Receive queue rQpeek8() { return this._rQ[this._rQi]; } @@ -173,7 +173,7 @@ export default class Websock { return false; } - // Send Queue + // Send queue sQpush8(num) { this._sQensureSpace(1); @@ -227,7 +227,7 @@ export default class Websock { } } - // Event Handlers + // Event handlers off(evt) { this._eventHandlers[evt] = () => {}; } @@ -325,7 +325,7 @@ export default class Websock { if (this._rQbufferSize > MAX_RQ_GROW_SIZE) { this._rQbufferSize = MAX_RQ_GROW_SIZE; if (this._rQbufferSize - (this._rQlen - this._rQi) < minFit) { - throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); + throw new Error("Receive queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); } } diff --git a/docs/API-internal.md b/docs/API-internal.md index c41e0f326..5b41548ed 100644 --- a/docs/API-internal.md +++ b/docs/API-internal.md @@ -1,4 +1,4 @@ -# 1. Internal Modules +# 1. Internal modules The noVNC client is composed of several internal modules that handle rendering, input, networking, etc. Each of the modules is designed to @@ -9,7 +9,7 @@ stable, and this documentation is not maintained as well as the official external API. -## 1.1 Module List +## 1.1 Module list * __Keyboard__ (core/input/keyboard.js): Keyboard input event handler with non-US keyboard support. Translates keyDown and keyUp events to X11 @@ -32,9 +32,9 @@ callback event name, and the callback function. ## 2. Modules -## 2.1 Keyboard Module +## 2.1 Keyboard module -### 2.1.1 Configuration Attributes +### 2.1.1 Configuration attributes None @@ -52,9 +52,9 @@ None | onkeypress | (keysym, code, down) | Handler for key press/release -## 2.2 Display Module +## 2.2 Display module -### 2.2.1 Configuration Attributes +### 2.2.1 Configuration attributes | name | type | mode | default | description | ------------ | ----- | ---- | ------- | ------------ diff --git a/docs/EMBEDDING.md b/docs/EMBEDDING.md index 105001410..b411de82b 100644 --- a/docs/EMBEDDING.md +++ b/docs/EMBEDDING.md @@ -1,4 +1,4 @@ -# Embedding and Deploying noVNC Application +# Embedding and deploying noVNC application This document describes how to embed and deploy the noVNC application, which includes settings and a full user interface. If you are looking for @@ -71,8 +71,8 @@ query string. Currently the following options are available: * `logging` - The console log level. Can be one of `error`, `warn`, `info` or `debug`. -## HTTP Serving Considerations -### Browser Cache Issue +## HTTP serving considerations +### Browser cache issue If you serve noVNC files using a web server that provides an ETag header, and include any options in the query string, a nasty browser cache issue can bite @@ -84,7 +84,7 @@ to always revalidate cached files using conditional requests. The correct semantics are achieved via the (confusingly named) `Cache-Control: no-cache` header that needs to be provided in the web server responses. -### Example Server Configurations +### Example server configurations Apache: diff --git a/docs/LIBRARY.md b/docs/LIBRARY.md index 3890bb20c..ec2f4e02c 100644 --- a/docs/LIBRARY.md +++ b/docs/LIBRARY.md @@ -16,7 +16,7 @@ noVNC includes a small example application called `vnc_lite.html`. This does not make use of all the features of noVNC, but is a good start to see how to do things. -## Conversion of Modules +## Conversion of modules noVNC is written using ECMAScript 6 modules. This is not supported by older versions of Node.js. To use noVNC with those older versions of Node.js the diff --git a/docs/novnc_proxy.1 b/docs/novnc_proxy.1 index 259e1b413..1a844e8d2 100644 --- a/docs/novnc_proxy.1 +++ b/docs/novnc_proxy.1 @@ -30,7 +30,7 @@ provides a cut-and-paste URL to go to. active connections .SH AUTHOR -The noVNC Authors +The noVNC authors https://github.com/novnc/noVNC .SH SEE ALSO diff --git a/po/Makefile b/po/Makefile index 61a233bdd..dcf5ba446 100644 --- a/po/Makefile +++ b/po/Makefile @@ -19,7 +19,7 @@ update-js: $(JSONFILES) update-pot: xgettext --output=noVNC.js.pot \ - --copyright-holder="The noVNC Authors" \ + --copyright-holder="The noVNC authors" \ --package-name="noVNC" \ --package-version="$(VERSION)" \ --msgid-bugs-address="novnc@googlegroups.com" \ diff --git a/po/po2js b/po/po2js index e293deda6..23b8bb24a 100755 --- a/po/po2js +++ b/po/po2js @@ -1,7 +1,7 @@ #!/usr/bin/env node /* * ps2js: gettext .po to noVNC .js converter - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/po/xgettext-html b/po/xgettext-html index ae53461ce..72d492354 100755 --- a/po/xgettext-html +++ b/po/xgettext-html @@ -1,7 +1,7 @@ #!/usr/bin/env node /* * xgettext-html: HTML gettext parser - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) */ diff --git a/tests/playback.js b/tests/playback.js index 955df0ee3..881a55bfe 100644 --- a/tests/playback.js +++ b/tests/playback.js @@ -1,6 +1,6 @@ /* * noVNC: HTML5 VNC client - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) */ diff --git a/tests/test.base64.js b/tests/test.base64.js index e5644dcdb..87a6aa517 100644 --- a/tests/test.base64.js +++ b/tests/test.base64.js @@ -1,6 +1,6 @@ import Base64 from '../core/base64.js'; -describe('Base64 Tools', function () { +describe('Base64 tools', function () { "use strict"; const BIN_ARR = new Array(256); diff --git a/tests/test.copyrect.js b/tests/test.copyrect.js index 60c395287..15323eb27 100644 --- a/tests/test.copyrect.js +++ b/tests/test.copyrect.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('CopyRect Decoder', function () { +describe('CopyRect decoder', function () { let decoder; let display; diff --git a/tests/test.display.js b/tests/test.display.js index d2c51793b..5844ce172 100644 --- a/tests/test.display.js +++ b/tests/test.display.js @@ -1,7 +1,7 @@ import Base64 from '../core/base64.js'; import Display from '../core/display.js'; -describe('Display/Canvas Helper', function () { +describe('Display/Canvas helper', function () { const checkedData = new Uint8ClampedArray([ 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, diff --git a/tests/test.h264.js b/tests/test.h264.js index e6fbacb8c..01bddadc3 100644 --- a/tests/test.h264.js +++ b/tests/test.h264.js @@ -108,7 +108,7 @@ function almost(a, b) { return diff < 5; } -describe('H.264 Parser', function () { +describe('H.264 parser', function () { it('should parse constrained baseline video', function () { let parser = new H264Parser(redGreenBlue16x16Video); @@ -130,7 +130,7 @@ describe('H.264 Parser', function () { }); }); -describe('H.264 Decoder Unit Test', function () { +describe('H.264 decoder unit test', function () { let decoder; beforeEach(function () { @@ -181,7 +181,7 @@ describe('H.264 Decoder Unit Test', function () { }); }); -describe('H.264 Decoder Functional Test', function () { +describe('H.264 decoder functional test', function () { let decoder; let display; diff --git a/tests/test.hextile.js b/tests/test.hextile.js index f788fd4dc..25e412ba1 100644 --- a/tests/test.hextile.js +++ b/tests/test.hextile.js @@ -36,7 +36,7 @@ function push32(arr, num) { num & 0xFF); } -describe('Hextile Decoder', function () { +describe('Hextile decoder', function () { let decoder; let display; diff --git a/tests/test.jpeg.js b/tests/test.jpeg.js index 5cc153f90..063a5f2c5 100644 --- a/tests/test.jpeg.js +++ b/tests/test.jpeg.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('JPEG Decoder', function () { +describe('JPEG decoder', function () { let decoder; let display; diff --git a/tests/test.keyboard.js b/tests/test.keyboard.js index 11c8b6eb7..47be623d8 100644 --- a/tests/test.keyboard.js +++ b/tests/test.keyboard.js @@ -1,6 +1,6 @@ import Keyboard from '../core/input/keyboard.js'; -describe('Key Event Handling', function () { +describe('Key event handling', function () { "use strict"; // The real KeyboardEvent constructor might not work everywhere we @@ -19,7 +19,7 @@ describe('Key Event Handling', function () { return e; } - describe('Decode Keyboard Events', function () { + describe('Decode keyboard events', function () { it('should decode keydown events', function (done) { const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { @@ -68,7 +68,7 @@ describe('Key Event Handling', function () { }); }); - describe('Track Key State', function () { + describe('Track key state', function () { it('should send release using the same keysym as the press', function (done) { const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { @@ -101,7 +101,7 @@ describe('Key Event Handling', function () { expect(kbd.onkeyevent).to.not.have.been.called; }); - describe('Legacy Events', function () { + describe('Legacy events', function () { it('should track keys using keyCode if no code', function (done) { const kbd = new Keyboard(document); kbd.onkeyevent = (keysym, code, down) => { diff --git a/tests/test.raw.js b/tests/test.raw.js index 19b2377f7..e40813ca1 100644 --- a/tests/test.raw.js +++ b/tests/test.raw.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('Raw Decoder', function () { +describe('Raw decoder', function () { let decoder; let display; diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 2be3bfbfc..19894ba11 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -67,7 +67,7 @@ function deflateWithSize(data) { return new Uint8Array(strm.output.buffer, 0, strm.next_out); } -describe('Remote Frame Buffer Protocol Client', function () { +describe('Remote Frame Buffer protocol client', function () { let clock; let raf; let fakeResizeObserver = null; @@ -287,7 +287,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Public API Basic Behavior', function () { + describe('Public API basic behavior', function () { let client; beforeEach(function () { client = makeRFB(); @@ -1027,7 +1027,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Misc Internals', function () { + describe('Misc internals', function () { describe('#_fail', function () { let client; beforeEach(function () { @@ -1068,7 +1068,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Protocol Initialization States', function () { + describe('Protocol initialization states', function () { let client; beforeEach(function () { client = makeRFB(); @@ -1226,7 +1226,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Legacy Authentication', function () { + describe('Legacy authentication', function () { it('should fail on auth scheme 0 (pre 3.7) with the given message', function () { const errMsg = "Whoopsies"; const data = [0, 0, 0, 0]; @@ -1286,7 +1286,7 @@ describe('Remote Frame Buffer Protocol Client', function () { expect(callback.args[0][0].detail.clean).to.be.false; }); - describe('VNC Authentication (type 2) Handler', function () { + describe('VNC authentication (type 2) handler', function () { it('should fire the credentialsrequired event if missing a password', function () { const spy = sinon.spy(); client.addEventListener("credentialsrequired", spy); @@ -1331,7 +1331,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('RSA-AES Authentication (type 6) Handler', function () { + describe('RSA-AES authentication (type 6) handler', function () { function fakeGetRandomValues(arr) { if (arr.length === 16) { arr.set(new Uint8Array([ @@ -1776,7 +1776,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('ARD Authentication (type 30) Handler', function () { + describe('ARD authentication (type 30) handler', function () { let byteArray = new Uint8Array(Array.from(new Uint8Array(128).keys())); function fakeGetRandomValues(arr) { if (arr.length == 128) { @@ -1869,7 +1869,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('MSLogonII Authentication (type 113) Handler', function () { + describe('MSLogonII authentication (type 113) handler', function () { function fakeGetRandomValues(arr) { if (arr.length == 8) { arr.set(new Uint8Array([0, 0, 0, 0, 5, 6, 7, 8])); @@ -1952,7 +1952,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('XVP Authentication (type 22) Handler', function () { + describe('XVP authentication (type 22) handler', function () { it('should fall through to standard VNC authentication upon completion', function () { client.addEventListener("credentialsrequired", () => { client.sendCredentials({ username: 'user', @@ -2001,7 +2001,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('TightVNC Authentication (type 16) Handler', function () { + describe('TightVNC authentication (type 16) handler', function () { beforeEach(function () { sendSecurity(16, client); client._sock._websocket._getSentData(); // skip the security reply @@ -2088,7 +2088,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('VeNCrypt Authentication (type 19) Handler', function () { + describe('VeNCrypt authentication (type 19) handler', function () { beforeEach(function () { sendSecurity(19, client); expect(client._sock).to.have.sent(new Uint8Array([19])); @@ -2171,7 +2171,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Plain Authentication (type 256) Handler', function () { + describe('Plain authentication (type 256) handler', function () { beforeEach(function () { sendSecurity(19, client); expect(client._sock).to.have.sent(new Uint8Array([19])); @@ -2430,7 +2430,7 @@ describe('Remote Frame Buffer Protocol Client', function () { expect(client._keyboard.grab).to.have.been.calledOnce; }); - describe('Initial Update Request', function () { + describe('Initial update request', function () { beforeEach(function () { sinon.spy(RFB.messages, "pixelFormat"); sinon.spy(RFB.messages, "clientEncodings"); @@ -2485,7 +2485,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Protocol Message Processing After Completing Initialization', function () { + describe('Protocol message processing after completing initialization', function () { let client; beforeEach(function () { @@ -2495,7 +2495,7 @@ describe('Remote Frame Buffer Protocol Client', function () { client._fbHeight = 20; }); - describe('Framebuffer Update Handling', function () { + describe('Framebuffer update handling', function () { function sendFbuMsg(rectInfo, rectData, client, rectCnt) { let data = []; @@ -2576,7 +2576,7 @@ describe('Remote Frame Buffer Protocol Client', function () { expect(callback.args[0][0].detail.clean).to.be.false; }); - describe('Message Encoding Handlers', function () { + describe('Message encoding handlers', function () { beforeEach(function () { // a really small frame client._fbWidth = 4; @@ -2817,7 +2817,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('the VMware Cursor pseudo-encoding handler', function () { + describe('the VMware cursor pseudo-encoding handler', function () { beforeEach(function () { sinon.spy(client._cursor, 'change'); }); @@ -3150,7 +3150,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('XVP Message Handling', function () { + describe('XVP message handling', function () { it('should set the XVP version and fire the callback with the version on XVP_INIT', function () { const spy = sinon.spy(); client.addEventListener("capabilities", spy); @@ -3172,7 +3172,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Normal Clipboard Handling Receive', function () { + describe('Normal clipboard handling receive', function () { it('should fire the clipboard callback with the retrieved text on ServerCutText', function () { const expectedStr = 'cheese!'; const data = [3, 0, 0, 0]; @@ -3187,7 +3187,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Extended clipboard Handling', function () { + describe('Extended clipboard handling', function () { describe('Extended clipboard initialization', function () { beforeEach(function () { @@ -3222,7 +3222,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); - describe('Extended Clipboard Handling Receive', function () { + describe('Extended clipboard handling receive', function () { beforeEach(function () { // Send our capabilities @@ -3493,7 +3493,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Asynchronous Events', function () { + describe('Asynchronous events', function () { let client; let pointerEvent; let keyEvent; @@ -3537,7 +3537,7 @@ describe('Remote Frame Buffer Protocol Client', function () { return res; } - describe('Mouse Events', function () { + describe('Mouse events', function () { function sendMouseMoveEvent(x, y) { let pos = elementToClient(x, y); let ev; @@ -3663,7 +3663,7 @@ describe('Remote Frame Buffer Protocol Client', function () { 50, 70, 0x0); }); - describe('Event Aggregation', function () { + describe('Event aggregation', function () { it('should send a single pointer event on mouse movement', function () { sendMouseMoveEvent(50, 70); clock.tick(100); @@ -3790,7 +3790,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Wheel Events', function () { + describe('Wheel events', function () { function sendWheelEvent(x, y, dx, dy, mode=0) { let pos = elementToClient(x, y); let ev; @@ -3900,7 +3900,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('Keyboard Events', function () { + describe('Keyboard events', function () { it('should send a key message on a key press', function () { let esock = new Websock(); let ews = new FakeWebSocket(); @@ -4613,7 +4613,7 @@ describe('Remote Frame Buffer Protocol Client', function () { }); }); - describe('WebSocket Events', function () { + describe('WebSocket events', function () { // message events it('should do nothing if we receive an empty message and have nothing in the queue', function () { sinon.spy(client, "_normalMsg"); @@ -4901,7 +4901,7 @@ describe('RFB messages', function () { sock.attach(websock); }); - describe('Input Events', function () { + describe('Input events', function () { it('should send correct data for keyboard events', function () { // FIXME: down should be boolean RFB.messages.keyEvent(sock, 0x12345678, 0); @@ -4936,7 +4936,7 @@ describe('RFB messages', function () { }); }); - describe('Clipboard Events', function () { + describe('Clipboard events', function () { it('should send correct data for clipboard events', function () { RFB.messages.clientCutText(sock, new Uint8Array([ 0x01, 0x23, 0x45, 0x67 ])); let expected = @@ -4946,7 +4946,7 @@ describe('RFB messages', function () { }); }); - describe('Extended Clipboard Handling Send', function () { + describe('Extended clipboard handling send', function () { it('should call clientCutText with correct Caps data', function () { let formats = { 0: 2, @@ -5133,7 +5133,7 @@ describe('RFB messages', function () { }); }); - describe('Screen Layout', function () { + describe('Screen layout', function () { it('should send correct data for screen layout changes', function () { RFB.messages.setDesktopSize(sock, 12345, 54321, 0x12345678, 0x90abcdef); let expected = @@ -5155,7 +5155,7 @@ describe('RFB messages', function () { }); }); - describe('Continuous Updates', function () { + describe('Continuous updates', function () { it('should send correct data for continuous updates configuration', function () { // FIXME: enable should be boolean RFB.messages.enableContinuousUpdates(sock, 0, 12345, 54321, 34343, 18181); @@ -5165,7 +5165,7 @@ describe('RFB messages', function () { }); }); - describe('Pixel Format', function () { + describe('Pixel format', function () { it('should send correct data for normal depth', function () { RFB.messages.pixelFormat(sock, 24, true); let expected = diff --git a/tests/test.rre.js b/tests/test.rre.js index 7b5f73d0e..b47fbcafd 100644 --- a/tests/test.rre.js +++ b/tests/test.rre.js @@ -41,7 +41,7 @@ function push32(arr, num) { num & 0xFF); } -describe('RRE Decoder', function () { +describe('RRE decoder', function () { let decoder; let display; diff --git a/tests/test.tight.js b/tests/test.tight.js index 3d6b555da..ebdfd969e 100644 --- a/tests/test.tight.js +++ b/tests/test.tight.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('Tight Decoder', function () { +describe('Tight decoder', function () { let decoder; let display; diff --git a/tests/test.tightpng.js b/tests/test.tightpng.js index e7edc8fa6..29c8caa47 100644 --- a/tests/test.tightpng.js +++ b/tests/test.tightpng.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('TightPng Decoder', function () { +describe('TightPng decoder', function () { let decoder; let display; diff --git a/tests/test.websock.js b/tests/test.websock.js index ab09f4508..62bcbfa59 100644 --- a/tests/test.websock.js +++ b/tests/test.websock.js @@ -535,7 +535,7 @@ describe('Websock', function () { }); }); - describe('WebSocket Receiving', function () { + describe('WebSocket receiving', function () { let sock; beforeEach(function () { sock = new Websock(); diff --git a/tests/test.zlib.js b/tests/test.zlib.js index bc72137e5..13411c1ff 100644 --- a/tests/test.zlib.js +++ b/tests/test.zlib.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('Zlib Decoder', function () { +describe('Zlib decoder', function () { let decoder; let display; diff --git a/tests/test.zrle.js b/tests/test.zrle.js index f7c6089d5..157291029 100644 --- a/tests/test.zrle.js +++ b/tests/test.zrle.js @@ -29,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) { return done; } -describe('ZRLE Decoder', function () { +describe('ZRLE decoder', function () { let decoder; let display; diff --git a/tests/vnc_playback.html b/tests/vnc_playback.html index ffa69906d..8b4ba39a4 100644 --- a/tests/vnc_playback.html +++ b/tests/vnc_playback.html @@ -1,7 +1,7 @@ - VNC Playback + VNC playback diff --git a/utils/genkeysymdef.js b/utils/genkeysymdef.js index f539a0b28..b10240ec4 100755 --- a/utils/genkeysymdef.js +++ b/utils/genkeysymdef.js @@ -1,7 +1,7 @@ #!/usr/bin/env node /* * genkeysymdef: X11 keysymdef.h to JavaScript converter - * Copyright (C) 2018 The noVNC Authors + * Copyright (C) 2018 The noVNC authors * Licensed under MPL 2.0 (see LICENSE.txt) */ diff --git a/utils/novnc_proxy b/utils/novnc_proxy index 4b2e3032d..6b55504a5 100755 --- a/utils/novnc_proxy +++ b/utils/novnc_proxy @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # Licensed under MPL 2.0 or any later version (see LICENSE.txt) usage() { @@ -82,7 +82,7 @@ cleanup() { fi } -# Process Arguments +# Process arguments # Arguments that only apply to chrooter itself while [ "$*" ]; do diff --git a/vnc.html b/vnc.html index fd8877304..c2cc4e555 100644 --- a/vnc.html +++ b/vnc.html @@ -4,7 +4,7 @@ +
    @@ -123,18 +123,18 @@

    no
    VNC

    + title="Move/Drag viewport"> - +
    + id="noVNC_keyboard_button" class="noVNC_button" title="Show keyboard">
    + title="Show extra keys">
    no
    VNC
    - + title="Full screen"> no
    VNC
    • - +
    • - +

    • - +
    • - +

    • @@ -261,15 +261,15 @@

      no
      VNC


    • - +
    • - +

    • - +

    • @@ -290,7 +290,7 @@

      no
      VNC

    - + @@ -305,7 +305,7 @@

    no
    VNC

    - +
    @@ -320,7 +320,7 @@

    no
    VNC

    - +
    @@ -344,7 +344,7 @@

    no
    VNC

    - +
    @@ -359,12 +359,12 @@

    no
    VNC

    - +
    - +
    diff --git a/vnc_lite.html b/vnc_lite.html index eaf75f869..79d481460 100644 --- a/vnc_lite.html +++ b/vnc_lite.html @@ -7,7 +7,7 @@ This is a self-contained file which doesn't import WebUtil or external CSS. - Copyright (C) 2019 The noVNC Authors + Copyright (C) 2019 The noVNC authors noVNC is licensed under the MPL 2.0 (see LICENSE.txt) This file is licensed under the 2-Clause BSD license (see LICENSE.txt). @@ -80,7 +80,7 @@ // When this function is called, the server requires // credentials to authenticate function credentialsAreRequired(e) { - const password = prompt("Password Required:"); + const password = prompt("Password required:"); rfb.sendCredentials({ password: password }); } From 7335bb440d1fc3eb527cb5e6851aa21c3a3293e3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 27 Nov 2024 14:57:55 +0100 Subject: [PATCH 14/19] Also adjust to "sentence case" in translations This would have resolved itself automatically on the next translation update, but this commit will reduce unnecessary noise in that change. --- app/locale/cs.json | 24 ++++++++++++------------ app/locale/de.json | 22 +++++++++++----------- app/locale/es.json | 16 ++++++++-------- app/locale/fr.json | 24 ++++++++++++------------ app/locale/it.json | 6 +++--- app/locale/ja.json | 28 ++++++++++++++-------------- app/locale/ko.json | 22 +++++++++++----------- app/locale/nl.json | 6 +++--- app/locale/pl.json | 12 ++++++------ app/locale/pt_BR.json | 26 +++++++++++++------------- app/locale/ru.json | 20 ++++++++++---------- app/locale/sv.json | 8 ++++---- app/locale/tr.json | 2 +- app/locale/zh_CN.json | 22 +++++++++++----------- app/locale/zh_TW.json | 22 +++++++++++----------- po/cs.po | 26 +++++++++++++------------- po/de.po | 24 ++++++++++++------------ po/el.po | 2 +- po/es.po | 18 +++++++++--------- po/fr.po | 26 +++++++++++++------------- po/it.po | 12 ++++++------ po/ja.po | 30 +++++++++++++++--------------- po/ko.po | 24 ++++++++++++------------ po/nl.po | 8 ++++---- po/noVNC.pot | 30 +++++++++++++++--------------- po/pl.po | 14 +++++++------- po/pt_BR.po | 28 ++++++++++++++-------------- po/ru.po | 20 ++++++++++---------- po/sv.po | 10 +++++----- po/tr.po | 4 ++-- po/zh_CN.po | 24 ++++++++++++------------ po/zh_TW.po | 24 ++++++++++++------------ 32 files changed, 292 insertions(+), 292 deletions(-) diff --git a/app/locale/cs.json b/app/locale/cs.json index 589145ef3..dd31e6c18 100644 --- a/app/locale/cs.json +++ b/app/locale/cs.json @@ -14,7 +14,7 @@ "Password is required": "Je vyžadováno heslo", "noVNC encountered an error:": "noVNC narazilo na chybu:", "Hide/Show the control bar": "Skrýt/zobrazit ovládací panel", - "Move/Drag Viewport": "Přesunout/přetáhnout výřez", + "Move/Drag viewport": "Přesunout/přetáhnout výřez", "viewport drag": "přesun výřezu", "Active Mouse Button": "Aktivní tlačítka myši", "No mousebutton": "Žádné", @@ -22,9 +22,9 @@ "Middle mousebutton": "Prostřední tlačítko myši", "Right mousebutton": "Pravé tlačítko myši", "Keyboard": "Klávesnice", - "Show Keyboard": "Zobrazit klávesnici", + "Show keyboard": "Zobrazit klávesnici", "Extra keys": "Extra klávesy", - "Show Extra Keys": "Zobrazit extra klávesy", + "Show extra keys": "Zobrazit extra klávesy", "Ctrl": "Ctrl", "Toggle Ctrl": "Přepnout Ctrl", "Alt": "Alt", @@ -45,13 +45,13 @@ "Clear": "Vymazat", "Fullscreen": "Celá obrazovka", "Settings": "Nastavení", - "Shared Mode": "Sdílený režim", - "View Only": "Pouze prohlížení", - "Clip to Window": "Přizpůsobit oknu", - "Scaling Mode:": "Přizpůsobení velikosti", + "Shared mode": "Sdílený režim", + "View only": "Pouze prohlížení", + "Clip to window": "Přizpůsobit oknu", + "Scaling mode:": "Přizpůsobení velikosti", "None": "Žádné", - "Local Scaling": "Místní", - "Remote Resizing": "Vzdálené", + "Local scaling": "Místní", + "Remote resizing": "Vzdálené", "Advanced": "Pokročilé", "Repeater ID:": "ID opakovače", "WebSocket": "WebSocket", @@ -59,9 +59,9 @@ "Host:": "Hostitel:", "Port:": "Port:", "Path:": "Cesta", - "Automatic Reconnect": "Automatická obnova připojení", - "Reconnect Delay (ms):": "Zpoždění připojení (ms)", - "Show Dot when No Cursor": "Tečka místo chybějícího kurzoru myši", + "Automatic reconnect": "Automatická obnova připojení", + "Reconnect delay (ms):": "Zpoždění připojení (ms)", + "Show dot when no cursor": "Tečka místo chybějícího kurzoru myši", "Logging:": "Logování:", "Disconnect": "Odpojit", "Connect": "Připojit", diff --git a/app/locale/de.json b/app/locale/de.json index 62e73360f..e92825a8b 100644 --- a/app/locale/de.json +++ b/app/locale/de.json @@ -13,7 +13,7 @@ "Password is required": "Passwort ist erforderlich", "noVNC encountered an error:": "Ein Fehler ist aufgetreten:", "Hide/Show the control bar": "Kontrollleiste verstecken/anzeigen", - "Move/Drag Viewport": "Ansichtsfenster verschieben/ziehen", + "Move/Drag viewport": "Ansichtsfenster verschieben/ziehen", "viewport drag": "Ansichtsfenster ziehen", "Active Mouse Button": "Aktive Maustaste", "No mousebutton": "Keine Maustaste", @@ -21,9 +21,9 @@ "Middle mousebutton": "Mittlere Maustaste", "Right mousebutton": "Rechte Maustaste", "Keyboard": "Tastatur", - "Show Keyboard": "Tastatur anzeigen", + "Show keyboard": "Tastatur anzeigen", "Extra keys": "Zusatztasten", - "Show Extra Keys": "Zusatztasten anzeigen", + "Show extra keys": "Zusatztasten anzeigen", "Ctrl": "Strg", "Toggle Ctrl": "Strg umschalten", "Alt": "Alt", @@ -44,13 +44,13 @@ "Clear": "Löschen", "Fullscreen": "Vollbild", "Settings": "Einstellungen", - "Shared Mode": "Geteilter Modus", - "View Only": "Nur betrachten", - "Clip to Window": "Auf Fenster begrenzen", - "Scaling Mode:": "Skalierungsmodus:", + "Shared mode": "Geteilter Modus", + "View only": "Nur betrachten", + "Clip to window": "Auf Fenster begrenzen", + "Scaling mode:": "Skalierungsmodus:", "None": "Keiner", - "Local Scaling": "Lokales skalieren", - "Remote Resizing": "Serverseitiges skalieren", + "Local scaling": "Lokales skalieren", + "Remote resizing": "Serverseitiges skalieren", "Advanced": "Erweitert", "Repeater ID:": "Repeater ID:", "WebSocket": "WebSocket", @@ -58,8 +58,8 @@ "Host:": "Server:", "Port:": "Port:", "Path:": "Pfad:", - "Automatic Reconnect": "Automatisch wiederverbinden", - "Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):", + "Automatic reconnect": "Automatisch wiederverbinden", + "Reconnect delay (ms):": "Wiederverbindungsverzögerung (ms):", "Logging:": "Protokollierung:", "Disconnect": "Verbindung trennen", "Connect": "Verbinden", diff --git a/app/locale/es.json b/app/locale/es.json index b9e663a3d..bb088243c 100644 --- a/app/locale/es.json +++ b/app/locale/es.json @@ -10,7 +10,7 @@ "Disconnect timeout": "Tiempo de desconexión agotado", "noVNC encountered an error:": "noVNC ha encontrado un error:", "Hide/Show the control bar": "Ocultar/Mostrar la barra de control", - "Move/Drag Viewport": "Mover/Arrastrar la ventana", + "Move/Drag viewport": "Mover/Arrastrar la ventana", "viewport drag": "Arrastrar la ventana", "Active Mouse Button": "Botón activo del ratón", "No mousebutton": "Ningún botón del ratón", @@ -18,7 +18,7 @@ "Middle mousebutton": "Botón central del ratón", "Right mousebutton": "Botón derecho del ratón", "Keyboard": "Teclado", - "Show Keyboard": "Mostrar teclado", + "Show keyboard": "Mostrar teclado", "Extra keys": "Teclas adicionales", "Show Extra Keys": "Mostrar Teclas Adicionales", "Ctrl": "Ctrl", @@ -43,13 +43,13 @@ "Settings": "Configuraciones", "Encrypt": "Encriptar", "Shared Mode": "Modo Compartido", - "View Only": "Solo visualización", - "Clip to Window": "Recortar al tamaño de la ventana", - "Scaling Mode:": "Modo de escalado:", + "View only": "Solo visualización", + "Clip to window": "Recortar al tamaño de la ventana", + "Scaling mode:": "Modo de escalado:", "None": "Ninguno", "Local Scaling": "Escalado Local", "Local Downscaling": "Reducción de escala local", - "Remote Resizing": "Cambio de tamaño remoto", + "Remote resizing": "Cambio de tamaño remoto", "Advanced": "Avanzado", "Local Cursor": "Cursor Local", "Repeater ID:": "ID del Repetidor:", @@ -57,8 +57,8 @@ "Host:": "Host:", "Port:": "Puerto:", "Path:": "Ruta:", - "Automatic Reconnect": "Reconexión automática", - "Reconnect Delay (ms):": "Retraso en la reconexión (ms):", + "Automatic reconnect": "Reconexión automática", + "Reconnect delay (ms):": "Retraso en la reconexión (ms):", "Logging:": "Registrando:", "Disconnect": "Desconectar", "Connect": "Conectar", diff --git a/app/locale/fr.json b/app/locale/fr.json index c0eeec7d3..be9a4f422 100644 --- a/app/locale/fr.json +++ b/app/locale/fr.json @@ -17,9 +17,9 @@ "Drag": "Faire glisser", "Move/Drag Viewport": "Déplacer/faire glisser le Viewport", "Keyboard": "Clavier", - "Show Keyboard": "Afficher le clavier", + "Show keyboard": "Afficher le clavier", "Extra keys": "Touches supplémentaires", - "Show Extra Keys": "Afficher les touches supplémentaires", + "Show extra keys": "Afficher les touches supplémentaires", "Ctrl": "Ctrl", "Toggle Ctrl": "Basculer Ctrl", "Alt": "Alt", @@ -42,13 +42,13 @@ "Clear": "Effacer", "Fullscreen": "Plein écran", "Settings": "Paramètres", - "Shared Mode": "Mode partagé", - "View Only": "Afficher uniquement", - "Clip to Window": "Clip à fenêtre", - "Scaling Mode:": "Mode mise à l'échelle :", + "Shared mode": "Mode partagé", + "View only": "Afficher uniquement", + "Clip to window": "Clip à fenêtre", + "Scaling mode:": "Mode mise à l'échelle :", "None": "Aucun", - "Local Scaling": "Mise à l'échelle locale", - "Remote Resizing": "Redimensionnement à distance", + "Local scaling": "Mise à l'échelle locale", + "Remote resizing": "Redimensionnement à distance", "Advanced": "Avancé", "Quality:": "Qualité :", "Compression level:": "Niveau de compression :", @@ -58,15 +58,15 @@ "Host:": "Hôte :", "Port:": "Port :", "Path:": "Chemin :", - "Automatic Reconnect": "Reconnecter automatiquemen", - "Reconnect Delay (ms):": "Délai de reconnexion (ms) :", - "Show Dot when No Cursor": "Afficher le point lorsqu'il n'y a pas de curseur", + "Automatic reconnect": "Reconnecter automatiquemen", + "Reconnect delay (ms):": "Délai de reconnexion (ms) :", + "Show dot when no cursor": "Afficher le point lorsqu'il n'y a pas de curseur", "Logging:": "Se connecter :", "Version:": "Version :", "Disconnect": "Déconnecter", "Connect": "Connecter", "Username:": "Nom d'utilisateur :", "Password:": "Mot de passe :", - "Send Credentials": "Envoyer les identifiants", + "Send credentials": "Envoyer les identifiants", "Cancel": "Annuler" } \ No newline at end of file diff --git a/app/locale/it.json b/app/locale/it.json index 18a7f7447..28e6f721b 100644 --- a/app/locale/it.json +++ b/app/locale/it.json @@ -15,7 +15,7 @@ "noVNC encountered an error:": "noVNC ha riscontrato un errore:", "Hide/Show the control bar": "Nascondi/Mostra la barra di controllo", "Keyboard": "Tastiera", - "Show Keyboard": "Mostra tastiera", + "Show keyboard": "Mostra tastiera", "Extra keys": "Tasti Aggiuntivi", "Show Extra Keys": "Mostra Tasti Aggiuntivi", "Ctrl": "Ctrl", @@ -40,9 +40,9 @@ "Clear": "Pulisci", "Fullscreen": "Schermo intero", "Settings": "Impostazioni", - "Shared Mode": "Modalità condivisa", + "Shared mode": "Modalità condivisa", "View Only": "Sola Visualizzazione", - "Scaling Mode:": "Modalità di ridimensionamento:", + "Scaling mode:": "Modalità di ridimensionamento:", "None": "Nessuna", "Local Scaling": "Ridimensionamento Locale", "Remote Resizing": "Ridimensionamento Remoto", diff --git a/app/locale/ja.json b/app/locale/ja.json index 70fd7a5d1..078adcc85 100644 --- a/app/locale/ja.json +++ b/app/locale/ja.json @@ -16,11 +16,11 @@ "noVNC encountered an error:": "noVNC でエラーが発生しました:", "Hide/Show the control bar": "コントロールバーを隠す/表示する", "Drag": "ドラッグ", - "Move/Drag Viewport": "ビューポートを移動/ドラッグ", + "Move/Drag viewport": "ビューポートを移動/ドラッグ", "Keyboard": "キーボード", - "Show Keyboard": "キーボードを表示", + "Show keyboard": "キーボードを表示", "Extra keys": "追加キー", - "Show Extra Keys": "追加キーを表示", + "Show extra keys": "追加キーを表示", "Ctrl": "Ctrl", "Toggle Ctrl": "Ctrl キーをトグル", "Alt": "Alt", @@ -41,15 +41,15 @@ "Reset": "リセット", "Clipboard": "クリップボード", "Edit clipboard content in the textarea below.": "以下の入力欄からクリップボードの内容を編集できます。", - "Full Screen": "全画面表示", + "Full screen": "全画面表示", "Settings": "設定", - "Shared Mode": "共有モード", - "View Only": "表示専用", - "Clip to Window": "ウィンドウにクリップ", - "Scaling Mode:": "スケーリングモード:", + "Shared mode": "共有モード", + "View only": "表示専用", + "Clip to window": "ウィンドウにクリップ", + "Scaling mode:": "スケーリングモード:", "None": "なし", - "Local Scaling": "ローカルスケーリング", - "Remote Resizing": "リモートでリサイズ", + "Local scaling": "ローカルスケーリング", + "Remote resizing": "リモートでリサイズ", "Advanced": "高度", "Quality:": "品質:", "Compression level:": "圧縮レベル:", @@ -59,9 +59,9 @@ "Host:": "ホスト:", "Port:": "ポート:", "Path:": "パス:", - "Automatic Reconnect": "自動再接続", - "Reconnect Delay (ms):": "再接続する遅延 (ミリ秒):", - "Show Dot when No Cursor": "カーソルがないときにドットを表示する", + "Automatic reconnect": "自動再接続", + "Reconnect delay (ms):": "再接続する遅延 (ミリ秒):", + "Show dot when no cursor": "カーソルがないときにドットを表示する", "Logging:": "ロギング:", "Version:": "バージョン:", "Disconnect": "切断", @@ -75,6 +75,6 @@ "Credentials": "資格情報", "Username:": "ユーザー名:", "Password:": "パスワード:", - "Send Credentials": "資格情報を送信", + "Send credentials": "資格情報を送信", "Cancel": "キャンセル" } \ No newline at end of file diff --git a/app/locale/ko.json b/app/locale/ko.json index e4ecddcfd..47b0805c9 100644 --- a/app/locale/ko.json +++ b/app/locale/ko.json @@ -14,7 +14,7 @@ "Password is required": "비밀번호가 필요합니다.", "noVNC encountered an error:": "noVNC에 오류가 발생했습니다:", "Hide/Show the control bar": "컨트롤 바 숨기기/보이기", - "Move/Drag Viewport": "움직이기/드래그 뷰포트", + "Move/Drag viewport": "움직이기/드래그 뷰포트", "viewport drag": "뷰포트 드래그", "Active Mouse Button": "마우스 버튼 활성화", "No mousebutton": "마우스 버튼 없음", @@ -22,9 +22,9 @@ "Middle mousebutton": "중간 마우스 버튼", "Right mousebutton": "오른쪽 마우스 버튼", "Keyboard": "키보드", - "Show Keyboard": "키보드 보이기", + "Show keyboard": "키보드 보이기", "Extra keys": "기타 키들", - "Show Extra Keys": "기타 키들 보이기", + "Show extra keys": "기타 키들 보이기", "Ctrl": "Ctrl", "Toggle Ctrl": "Ctrl 켜기/끄기", "Alt": "Alt", @@ -45,13 +45,13 @@ "Clear": "지우기", "Fullscreen": "전체화면", "Settings": "설정", - "Shared Mode": "공유 모드", - "View Only": "보기 전용", - "Clip to Window": "창에 클립", - "Scaling Mode:": "스케일링 모드:", + "Shared mode": "공유 모드", + "View only": "보기 전용", + "Clip to window": "창에 클립", + "Scaling mode:": "스케일링 모드:", "None": "없음", - "Local Scaling": "로컬 스케일링", - "Remote Resizing": "원격 크기 조절", + "Local scaling": "로컬 스케일링", + "Remote resizing": "원격 크기 조절", "Advanced": "고급", "Repeater ID:": "중계 ID", "WebSocket": "웹소켓", @@ -59,8 +59,8 @@ "Host:": "호스트:", "Port:": "포트:", "Path:": "위치:", - "Automatic Reconnect": "자동 재연결", - "Reconnect Delay (ms):": "재연결 지연 시간 (ms)", + "Automatic reconnect": "자동 재연결", + "Reconnect delay (ms):": "재연결 지연 시간 (ms)", "Logging:": "로깅", "Disconnect": "연결 해제", "Connect": "연결", diff --git a/app/locale/nl.json b/app/locale/nl.json index 0cdcc92a9..ea6335bd8 100644 --- a/app/locale/nl.json +++ b/app/locale/nl.json @@ -49,8 +49,8 @@ "Settings": "Instellingen", "Shared Mode": "Gedeelde Modus", "View Only": "Alleen Kijken", - "Clip to Window": "Randen buiten venster afsnijden", - "Scaling Mode:": "Schaalmodus:", + "Clip to window": "Randen buiten venster afsnijden", + "Scaling mode:": "Schaalmodus:", "None": "Geen", "Local Scaling": "Lokaal Schalen", "Remote Resizing": "Op Afstand Formaat Wijzigen", @@ -63,7 +63,7 @@ "Path:": "Pad:", "Automatic Reconnect": "Automatisch Opnieuw Verbinden", "Reconnect Delay (ms):": "Vertraging voor Opnieuw Verbinden (ms):", - "Show Dot when No Cursor": "Geef stip weer indien geen cursor", + "Show dot when no cursor": "Geef stip weer indien geen cursor", "Logging:": "Logmeldingen:", "Disconnect": "Verbinding verbreken", "Connect": "Verbinden", diff --git a/app/locale/pl.json b/app/locale/pl.json index 006ac7a55..865f90ca1 100644 --- a/app/locale/pl.json +++ b/app/locale/pl.json @@ -21,9 +21,9 @@ "Middle mousebutton": "Środkowy przycisk myszy", "Right mousebutton": "Prawy przycisk myszy", "Keyboard": "Klawiatura", - "Show Keyboard": "Pokaż klawiaturę", + "Show keyboard": "Pokaż klawiaturę", "Extra keys": "Przyciski dodatkowe", - "Show Extra Keys": "Pokaż przyciski dodatkowe", + "Show extra keys": "Pokaż przyciski dodatkowe", "Ctrl": "Ctrl", "Toggle Ctrl": "Przełącz Ctrl", "Alt": "Alt", @@ -49,8 +49,8 @@ "Clip to Window": "Przytnij do Okna", "Scaling Mode:": "Tryb Skalowania:", "None": "Brak", - "Local Scaling": "Skalowanie lokalne", - "Remote Resizing": "Skalowanie zdalne", + "Local scaling": "Skalowanie lokalne", + "Remote resizing": "Skalowanie zdalne", "Advanced": "Zaawansowane", "Repeater ID:": "ID Repeatera:", "WebSocket": "WebSocket", @@ -58,8 +58,8 @@ "Host:": "Host:", "Port:": "Port:", "Path:": "Ścieżka:", - "Automatic Reconnect": "Automatycznie wznawiaj połączenie", - "Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):", + "Automatic reconnect": "Automatycznie wznawiaj połączenie", + "Reconnect delay (ms):": "Opóźnienie wznawiania (ms):", "Logging:": "Poziom logowania:", "Disconnect": "Rozłącz", "Connect": "Połącz", diff --git a/app/locale/pt_BR.json b/app/locale/pt_BR.json index aa130f764..224b86efd 100644 --- a/app/locale/pt_BR.json +++ b/app/locale/pt_BR.json @@ -15,11 +15,11 @@ "noVNC encountered an error:": "O noVNC encontrou um erro:", "Hide/Show the control bar": "Esconder/mostrar a barra de controles", "Drag": "Arrastar", - "Move/Drag Viewport": "Mover/arrastar a janela", + "Move/Drag viewport": "Mover/arrastar a janela", "Keyboard": "Teclado", - "Show Keyboard": "Mostrar teclado", + "Show keyboard": "Mostrar teclado", "Extra keys": "Teclas adicionais", - "Show Extra Keys": "Mostar teclas adicionais", + "Show extra keys": "Mostar teclas adicionais", "Ctrl": "Ctrl", "Toggle Ctrl": "Pressionar/soltar Ctrl", "Alt": "Alt", @@ -42,13 +42,13 @@ "Clear": "Limpar", "Fullscreen": "Tela cheia", "Settings": "Configurações", - "Shared Mode": "Modo compartilhado", - "View Only": "Apenas visualizar", - "Clip to Window": "Recortar à janela", - "Scaling Mode:": "Modo de dimensionamento:", + "Shared mode": "Modo compartilhado", + "View only": "Apenas visualizar", + "Clip to window": "Recortar à janela", + "Scaling mode:": "Modo de dimensionamento:", "None": "Nenhum", - "Local Scaling": "Local", - "Remote Resizing": "Remoto", + "Local scaling": "Local", + "Remote resizing": "Remoto", "Advanced": "Avançado", "Quality:": "Qualidade:", "Compression level:": "Nível de compressão:", @@ -58,15 +58,15 @@ "Host:": "Host:", "Port:": "Porta:", "Path:": "Caminho:", - "Automatic Reconnect": "Reconexão automática", - "Reconnect Delay (ms):": "Atraso da reconexão (ms)", - "Show Dot when No Cursor": "Mostrar ponto quando não há cursor", + "Automatic reconnect": "Reconexão automática", + "Reconnect delay (ms):": "Atraso da reconexão (ms)", + "Show dot when no cursor": "Mostrar ponto quando não há cursor", "Logging:": "Registros:", "Version:": "Versão:", "Disconnect": "Desconectar", "Connect": "Conectar", "Username:": "Nome de usuário:", "Password:": "Senha:", - "Send Credentials": "Enviar credenciais", + "Send credentials": "Enviar credenciais", "Cancel": "Cancelar" } \ No newline at end of file diff --git a/app/locale/ru.json b/app/locale/ru.json index 5a1a1b9ba..bd1bb534a 100644 --- a/app/locale/ru.json +++ b/app/locale/ru.json @@ -15,9 +15,9 @@ "noVNC encountered an error:": "Ошибка noVNC: ", "Hide/Show the control bar": "Скрыть/Показать контрольную панель", "Drag": "Переместить", - "Move/Drag Viewport": "Переместить окно", + "Move/Drag viewport": "Переместить окно", "Keyboard": "Клавиатура", - "Show Keyboard": "Показать клавиатуру", + "Show keyboard": "Показать клавиатуру", "Extra keys": "Дополнительные Кнопки", "Show Extra Keys": "Показать Дополнительные Кнопки", "Ctrl": "Ctrl", @@ -42,13 +42,13 @@ "Clear": "Очистить", "Fullscreen": "Во весь экран", "Settings": "Настройки", - "Shared Mode": "Общий режим", + "Shared mode": "Общий режим", "View Only": "Только Просмотр", - "Clip to Window": "В окно", - "Scaling Mode:": "Масштаб:", + "Clip to window": "В окно", + "Scaling mode:": "Масштаб:", "None": "Нет", - "Local Scaling": "Локальный масштаб", - "Remote Resizing": "Удаленная перенастройка размера", + "Local scaling": "Локальный масштаб", + "Remote resizing": "Удаленная перенастройка размера", "Advanced": "Дополнительно", "Quality:": "Качество", "Compression level:": "Уровень Сжатия", @@ -58,9 +58,9 @@ "Host:": "Сервер:", "Port:": "Порт:", "Path:": "Путь:", - "Automatic Reconnect": "Автоматическое переподключение", - "Reconnect Delay (ms):": "Задержка переподключения (мс):", - "Show Dot when No Cursor": "Показать точку вместо курсора", + "Automatic reconnect": "Автоматическое переподключение", + "Reconnect delay (ms):": "Задержка переподключения (мс):", + "Show dot when no cursor": "Показать точку вместо курсора", "Logging:": "Лог:", "Version:": "Версия", "Disconnect": "Отключение", diff --git a/app/locale/sv.json b/app/locale/sv.json index 80a400bfa..83385cd24 100644 --- a/app/locale/sv.json +++ b/app/locale/sv.json @@ -42,12 +42,12 @@ "Reset": "Återställ", "Clipboard": "Urklipp", "Edit clipboard content in the textarea below.": "Redigera urklippets innehåll i fältet nedan.", - "Full Screen": "Fullskärm", + "Full screen": "Fullskärm", "Settings": "Inställningar", "Shared Mode": "Delat Läge", "View Only": "Endast Visning", "Clip to Window": "Begränsa till Fönster", - "Scaling Mode:": "Skalningsläge:", + "Scaling mode:": "Skalningsläge:", "None": "Ingen", "Local Scaling": "Lokal Skalning", "Remote Resizing": "Ändra Storlek", @@ -61,8 +61,8 @@ "Port:": "Port:", "Path:": "Sökväg:", "Automatic Reconnect": "Automatisk Återanslutning", - "Reconnect Delay (ms):": "Fördröjning (ms):", - "Show Dot when No Cursor": "Visa prick när ingen muspekare finns", + "Reconnect delay (ms):": "Fördröjning (ms):", + "Show dot when no cursor": "Visa prick när ingen muspekare finns", "Logging:": "Loggning:", "Version:": "Version:", "Disconnect": "Koppla från", diff --git a/app/locale/tr.json b/app/locale/tr.json index 451c1b8a6..90f816244 100644 --- a/app/locale/tr.json +++ b/app/locale/tr.json @@ -23,7 +23,7 @@ "Keyboard": "Klavye", "Show Keyboard": "Klavye Düzenini Göster", "Extra keys": "Ekstra tuşlar", - "Show Extra Keys": "Ekstra tuşları göster", + "Show extra keys": "Ekstra tuşları göster", "Ctrl": "Ctrl", "Toggle Ctrl": "Ctrl Değiştir ", "Alt": "Alt", diff --git a/app/locale/zh_CN.json b/app/locale/zh_CN.json index 3679eaddd..63014c017 100644 --- a/app/locale/zh_CN.json +++ b/app/locale/zh_CN.json @@ -10,7 +10,7 @@ "Disconnect timeout": "超时断开", "noVNC encountered an error:": "noVNC 遇到一个错误:", "Hide/Show the control bar": "显示/隐藏控制栏", - "Move/Drag Viewport": "移动/拖动窗口", + "Move/Drag viewport": "移动/拖动窗口", "viewport drag": "窗口拖动", "Active Mouse Button": "启动鼠标按键", "No mousebutton": "禁用鼠标按键", @@ -18,9 +18,9 @@ "Middle mousebutton": "鼠标中键", "Right mousebutton": "鼠标右键", "Keyboard": "键盘", - "Show Keyboard": "显示键盘", + "Show keyboard": "显示键盘", "Extra keys": "额外按键", - "Show Extra Keys": "显示额外按键", + "Show extra keys": "显示额外按键", "Ctrl": "Ctrl", "Toggle Ctrl": "切换 Ctrl", "Edit clipboard content in the textarea below.": "在下面的文本区域中编辑剪贴板内容。", @@ -43,14 +43,14 @@ "Fullscreen": "全屏", "Settings": "设置", "Encrypt": "加密", - "Shared Mode": "分享模式", - "View Only": "仅查看", - "Clip to Window": "限制/裁切窗口大小", - "Scaling Mode:": "缩放模式:", + "Shared mode": "分享模式", + "View only": "仅查看", + "Clip to window": "限制/裁切窗口大小", + "Scaling mode:": "缩放模式:", "None": "无", - "Local Scaling": "本地缩放", + "Local scaling": "本地缩放", "Local Downscaling": "降低本地尺寸", - "Remote Resizing": "远程调整大小", + "Remote resizing": "远程调整大小", "Advanced": "高级", "Local Cursor": "本地光标", "Repeater ID:": "中继站 ID", @@ -58,8 +58,8 @@ "Host:": "主机:", "Port:": "端口:", "Path:": "路径:", - "Automatic Reconnect": "自动重新连接", - "Reconnect Delay (ms):": "重新连接间隔 (ms):", + "Automatic reconnect": "自动重新连接", + "Reconnect delay (ms):": "重新连接间隔 (ms):", "Logging:": "日志级别:", "Disconnect": "断开连接", "Connect": "连接", diff --git a/app/locale/zh_TW.json b/app/locale/zh_TW.json index 8ddf813f0..9d292a315 100644 --- a/app/locale/zh_TW.json +++ b/app/locale/zh_TW.json @@ -14,7 +14,7 @@ "Password is required": "請提供密碼", "noVNC encountered an error:": "noVNC 遇到一個錯誤:", "Hide/Show the control bar": "顯示/隱藏控制列", - "Move/Drag Viewport": "拖放顯示範圍", + "Move/Drag viewport": "拖放顯示範圍", "viewport drag": "顯示範圍拖放", "Active Mouse Button": "啟用滑鼠按鍵", "No mousebutton": "無滑鼠按鍵", @@ -22,9 +22,9 @@ "Middle mousebutton": "滑鼠中鍵", "Right mousebutton": "滑鼠右鍵", "Keyboard": "鍵盤", - "Show Keyboard": "顯示鍵盤", + "Show keyboard": "顯示鍵盤", "Extra keys": "額外按鍵", - "Show Extra Keys": "顯示額外按鍵", + "Show extra keys": "顯示額外按鍵", "Ctrl": "Ctrl", "Toggle Ctrl": "切換 Ctrl", "Alt": "Alt", @@ -45,13 +45,13 @@ "Clear": "清除", "Fullscreen": "全螢幕", "Settings": "設定", - "Shared Mode": "分享模式", - "View Only": "僅檢視", - "Clip to Window": "限制/裁切視窗大小", - "Scaling Mode:": "縮放模式:", + "Shared mode": "分享模式", + "View only": "僅檢視", + "Clip to window": "限制/裁切視窗大小", + "Scaling mode:": "縮放模式:", "None": "無", - "Local Scaling": "本機縮放", - "Remote Resizing": "遠端調整大小", + "Local scaling": "本機縮放", + "Remote resizing": "遠端調整大小", "Advanced": "進階", "Repeater ID:": "中繼站 ID", "WebSocket": "WebSocket", @@ -59,8 +59,8 @@ "Host:": "主機:", "Port:": "連接埠:", "Path:": "路徑:", - "Automatic Reconnect": "自動重新連線", - "Reconnect Delay (ms):": "重新連線間隔 (ms):", + "Automatic reconnect": "自動重新連線", + "Reconnect delay (ms):": "重新連線間隔 (ms):", "Logging:": "日誌級別:", "Disconnect": "中斷連線", "Connect": "連線", diff --git a/po/cs.po b/po/cs.po index 2b1efd8d9..cb3773c4e 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1,5 +1,5 @@ # Czech translations for noVNC package. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Petr , 2018. # @@ -78,7 +78,7 @@ msgid "Hide/Show the control bar" msgstr "Skrýt/zobrazit ovládací panel" #: ../vnc.html:101 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "Přesunout/přetáhnout výřez" #: ../vnc.html:101 @@ -110,7 +110,7 @@ msgid "Keyboard" msgstr "Klávesnice" #: ../vnc.html:119 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Zobrazit klávesnici" #: ../vnc.html:126 @@ -118,7 +118,7 @@ msgid "Extra keys" msgstr "Extra klávesy" #: ../vnc.html:126 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "Zobrazit extra klávesy" #: ../vnc.html:131 @@ -202,19 +202,19 @@ msgid "Settings" msgstr "Nastavení" #: ../vnc.html:197 -msgid "Shared Mode" +msgid "Shared mode" msgstr "Sdílený režim" #: ../vnc.html:200 -msgid "View Only" +msgid "View only" msgstr "Pouze prohlížení" #: ../vnc.html:204 -msgid "Clip to Window" +msgid "Clip to window" msgstr "Přizpůsobit oknu" #: ../vnc.html:207 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Přizpůsobení velikosti" #: ../vnc.html:209 @@ -222,11 +222,11 @@ msgid "None" msgstr "Žádné" #: ../vnc.html:210 -msgid "Local Scaling" +msgid "Local scaling" msgstr "Místní" #: ../vnc.html:211 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Vzdálené" #: ../vnc.html:216 @@ -258,15 +258,15 @@ msgid "Path:" msgstr "Cesta" #: ../vnc.html:244 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Automatická obnova připojení" #: ../vnc.html:247 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Zpoždění připojení (ms)" #: ../vnc.html:252 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "Tečka místo chybějícího kurzoru myši" #: ../vnc.html:257 diff --git a/po/de.po b/po/de.po index 0c3fa0d48..d06ce4285 100644 --- a/po/de.po +++ b/po/de.po @@ -1,6 +1,6 @@ # German translations for noVNC package # German translation for noVNC. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Loek Janssen , 2016. # @@ -76,7 +76,7 @@ msgid "Hide/Show the control bar" msgstr "Kontrollleiste verstecken/anzeigen" #: ../vnc.html:106 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "Ansichtsfenster verschieben/ziehen" #: ../vnc.html:106 @@ -108,7 +108,7 @@ msgid "Keyboard" msgstr "Tastatur" #: ../vnc.html:124 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Tastatur anzeigen" #: ../vnc.html:131 @@ -116,7 +116,7 @@ msgid "Extra keys" msgstr "Zusatztasten" #: ../vnc.html:131 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "Zusatztasten anzeigen" #: ../vnc.html:136 @@ -200,19 +200,19 @@ msgid "Settings" msgstr "Einstellungen" #: ../vnc.html:202 -msgid "Shared Mode" +msgid "Shared mode" msgstr "Geteilter Modus" #: ../vnc.html:205 -msgid "View Only" +msgid "View only" msgstr "Nur betrachten" #: ../vnc.html:209 -msgid "Clip to Window" +msgid "Clip to window" msgstr "Auf Fenster begrenzen" #: ../vnc.html:212 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Skalierungsmodus:" #: ../vnc.html:214 @@ -220,11 +220,11 @@ msgid "None" msgstr "Keiner" #: ../vnc.html:215 -msgid "Local Scaling" +msgid "Local scaling" msgstr "Lokales skalieren" #: ../vnc.html:216 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Serverseitiges skalieren" #: ../vnc.html:221 @@ -256,11 +256,11 @@ msgid "Path:" msgstr "Pfad:" #: ../vnc.html:249 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Automatisch wiederverbinden" #: ../vnc.html:252 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Wiederverbindungsverzögerung (ms):" #: ../vnc.html:258 diff --git a/po/el.po b/po/el.po index de690fe93..2939270ab 100644 --- a/po/el.po +++ b/po/el.po @@ -1,5 +1,5 @@ # Greek translations for noVNC package. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Giannis Kosmas , 2016. # diff --git a/po/es.po b/po/es.po index 1230402f6..27aaaefea 100644 --- a/po/es.po +++ b/po/es.po @@ -1,6 +1,6 @@ # Spanish translations for noVNC package # Traducciones al español para el paquete noVNC. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Juanjo Diaz , 2018. # Adrian Scillato , 2021. @@ -64,7 +64,7 @@ msgid "Hide/Show the control bar" msgstr "Ocultar/Mostrar la barra de control" #: ../vnc.html:106 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "Mover/Arrastrar la ventana" #: ../vnc.html:106 @@ -96,7 +96,7 @@ msgid "Keyboard" msgstr "Teclado" #: ../vnc.html:124 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Mostrar teclado" #: ../vnc.html:131 @@ -196,15 +196,15 @@ msgid "Shared Mode" msgstr "Modo Compartido" #: ../vnc.html:205 -msgid "View Only" +msgid "View only" msgstr "Solo visualización" #: ../vnc.html:209 -msgid "Clip to Window" +msgid "Clip to window" msgstr "Recortar al tamaño de la ventana" #: ../vnc.html:212 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Modo de escalado:" #: ../vnc.html:214 @@ -220,7 +220,7 @@ msgid "Local Downscaling" msgstr "Reducción de escala local" #: ../vnc.html:217 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Cambio de tamaño remoto" #: ../vnc.html:222 @@ -252,11 +252,11 @@ msgid "Path:" msgstr "Ruta:" #: ../vnc.html:254 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Reconexión automática" #: ../vnc.html:257 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Retraso en la reconexión (ms):" #: ../vnc.html:263 diff --git a/po/fr.po b/po/fr.po index 748a4dbed..fa3619cc3 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,6 +1,6 @@ # French translations for noVNC package # Traductions françaises du paquet noVNC. -# Copyright (C) 2021 The noVNC Authors +# Copyright (C) 2021 The noVNC authors # This file is distributed under the same license as the noVNC package. # Jose , 2021. # Lowxorx , 2022. @@ -92,7 +92,7 @@ msgid "Keyboard" msgstr "Clavier" #: ../vnc.html:97 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Afficher le clavier" #: ../vnc.html:102 @@ -100,7 +100,7 @@ msgid "Extra keys" msgstr "Touches supplémentaires" #: ../vnc.html:102 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "Afficher les touches supplémentaires" #: ../vnc.html:107 @@ -192,19 +192,19 @@ msgid "Settings" msgstr "Paramètres" #: ../vnc.html:175 -msgid "Shared Mode" +msgid "Shared mode" msgstr "Mode partagé" #: ../vnc.html:178 -msgid "View Only" +msgid "View only" msgstr "Afficher uniquement" #: ../vnc.html:182 -msgid "Clip to Window" +msgid "Clip to window" msgstr "Clip à fenêtre" #: ../vnc.html:185 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Mode mise à l'échelle :" #: ../vnc.html:187 @@ -212,11 +212,11 @@ msgid "None" msgstr "Aucun" #: ../vnc.html:188 -msgid "Local Scaling" +msgid "Local scaling" msgstr "Mise à l'échelle locale" #: ../vnc.html:189 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Redimensionnement à distance" #: ../vnc.html:194 @@ -256,15 +256,15 @@ msgid "Path:" msgstr "Chemin :" #: ../vnc.html:231 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Reconnecter automatiquemen" #: ../vnc.html:234 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Délai de reconnexion (ms) :" #: ../vnc.html:239 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "Afficher le point lorsqu'il n'y a pas de curseur" #: ../vnc.html:244 @@ -292,7 +292,7 @@ msgid "Password:" msgstr "Mot de passe :" #: ../vnc.html:298 -msgid "Send Credentials" +msgid "Send credentials" msgstr "Envoyer les identifiants" #: ../vnc.html:308 diff --git a/po/it.po b/po/it.po index d08ec5384..a066bb3a4 100644 --- a/po/it.po +++ b/po/it.po @@ -1,6 +1,6 @@ # Italian translations for noVNC # Traduzione italiana di noVNC -# Copyright (C) 2022 The noVNC Authors +# Copyright (C) 2022 The noVNC authors # This file is distributed under the same license as the noVNC package. # Fabio Fantoni , 2022. # @@ -84,7 +84,7 @@ msgid "Drag" msgstr "" #: ../vnc.html:78 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "" #: ../vnc.html:84 @@ -92,7 +92,7 @@ msgid "Keyboard" msgstr "Tastiera" #: ../vnc.html:84 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Mostra tastiera" #: ../vnc.html:89 @@ -192,7 +192,7 @@ msgid "Settings" msgstr "Impostazioni" #: ../vnc.html:162 -msgid "Shared Mode" +msgid "Shared mode" msgstr "Modalità condivisa" #: ../vnc.html:165 @@ -200,11 +200,11 @@ msgid "View Only" msgstr "Sola Visualizzazione" #: ../vnc.html:169 -msgid "Clip to Window" +msgid "Clip to window" msgstr "" #: ../vnc.html:172 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Modalità di ridimensionamento:" #: ../vnc.html:174 diff --git a/po/ja.po b/po/ja.po index 64da73237..0f95bc6fe 100644 --- a/po/ja.po +++ b/po/ja.po @@ -1,6 +1,6 @@ # Japanese translations for noVNC package # noVNC パッケージに対する日訳 -# Copyright (C) 2019 The noVNC Authors +# Copyright (C) 2019 The noVNC authors # This file is distributed under the same license as the noVNC package. # nnn1590 , 2019-2020. # @@ -88,7 +88,7 @@ msgid "Drag" msgstr "ドラッグ" #: ../vnc.html:76 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "ビューポートを移動/ドラッグ" #: ../vnc.html:82 @@ -96,7 +96,7 @@ msgid "Keyboard" msgstr "キーボード" #: ../vnc.html:82 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "キーボードを表示" #: ../vnc.html:87 @@ -104,7 +104,7 @@ msgid "Extra keys" msgstr "追加キー" #: ../vnc.html:87 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "追加キーを表示" #: ../vnc.html:92 @@ -188,7 +188,7 @@ msgid "Edit clipboard content in the textarea below." msgstr "以下の入力欄からクリップボードの内容を編集できます。" #: ../vnc.html:145 -msgid "Full Screen" +msgid "Full screen" msgstr "全画面表示" #: ../vnc.html:150 ../vnc.html:156 @@ -196,19 +196,19 @@ msgid "Settings" msgstr "設定" #: ../vnc.html:160 -msgid "Shared Mode" +msgid "Shared mode" msgstr "共有モード" #: ../vnc.html:163 -msgid "View Only" +msgid "View only" msgstr "表示専用" #: ../vnc.html:167 -msgid "Clip to Window" +msgid "Clip to window" msgstr "ウィンドウにクリップ" #: ../vnc.html:170 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "スケーリングモード:" #: ../vnc.html:172 @@ -216,11 +216,11 @@ msgid "None" msgstr "なし" #: ../vnc.html:173 -msgid "Local Scaling" +msgid "Local scaling" msgstr "ローカルスケーリング" #: ../vnc.html:174 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "リモートでリサイズ" #: ../vnc.html:179 @@ -260,15 +260,15 @@ msgid "Path:" msgstr "パス:" #: ../vnc.html:216 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "自動再接続" #: ../vnc.html:219 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "再接続する遅延 (ミリ秒):" #: ../vnc.html:224 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "カーソルがないときにドットを表示する" #: ../vnc.html:229 @@ -328,7 +328,7 @@ msgid "Password:" msgstr "パスワード:" #: ../vnc.html:314 -msgid "Send Credentials" +msgid "Send credentials" msgstr "資格情報を送信" #: ../vnc.html:323 diff --git a/po/ko.po b/po/ko.po index 87ae10697..4673927da 100644 --- a/po/ko.po +++ b/po/ko.po @@ -1,5 +1,5 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Baw Appie , 2018. # @@ -78,7 +78,7 @@ msgid "Hide/Show the control bar" msgstr "컨트롤 바 숨기기/보이기" #: ../vnc.html:108 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "움직이기/드래그 뷰포트" #: ../vnc.html:108 @@ -110,7 +110,7 @@ msgid "Keyboard" msgstr "키보드" #: ../vnc.html:126 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "키보드 보이기" #: ../vnc.html:133 @@ -118,7 +118,7 @@ msgid "Extra keys" msgstr "기타 키들" #: ../vnc.html:133 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "기타 키들 보이기" #: ../vnc.html:138 @@ -202,19 +202,19 @@ msgid "Settings" msgstr "설정" #: ../vnc.html:204 -msgid "Shared Mode" +msgid "Shared mode" msgstr "공유 모드" #: ../vnc.html:207 -msgid "View Only" +msgid "View only" msgstr "보기 전용" #: ../vnc.html:211 -msgid "Clip to Window" +msgid "Clip to window" msgstr "창에 클립" #: ../vnc.html:214 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "스케일링 모드:" #: ../vnc.html:216 @@ -222,11 +222,11 @@ msgid "None" msgstr "없음" #: ../vnc.html:217 -msgid "Local Scaling" +msgid "Local scaling" msgstr "로컬 스케일링" #: ../vnc.html:218 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "원격 크기 조절" #: ../vnc.html:223 @@ -258,11 +258,11 @@ msgid "Path:" msgstr "위치:" #: ../vnc.html:251 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "자동 재연결" #: ../vnc.html:254 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "재연결 지연 시간 (ms)" #: ../vnc.html:260 diff --git a/po/nl.po b/po/nl.po index 343204a9f..80f9d6f4d 100644 --- a/po/nl.po +++ b/po/nl.po @@ -1,6 +1,6 @@ # Dutch translations for noVNC package # Nederlandse vertalingen voor het pakket noVNC. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Loek Janssen , 2016. # @@ -219,11 +219,11 @@ msgid "View Only" msgstr "Alleen Kijken" #: ../vnc.html:202 -msgid "Clip to Window" +msgid "Clip to window" msgstr "Randen buiten venster afsnijden" #: ../vnc.html:205 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Schaalmodus:" #: ../vnc.html:207 @@ -275,7 +275,7 @@ msgid "Reconnect Delay (ms):" msgstr "Vertraging voor Opnieuw Verbinden (ms):" #: ../vnc.html:250 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "Geef stip weer indien geen cursor" #: ../vnc.html:255 diff --git a/po/noVNC.pot b/po/noVNC.pot index 0f85a82e5..a939d5366 100644 --- a/po/noVNC.pot +++ b/po/noVNC.pot @@ -1,5 +1,5 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR The noVNC Authors +# Copyright (C) YEAR The noVNC authors # This file is distributed under the same license as the noVNC package. # FIRST AUTHOR , YEAR. # @@ -91,7 +91,7 @@ msgid "Drag" msgstr "" #: ../vnc.html:74 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "" #: ../vnc.html:80 @@ -99,7 +99,7 @@ msgid "Keyboard" msgstr "" #: ../vnc.html:80 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "" #: ../vnc.html:85 @@ -107,7 +107,7 @@ msgid "Extra keys" msgstr "" #: ../vnc.html:85 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "" #: ../vnc.html:90 @@ -191,7 +191,7 @@ msgid "Edit clipboard content in the textarea below." msgstr "" #: ../vnc.html:143 -msgid "Full Screen" +msgid "Full screen" msgstr "" #: ../vnc.html:148 ../vnc.html:154 @@ -199,19 +199,19 @@ msgid "Settings" msgstr "" #: ../vnc.html:158 -msgid "Shared Mode" +msgid "Shared mode" msgstr "" #: ../vnc.html:161 -msgid "View Only" +msgid "View only" msgstr "" #: ../vnc.html:165 -msgid "Clip to Window" +msgid "Clip to window" msgstr "" #: ../vnc.html:168 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "" #: ../vnc.html:170 @@ -219,11 +219,11 @@ msgid "None" msgstr "" #: ../vnc.html:171 -msgid "Local Scaling" +msgid "Local scaling" msgstr "" #: ../vnc.html:172 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "" #: ../vnc.html:177 @@ -263,15 +263,15 @@ msgid "Path:" msgstr "" #: ../vnc.html:214 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "" #: ../vnc.html:217 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "" #: ../vnc.html:222 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "" #: ../vnc.html:227 @@ -329,7 +329,7 @@ msgid "Password:" msgstr "" #: ../vnc.html:312 -msgid "Send Credentials" +msgid "Send credentials" msgstr "" #: ../vnc.html:321 diff --git a/po/pl.po b/po/pl.po index 5acfdc4f4..8e696f44d 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1,5 +1,5 @@ # Polish translations for noVNC package. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Mariusz Jamro , 2017. # @@ -108,7 +108,7 @@ msgid "Keyboard" msgstr "Klawiatura" #: ../vnc.html:124 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Pokaż klawiaturę" #: ../vnc.html:131 @@ -116,7 +116,7 @@ msgid "Extra keys" msgstr "Przyciski dodatkowe" #: ../vnc.html:131 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "Pokaż przyciski dodatkowe" #: ../vnc.html:136 @@ -220,11 +220,11 @@ msgid "None" msgstr "Brak" #: ../vnc.html:215 -msgid "Local Scaling" +msgid "Local scaling" msgstr "Skalowanie lokalne" #: ../vnc.html:216 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Skalowanie zdalne" #: ../vnc.html:221 @@ -256,11 +256,11 @@ msgid "Path:" msgstr "Ścieżka:" #: ../vnc.html:249 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Automatycznie wznawiaj połączenie" #: ../vnc.html:252 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Opóźnienie wznawiania (ms):" #: ../vnc.html:258 diff --git a/po/pt_BR.po b/po/pt_BR.po index 77951aef0..422b94266 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -1,5 +1,5 @@ # Portuguese translations for noVNC package. -# Copyright (C) 2021 The noVNC Authors +# Copyright (C) 2021 The noVNC authors # This file is distributed under the same license as the noVNC package. # , 2021. # @@ -83,7 +83,7 @@ msgid "Drag" msgstr "Arrastar" #: ../vnc.html:78 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "Mover/arrastar a janela" #: ../vnc.html:84 @@ -91,7 +91,7 @@ msgid "Keyboard" msgstr "Teclado" #: ../vnc.html:84 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Mostrar teclado" #: ../vnc.html:89 @@ -99,7 +99,7 @@ msgid "Extra keys" msgstr "Teclas adicionais" #: ../vnc.html:89 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "Mostar teclas adicionais" #: ../vnc.html:94 @@ -191,19 +191,19 @@ msgid "Settings" msgstr "Configurações" #: ../vnc.html:162 -msgid "Shared Mode" +msgid "Shared mode" msgstr "Modo compartilhado" #: ../vnc.html:165 -msgid "View Only" +msgid "View only" msgstr "Apenas visualizar" #: ../vnc.html:169 -msgid "Clip to Window" +msgid "Clip to window" msgstr "Recortar à janela" #: ../vnc.html:172 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Modo de dimensionamento:" #: ../vnc.html:174 @@ -211,11 +211,11 @@ msgid "None" msgstr "Nenhum" #: ../vnc.html:175 -msgid "Local Scaling" +msgid "Local scaling" msgstr "Local" #: ../vnc.html:176 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Remoto" #: ../vnc.html:181 @@ -255,15 +255,15 @@ msgid "Path:" msgstr "Caminho:" #: ../vnc.html:218 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Reconexão automática" #: ../vnc.html:221 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Atraso da reconexão (ms)" #: ../vnc.html:226 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "Mostrar ponto quando não há cursor" #: ../vnc.html:231 @@ -291,7 +291,7 @@ msgid "Password:" msgstr "Senha:" #: ../vnc.html:285 -msgid "Send Credentials" +msgid "Send credentials" msgstr "Enviar credenciais" #: ../vnc.html:295 diff --git a/po/ru.po b/po/ru.po index dbc1d840f..1a19e4ebd 100644 --- a/po/ru.po +++ b/po/ru.po @@ -86,7 +86,7 @@ msgid "Drag" msgstr "Переместить" #: ../vnc.html:78 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "Переместить окно" #: ../vnc.html:84 @@ -94,7 +94,7 @@ msgid "Keyboard" msgstr "Клавиатура" #: ../vnc.html:84 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "Показать клавиатуру" #: ../vnc.html:89 @@ -194,7 +194,7 @@ msgid "Settings" msgstr "Настройки" #: ../vnc.html:162 -msgid "Shared Mode" +msgid "Shared mode" msgstr "Общий режим" #: ../vnc.html:165 @@ -202,11 +202,11 @@ msgid "View Only" msgstr "Только Просмотр" #: ../vnc.html:169 -msgid "Clip to Window" +msgid "Clip to window" msgstr "В окно" #: ../vnc.html:172 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Масштаб:" #: ../vnc.html:174 @@ -214,11 +214,11 @@ msgid "None" msgstr "Нет" #: ../vnc.html:175 -msgid "Local Scaling" +msgid "Local scaling" msgstr "Локальный масштаб" #: ../vnc.html:176 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "Удаленная перенастройка размера" #: ../vnc.html:181 @@ -258,15 +258,15 @@ msgid "Path:" msgstr "Путь:" #: ../vnc.html:218 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "Автоматическое переподключение" #: ../vnc.html:221 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Задержка переподключения (мс):" #: ../vnc.html:226 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "Показать точку вместо курсора" #: ../vnc.html:231 diff --git a/po/sv.po b/po/sv.po index 85c4e3054..f86c1ef37 100644 --- a/po/sv.po +++ b/po/sv.po @@ -1,6 +1,6 @@ # Swedish translations for noVNC package # Svenska översättningar för paketet noVNC. -# Copyright (C) 2020 The noVNC Authors +# Copyright (C) 2020 The noVNC authors # This file is distributed under the same license as the noVNC package. # Samuel Mannehed , 2020. # @@ -195,7 +195,7 @@ msgid "Edit clipboard content in the textarea below." msgstr "Redigera urklippets innehåll i fältet nedan." #: ../vnc.html:143 -msgid "Full Screen" +msgid "Full screen" msgstr "Fullskärm" #: ../vnc.html:148 ../vnc.html:154 @@ -215,7 +215,7 @@ msgid "Clip to Window" msgstr "Begränsa till Fönster" #: ../vnc.html:168 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "Skalningsläge:" #: ../vnc.html:170 @@ -271,11 +271,11 @@ msgid "Automatic Reconnect" msgstr "Automatisk Återanslutning" #: ../vnc.html:217 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "Fördröjning (ms):" #: ../vnc.html:222 -msgid "Show Dot when No Cursor" +msgid "Show dot when no cursor" msgstr "Visa prick när ingen muspekare finns" #: ../vnc.html:227 diff --git a/po/tr.po b/po/tr.po index 8b5c18134..010a1a876 100644 --- a/po/tr.po +++ b/po/tr.po @@ -1,6 +1,6 @@ # Turkish translations for noVNC package # Turkish translation for noVNC. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Ömer ÇAKMAK , 2018. # @@ -116,7 +116,7 @@ msgid "Extra keys" msgstr "Ekstra tuşlar" #: ../vnc.html:131 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "Ekstra tuşları göster" #: ../vnc.html:136 diff --git a/po/zh_CN.po b/po/zh_CN.po index caae28504..ef0a48497 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -1,5 +1,5 @@ # Simplified Chinese translations for noVNC package. -# Copyright (C) 2020 The noVNC Authors +# Copyright (C) 2020 The noVNC authors # This file is distributed under the same license as the noVNC package. # Peter Dave Hello , 2018. # @@ -60,7 +60,7 @@ msgid "Hide/Show the control bar" msgstr "显示/隐藏控制栏" #: ../vnc.html:106 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "移动/拖动窗口" #: ../vnc.html:106 @@ -92,7 +92,7 @@ msgid "Keyboard" msgstr "键盘" #: ../vnc.html:124 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "显示键盘" #: ../vnc.html:131 @@ -100,7 +100,7 @@ msgid "Extra keys" msgstr "额外按键" #: ../vnc.html:131 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "显示额外按键" #: ../vnc.html:136 @@ -192,19 +192,19 @@ msgid "Encrypt" msgstr "加密" #: ../vnc.html:202 -msgid "Shared Mode" +msgid "Shared mode" msgstr "分享模式" #: ../vnc.html:205 -msgid "View Only" +msgid "View only" msgstr "仅查看" #: ../vnc.html:209 -msgid "Clip to Window" +msgid "Clip to window" msgstr "限制/裁切窗口大小" #: ../vnc.html:212 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "缩放模式:" #: ../vnc.html:214 @@ -212,7 +212,7 @@ msgid "None" msgstr "无" #: ../vnc.html:215 -msgid "Local Scaling" +msgid "Local scaling" msgstr "本地缩放" #: ../vnc.html:216 @@ -220,7 +220,7 @@ msgid "Local Downscaling" msgstr "降低本地尺寸" #: ../vnc.html:217 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "远程调整大小" #: ../vnc.html:222 @@ -252,11 +252,11 @@ msgid "Path:" msgstr "路径:" #: ../vnc.html:254 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "自动重新连接" #: ../vnc.html:257 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "重新连接间隔 (ms):" #: ../vnc.html:263 diff --git a/po/zh_TW.po b/po/zh_TW.po index 9ddf550c1..61a4523d3 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -1,5 +1,5 @@ # Traditional Chinese translations for noVNC package. -# Copyright (C) 2018 The noVNC Authors +# Copyright (C) 2018 The noVNC authors # This file is distributed under the same license as the noVNC package. # Peter Dave Hello , 2018. # @@ -77,7 +77,7 @@ msgid "Hide/Show the control bar" msgstr "顯示/隱藏控制列" #: ../vnc.html:106 -msgid "Move/Drag Viewport" +msgid "Move/Drag viewport" msgstr "拖放顯示範圍" #: ../vnc.html:106 @@ -109,7 +109,7 @@ msgid "Keyboard" msgstr "鍵盤" #: ../vnc.html:124 -msgid "Show Keyboard" +msgid "Show keyboard" msgstr "顯示鍵盤" #: ../vnc.html:131 @@ -117,7 +117,7 @@ msgid "Extra keys" msgstr "額外按鍵" #: ../vnc.html:131 -msgid "Show Extra Keys" +msgid "Show extra keys" msgstr "顯示額外按鍵" #: ../vnc.html:136 @@ -201,19 +201,19 @@ msgid "Settings" msgstr "設定" #: ../vnc.html:202 -msgid "Shared Mode" +msgid "Shared mode" msgstr "分享模式" #: ../vnc.html:205 -msgid "View Only" +msgid "View only" msgstr "僅檢視" #: ../vnc.html:209 -msgid "Clip to Window" +msgid "Clip to window" msgstr "限制/裁切視窗大小" #: ../vnc.html:212 -msgid "Scaling Mode:" +msgid "Scaling mode:" msgstr "縮放模式:" #: ../vnc.html:214 @@ -221,11 +221,11 @@ msgid "None" msgstr "無" #: ../vnc.html:215 -msgid "Local Scaling" +msgid "Local scaling" msgstr "本機縮放" #: ../vnc.html:216 -msgid "Remote Resizing" +msgid "Remote resizing" msgstr "遠端調整大小" #: ../vnc.html:221 @@ -257,11 +257,11 @@ msgid "Path:" msgstr "路徑:" #: ../vnc.html:249 -msgid "Automatic Reconnect" +msgid "Automatic reconnect" msgstr "自動重新連線" #: ../vnc.html:252 -msgid "Reconnect Delay (ms):" +msgid "Reconnect delay (ms):" msgstr "重新連線間隔 (ms):" #: ../vnc.html:258 From 663a198ad5a9384aa926698835c899345c4b4ac1 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Tue, 28 May 2024 14:41:15 +0200 Subject: [PATCH 15/19] Add UltraVNC touch gestures support --- app/ui.js | 7 +- core/encodings.js | 1 + core/input/touchhandlerultravnc.js | 112 ++++++++++++++++++ core/rfb.js | 184 +++++++++++++++++++++++++++-- vnc.html | 1 + 5 files changed, 297 insertions(+), 8 deletions(-) create mode 100644 core/input/touchhandlerultravnc.js diff --git a/app/ui.js b/app/ui.js index fd23c8007..adab59a8d 100644 --- a/app/ui.js +++ b/app/ui.js @@ -185,6 +185,7 @@ const UI = { UI.initSetting('bell', 'on'); UI.initSetting('view_only', false); UI.initSetting('show_dot', false); + UI.initSetting('ultravnc_gestures', false); UI.initSetting('path', 'websockify'); UI.initSetting('repeaterID', ''); UI.initSetting('reconnect', false); @@ -371,6 +372,7 @@ const UI = { UI.addSettingChangeHandler('view_only', UI.updateViewOnly); UI.addSettingChangeHandler('show_dot'); UI.addSettingChangeHandler('show_dot', UI.updateShowDotCursor); + UI.addSettingChangeHandler('ultravnc_gestures'); UI.addSettingChangeHandler('host'); UI.addSettingChangeHandler('port'); UI.addSettingChangeHandler('path'); @@ -441,6 +443,7 @@ const UI = { UI.disableSetting('port'); UI.disableSetting('path'); UI.disableSetting('repeaterID'); + UI.disableSetting('ultravnc_gestures'); // Hide the controlbar after 2 seconds UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000); @@ -451,6 +454,7 @@ const UI = { UI.enableSetting('port'); UI.enableSetting('path'); UI.enableSetting('repeaterID'); + UI.enableSetting('ultravnc_gestures'); UI.updatePowerButton(); UI.keepControlbar(); } @@ -1072,7 +1076,8 @@ const UI = { url.href, { shared: UI.getSetting('shared'), repeaterID: UI.getSetting('repeaterID'), - credentials: { password: password } }); + credentials: { password: password }, + useUltraVNCGestures: UI.getSetting('ultravnc_gestures') }); } catch (exc) { Log.Error("Failed to connect to server: " + exc); UI.updateVisualState('disconnected'); diff --git a/core/encodings.js b/core/encodings.js index bf25ac917..27a635da0 100644 --- a/core/encodings.js +++ b/core/encodings.js @@ -25,6 +25,7 @@ export const encodings = { pseudoEncodingCursor: -239, pseudoEncodingQEMUExtendedKeyEvent: -258, pseudoEncodingQEMULedEvent: -261, + pseudoEncodingGii: -305, pseudoEncodingDesktopName: -307, pseudoEncodingExtendedDesktopSize: -308, pseudoEncodingXvp: -309, diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js new file mode 100644 index 000000000..c9ccac919 --- /dev/null +++ b/core/input/touchhandlerultravnc.js @@ -0,0 +1,112 @@ +import * as Log from '../util/logging.js'; + +export default class TouchHandlerUltraVNC { + static PF_flag = 0x80000000; // Pressed Flag : active if the touch event is pressed, inactive if it's being released. + static R1_flag = 0x40000000; // Reserved 1 + static IF_flag = 0x20000000; // Primary Flag : active if the touch event is the primary touch event. + static S1_flag = 0x10000000; // Size Flag : active if the message contains information about the size of the touch event. The events are currently all sent as symetrical ellipses. + static S2_flag = 0x8000000; // Reserved for asymetrical ellipses. Not supported yet and should be 0. + static RT_flag = 0x4000000; // Rectangle : the touch event is a rectangle instead of an ellipse. + static PR_flag = 0x2000000; // Pressure Flag : pressure of the touch. Currently unused. + static TI_flag = 0x1000000; // Timestamp : the timestamp of the touch event. + static HC_flag = 0x800000; // High Performance Counter + + static LENGTH_16_flag = 0x10; // 16 bits signed for x touch coordinate followed by 16 bits signed for y together in a 32 bits word + static IDFORMAT_32 = 0x1; // 32 bits ID + static IDFORMAT_CLEAR = 0xF; // No more touch points + + constructor() { + this._target = null; + + this._currentTouches = []; + this._sendTouchesIntervalId = -1; + this._giiDeviceOrigin = 0; + this._isUltraVNCTouchActivated = false; + + this._boundEventHandler = this._handleTouch.bind(this); + } + + attach(target) { + this.detach(); + + this._target = target; + this._target.addEventListener('touchstart', + this._boundEventHandler); + this._target.addEventListener('touchmove', + this._boundEventHandler); + this._target.addEventListener('touchend', + this._boundEventHandler); + this._target.addEventListener('touchcancel', + this._boundEventHandler); + } + + detach() { + if (!this._target) { + return; + } + + this._target.removeEventListener('touchstart', + this._boundEventHandler); + this._target.removeEventListener('touchmove', + this._boundEventHandler); + this._target.removeEventListener('touchend', + this._boundEventHandler); + this._target.removeEventListener('touchcancel', + this._boundEventHandler); + + clearInterval(this._sendTouchesIntervalId); + this._sendTouchesIntervalId = -1; + + this._target = null; + } + + _handleTouch(ev) { + Log.Debug("Gesture: " + ev.type); + + if (!this._isUltraVNCTouchActivated) { + return; + } + + if (ev.type === "touchstart") { + for (let i = 0; i < ev.changedTouches.length; i++) { + this._currentTouches.push({ event: ev.changedTouches[i], status: "POINTER_DOWN" }); + } + + if (this._sendTouchesIntervalId === -1 && this._target) { + this._dispatchTouchEvent(ev); + this._sendTouchesIntervalId = setInterval(() => { + this._dispatchTouchEvent(ev); + }, 200); + } + } else if (ev.type === "touchmove") { + for (let i = 0; i < ev.changedTouches.length; i++) { + const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); + if (index !== -1) { + this._currentTouches[index].event = ev.changedTouches[i]; + this._currentTouches[index].status = "POINTER_UPDATE"; + } + } + } else if (ev.type === "touchend" || ev.type === "touchcancel") { + for (let i = 0; i < ev.changedTouches.length; i++) { + const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); + if (index !== -1) { + this._currentTouches[index].status = "POINTER_UP"; + } + } + } + } + + _dispatchTouchEvent(ev) { + let tev = new CustomEvent('ultravnctouch', { event: ev, detail: { currentTouches: this._currentTouches, giiDeviceOrigin: this._giiDeviceOrigin } }); + this._target.dispatchEvent(tev); + } + + _removeTouch(index) { + this._currentTouches.splice(index, 1); + } + + _interruptTouches() { + clearInterval(this._sendTouchesIntervalId); + this._sendTouchesIntervalId = -1; + } +} \ No newline at end of file diff --git a/core/rfb.js b/core/rfb.js index 9559e487d..995ab798c 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -19,6 +19,7 @@ import Inflator from "./inflator.js"; import Deflator from "./deflator.js"; import Keyboard from "./input/keyboard.js"; import GestureHandler from "./input/gesturehandler.js"; +import TouchHandlerUltraVNC from "./input/touchhandlerultravnc.js"; import Cursor from "./util/cursor.js"; import Websock from "./websock.js"; import KeyTable from "./input/keysym.js"; @@ -119,6 +120,7 @@ export default class RFB extends EventTargetMixin { this._shared = 'shared' in options ? !!options.shared : true; this._repeaterID = options.repeaterID || ''; this._wsProtocols = options.wsProtocols || []; + this._useUltraVNCGestures = options.useUltraVNCGestures || false; // Internal state this._rfbConnectionState = ''; @@ -204,6 +206,7 @@ export default class RFB extends EventTargetMixin { handleMouse: this._handleMouse.bind(this), handleWheel: this._handleWheel.bind(this), handleGesture: this._handleGesture.bind(this), + handleUltraVNCTouch: this._handleUltraVNCTouch.bind(this), handleRSAAESCredentialsRequired: this._handleRSAAESCredentialsRequired.bind(this), handleRSAAESServerVerification: this._handleRSAAESServerVerification.bind(this), }; @@ -267,7 +270,11 @@ export default class RFB extends EventTargetMixin { this._remoteCapsLock = null; // Null indicates unknown or irrelevant this._remoteNumLock = null; - this._gestures = new GestureHandler(); + if (this._useUltraVNCGestures) { + this._gestures = new TouchHandlerUltraVNC(); + } else { + this._gestures = new GestureHandler(); + } this._sock = new Websock(); this._sock.on('open', this._socketOpen.bind(this)); @@ -598,9 +605,13 @@ export default class RFB extends EventTargetMixin { this._canvas.addEventListener("wheel", this._eventHandlers.handleWheel); // Gesture events - this._canvas.addEventListener("gesturestart", this._eventHandlers.handleGesture); - this._canvas.addEventListener("gesturemove", this._eventHandlers.handleGesture); - this._canvas.addEventListener("gestureend", this._eventHandlers.handleGesture); + if (this._useUltraVNCGestures) { + this._canvas.addEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); + } else { + this._canvas.addEventListener('gesturestart', this._eventHandlers.handleGesture); + this._canvas.addEventListener('gesturemove', this._eventHandlers.handleGesture); + this._canvas.addEventListener('gestureend', this._eventHandlers.handleGesture); + } Log.Debug("<< RFB.connect"); } @@ -608,9 +619,13 @@ export default class RFB extends EventTargetMixin { _disconnect() { Log.Debug(">> RFB.disconnect"); this._cursor.detach(); - this._canvas.removeEventListener("gesturestart", this._eventHandlers.handleGesture); - this._canvas.removeEventListener("gesturemove", this._eventHandlers.handleGesture); - this._canvas.removeEventListener("gestureend", this._eventHandlers.handleGesture); + if (this._useUltraVNCGestures) { + this._canvas.removeEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); + } else { + this._canvas.removeEventListener('gesturestart', this._eventHandlers.handleGesture); + this._canvas.removeEventListener('gesturemove', this._eventHandlers.handleGesture); + this._canvas.removeEventListener('gestureend', this._eventHandlers.handleGesture); + } this._canvas.removeEventListener("wheel", this._eventHandlers.handleWheel); this._canvas.removeEventListener('mousedown', this._eventHandlers.handleMouse); this._canvas.removeEventListener('mouseup', this._eventHandlers.handleMouse); @@ -1378,6 +1393,87 @@ export default class RFB extends EventTargetMixin { } } + _handleUltraVNCTouch(ev) { + Log.Debug("SENDING " + ev.detail.currentTouches.length + " TOUCH(ES)"); + this._sock.sQpush8(253); // GII message type + this._sock.sQpush8(128); // GII event + this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length + this._sock.sQpush8(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // eventSize + this._sock.sQpush8(12); // eventType + this._sock.sQpush16(0); // padding + this._sock.sQpush32(ev.detail.giiDeviceOrigin); // deviceOrigin + this._sock.sQpush32(ev.detail.currentTouches.length); // first + this._sock.sQpush32(6 * ev.detail.currentTouches.length); // count + + let pointerUpIds = []; + + // Send all current touches + for (let i = 0; i < ev.detail.currentTouches.length; i++) { + Log.Debug("Touch Id: " + ev.detail.currentTouches[i].event.identifier); + let valuatorFlag = 0x00000000; + valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; + valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; + if (ev.detail.currentTouches[i].status !== "POINTER_UP") valuatorFlag |= TouchHandlerUltraVNC.PF_flag; + if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag + + this._sock.sQpush32(valuatorFlag); + this._sock.sQpush32(ev.detail.currentTouches[i].event.identifier); + + let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, + this._canvas); + + if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { + let scaledX16 = Math.floor(scaledPosition.x) & 0xFFFF; + let scaledY16 = Math.floor(scaledPosition.y) & 0xFFFF; + let coordinates = (Math.floor(scaledX16) << 16) | (Math.floor(scaledY16)); + this._sock.sQpush32(coordinates); + } + + // Keep track of last released touches + if (ev.detail.currentTouches[i].status === "POINTER_UP") { + pointerUpIds.push(ev.detail.currentTouches[i].event.identifier); + } + } + + this._sock.flush(); + + // Remove released touches from current touches in handler + for (let i = 0; i < pointerUpIds.length; i++) { + const index = ev.detail.currentTouches.findIndex(t => t.event.identifier === pointerUpIds[i]); + if (index !== -1) { + this._gestures._removeTouch(index); + } + } + + // Interrupt touch sending interval + if (ev.detail.currentTouches.length === 0 && this._sendTouchesIntervalId !== -1) { + Log.Debug("NO MORE TOUCHES\n"); + this._gestures._interruptTouches(); + this._sendEmptyTouch(ev.detail.giiDeviceOrigin); + return; + } + } + + _sendEmptyTouch(giiDeviceOrigin) { + let valuatorFlag = 0x00000000; + valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; + valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_CLEAR; + + this._sock.sQpush8(253); // GII message type + this._sock.sQpush8(128); // GII event + this._sock.sQpush16(24); // Header length + this._sock.sQpush8(24); // Event size + this._sock.sQpush8(12); // eventType + this._sock.sQpush16(0); // padding + this._sock.sQpush32(giiDeviceOrigin); // deviceOrigin + this._sock.sQpush32(1); // first + this._sock.sQpush32(4); // Count + this._sock.sQpush32(valuatorFlag); // Flag + this._sock.sQpush32(0); // Empty Id + this._sock.sQpush32(0); // Empty coordinates + this._sock.flush(); + } + // Message handlers _negotiateProtocolVersion() { @@ -2147,6 +2243,10 @@ export default class RFB extends EventTargetMixin { encs.push(encodings.pseudoEncodingDesktopName); encs.push(encodings.pseudoEncodingExtendedClipboard); + if (this._useUltraVNCGestures) { + encs.push(encodings.pseudoEncodingGii); + } + if (this._fbDepth == 24) { encs.push(encodings.pseudoEncodingVMwareCursor); encs.push(encodings.pseudoEncodingCursor); @@ -2442,6 +2542,25 @@ export default class RFB extends EventTargetMixin { return true; } + _handleGiiMsg() { + let giiMsgSubtype = this._sock.rQshift8(); + + switch (giiMsgSubtype) { + case 129: // GII Version Message + this._sock.rQskipBytes(34); + RFB.messages.giiVersionMessage(this._sock); + RFB.messages.giiDeviceCreation(this._sock); + break; + case 130: // GII Device Creation + this._sock.rQshiftBytes(2); + this._gestures._giiDeviceOrigin = this._sock.rQshift32(); + if (this._gestures._giiDeviceOrigin) this._gestures._isUltraVNCTouchActivated = true; + break; + } + + return true; + } + _normalMsg() { let msgType; if (this._FBU.rects > 0) { @@ -2493,6 +2612,9 @@ export default class RFB extends EventTargetMixin { case 250: // XVP return this._handleXvpMsg(); + case 253: // GII + return this._handleGiiMsg(); + default: this._fail("Unexpected server message (type " + msgType + ")"); Log.Debug("sock.rQpeekBytes(30): " + this._sock.rQpeekBytes(30)); @@ -2941,6 +3063,16 @@ export default class RFB extends EventTargetMixin { "raw", passwordChars, { name: "DES-ECB" }, false, ["encrypt"]); return legacyCrypto.encrypt({ name: "DES-ECB" }, key, challenge); } + + static stringAsByteArrayWithPadding(str, size) { + let full = new Uint8Array(size); + let utf8Encode = new TextEncoder(); + let strArray = utf8Encode.encode(str); + for (let i = 0; i < strArray.length; i++) { + full[i] = strArray[i]; + } + return full; + } } // Class Methods @@ -3232,6 +3364,44 @@ RFB.messages = { sock.sQpush8(ver); sock.sQpush8(op); + sock.flush(); + }, + + giiVersionMessage(sock) { + sock.sQpush8(253); // gii msg-type + sock.sQpush8(129); // gii version sub-msg-type + sock.sQpush16(2); // length + sock.sQpush16(1); // version + + sock.flush(); + }, + + giiDeviceCreation(sock) { + sock.sQpush8(253); // gii msg-type + sock.sQpush8(130); // gii device creation sub-msg-type + sock.sQpush16(172); // length + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NOVNC-MT", 31)); // device name + sock.sQpush8(0); // DNTerm + sock.sQpush32(0x0908); // vendorID + sock.sQpush32(0x000b); // productID + sock.sQpush32(0x00002000); // eventMask + sock.sQpush32(0); // numRegisters + sock.sQpush32(1); // numValuators + sock.sQpush32(5); // numButtons + sock.sQpush32(0); // index + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NOVNC Multitouch Device", 74)); // longName + sock.sQpush8(0); // LNTerm + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NMD", 4)); // shortName + sock.sQpush8(0); // SNTerm + sock.sQpush32(0); // rangeMin + sock.sQpush32(0); // rangeCenter + sock.sQpush32(0); // rangeMax + sock.sQpush32(0); // SIUnit + sock.sQpush32(0); // SIAdd + sock.sQpush32(0); // SIMul + sock.sQpush32(0); // SIDiv + sock.sQpush32(0); // SIShift + sock.flush(); } }; diff --git a/vnc.html b/vnc.html index c2cc4e555..44c437186 100644 --- a/vnc.html +++ b/vnc.html @@ -270,6 +270,7 @@

    no
    VNC


  • +

  • From 8af21c7082a61496f3ed7b44d522ac3f9906dc91 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Wed, 31 Jul 2024 15:44:55 +0200 Subject: [PATCH 16/19] Fix local scaling touch position --- core/rfb.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/rfb.js b/core/rfb.js index 995ab798c..ee9f56314 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -1423,9 +1423,9 @@ export default class RFB extends EventTargetMixin { this._canvas); if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { - let scaledX16 = Math.floor(scaledPosition.x) & 0xFFFF; - let scaledY16 = Math.floor(scaledPosition.y) & 0xFFFF; - let coordinates = (Math.floor(scaledX16) << 16) | (Math.floor(scaledY16)); + let scaledX16 = this._display.absX(scaledPosition.x) & 0xFFFF; + let scaledY16 = this._display.absY(scaledPosition.y) & 0xFFFF; + let coordinates = (scaledX16 << 16) | scaledY16; this._sock.sQpush32(coordinates); } @@ -2543,15 +2543,20 @@ export default class RFB extends EventTargetMixin { } _handleGiiMsg() { + if (this._sock.rQwait("GII message subtype", 1, 1)) { + return false; + } let giiMsgSubtype = this._sock.rQshift8(); switch (giiMsgSubtype) { case 129: // GII Version Message + if (this._sock.rQwait("GII version message", 34, 1)) { return false; } this._sock.rQskipBytes(34); RFB.messages.giiVersionMessage(this._sock); RFB.messages.giiDeviceCreation(this._sock); break; case 130: // GII Device Creation + if (this._sock.rQwait("GII device creation", 6, 1)) { return false; } this._sock.rQshiftBytes(2); this._gestures._giiDeviceOrigin = this._sock.rQshift32(); if (this._gestures._giiDeviceOrigin) this._gestures._isUltraVNCTouchActivated = true; From b673af9925e57828783b5e2ef5a54aa858436ad9 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Wed, 31 Jul 2024 15:45:33 +0200 Subject: [PATCH 17/19] Fix touches with same id not being removed properly --- core/input/touchhandlerultravnc.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js index c9ccac919..05fba0efa 100644 --- a/core/input/touchhandlerultravnc.js +++ b/core/input/touchhandlerultravnc.js @@ -88,14 +88,20 @@ export default class TouchHandlerUltraVNC { } } else if (ev.type === "touchend" || ev.type === "touchcancel") { for (let i = 0; i < ev.changedTouches.length; i++) { - const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); - if (index !== -1) { - this._currentTouches[index].status = "POINTER_UP"; - } + const indexes = this._getAllIndexes(this._currentTouches, (t) => t.event.identifier === ev.changedTouches[i].identifier) + indexes.forEach((index) => this._currentTouches[index].status = "POINTER_UP"); } } } + _getAllIndexes(arr, func) { + var indexes = [], i; + for (i = 0; i < arr.length; i++) + if (func(arr[i])) + indexes.push(i); + return indexes; + } + _dispatchTouchEvent(ev) { let tev = new CustomEvent('ultravnctouch', { event: ev, detail: { currentTouches: this._currentTouches, giiDeviceOrigin: this._giiDeviceOrigin } }); this._target.dispatchEvent(tev); From d78d8752dff364533a23cefc0d4f5fbb0806e14a Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Tue, 24 Sep 2024 09:23:45 +0200 Subject: [PATCH 18/19] Add preventDefault in UltraVNC touch and manage touch ids manually --- core/input/touchhandlerultravnc.js | 12 +++++++++++- core/rfb.js | 4 +--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js index 05fba0efa..48bb0015c 100644 --- a/core/input/touchhandlerultravnc.js +++ b/core/input/touchhandlerultravnc.js @@ -61,7 +61,8 @@ export default class TouchHandlerUltraVNC { } _handleTouch(ev) { - Log.Debug("Gesture: " + ev.type); + ev.preventDefault(); + ev.stopImmediatePropagation(); if (!this._isUltraVNCTouchActivated) { return; @@ -69,6 +70,7 @@ export default class TouchHandlerUltraVNC { if (ev.type === "touchstart") { for (let i = 0; i < ev.changedTouches.length; i++) { + ev.changedTouches[i].touchIdentifier = this._getTouchIdentifier(); this._currentTouches.push({ event: ev.changedTouches[i], status: "POINTER_DOWN" }); } @@ -82,6 +84,7 @@ export default class TouchHandlerUltraVNC { for (let i = 0; i < ev.changedTouches.length; i++) { const index = this._currentTouches.findIndex(t => t.event.identifier === ev.changedTouches[i].identifier); if (index !== -1) { + ev.changedTouches[i].touchIdentifier = this._currentTouches[index].event.touchIdentifier; this._currentTouches[index].event = ev.changedTouches[i]; this._currentTouches[index].status = "POINTER_UPDATE"; } @@ -102,6 +105,13 @@ export default class TouchHandlerUltraVNC { return indexes; } + _getTouchIdentifier() { + const ids = this._currentTouches.map((ev) => ev.event.touchIdentifier); + let i = 0; + while (ids.includes(i)) { i++; } + return i; + } + _dispatchTouchEvent(ev) { let tev = new CustomEvent('ultravnctouch', { event: ev, detail: { currentTouches: this._currentTouches, giiDeviceOrigin: this._giiDeviceOrigin } }); this._target.dispatchEvent(tev); diff --git a/core/rfb.js b/core/rfb.js index ee9f56314..050a2e35e 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -1394,7 +1394,6 @@ export default class RFB extends EventTargetMixin { } _handleUltraVNCTouch(ev) { - Log.Debug("SENDING " + ev.detail.currentTouches.length + " TOUCH(ES)"); this._sock.sQpush8(253); // GII message type this._sock.sQpush8(128); // GII event this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length @@ -1409,7 +1408,6 @@ export default class RFB extends EventTargetMixin { // Send all current touches for (let i = 0; i < ev.detail.currentTouches.length; i++) { - Log.Debug("Touch Id: " + ev.detail.currentTouches[i].event.identifier); let valuatorFlag = 0x00000000; valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; @@ -1417,7 +1415,7 @@ export default class RFB extends EventTargetMixin { if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag this._sock.sQpush32(valuatorFlag); - this._sock.sQpush32(ev.detail.currentTouches[i].event.identifier); + this._sock.sQpush32(ev.detail.currentTouches[i].event.touchIdentifier); let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, this._canvas); From ac919414159d6035c71cca68b5e72c6866a73b72 Mon Sep 17 00:00:00 2001 From: Rui Reis Date: Tue, 10 Dec 2024 14:14:32 +0100 Subject: [PATCH 19/19] Change gestures selector to dropdown in UI, use constants instead of hardcoded values for gii events --- app/ui.js | 10 +- core/input/touchhandlerultravnc.js | 42 ++++ core/rfb.js | 307 ++++++++--------------------- vnc.html | 6 +- 4 files changed, 130 insertions(+), 235 deletions(-) diff --git a/app/ui.js b/app/ui.js index adab59a8d..876492585 100644 --- a/app/ui.js +++ b/app/ui.js @@ -185,7 +185,7 @@ const UI = { UI.initSetting('bell', 'on'); UI.initSetting('view_only', false); UI.initSetting('show_dot', false); - UI.initSetting('ultravnc_gestures', false); + UI.initSetting('gestures_mode', 'novnc'); UI.initSetting('path', 'websockify'); UI.initSetting('repeaterID', ''); UI.initSetting('reconnect', false); @@ -372,7 +372,7 @@ const UI = { UI.addSettingChangeHandler('view_only', UI.updateViewOnly); UI.addSettingChangeHandler('show_dot'); UI.addSettingChangeHandler('show_dot', UI.updateShowDotCursor); - UI.addSettingChangeHandler('ultravnc_gestures'); + UI.addSettingChangeHandler('gestures_mode'); UI.addSettingChangeHandler('host'); UI.addSettingChangeHandler('port'); UI.addSettingChangeHandler('path'); @@ -443,7 +443,7 @@ const UI = { UI.disableSetting('port'); UI.disableSetting('path'); UI.disableSetting('repeaterID'); - UI.disableSetting('ultravnc_gestures'); + UI.disableSetting('gestures_mode'); // Hide the controlbar after 2 seconds UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000); @@ -454,7 +454,7 @@ const UI = { UI.enableSetting('port'); UI.enableSetting('path'); UI.enableSetting('repeaterID'); - UI.enableSetting('ultravnc_gestures'); + UI.enableSetting('gestures_mode'); UI.updatePowerButton(); UI.keepControlbar(); } @@ -1077,7 +1077,7 @@ const UI = { { shared: UI.getSetting('shared'), repeaterID: UI.getSetting('repeaterID'), credentials: { password: password }, - useUltraVNCGestures: UI.getSetting('ultravnc_gestures') }); + gesturesMode: UI.getSetting('gestures_mode') }); } catch (exc) { Log.Error("Failed to connect to server: " + exc); UI.updateVisualState('disconnected'); diff --git a/core/input/touchhandlerultravnc.js b/core/input/touchhandlerultravnc.js index 48bb0015c..f44a660e5 100644 --- a/core/input/touchhandlerultravnc.js +++ b/core/input/touchhandlerultravnc.js @@ -15,6 +15,48 @@ export default class TouchHandlerUltraVNC { static IDFORMAT_32 = 0x1; // 32 bits ID static IDFORMAT_CLEAR = 0xF; // No more touch points + // GII + static giiMsgType = 253; + static giiEventInjectionMsgType = 128; + static giiDeviceVersionMsgType = 129; + static giiDeviceCreationMsgType = 130; + + static giiDeviceCreationMsgSize = 172; + static giiDeviceVersion = 1; + static giiDeviceVersionMsgSize = 2; + + static giiEventInjectionHeaderSize = 4; + static giiEventInjectionSize = this.giiEventInjectionHeaderSize + 16; + static giiEventInjectionTouchSize = 12; + static giiEventInjectionEventType = 12; + + static giiDeviceName = "NOVNC-MT"; + static giiDeviceNameSize = 31; + static giiDeviceLongName = "noVNC Multitouch Device"; + static giiDeviceLongNameSize = 74; + static giiDeviceShortName = "NMD"; + static giiDeviceShortNameSize = 4; + + static giiDNTerm = 0; + static giiVendorID = 0x0908; + static giiProductID = 0x000b; + static giiEventMask = 0x00002000; + static giiNumRegisters = 0; + static giiNumValuators = 1; + static giiNumButtons = 5; + static giiNumTouches = 6; + static giiIndex = 0; + static giiLNTerm = 0; + static giiSNTerm = 0; + static giiRangeMin = 0; + static giiRangeCenter = 0; + static giiRangeMax = 0; + static giiSIUnit = 0; + static giiSIAdd = 0; + static giiSIMul = 0; + static giiSIDiv = 0; + static giiSIShift = 0; + constructor() { this._target = null; diff --git a/core/rfb.js b/core/rfb.js index 3ee105221..cc38f32ba 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -120,7 +120,7 @@ export default class RFB extends EventTargetMixin { this._shared = 'shared' in options ? !!options.shared : true; this._repeaterID = options.repeaterID || ''; this._wsProtocols = options.wsProtocols || []; - this._useUltraVNCGestures = options.useUltraVNCGestures || false; + this._gesturesMode = options.gesturesMode || '' // Internal state this._rfbConnectionState = ''; @@ -270,10 +270,12 @@ export default class RFB extends EventTargetMixin { this._remoteCapsLock = null; // Null indicates unknown or irrelevant this._remoteNumLock = null; - if (this._useUltraVNCGestures) { - this._gestures = new TouchHandlerUltraVNC(); - } else { - this._gestures = new GestureHandler(); + switch (this._gesturesMode) { + case 'ultravnc': + this._gestures = new TouchHandlerUltraVNC(); + break; + default: + this._gestures = new GestureHandler(); } this._sock = new Websock(); @@ -605,12 +607,14 @@ export default class RFB extends EventTargetMixin { this._canvas.addEventListener("wheel", this._eventHandlers.handleWheel); // Gesture events - if (this._useUltraVNCGestures) { - this._canvas.addEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); - } else { - this._canvas.addEventListener('gesturestart', this._eventHandlers.handleGesture); - this._canvas.addEventListener('gesturemove', this._eventHandlers.handleGesture); - this._canvas.addEventListener('gestureend', this._eventHandlers.handleGesture); + switch (this._gesturesMode) { + case 'ultravnc': + this._canvas.addEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); + break; + default: + this._canvas.addEventListener('gesturestart', this._eventHandlers.handleGesture); + this._canvas.addEventListener('gesturemove', this._eventHandlers.handleGesture); + this._canvas.addEventListener('gestureend', this._eventHandlers.handleGesture); } Log.Debug("<< RFB.connect"); @@ -619,13 +623,17 @@ export default class RFB extends EventTargetMixin { _disconnect() { Log.Debug(">> RFB.disconnect"); this._cursor.detach(); - if (this._useUltraVNCGestures) { - this._canvas.removeEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); - } else { - this._canvas.removeEventListener('gesturestart', this._eventHandlers.handleGesture); - this._canvas.removeEventListener('gesturemove', this._eventHandlers.handleGesture); - this._canvas.removeEventListener('gestureend', this._eventHandlers.handleGesture); + + switch (this._gesturesMode) { + case 'ultravnc': + this._canvas.removeEventListener('ultravnctouch', this._eventHandlers.handleUltraVNCTouch); + break; + default: + this._canvas.removeEventListener('gesturestart', this._eventHandlers.handleGesture); + this._canvas.removeEventListener('gesturemove', this._eventHandlers.handleGesture); + this._canvas.removeEventListener('gestureend', this._eventHandlers.handleGesture); } + this._canvas.removeEventListener("wheel", this._eventHandlers.handleWheel); this._canvas.removeEventListener('mousedown', this._eventHandlers.handleMouse); this._canvas.removeEventListener('mouseup', this._eventHandlers.handleMouse); @@ -1394,97 +1402,18 @@ export default class RFB extends EventTargetMixin { } _handleUltraVNCTouch(ev) { - this._sock.sQpush8(253); // GII message type - this._sock.sQpush8(128); // GII event - this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length - this._sock.sQpush8(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // eventSize - this._sock.sQpush8(12); // eventType - this._sock.sQpush16(0); // padding - this._sock.sQpush32(ev.detail.giiDeviceOrigin); // deviceOrigin - this._sock.sQpush32(ev.detail.currentTouches.length); // first - this._sock.sQpush32(6 * ev.detail.currentTouches.length); // count - - let pointerUpIds = []; - - // Send all current touches - for (let i = 0; i < ev.detail.currentTouches.length; i++) { - let valuatorFlag = 0x00000000; - valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; - valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; - if (ev.detail.currentTouches[i].status !== "POINTER_UP") valuatorFlag |= TouchHandlerUltraVNC.PF_flag; - if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag - - this._sock.sQpush32(valuatorFlag); - this._sock.sQpush32(ev.detail.currentTouches[i].event.touchIdentifier); - - let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, - this._canvas); - - if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { - let scaledX16 = this._display.absX(scaledPosition.x) & 0xFFFF; - let scaledY16 = this._display.absY(scaledPosition.y) & 0xFFFF; - let coordinates = (scaledX16 << 16) | scaledY16; - this._sock.sQpush32(coordinates); - } - - // Keep track of last released touches - if (ev.detail.currentTouches[i].status === "POINTER_UP") { - pointerUpIds.push(ev.detail.currentTouches[i].event.identifier); - } - } - - this._sock.flush(); - - // Remove released touches from current touches in handler - for (let i = 0; i < pointerUpIds.length; i++) { - const index = ev.detail.currentTouches.findIndex(t => t.event.identifier === pointerUpIds[i]); - if (index !== -1) { - this._gestures._removeTouch(index); - } - } - - // Interrupt touch sending interval - if (ev.detail.currentTouches.length === 0 && this._sendTouchesIntervalId !== -1) { - Log.Debug("NO MORE TOUCHES\n"); - this._gestures._interruptTouches(); - this._sendEmptyTouch(ev.detail.giiDeviceOrigin); - return; - } - } - - _sendEmptyTouch(giiDeviceOrigin) { - let valuatorFlag = 0x00000000; - valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; - valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_CLEAR; - - this._sock.sQpush8(253); // GII message type - this._sock.sQpush8(128); // GII event - this._sock.sQpush16(24); // Header length - this._sock.sQpush8(24); // Event size - this._sock.sQpush8(12); // eventType + this._sock.sQpush8(TouchHandlerUltraVNC.giiMsgType); // GII message type + this._sock.sQpush8(TouchHandlerUltraVNC.giiEventInjectionMsgType); // GII event + this._sock.sQpush16(TouchHandlerUltraVNC.giiEventInjectionSize + (TouchHandlerUltraVNC.giiEventInjectionTouchSize * ev.detail.currentTouches.length)); // length, not used + this._sock.sQpush8(TouchHandlerUltraVNC.giiEventInjectionSize + (TouchHandlerUltraVNC.giiEventInjectionTouchSize * ev.detail.currentTouches.length)); // eventSize, not used + this._sock.sQpush8(TouchHandlerUltraVNC.giiEventInjectionEventType); // eventType, not used this._sock.sQpush16(0); // padding - this._sock.sQpush32(giiDeviceOrigin); // deviceOrigin - this._sock.sQpush32(1); // first - this._sock.sQpush32(4); // Count - this._sock.sQpush32(valuatorFlag); // Flag - this._sock.sQpush32(0); // Empty Id - this._sock.sQpush32(0); // Empty coordinates - this._sock.flush(); - } + this._sock.sQpush32(ev.detail.giiDeviceOrigin); + this._sock.sQpush32(ev.detail.currentTouches.length); // nb of touch events + this._sock.sQpush32(TouchHandlerUltraVNC.giiNumTouches * ev.detail.currentTouches.length); // count - _handleUltraVNCTouch(ev) { - this._sock.sQpush8(253); // GII message type - this._sock.sQpush8(128); // GII event - this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length - this._sock.sQpush8(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // eventSize - this._sock.sQpush8(12); // eventType - this._sock.sQpush16(0); // padding - this._sock.sQpush32(ev.detail.giiDeviceOrigin); // deviceOrigin - this._sock.sQpush32(ev.detail.currentTouches.length); // first - this._sock.sQpush32(6 * ev.detail.currentTouches.length); // count - let pointerUpIds = []; - + // Send all current touches for (let i = 0; i < ev.detail.currentTouches.length; i++) { let valuatorFlag = 0x00000000; @@ -1492,107 +1421,28 @@ export default class RFB extends EventTargetMixin { valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; if (ev.detail.currentTouches[i].status !== "POINTER_UP") valuatorFlag |= TouchHandlerUltraVNC.PF_flag; if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag - + this._sock.sQpush32(valuatorFlag); this._sock.sQpush32(ev.detail.currentTouches[i].event.touchIdentifier); - + let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, this._canvas); - + if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { let scaledX16 = this._display.absX(scaledPosition.x) & 0xFFFF; let scaledY16 = this._display.absY(scaledPosition.y) & 0xFFFF; let coordinates = (scaledX16 << 16) | scaledY16; this._sock.sQpush32(coordinates); } - + // Keep track of last released touches if (ev.detail.currentTouches[i].status === "POINTER_UP") { pointerUpIds.push(ev.detail.currentTouches[i].event.identifier); } } - - this._sock.flush(); - - // Remove released touches from current touches in handler - for (let i = 0; i < pointerUpIds.length; i++) { - const index = ev.detail.currentTouches.findIndex(t => t.event.identifier === pointerUpIds[i]); - if (index !== -1) { - this._gestures._removeTouch(index); - } - } - - // Interrupt touch sending interval - if (ev.detail.currentTouches.length === 0 && this._sendTouchesIntervalId !== -1) { - Log.Debug("NO MORE TOUCHES\n"); - this._gestures._interruptTouches(); - this._sendEmptyTouch(ev.detail.giiDeviceOrigin); - return; - } - } - _sendEmptyTouch(giiDeviceOrigin) { - let valuatorFlag = 0x00000000; - valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; - valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_CLEAR; - - this._sock.sQpush8(253); // GII message type - this._sock.sQpush8(128); // GII event - this._sock.sQpush16(24); // Header length - this._sock.sQpush8(24); // Event size - this._sock.sQpush8(12); // eventType - this._sock.sQpush16(0); // padding - this._sock.sQpush32(giiDeviceOrigin); // deviceOrigin - this._sock.sQpush32(1); // first - this._sock.sQpush32(4); // Count - this._sock.sQpush32(valuatorFlag); // Flag - this._sock.sQpush32(0); // Empty Id - this._sock.sQpush32(0); // Empty coordinates this._sock.flush(); - } - _handleUltraVNCTouch(ev) { - this._sock.sQpush8(253); // GII message type - this._sock.sQpush8(128); // GII event - this._sock.sQpush16(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // Length - this._sock.sQpush8(4 + 16 + (6 * 2 * ev.detail.currentTouches.length)); // eventSize - this._sock.sQpush8(12); // eventType - this._sock.sQpush16(0); // padding - this._sock.sQpush32(ev.detail.giiDeviceOrigin); // deviceOrigin - this._sock.sQpush32(ev.detail.currentTouches.length); // first - this._sock.sQpush32(6 * ev.detail.currentTouches.length); // count - - let pointerUpIds = []; - - // Send all current touches - for (let i = 0; i < ev.detail.currentTouches.length; i++) { - let valuatorFlag = 0x00000000; - valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; - valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_32; - if (ev.detail.currentTouches[i].status !== "POINTER_UP") valuatorFlag |= TouchHandlerUltraVNC.PF_flag; - if (ev.detail.currentTouches[i].event.identifier === 0) valuatorFlag |= TouchHandlerUltraVNC.IF_flag; // IF_flag - - this._sock.sQpush32(valuatorFlag); - this._sock.sQpush32(ev.detail.currentTouches[i].event.touchIdentifier); - - let scaledPosition = clientToElement(ev.detail.currentTouches[i].event.clientX, ev.detail.currentTouches[i].event.clientY, - this._canvas); - - if ((valuatorFlag & TouchHandlerUltraVNC.LENGTH_16_flag) !== 0) { - let scaledX16 = this._display.absX(scaledPosition.x) & 0xFFFF; - let scaledY16 = this._display.absY(scaledPosition.y) & 0xFFFF; - let coordinates = (scaledX16 << 16) | scaledY16; - this._sock.sQpush32(coordinates); - } - - // Keep track of last released touches - if (ev.detail.currentTouches[i].status === "POINTER_UP") { - pointerUpIds.push(ev.detail.currentTouches[i].event.identifier); - } - } - - this._sock.flush(); - // Remove released touches from current touches in handler for (let i = 0; i < pointerUpIds.length; i++) { const index = ev.detail.currentTouches.findIndex(t => t.event.identifier === pointerUpIds[i]); @@ -1600,10 +1450,9 @@ export default class RFB extends EventTargetMixin { this._gestures._removeTouch(index); } } - + // Interrupt touch sending interval if (ev.detail.currentTouches.length === 0 && this._sendTouchesIntervalId !== -1) { - Log.Debug("NO MORE TOUCHES\n"); this._gestures._interruptTouches(); this._sendEmptyTouch(ev.detail.giiDeviceOrigin); return; @@ -1615,18 +1464,18 @@ export default class RFB extends EventTargetMixin { valuatorFlag |= TouchHandlerUltraVNC.LENGTH_16_flag; valuatorFlag |= TouchHandlerUltraVNC.IDFORMAT_CLEAR; - this._sock.sQpush8(253); // GII message type - this._sock.sQpush8(128); // GII event - this._sock.sQpush16(24); // Header length - this._sock.sQpush8(24); // Event size - this._sock.sQpush8(12); // eventType + this._sock.sQpush8(TouchHandlerUltraVNC.giiMsgType); // GII message type + this._sock.sQpush8(TouchHandlerUltraVNC.giiEventInjectionMsgType); // GII event + this._sock.sQpush16(TouchHandlerUltraVNC.giiEventInjectionHeaderSize + TouchHandlerUltraVNC.giiEventInjectionSize); + this._sock.sQpush8(TouchHandlerUltraVNC.giiEventInjectionHeaderSize + TouchHandlerUltraVNC.giiEventInjectionSize); + this._sock.sQpush8(TouchHandlerUltraVNC.giiEventInjectionEventType); this._sock.sQpush16(0); // padding this._sock.sQpush32(giiDeviceOrigin); // deviceOrigin - this._sock.sQpush32(1); // first - this._sock.sQpush32(4); // Count - this._sock.sQpush32(valuatorFlag); // Flag - this._sock.sQpush32(0); // Empty Id - this._sock.sQpush32(0); // Empty coordinates + this._sock.sQpush32(1); // nb of touchevents + this._sock.sQpush32(4); // nb of values, not used + this._sock.sQpush32(valuatorFlag); + this._sock.sQpush32(0); // empty Id + this._sock.sQpush32(0); // empty coordinates this._sock.flush(); } @@ -2399,7 +2248,7 @@ export default class RFB extends EventTargetMixin { encs.push(encodings.pseudoEncodingDesktopName); encs.push(encodings.pseudoEncodingExtendedClipboard); - if (this._useUltraVNCGestures) { + if (this._gesturesMode === 'ultravnc') { encs.push(encodings.pseudoEncodingGii); } @@ -3529,39 +3378,39 @@ RFB.messages = { }, giiVersionMessage(sock) { - sock.sQpush8(253); // gii msg-type - sock.sQpush8(129); // gii version sub-msg-type - sock.sQpush16(2); // length - sock.sQpush16(1); // version + sock.sQpush8(TouchHandlerUltraVNC.giiMsgType); + sock.sQpush8(TouchHandlerUltraVNC.giiDeviceVersionMsgType); + sock.sQpush16(TouchHandlerUltraVNC.giiDeviceVersionMsgSize); + sock.sQpush16(TouchHandlerUltraVNC.giiDeviceVersion); sock.flush(); }, giiDeviceCreation(sock) { - sock.sQpush8(253); // gii msg-type - sock.sQpush8(130); // gii device creation sub-msg-type - sock.sQpush16(172); // length - sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NOVNC-MT", 31)); // device name - sock.sQpush8(0); // DNTerm - sock.sQpush32(0x0908); // vendorID - sock.sQpush32(0x000b); // productID - sock.sQpush32(0x00002000); // eventMask - sock.sQpush32(0); // numRegisters - sock.sQpush32(1); // numValuators - sock.sQpush32(5); // numButtons - sock.sQpush32(0); // index - sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NOVNC Multitouch Device", 74)); // longName - sock.sQpush8(0); // LNTerm - sock.sQpushBytes(RFB.stringAsByteArrayWithPadding("NMD", 4)); // shortName - sock.sQpush8(0); // SNTerm - sock.sQpush32(0); // rangeMin - sock.sQpush32(0); // rangeCenter - sock.sQpush32(0); // rangeMax - sock.sQpush32(0); // SIUnit - sock.sQpush32(0); // SIAdd - sock.sQpush32(0); // SIMul - sock.sQpush32(0); // SIDiv - sock.sQpush32(0); // SIShift + sock.sQpush8(TouchHandlerUltraVNC.giiMsgType); + sock.sQpush8(TouchHandlerUltraVNC.giiDeviceCreationMsgType); + sock.sQpush16(TouchHandlerUltraVNC.giiDeviceCreationMsgSize); + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding(TouchHandlerUltraVNC.giiDeviceName, TouchHandlerUltraVNC.giiDeviceNameSize)); + sock.sQpush8(TouchHandlerUltraVNC.giiDNTerm); + sock.sQpush32(TouchHandlerUltraVNC.giiVendorID); + sock.sQpush32(TouchHandlerUltraVNC.giiProductID); + sock.sQpush32(TouchHandlerUltraVNC.giiEventMask); + sock.sQpush32(TouchHandlerUltraVNC.giiNumRegisters); + sock.sQpush32(TouchHandlerUltraVNC.giiNumValuators); + sock.sQpush32(TouchHandlerUltraVNC.giiNumButtons); + sock.sQpush32(TouchHandlerUltraVNC.giiIndex); + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding(TouchHandlerUltraVNC.giiDeviceLongName, TouchHandlerUltraVNC.giiDeviceLongNameSize)); + sock.sQpush8(TouchHandlerUltraVNC.giiLNTerm); + sock.sQpushBytes(RFB.stringAsByteArrayWithPadding(TouchHandlerUltraVNC.giiDeviceShortName, TouchHandlerUltraVNC.giiDeviceShortNameSize)); + sock.sQpush8(TouchHandlerUltraVNC.giiSNTerm); + sock.sQpush32(TouchHandlerUltraVNC.giiRangeMin); + sock.sQpush32(TouchHandlerUltraVNC.giiRangeCenter); + sock.sQpush32(TouchHandlerUltraVNC.giiRangeMax); + sock.sQpush32(TouchHandlerUltraVNC.giiSIUnit); + sock.sQpush32(TouchHandlerUltraVNC.giiSIAdd); + sock.sQpush32(TouchHandlerUltraVNC.giiSIMul); + sock.sQpush32(TouchHandlerUltraVNC.giiSIDiv); + sock.sQpush32(TouchHandlerUltraVNC.giiSIShift); sock.flush(); } diff --git a/vnc.html b/vnc.html index 44c437186..e4c9a6017 100644 --- a/vnc.html +++ b/vnc.html @@ -270,7 +270,11 @@

    no
    VNC


  • - + +