summaryrefslogtreecommitdiff
path: root/kvmd/web
diff options
context:
space:
mode:
Diffstat (limited to 'kvmd/web')
-rw-r--r--kvmd/web/css/stream.css8
-rw-r--r--kvmd/web/js/hid.js34
-rw-r--r--kvmd/web/js/keyboard.js6
-rw-r--r--kvmd/web/js/mouse.js31
-rw-r--r--kvmd/web/js/stream.js4
-rw-r--r--kvmd/web/svg/stream-mouse-cursor.svg68
6 files changed, 110 insertions, 41 deletions
diff --git a/kvmd/web/css/stream.css b/kvmd/web/css/stream.css
index 96b19810..fa892545 100644
--- a/kvmd/web/css/stream.css
+++ b/kvmd/web/css/stream.css
@@ -2,7 +2,6 @@ img#stream-image {
width: 640px;
height: 480px;
display: inline-block;
- border: var(--dark-border);
background-color: var(--bg-color-stream-screen);
}
@@ -19,9 +18,7 @@ img.stream-image-inactive {
div#stream-box {
position: relative;
display: inline-block;
-}
-div.stream-box-active: {
- cursor: crosshair;
+ border: var(--dark-border);
}
div.stream-box-inactive::after {
cursor: wait;
@@ -34,3 +31,6 @@ div.stream-box-inactive::after {
display: inline-block;
background: radial-gradient(transparent 20%, black);
}
+div.stream-box-mouse-enabled {
+ cursor: url("../svg/stream-mouse-cursor.svg"), pointer;
+}
diff --git a/kvmd/web/js/hid.js b/kvmd/web/js/hid.js
index a8a5d653..cb6c37bf 100644
--- a/kvmd/web/js/hid.js
+++ b/kvmd/web/js/hid.js
@@ -1,10 +1,4 @@
var hid = new function() {
- var __install_timer = null;
- var __installed = false;
-
- var __hidden_attr = null;
- var __visibility_change_attr = null;
-
this.init = function() {
keyboard.init();
mouse.init();
@@ -32,32 +26,12 @@ var hid = new function() {
};
this.installCapture = function(ws) {
- var http = tools.makeRequest("GET", "/kvmd/hid", function() {
- if (http.readyState === 4) {
- if (http.status === 200) {
- features = JSON.parse(http.responseText).result.features;
- if (features.mouse) {
- mouse.setSocket(ws);
- }
- keyboard.setSocket(ws);
- __installed = true;
- } else {
- tools.error("Can't resolve HID features:", http.responseText);
- __install_timer = setTimeout(() => hid.installCapture(ws), 1000);
- }
- }
- });
+ keyboard.setSocket(ws);
+ mouse.setSocket(ws);
};
this.clearCapture = function() {
- if (__install_timer) {
- clearTimeout(__install_timer);
- __install_timer = null;
- }
- if (__installed) {
- mouse.setSocket(null);
- keyboard.setSocket(null);
- __installed = false;
- }
+ mouse.setSocket(null);
+ keyboard.setSocket(null);
};
}
diff --git a/kvmd/web/js/keyboard.js b/kvmd/web/js/keyboard.js
index 9d3f65e6..3618f447 100644
--- a/kvmd/web/js/keyboard.js
+++ b/kvmd/web/js/keyboard.js
@@ -27,8 +27,10 @@ var keyboard = new function() {
};
this.setSocket = function(ws) {
- keyboard.releaseAll();
- __ws = ws;
+ if (ws !== __ws) {
+ keyboard.releaseAll();
+ __ws = ws;
+ }
keyboard.updateLeds();
};
diff --git a/kvmd/web/js/mouse.js b/kvmd/web/js/mouse.js
index b9d27e67..ba4eb264 100644
--- a/kvmd/web/js/mouse.js
+++ b/kvmd/web/js/mouse.js
@@ -2,9 +2,12 @@ var mouse = new function() {
var __ws = null;
var __current_pos = {x: 0, y:0};
var __sent_pos = {x: 0, y:0};
+ var __stream_hovered = false;
this.init = function() {
el_stream_box = $("stream-box");
+ el_stream_box.onmouseenter = __hoverStream;
+ el_stream_box.onmouseleave = __leaveStream;
el_stream_box.onmousedown = (event) => __buttonHandler(event, true);
el_stream_box.onmouseup = (event) => __buttonHandler(event, false);
el_stream_box.oncontextmenu = (event) => event.preventDefault();
@@ -15,11 +18,25 @@ var mouse = new function() {
this.setSocket = function(ws) {
__ws = ws;
+ if (ws) {
+ $("stream-box").classList.add("stream-box-mouse-enabled");
+ } else {
+ $("stream-box").classList.remove("stream-box-mouse-enabled");
+ }
+ };
+
+ var __hoverStream = function() {
+ __stream_hovered = true;
+ mouse.updateLeds();
+ };
+
+ var __leaveStream = function() {
+ __stream_hovered = false;
+ mouse.updateLeds();
};
this.updateLeds = function() {
- var focused = (__ws && document.activeElement === $("stream-window"));
- $("hid-mouse-led").className = (focused ? "led-on" : "led-off");
+ $("hid-mouse-led").className = (__ws && __stream_hovered ? "led-on" : "led-off");
};
var __buttonHandler = function(event, state) {
@@ -56,15 +73,23 @@ var mouse = new function() {
if (pos.x !== __sent_pos.x || pos.y !== __sent_pos.y) {
tools.debug("Mouse move:", pos);
if (__ws) {
+ el_stream_image = $("stream-image");
__ws.send(JSON.stringify({
event_type: "mouse_move",
- to: pos,
+ to: {
+ x: __translate(pos.x, 0, el_stream_image.clientWidth, -32768, 32767),
+ y: __translate(pos.y, 0, el_stream_image.clientHeight, -32768, 32767),
+ },
}));
}
__sent_pos = pos;
}
};
+ var __translate = function(x, a, b, c, d) {
+ return Math.round((x - a) / (b - a) * (d - c) + c);
+ };
+
var __wheelHandler = function(event) {
// https://learn.javascript.ru/mousewheel
if (event.preventDefault) {
diff --git a/kvmd/web/js/stream.js b/kvmd/web/js/stream.js
index 51e00a96..e7bd82d4 100644
--- a/kvmd/web/js/stream.js
+++ b/kvmd/web/js/stream.js
@@ -11,14 +11,14 @@ var stream = new function() {
tools.info("Refreshing stream ...");
__prev_state = false;
$("stream-image").className = "stream-image-inactive";
- $("stream-box").className = "stream-box-inactive";
+ $("stream-box").classList.add("stream-box-inactive");
$("stream-led").className = "led-off";
$("stream-reset-button").disabled = true;
} else if (!__prev_state) {
__refreshImage();
__prev_state = true;
$("stream-image").className = "stream-image-active";
- $("stream-box").className = "stream-box-active";
+ $("stream-box").classList.remove("stream-box-inactive");
$("stream-led").className = "led-on";
$("stream-reset-button").disabled = false;
}
diff --git a/kvmd/web/svg/stream-mouse-cursor.svg b/kvmd/web/svg/stream-mouse-cursor.svg
new file mode 100644
index 00000000..ff852ef6
--- /dev/null
+++ b/kvmd/web/svg/stream-mouse-cursor.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="2.6458335mm"
+ height="2.6458335mm"
+ viewBox="0 0 2.6458335 2.6458335"
+ version="1.1"
+ id="svg8"
+ sodipodi:docname="stream-mouse-cursor.svg"
+ inkscape:version="0.92.2 2405546, 2018-03-11">
+ <defs
+ id="defs2" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="31.678384"
+ inkscape:cx="13.114187"
+ inkscape:cy="8.129091"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:window-width="1920"
+ inkscape:window-height="1020"
+ inkscape:window-x="0"
+ inkscape:window-y="30"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-102.90015,-148.41315)">
+ <circle
+ style="opacity:1;fill:#5b90bb;fill-opacity:1;stroke:#e8e8e8;stroke-width:0.26458332;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:75.59055328;stroke-opacity:0.80303034;paint-order:normal"
+ id="path4915"
+ cx="104.22307"
+ cy="149.73607"
+ r="1.1906251" />
+ </g>
+</svg>