summaryrefslogtreecommitdiff
path: root/kvmd/web/js/hid.js
diff options
context:
space:
mode:
Diffstat (limited to 'kvmd/web/js/hid.js')
-rw-r--r--kvmd/web/js/hid.js130
1 files changed, 117 insertions, 13 deletions
diff --git a/kvmd/web/js/hid.js b/kvmd/web/js/hid.js
index 130b66a8..86d3931d 100644
--- a/kvmd/web/js/hid.js
+++ b/kvmd/web/js/hid.js
@@ -1,7 +1,24 @@
var hid = new function() {
+ var __ws = null;
+ var __chars_to_codes = {};
+ var __codes_delay = 50;
+
this.init = function() {
keyboard.init();
mouse.init();
+ if (window.navigator.clipboard && window.navigator.clipboard.readText) {
+ __chars_to_codes = __buildCharsToCodes();
+ $("pak-button").onclick = __pasteAsKeys;
+ } else {
+ $("pak-button").title = "Your browser does not support the Clipboard API.\nUse Google Chrome or Chromium.";
+ }
+ };
+
+ this.setSocket = function(ws) {
+ __ws = ws;
+ keyboard.setSocket(ws);
+ mouse.setSocket(ws);
+ $("pak-button").disabled = !(window.navigator.clipboard && window.navigator.clipboard.readText && ws);
};
this.updateLeds = function() {
@@ -14,24 +31,111 @@ var hid = new function() {
};
this.emitShortcut = function(...codes) {
- tools.debug("Emitted keys:", codes);
- var delay = 0;
- [[codes, true], [codes.slice().reverse(), false]].forEach(function(op) {
- var [op_codes, state] = op;
- op_codes.forEach(function(code) {
- setTimeout(() => keyboard.fireEvent(code, state), delay);
- delay += 100;
+ return new Promise(function(resolve) {
+ tools.debug("Emitting keys:", codes);
+
+ var raw_events = [];
+ [[codes, true], [codes.slice().reverse(), false]].forEach(function(op) {
+ var [op_codes, state] = op;
+ op_codes.forEach(function(code) {
+ raw_events.push({code: code, state: state});
+ });
});
+
+ var index = 0;
+ var iterate = () => setTimeout(function() {
+ keyboard.fireEvent(raw_events[index].code, raw_events[index].state);
+ ++index;
+ if (index < raw_events.length) {
+ iterate();
+ } else {
+ resolve(null);
+ }
+ }, __codes_delay);
+ iterate();
});
};
- this.installCapture = function(ws) {
- keyboard.setSocket(ws);
- mouse.setSocket(ws);
+ var __buildCharsToCodes = function() {
+ var chars_to_codes = {
+ "\n": ["Enter"],
+ "\t": ["Tab"],
+ " ": ["Space"],
+ "`": ["Backquote"], "~": ["ShiftLeft", "Backquote"],
+ "\\": ["Backslash"], "|": ["ShiftLeft", "Backslash"],
+ "[": ["BracketLeft"], "{": ["ShiftLeft", "BracketLeft"],
+ "]": ["BracketLeft"], "}": ["ShiftLeft", "BracketRight"],
+ ",": ["Comma"], "<": ["ShiftLeft", "Comma"],
+ ".": ["Period"], ">": ["ShiftLeft", "Period"],
+ "1": ["Digit1"], "!": ["ShiftLeft", "Digit1"],
+ "2": ["Digit2"], "@": ["ShiftLeft", "Digit2"],
+ "3": ["Digit3"], "#": ["ShiftLeft", "Digit3"],
+ "4": ["Digit4"], "$": ["ShiftLeft", "Digit4"],
+ "5": ["Digit5"], "%": ["ShiftLeft", "Digit5"],
+ "6": ["Digit6"], "^": ["ShiftLeft", "Digit6"],
+ "7": ["Digit7"], "&": ["ShiftLeft", "Digit7"],
+ "8": ["Digit8"], "*": ["ShiftLeft", "Digit8"],
+ "9": ["Digit9"], "(": ["ShiftLeft", "Digit9"],
+ "0": ["Digit0"], ")": ["ShiftLeft", "Digit0"],
+ "-": ["Minus"], "_": ["ShiftLeft", "Minus"],
+ "'": ["Quote"], "\"": ["ShiftLeft", "Quote"],
+ ";": ["Semicolon"], ":": ["ShiftLeft", "Semicolon"],
+ "/": ["Slash"], "?": ["ShiftLeft", "Slash"],
+ "=": ["Equal"], "+": ["ShiftLeft", "Equal"],
+ };
+
+ for (var ch = "a".charCodeAt(0); ch <= "z".charCodeAt(0); ++ch) {
+ var low = String.fromCharCode(ch);
+ var up = low.toUpperCase();
+ var code = "Key" + up;
+ chars_to_codes[low] = [code];
+ chars_to_codes[up] = ["ShiftLeft", code];
+ }
+
+ return chars_to_codes;
};
- this.clearCapture = function() {
- mouse.setSocket(null);
- keyboard.setSocket(null);
+ var __pasteAsKeys = function() {
+ window.navigator.clipboard.readText().then(function(clipboard_text) {
+ clipboard_text = clipboard_text.replace(/[^\x00-\x7F]/g, ""); // eslint-disable-line no-control-regex
+ if (clipboard_text) {
+ var clipboard_codes = [];
+ var codes_count = 0;
+ [...clipboard_text].forEach(function(ch) {
+ var codes = __chars_to_codes[ch];
+ if (codes) {
+ codes_count += codes.length;
+ clipboard_codes.push(codes);
+ }
+ });
+
+ var confirm_msg = (
+ "You are going to automatically type " + codes_count
+ + " characters from the system clipboard.\nAre you sure you want to continue?\n"
+ + "It will take " + (__codes_delay * codes_count * 2 / 1000) + " seconds."
+ );
+
+ if (codes_count <= 256 || confirm(confirm_msg)) {
+ $("pak-button").disabled = true;
+ $("pak-led").className = "led-pak-typing";
+
+ tools.debug("Paste-as-keys:", clipboard_text);
+
+ var index = 0;
+ var iterate = function() {
+ hid.emitShortcut(...clipboard_codes[index]).then(function() {
+ ++index;
+ if (index < clipboard_codes.length && __ws) {
+ iterate();
+ } else {
+ $("pak-button").disabled = false;
+ $("pak-led").className = "led-off";
+ }
+ });
+ };
+ iterate();
+ }
+ }
+ });
};
};