diff options
Diffstat (limited to 'kvmd/web')
-rw-r--r-- | kvmd/web/css/stream.css | 8 | ||||
-rw-r--r-- | kvmd/web/js/hid.js | 34 | ||||
-rw-r--r-- | kvmd/web/js/keyboard.js | 6 | ||||
-rw-r--r-- | kvmd/web/js/mouse.js | 31 | ||||
-rw-r--r-- | kvmd/web/js/stream.js | 4 | ||||
-rw-r--r-- | kvmd/web/svg/stream-mouse-cursor.svg | 68 |
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> |