From 0a6f8c0f8c00c39e1bc5b43285bec6f0db344e78 Mon Sep 17 00:00:00 2001 From: lxsang Date: Tue, 29 Dec 2020 19:36:35 +0000 Subject: [PATCH] update remoteDesktop --- RemoteDesktop/README.md | 5 +- RemoteDesktop/build/debug/README.md | 5 +- RemoteDesktop/build/debug/main.js | 2 +- RemoteDesktop/build/debug/package.json | 3 +- RemoteDesktop/build/release/RemoteDesktop.zip | Bin 308541 -> 301978 bytes RemoteDesktop/coffees/main.coffee | 23 +- RemoteDesktop/javascripts/decoder.js | 1 - RemoteDesktop/javascripts/wvnc.js | 1 - RemoteDesktop/javascripts/wvnc_asm.js | 5 - RemoteDesktop/javascripts/wvnc_asm.wasm | Bin 265189 -> 0 bytes RemoteDesktop/package.json | 3 +- RemoteDesktop/project.json | 4 +- libwvnc/README.md | 74 ++++ libwvnc/build/debug/README.md | 74 ++++ libwvnc/build/debug/decoder.js | 112 +++++++ libwvnc/build/debug/main.js | 1 + libwvnc/build/debug/package.json | 15 + libwvnc/build/release/libwvnc.zip | Bin 0 -> 11690 bytes libwvnc/decoder.js | 112 +++++++ libwvnc/main.coffee | 315 ++++++++++++++++++ libwvnc/package.json | 15 + libwvnc/project.json | 7 + packages.json | 14 +- 23 files changed, 757 insertions(+), 34 deletions(-) delete mode 100644 RemoteDesktop/javascripts/decoder.js delete mode 100644 RemoteDesktop/javascripts/wvnc.js delete mode 100644 RemoteDesktop/javascripts/wvnc_asm.js delete mode 100644 RemoteDesktop/javascripts/wvnc_asm.wasm create mode 100644 libwvnc/README.md create mode 100644 libwvnc/build/debug/README.md create mode 100644 libwvnc/build/debug/decoder.js create mode 100644 libwvnc/build/debug/main.js create mode 100644 libwvnc/build/debug/package.json create mode 100644 libwvnc/build/release/libwvnc.zip create mode 100644 libwvnc/decoder.js create mode 100644 libwvnc/main.coffee create mode 100644 libwvnc/package.json create mode 100644 libwvnc/project.json diff --git a/RemoteDesktop/README.md b/RemoteDesktop/README.md index 4ef2bf5..bcfc2f0 100644 --- a/RemoteDesktop/README.md +++ b/RemoteDesktop/README.md @@ -5,11 +5,8 @@ A web based VNC client allowing to control remote VNC desktop from browser. The Further information on **wvnc**: [https://blog.lxsang.me/post/id/23](https://blog.lxsang.me/post/id/23) -**Credit** -* antd-wvnc-plugin: [https://github.com/lxsang/antd-wvnc-plugin](https://github.com/lxsang/antd-wvnc-plugin) -* wvnc.js: [https://github.com/lxsang/wvnc.js](https://github.com/lxsang/wvnc.js) -* ## Change logs +* v0.1.5 - add package dependencies and use the new **libwvnc** * v0.1.0 - adapt to the new AntOS API \ No newline at end of file diff --git a/RemoteDesktop/build/debug/README.md b/RemoteDesktop/build/debug/README.md index 4ef2bf5..bcfc2f0 100644 --- a/RemoteDesktop/build/debug/README.md +++ b/RemoteDesktop/build/debug/README.md @@ -5,11 +5,8 @@ A web based VNC client allowing to control remote VNC desktop from browser. The Further information on **wvnc**: [https://blog.lxsang.me/post/id/23](https://blog.lxsang.me/post/id/23) -**Credit** -* antd-wvnc-plugin: [https://github.com/lxsang/antd-wvnc-plugin](https://github.com/lxsang/antd-wvnc-plugin) -* wvnc.js: [https://github.com/lxsang/wvnc.js](https://github.com/lxsang/wvnc.js) -* ## Change logs +* v0.1.5 - add package dependencies and use the new **libwvnc** * v0.1.0 - adapt to the new AntOS API \ No newline at end of file diff --git a/RemoteDesktop/build/debug/main.js b/RemoteDesktop/build/debug/main.js index 8263c4a..a6e0383 100644 --- a/RemoteDesktop/build/debug/main.js +++ b/RemoteDesktop/build/debug/main.js @@ -1 +1 @@ -(function(){var t,e,n;(t=class t extends this.OS.GUI.BasicDialog{constructor(){super("ConnectionDialog",t.scheme)}main(){return super.main(),this.find("bbp").data=[{text:"16 bits",value:16,selected:!0},{text:"32 bits",value:32}],this.find("compression").data=[{text:"No compression",value:0},{text:"JPEG",value:1},{text:"zLib",value:2},{text:"JPEG & zLib",value:3,selected:!0}],this.find("jq").value=40,this.find("bt-ok").onbtclick=t=>{var e;if(this.handle)return e={wvnc:this.find("txtWVNC").value,server:this.find("txtServer").value,bbp:this.find("bbp").selectedItem.data.value,flag:this.find("compression").selectedItem.data.value,quality:this.find("jq").value},this.handle(e),this.quit()},this.find("bt-cancel").onbtclick=t=>this.quit()}}).scheme='\n \n
\n \n \n \n \n \n
\n \n \n
\n \n \n
\n \n \n \n
\n \n \n
\n
\n
\n
\n
\n
\n
\n',(e=class t extends this.OS.GUI.BasicDialog{constructor(){super("CredentialDialog",t.scheme)}main(){return this.find("bt-ok").onbtclick=()=>{var t;return this.handle?(t={username:this.find("txtUser").value,password:this.find("txtPass").value},this.handle(t),this.quit()):this.quit()},this.find("bt-cancel").onbtclick=()=>this.quit()}}).scheme='\n \n \n \n \n \n \n
\n \n \n
\n
\n
\n
\n
\n',n=class extends this.OS.application.BaseApplication{constructor(t){super("RemoteDesktop",t)}main(){return this.canvas=this.find("screen"),this.container=this.find("container"),this.client=new WVNC({element:this.canvas,worker:`${this._api.handle.get}/${this.meta().path}/decoder.js`}),this.client.onerror=t=>(this.error(t),this.showConnectionDialog()),this.client.onresize=()=>this.setScale(),this.client.onpassword=()=>new Promise((t,e)=>this.openDialog("PromptDialog",{title:__("VNC password"),label:__("VNC password"),value:"!x$@n9ph",type:"password"}).then((function(e){return t(e)}))),this.client.oncredential=()=>new Promise((t,n)=>this.openDialog(new e,{title:__("User credential")}).then((function(e){return t(e.username,e.password)}))),this.on("resize",t=>this.setScale()),this.on("focus",t=>$(this.canvas).focus()),this.client.init().then(()=>this.showConnectionDialog())}setScale(){var t,e,n,a;if(this.client&&this.client.resolution)return a=$(this.container).width(),t=$(this.container).height(),(e=a/this.client.resolution.w)>(n=t/this.client.resolution.h)?this.client.setScale(n):this.client.setScale(e)}menu(){return[{text:"__(Connection)",nodes:[{text:"__(New Connection)",dataid:this.name+"-new"},{text:"__(Disconnect)",dataid:this.name+"-close"}],onchildselect:t=>this.actionConnection()}]}actionConnection(t){return this.client&&this.client.disconnect(),this.showConnectionDialog()}showConnectionDialog(){return this.openDialog(new t,{title:__("Connection")}).then(t=>(this.client.ws=t.wvnc,console.log(t),this.client.connect(t.server,t)))}cleanup(){if(this.client)return this.client.disconnect()}},this.OS.register("RemoteDesktop",n)}).call(this),function(){var t;t=function(){function t(t){var e,n;this.socket=void 0,this.ws=void 0,this.canvas=void 0,n="decoder.js",this.scale=1,t.ws&&(this.ws=t.ws),this.canvas=t.element,"string"==typeof this.canvas&&(this.canvas=document.getElementById(this.canvas)),t.worker&&(n=t.worker),this.decoder=new Worker(n),this.enableEvent=!0,(e=this).mouseMask=0,this.decoder.onmessage=function(t){return e.process(t.data)}}return t.prototype.init=function(){var t;return t=this,new Promise((function(e,n){return t.canvas?($(t.canvas).attr("tabindex","1"),t.initInputEvent(),e()):n("Canvas is not set")}))},t.prototype.initInputEvent=function(){var t,e,n,a;if((n=this).canvas&&(e=function(t){var e;return e=n.canvas.getBoundingClientRect(),{x:Math.floor((t.clientX-e.left)/n.scale),y:Math.floor((t.clientY-e.top)/n.scale)}},a=function(t){var a;if(n.enableEvent)return a=e(t),n.sendPointEvent(a.x,a.y,n.mouseMask)},n.canvas))return n.canvas.oncontextmenu=function(t){return t.preventDefault(),!1},n.canvas.onmousemove=function(t){return a(t)},n.canvas.onmousedown=function(t){var e;return e=1<>8,a[2]=255&e,a[3]=e>>8,a[4]=n,this.socket.send(this.buildCommand(5,a))},t.prototype.sendKeyEvent=function(t,e){var n;if(this.socket&&this.enableEvent)return(n=new Uint8Array(3))[0]=255&t,n[1]=t>>8,n[2]=e,this.socket.send(this.buildCommand(6,n))},t.prototype.buildCommand=function(t,e){var n,a;switch(a=void 0,typeof e){case"string":a=(new TextEncoder).encode(e);break;case"number":a=new Uint8Array([e]);break;default:a=e}return(n=new Uint8Array(a.length+3))[0]=t,n[2]=a.length>>8,n[1]=15&a.length,n.set(a,3),n.buffer},t.prototype.oncopy=function(t){return console.log("Get clipboard text: "+t)},t.prototype.onpassword=function(){return new Promise((function(t,e){return e("onpassword is not implemented")}))},t.prototype.sendTextAsClipboard=function(t){if(this.socket)return console.log("send ",t),this.socket.send(this.buildCommand(7,t))},t.prototype.oncredential=function(){return new Promise((function(t,e){return e("oncredential is not implemented")}))},t.prototype.onerror=function(t){return console.log("Error",t)},t.prototype.onresize=function(){return console.log("resize")},t.prototype.consume=function(t){var e,n,a,i,s,o,r;switch(e=(n=new Uint8Array(t.data))[0],o=this,e){case 254:return n=n.subarray(1,n.length-1),a=new TextDecoder("utf-8"),this.onerror(a.decode(n));case 129:return console.log("Request for password"),this.enableEvent=!1,this.onpassword().then((function(t){return o.socket.send(o.buildCommand(2,t)),o.enableEvent=!0}));case 130:return console.log("Request for login"),this.enableEvent=!1,this.oncredential().then((function(t,e){var n;return(n=new Uint8Array(t.length+e.length+1)).set((new TextEncoder).encode(t),0),n.set(["\0"],t.length),n.set((new TextEncoder).encode(e),t.length+1),o.socket.send(o.buildCommand(3,n)),o.enableEvent=!0}));case 131:return r=n[1]|n[2]<<8,s=n[3]|n[4]<<8,i=n[5],this.initCanvas(r,s,i),this.socket.send(this.buildCommand(4,1)),this.onresize();case 132:return this.decoder.postMessage(n.buffer,[n.buffer]);case 133:return n=n.subarray(1),a=new TextDecoder("utf-8"),this.oncopy(a.decode(n)),this.socket.send(this.buildCommand(4,1));default:return console.log(e)}},t}(),window.WVNC=t}.call(this); \ No newline at end of file +(function(){var t,e,i;(t=class t extends this.OS.GUI.BasicDialog{constructor(){super("ConnectionDialog",t.scheme)}main(){return super.main(),this.find("bbp").data=[{text:"16 bits",value:16,selected:!0},{text:"32 bits",value:32}],this.find("compression").data=[{text:"No compression",value:0},{text:"JPEG",value:1,selected:!0}],this.find("jq").value=40,this.find("bt-ok").onbtclick=t=>{var e;if(this.handle)return e={wvnc:this.find("txtWVNC").value,server:this.find("txtServer").value,bbp:this.find("bbp").selectedItem.data.value,flag:this.find("compression").selectedItem.data.value,quality:this.find("jq").value},this.handle(e),this.quit()},this.find("bt-cancel").onbtclick=t=>this.quit()}}).scheme='\n \n
\n \n \n \n \n \n
\n \n \n
\n \n \n
\n \n \n \n
\n \n \n
\n
\n
\n
\n
\n
\n
\n',(e=class t extends this.OS.GUI.BasicDialog{constructor(){super("CredentialDialog",t.scheme)}main(){return this.find("bt-ok").onbtclick=()=>{var t;return this.handle?(t={username:this.find("txtUser").value,password:this.find("txtPass").value},this.handle(t),this.quit()):this.quit()},this.find("bt-cancel").onbtclick=()=>this.quit()}}).scheme='\n \n \n \n \n \n \n
\n \n \n
\n
\n
\n
\n
\n',(i=class extends this.OS.application.BaseApplication{constructor(t){super("RemoteDesktop",t)}main(){return this.canvas=this.find("screen"),this.container=this.find("container"),this.client=new WVNC({element:this.canvas,libjpeg:"pkg://libjpeg/jpg.js".asFileHandle().getlink()}),this.client.onerror=t=>(this.error(t),this.showConnectionDialog()),this.client.onresize=()=>this.setScale(),this.client.onpassword=()=>new Promise((t,e)=>this.openDialog("PromptDialog",{title:__("VNC password"),label:__("VNC password"),value:"password",type:"password"}).then((function(e){return t(e)}))),this.client.oncredential=()=>new Promise((t,i)=>this.openDialog(new e,{title:__("User credential")}).then((function(e){return t(e.username,e.password)}))),this.on("resize",t=>this.setScale()),this.on("focus",t=>$(this.canvas).focus()),this.client.init().then(()=>this.showConnectionDialog())}setScale(){var t,e,i,a;if(this.client&&this.client.resolution)return a=$(this.container).width(),t=$(this.container).height(),(e=a/this.client.resolution.w)>(i=t/this.client.resolution.h)?this.client.setScale(i):this.client.setScale(e)}menu(){return[{text:"__(Connection)",nodes:[{text:"__(New Connection)",dataid:this.name+"-new"},{text:"__(Disconnect)",dataid:this.name+"-close"}],onchildselect:t=>this.actionConnection()}]}actionConnection(t){return this.client&&this.client.disconnect(!1),this.showConnectionDialog()}showConnectionDialog(){return this.openDialog(new t,{title:__("Connection")}).then(t=>(this.client.ws=t.wvnc,this.client.connect(t.server,t)))}cleanup(){if(this.client)return this.client.disconnect(!0)}}).dependencies=["pkg://libwvnc/main.js"],this.OS.register("RemoteDesktop",i)}).call(this); \ No newline at end of file diff --git a/RemoteDesktop/build/debug/package.json b/RemoteDesktop/build/debug/package.json index 7c7db2d..5422089 100644 --- a/RemoteDesktop/build/debug/package.json +++ b/RemoteDesktop/build/debug/package.json @@ -6,7 +6,8 @@ "author": "", "email": "" }, - "version":"0.1.0-a", + "version":"0.1.5-a", + "dependencies": ["libwvnc@0.1.2-a"], "category":"Other", "icon": "icon.png", "mimes":["none"] diff --git a/RemoteDesktop/build/release/RemoteDesktop.zip b/RemoteDesktop/build/release/RemoteDesktop.zip index 8fa829a9d86cca2d8fdba45bc1103baa3166903e..c903c3673df54860bf9cdf627dab787c3791fc67 100644 GIT binary patch delta 929 zcmZuvO=uHA6rN3A?2oaBHvO^1cC$rDLbFLDwVERKBw{c1sHN7;?vPBgyIHf*9JEwy zX{jI-({`%ZqZUL^n?h6&#EVG5lLtL`5Co+lw4xRS(U}lwwm8e%o!R%j_r3Yvd%n?d zyV%e=G*|_7h_CZ^mQTN3pv#+$2yHgfcT?aKNb%PcbP2_wX*gF^9qo(t9*y+StvT=( zU(doyjmuByg`4ocPbcv)3nyZdl}g0I;qoy&W+mh?Tap#~1kv$H#ng1{56B6e)rpz% z2k2}be%4ruZRgS%jn2$NoN;c{{YQ8;jW_7EPQJgF$wG&KnHo zGe!gyrYv2bgg^CscP;tgWjjmXF3|2(coOOjDN=Wx$d*)@Rf>tjQaR5+MDCHJ3^zi* ztimbJzn1ZIg?q+VcZs6#ku(dXU2$asM1VMRPf~k^+5$5dv#KJs!Q&};9@oDjqk_we z{?~qls!Kyr`6`PzH0TW4kqe>PN<3=v(l-TY@$oW$e;?0%U|w!D4%DG$L?5m}(}YtT zggg$|;TD9->a$L!&B`)(De`C>zM9DNW*Gc!x>gpC5DSnI~m4xzl-*-L3>GbI#7VNgU`Z% Y_fUng1!Qvd(} delta 7485 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 diff --git a/RemoteDesktop/coffees/main.coffee b/RemoteDesktop/coffees/main.coffee index 9d6dd67..098ce5f 100644 --- a/RemoteDesktop/coffees/main.coffee +++ b/RemoteDesktop/coffees/main.coffee @@ -6,14 +6,12 @@ class ConnectionDialog extends this.OS.GUI.BasicDialog main: () -> super.main() @find("bbp").data = [ - { text: "16 bits", value: 16, selected: true }, + { text: "16 bits", value: 16, selected: true }, { text: "32 bits", value: 32 } ] @find("compression").data = [ {text: "No compression", value:0}, - {text: "JPEG", value:1}, - {text: "zLib", value:2}, - {text: "JPEG & zLib", value:3, selected:true} + {text: "JPEG", value:1, selected: true} ] @find("jq").value = 40 @find("bt-ok").onbtclick = (e) => @@ -38,7 +36,7 @@ ConnectionDialog.scheme = """ - +
@@ -106,7 +104,7 @@ class RemoteDesktop extends this.OS.application.BaseApplication @container = @find "container" @client = new WVNC { element: @canvas, - worker: "#{@_api.handle.get}/#{@meta().path}/decoder.js" + libjpeg: "pkg://libjpeg/jpg.js".asFileHandle().getlink() } @client.onerror = (m) => @error m @@ -118,7 +116,7 @@ class RemoteDesktop extends this.OS.application.BaseApplication @openDialog "PromptDialog", { title: __("VNC password"), label: __("VNC password"), - value: "!x$@n9ph", + value: "password", type: "password" } .then (d) -> @@ -156,7 +154,7 @@ class RemoteDesktop extends this.OS.application.BaseApplication ] actionConnection: (e) -> - @client.disconnect() if @client + @client.disconnect(false) if @client @showConnectionDialog() showConnectionDialog: () -> @@ -164,11 +162,12 @@ class RemoteDesktop extends this.OS.application.BaseApplication @openDialog new ConnectionDialog, { title: __("Connection")} .then (d) => @client.ws = d.wvnc - console.log d @client.connect d.server, d cleanup: () -> - @client.disconnect() if @client - - + @client.disconnect(true) if @client + +RemoteDesktop.dependencies = [ + "pkg://libwvnc/main.js" +] this.OS.register "RemoteDesktop", RemoteDesktop \ No newline at end of file diff --git a/RemoteDesktop/javascripts/decoder.js b/RemoteDesktop/javascripts/decoder.js deleted file mode 100644 index e60e095..0000000 --- a/RemoteDesktop/javascripts/decoder.js +++ /dev/null @@ -1 +0,0 @@ -var api,onmessage,resolution,wasm_update;importScripts("wvnc_asm.js"),api={},resolution=void 0,Module.onRuntimeInitialized=function(){return api={createBuffer:Module.cwrap("create_buffer","number",["number","number"]),destroyBuffer:Module.cwrap("destroy_buffer","",["number"]),updateBuffer:Module.cwrap("update","number",["number","number","number","number","number","number"]),decodeBuffer:Module.cwrap("decode","number",["number","number","number","number"])}},wasm_update=function(e){var r,u,n,t,a,o,d,f,i,s,m;if(s=(r=new Uint8Array(e))[1]|r[2]<<8,m=r[3]|r[4]<<8,i=r[5]|r[6]<<8,t=r[7]|r[8]<<8,n=r[9],a=api.createBuffer(r.length),Module.HEAP8.set(r,a),d=i*t*4,o=api.decodeBuffer(a,r.length,resolution.depth,d),u=new Uint8Array(Module.HEAP8.buffer,o,d),e={},(f=new Uint8Array(d)).set(u,0),e.pixels=f.buffer,e.x=s,e.y=m,e.w=i,e.h=t,postMessage(e,[e.pixels]),api.destroyBuffer(a),0!==n||32!==resolution.depth)return api.destroyBuffer(o)},onmessage=function(e){return e.data.depth?resolution=e.data:wasm_update(e.data)}; diff --git a/RemoteDesktop/javascripts/wvnc.js b/RemoteDesktop/javascripts/wvnc.js deleted file mode 100644 index 6903e09..0000000 --- a/RemoteDesktop/javascripts/wvnc.js +++ /dev/null @@ -1 +0,0 @@ -(function(){var e;e=function(){function e(e){var t,n;this.socket=void 0,this.ws=void 0,this.canvas=void 0,n="decoder.js",this.scale=1,e.ws&&(this.ws=e.ws),this.canvas=e.element,"string"==typeof this.canvas&&(this.canvas=document.getElementById(this.canvas)),e.worker&&(n=e.worker),this.decoder=new Worker(n),this.enableEvent=!0,(t=this).mouseMask=0,this.decoder.onmessage=function(e){return t.process(e.data)}}return e.prototype.init=function(){var n;return n=this,new Promise(function(e,t){return n.canvas?($(n.canvas).attr("tabindex","1"),n.initInputEvent(),e()):t("Canvas is not set")})},e.prototype.initInputEvent=function(){var e,n,o,s;if((o=this).canvas&&(n=function(e){var t;return t=o.canvas.getBoundingClientRect(),{x:Math.floor((e.clientX-t.left)/o.scale),y:Math.floor((e.clientY-t.top)/o.scale)}},s=function(e){var t;if(o.enableEvent)return t=n(e),o.sendPointEvent(t.x,t.y,o.mouseMask)},o.canvas))return o.canvas.oncontextmenu=function(e){return e.preventDefault(),!1},o.canvas.onmousemove=function(e){return s(e)},o.canvas.onmousedown=function(e){var t;return t=1<>8,o[2]=255&t,o[3]=t>>8,o[4]=n,this.socket.send(this.buildCommand(5,o))},e.prototype.sendKeyEvent=function(e,t){var n;if(this.socket&&this.enableEvent)return(n=new Uint8Array(3))[0]=255&e,n[1]=e>>8,n[2]=t,this.socket.send(this.buildCommand(6,n))},e.prototype.buildCommand=function(e,t){var n,o;switch(o=void 0,typeof t){case"string":o=(new TextEncoder).encode(t);break;case"number":o=new Uint8Array([t]);break;default:o=t}return(n=new Uint8Array(o.length+3))[0]=e,n[2]=o.length>>8,n[1]=15&o.length,n.set(o,3),n.buffer},e.prototype.oncopy=function(e){return console.log("Get clipboard text: "+e)},e.prototype.onpassword=function(){return new Promise(function(e,t){return t("onpassword is not implemented")})},e.prototype.sendTextAsClipboard=function(e){if(this.socket)return console.log("send ",e),this.socket.send(this.buildCommand(7,e))},e.prototype.oncredential=function(){return new Promise(function(e,t){return t("oncredential is not implemented")})},e.prototype.onerror=function(e){return console.log("Error",e)},e.prototype.onresize=function(){return console.log("resize")},e.prototype.consume=function(e){var t,n,o,s,a,r,i;switch(t=(n=new Uint8Array(e.data))[0],r=this,t){case 254:return n=n.subarray(1,n.length-1),o=new TextDecoder("utf-8"),this.onerror(o.decode(n));case 129:return console.log("Request for password"),this.enableEvent=!1,this.onpassword().then(function(e){return r.socket.send(r.buildCommand(2,e)),r.enableEvent=!0});case 130:return console.log("Request for login"),this.enableEvent=!1,this.oncredential().then(function(e,t){var n;return(n=new Uint8Array(e.length+t.length+1)).set((new TextEncoder).encode(e),0),n.set(["\0"],e.length),n.set((new TextEncoder).encode(t),e.length+1),r.socket.send(r.buildCommand(3,n)),r.enableEvent=!0});case 131:return i=n[1]|n[2]<<8,a=n[3]|n[4]<<8,s=n[5],this.initCanvas(i,a,s),this.socket.send(this.buildCommand(4,1)),this.onresize();case 132:return this.decoder.postMessage(n.buffer,[n.buffer]);case 133:return n=n.subarray(1),o=new TextDecoder("utf-8"),this.oncopy(o.decode(n)),this.socket.send(this.buildCommand(4,1));default:return console.log(t)}},e}(),window.WVNC=e}).call(this); \ No newline at end of file diff --git a/RemoteDesktop/javascripts/wvnc_asm.js b/RemoteDesktop/javascripts/wvnc_asm.js deleted file mode 100644 index d257dac..0000000 --- a/RemoteDesktop/javascripts/wvnc_asm.js +++ /dev/null @@ -1,5 +0,0 @@ -var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw toThrow});Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}else{return scriptDirectory+path}}if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";var nodeFS;var nodePath;Module["read"]=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));process["on"]("unhandledRejection",(function(reason,p){process["exit"](1)}));Module["quit"]=(function(status){process["exit"](status)});Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){Module["read"]=function shell_read(f){return read(f)}}Module["readBinary"]=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=(function(status){quit(status)})}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WEB){if(document.currentScript){scriptDirectory=document.currentScript.src}}else{scriptDirectory=self.location.href}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};Module["setWindowTitle"]=(function(title){document.title=title})}else{}var out=Module["print"]||(typeof console!=="undefined"?console.log.bind(console):typeof print!=="undefined"?print:null);var err=Module["printErr"]||(typeof printErr!=="undefined"?printErr:typeof console!=="undefined"&&console.warn.bind(console)||out);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var STACK_ALIGN=16;function staticAlloc(size){var ret=STATICTOP;STATICTOP=STATICTOP+size+15&-16;return ret}function dynamicAlloc(size){var ret=HEAP32[DYNAMICTOP_PTR>>2];var end=ret+size+15&-16;HEAP32[DYNAMICTOP_PTR>>2]=end;if(end>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){HEAP32[DYNAMICTOP_PTR>>2]=ret;return 0}}return ret}function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;var ret=size=Math.ceil(size/factor)*factor;return ret}var asm2wasmImports={"f64-rem":(function(x,y){return x%y}),"debugger":(function(){debugger})};var functionPointers=new Array(0);var GLOBAL_BASE=1024;var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}var JSfuncs={"stackSave":(function(){stackSave()}),"stackRestore":(function(){stackRestore()}),"arrayToC":(function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};function ccall(ident,returnType,argTypes,args,opts){function convertReturnValue(ret){if(returnType==="string")return Pointer_stringify(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return UTF8ToString(ptr)}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx){var endPtr=idx;while(u8Array[endPtr])++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}}function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}var WASM_PAGE_SIZE=65536;var ASMJS_PAGE_SIZE=16777216;var MIN_TOTAL_MEMORY=16777216;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBuffer(buf){Module["buffer"]=buffer=buf}function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed;var STACK_BASE,STACKTOP,STACK_MAX;var DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0;staticSealed=false;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}if(!Module["reallocBuffer"])Module["reallocBuffer"]=(function(size){var ret;try{var oldHEAP8=HEAP8;ret=new ArrayBuffer(size);var temp=new Int8Array(ret);temp.set(oldHEAP8)}catch(e){return false}var success=_emscripten_replace_memory(ret);if(!success)return false;return ret});function enlargeMemory(){var PAGE_MULTIPLE=Module["usingWasm"]?WASM_PAGE_SIZE:ASMJS_PAGE_SIZE;var LIMIT=2147483648-PAGE_MULTIPLE;if(HEAP32[DYNAMICTOP_PTR>>2]>LIMIT){return false}var OLD_TOTAL_MEMORY=TOTAL_MEMORY;TOTAL_MEMORY=Math.max(TOTAL_MEMORY,MIN_TOTAL_MEMORY);while(TOTAL_MEMORY>2]){if(TOTAL_MEMORY<=536870912){TOTAL_MEMORY=alignUp(2*TOTAL_MEMORY,PAGE_MULTIPLE)}else{TOTAL_MEMORY=Math.min(alignUp((3*TOTAL_MEMORY+2147483648)/4,PAGE_MULTIPLE),LIMIT)}}var replacement=Module["reallocBuffer"](TOTAL_MEMORY);if(!replacement||replacement.byteLength!=TOTAL_MEMORY){TOTAL_MEMORY=OLD_TOTAL_MEMORY;return false}updateGlobalBuffer(replacement);updateGlobalBufferViews();return true}var byteLength;try{byteLength=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,"byteLength").get);byteLength(new ArrayBuffer(4))}catch(e){byteLength=(function(buffer){return buffer.byteLength})}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(TOTAL_MEMORY0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}function integrateWasmJS(){var wasmTextFile="wvnc_asm.wast";var wasmBinaryFile="wvnc_asm.wasm";var asmjsCodeFile="wvnc_asm.temp.asm.js";if(!isDataURI(wasmTextFile)){wasmTextFile=locateFile(wasmTextFile)}if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}if(!isDataURI(asmjsCodeFile)){asmjsCodeFile=locateFile(asmjsCodeFile)}var wasmPageSize=64*1024;var info={"global":null,"env":null,"asm2wasm":asm2wasmImports,"parent":Module};var exports=null;function mergeMemory(newBuffer){var oldBuffer=Module["buffer"];if(newBuffer.byteLength>2]=poolPtr;HEAP32[environ>>2]=envPtr}else{envPtr=HEAP32[environ>>2];poolPtr=HEAP32[envPtr>>2]}var strings=[];var totalSize=0;for(var key in ENV){if(typeof ENV[key]==="string"){var line=key+"="+ENV[key];strings.push(line);totalSize+=line.length}}if(totalSize>TOTAL_ENV_SIZE){throw new Error("Environment size exceeded TOTAL_ENV_SIZE!")}var ptrSize=4;for(var i=0;i>2]=poolPtr;poolPtr+=line.length+1}HEAP32[envPtr+strings.length*ptrSize>>2]=0}var SYSCALLS={varargs:0,get:(function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret}),getStr:(function(){var ret=Pointer_stringify(SYSCALLS.get());return ret}),get64:(function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low}),getZero:(function(){assert(SYSCALLS.get()===0)})};function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();var offset=offset_low;FS.llseek(stream,offset,whence);HEAP32[result>>2]=stream.position;if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.get(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();var ret=0;if(!___syscall146.buffers){___syscall146.buffers=[null,[],[]];___syscall146.printChar=(function(stream,curr){var buffer=___syscall146.buffers[stream];assert(buffer);if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}})}for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=value;return value}DYNAMICTOP_PTR=staticAlloc(4);STACK_BASE=STACKTOP=alignMemory(STATICTOP);STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=alignMemory(STACK_MAX);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;staticSealed=true;Module["wasmTableSize"]=212;Module["wasmMaxTableSize"]=212;Module.asmGlobalArg={};Module.asmLibraryArg={"abort":abort,"enlargeMemory":enlargeMemory,"getTotalMemory":getTotalMemory,"abortOnCannotGrowMemory":abortOnCannotGrowMemory,"___buildEnvironment":___buildEnvironment,"___setErrNo":___setErrNo,"___syscall140":___syscall140,"___syscall146":___syscall146,"___syscall54":___syscall54,"___syscall6":___syscall6,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_exit":_exit,"_getenv":_getenv,"DYNAMICTOP_PTR":DYNAMICTOP_PTR,"STACKTOP":STACKTOP};var asm=Module["asm"](Module.asmGlobalArg,Module.asmLibraryArg,buffer);Module["asm"]=asm;var ___emscripten_environ_constructor=Module["___emscripten_environ_constructor"]=(function(){return Module["asm"]["___emscripten_environ_constructor"].apply(null,arguments)});var ___errno_location=Module["___errno_location"]=(function(){return Module["asm"]["___errno_location"].apply(null,arguments)});var _create_buffer=Module["_create_buffer"]=(function(){return Module["asm"]["_create_buffer"].apply(null,arguments)});var _decode=Module["_decode"]=(function(){return Module["asm"]["_decode"].apply(null,arguments)});var _destroy_buffer=Module["_destroy_buffer"]=(function(){return Module["asm"]["_destroy_buffer"].apply(null,arguments)});var _emscripten_replace_memory=Module["_emscripten_replace_memory"]=(function(){return Module["asm"]["_emscripten_replace_memory"].apply(null,arguments)});var _free=Module["_free"]=(function(){return Module["asm"]["_free"].apply(null,arguments)});var _malloc=Module["_malloc"]=(function(){return Module["asm"]["_malloc"].apply(null,arguments)});var _update=Module["_update"]=(function(){return Module["asm"]["_update"].apply(null,arguments)});var stackAlloc=Module["stackAlloc"]=(function(){return Module["asm"]["stackAlloc"].apply(null,arguments)});var stackRestore=Module["stackRestore"]=(function(){return Module["asm"]["stackRestore"].apply(null,arguments)});var stackSave=Module["stackSave"]=(function(){return Module["asm"]["stackSave"].apply(null,arguments)});var dynCall_vi=Module["dynCall_vi"]=(function(){return Module["asm"]["dynCall_vi"].apply(null,arguments)});Module["asm"]=asm;Module["cwrap"]=cwrap;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};function run(args){args=args||Module["arguments"];if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]&&status===0){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}Module["quit"](status,new ExitStatus(status))}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){out(what);err(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}Module["noExitRuntime"]=true;run() - - - - diff --git a/RemoteDesktop/javascripts/wvnc_asm.wasm b/RemoteDesktop/javascripts/wvnc_asm.wasm deleted file mode 100644 index b54362f51d764c66b19a23472eff34315b9aa83a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 265189 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 diff --git a/RemoteDesktop/package.json b/RemoteDesktop/package.json index 7c7db2d..5422089 100644 --- a/RemoteDesktop/package.json +++ b/RemoteDesktop/package.json @@ -6,7 +6,8 @@ "author": "", "email": "" }, - "version":"0.1.0-a", + "version":"0.1.5-a", + "dependencies": ["libwvnc@0.1.2-a"], "category":"Other", "icon": "icon.png", "mimes":["none"] diff --git a/RemoteDesktop/project.json b/RemoteDesktop/project.json index f6b658f..9d9cfc4 100644 --- a/RemoteDesktop/project.json +++ b/RemoteDesktop/project.json @@ -1,7 +1,7 @@ { "name": "RemoteDesktop", "css": ["assets/main.css"], - "javascripts": ["javascripts/wvnc.js"], + "javascripts": [], "coffees": ["coffees/main.coffee"], - "copies": ["assets/scheme.html", "package.json", "README.md", "javascripts/decoder.js", "javascripts/wvnc_asm.js", "javascripts/wvnc_asm.wasm", "assets/icon.png"] + "copies": ["assets/scheme.html", "package.json", "README.md","assets/icon.png"] } \ No newline at end of file diff --git a/libwvnc/README.md b/libwvnc/README.md new file mode 100644 index 0000000..f56b5a5 --- /dev/null +++ b/libwvnc/README.md @@ -0,0 +1,74 @@ +# libwvnc + +Overview about WVNC: [https://blog.lxsang.me/r/id/23](https://blog.lxsang.me/r/id/23) + +**libwvnc** is the client side protocol API for my [Antd's **wvnc**](https://github.com/lxsang/antd-wvnc-plugin) server side plugin. It allows to acess VNC server from the web using websocket (via the **wvnc** server plugin). + +Since the **wvnc** plugin offers data compression using JPEG, **wvnc.js** depends on the **libjpeg** package and **web worker** to speed up the data decoding process, thus speed up the screen rendering on HTML canvas. + + +## Example +It is straight forward to use the api: + +Html code: + +```html + ... + +``` + +Javascript: + +```javascript + var args, client; + args = { + // the canvas element + element: 'screen', + // The websocket uri to the wvnc server side plugin + ws: 'wss://localhost/wvnc', + // the decoder worker + libjpeg: 'path/to/jpg.js' + }; + client = new WVNC(args); + + // This function responds to a VNC server password request + // should return a promise + client.onpassword = function() { + return new Promise(function(r, e) { + return r('password'); + }); + }; + + // this function responds to the remote OS username and password request + // should return a promise + client.oncredential = function() { + return new Promise(function(r, e) { + return r('username', 'password'); + }); + }; + // event fired when a text is copied on + // the remote computer + client.oncopy = function(text) { + console.log(text); + }; + // init the WVNC client + client.init() + .then(function() { + client.connect( + // VNC server + "192.168.1.20:5901", + { + // bits per pixel + bbp: 32, + // data compression flag + // 1 is for both JPEG + // 0 is for raw data + flag: 1, + // JPEG quality % + quality: 50 + }); + }) + .catch(function(m, s) { + return console.error(m, s); + }); +``` diff --git a/libwvnc/build/debug/README.md b/libwvnc/build/debug/README.md new file mode 100644 index 0000000..f56b5a5 --- /dev/null +++ b/libwvnc/build/debug/README.md @@ -0,0 +1,74 @@ +# libwvnc + +Overview about WVNC: [https://blog.lxsang.me/r/id/23](https://blog.lxsang.me/r/id/23) + +**libwvnc** is the client side protocol API for my [Antd's **wvnc**](https://github.com/lxsang/antd-wvnc-plugin) server side plugin. It allows to acess VNC server from the web using websocket (via the **wvnc** server plugin). + +Since the **wvnc** plugin offers data compression using JPEG, **wvnc.js** depends on the **libjpeg** package and **web worker** to speed up the data decoding process, thus speed up the screen rendering on HTML canvas. + + +## Example +It is straight forward to use the api: + +Html code: + +```html + ... + +``` + +Javascript: + +```javascript + var args, client; + args = { + // the canvas element + element: 'screen', + // The websocket uri to the wvnc server side plugin + ws: 'wss://localhost/wvnc', + // the decoder worker + libjpeg: 'path/to/jpg.js' + }; + client = new WVNC(args); + + // This function responds to a VNC server password request + // should return a promise + client.onpassword = function() { + return new Promise(function(r, e) { + return r('password'); + }); + }; + + // this function responds to the remote OS username and password request + // should return a promise + client.oncredential = function() { + return new Promise(function(r, e) { + return r('username', 'password'); + }); + }; + // event fired when a text is copied on + // the remote computer + client.oncopy = function(text) { + console.log(text); + }; + // init the WVNC client + client.init() + .then(function() { + client.connect( + // VNC server + "192.168.1.20:5901", + { + // bits per pixel + bbp: 32, + // data compression flag + // 1 is for both JPEG + // 0 is for raw data + flag: 1, + // JPEG quality % + quality: 50 + }); + }) + .catch(function(m, s) { + return console.error(m, s); + }); +``` diff --git a/libwvnc/build/debug/decoder.js b/libwvnc/build/debug/decoder.js new file mode 100644 index 0000000..c9a0890 --- /dev/null +++ b/libwvnc/build/debug/decoder.js @@ -0,0 +1,112 @@ +let resolution; + +decode_jpeg = (raw, msg) => +{ + if(!JpegImage) + { + console.error("The JPEG library is not available"); + return 0; + } + let jpeg = new JpegImage() + jpeg.parse(raw) + if(jpeg.width != msg.w || jpeg.height != msg.h) + { + console.error("Incorrect data size: expect " + msg.w*msg.h*4 + " got " + jpeg.width*jpeg.height*4); + return 0; + } + msg.pixels = new Uint8Array(msg.w*msg.h*4); + let data = jpeg.getData(msg.w, msg.h); + for(let j = 0; j < msg.h; j++) + { + for(let i = 0; i < msg.w; i++) + { + let index = j*msg.w*4 + i*4; + msg.pixels[index] = data[j*msg.w*3 + i*3]; + msg.pixels[index+1] = data[j*msg.w*3 + i*3 + 1]; + msg.pixels[index+2] = data[j*msg.w*3 + i*3 + 2]; + msg.pixels[index+3] = 255; + } + } + return msg.pixels.length; +} + +decode_raw = (raw, msg) => +{ + let size =raw.length; + if(resolution.depth == 32) + { + msg.pixels = new Uint8Array(raw); + return size; + } + if(resolution.depth != 16) + { + console.error("Unsupported depth" + resolution.depth); + return 0; + } + let bytes = resolution.depth/8; + let npixels = size / bytes; + let outsize = npixels*4; + if(outsize != msg.w*msg.h*4) + { + console.error("Incorrect data size: expect " + msg.w*msg.h*4 + " got " + outsize); + return 0; + } + msg.pixels = new Uint8Array(outsize); + let value = 0; + let px = {}; + for(let i = 0; i < npixels; i++) + { + value = 0; + for(let j=0; j < bytes; j++ ) + value = (raw[i * bytes + j] << (j*8)) | value ; + // lookup for pixel + msg.pixels[i*4] = (value & 0x1F) * (255 / 31); + msg.pixels[i*4+1] = ((value >> 5) & 0x3F) * (255 / 63); + msg.pixels[i*4+2] = ((value >> 11) & 0x1F) * (255 / 31); + msg.pixels[i*4+3] = 255; + } + return outsize; +} + +decode = (arr) => +{ + let datain = new Uint8Array(arr); + let msg = { + x: datain[1] | (datain[2] << 8), + y: datain[3] | (datain[4] << 8), + w: datain[5] | (datain[6] << 8), + h: datain[7] | (datain[8] << 8), + flag: datain[9], + pixels: undefined + } + switch (msg.flag) { + case 0x0: + decode_raw(datain.subarray(10), msg); + break; + case 0x1: + decode_jpeg(datain.subarray(10), msg); + break; + default: + console.error("Unknow flag: " + msg.flag); + } + if(msg.pixels) + { + msg.pixels = msg.pixels.buffer; + postMessage(msg, [msg.pixels]); + } +} + +onmessage = (e) => { + if(e.data.depth) + { + resolution = e.data; + } + else if(e.data.libjpeg) + { + importScripts(e.data.libjpeg); + } + else + { + decode(e.data); + } +} \ No newline at end of file diff --git a/libwvnc/build/debug/main.js b/libwvnc/build/debug/main.js new file mode 100644 index 0000000..bd79c80 --- /dev/null +++ b/libwvnc/build/debug/main.js @@ -0,0 +1 @@ +(function(){var e;e=class{constructor(e){var t,n,s;this.socket=void 0,this.ws=void 0,this.canvas=void 0,s="pkg://libwvnc/decoder.js".asFileHandle().getlink(),this.scale=1,e.ws&&(this.ws=e.ws),this.canvas=e.element,"string"==typeof this.canvas&&(this.canvas=document.getElementById(this.canvas)),e.libjpeg&&(t=e.libjpeg),this.decoder=new Worker(s),this.enableEvent=!0,n=this,this.mouseMask=0,this.decoder.postMessage({libjpeg:t}),this.decoder.onmessage=function(e){return n.process(e.data)}}init(){var e;return e=this,new Promise((function(t,n){return e.canvas?($(e.canvas).attr("tabindex","1"),e.initInputEvent(),t()):n("Canvas is not set")}))}initInputEvent(){var e,t,n,s;if(n=this,this.canvas&&(t=function(e){var t;return t=n.canvas.getBoundingClientRect(),{x:Math.floor((e.clientX-t.left)/n.scale),y:Math.floor((e.clientY-t.top)/n.scale)}},s=function(e){var s;if(n.enableEvent)return s=t(e),n.sendPointEvent(s.x,s.y,n.mouseMask)},n.canvas))return n.canvas.oncontextmenu=function(e){return e.preventDefault(),!1},n.canvas.onmousemove=function(e){return s(e)},n.canvas.onmousedown=function(e){var t;return t=1<this.disconnect(!0),window.addEventListener("unload",e),window.addEventListener("beforeunload",e)}initCanvas(e,t,n){return this.depth=n,this.canvas.width=e,this.canvas.height=t,this.resolution={w:e,h:t,depth:this.depth},this.decoder.postMessage(this.resolution),this.canvas.style.cursor="none",this.setScale(this.scale)}process(e){var t,n,s;if(this.socket)return n=new Uint8Array(e.pixels),(s=(t=this.canvas.getContext("2d",{alpha:!1})).createImageData(e.w,e.h)).data.set(n),t.putImageData(s,e.x,e.y)}setScale(e){if(this.scale=e,this.canvas)return this.canvas.style.transformOrigin="0 0",this.canvas.style.transform="scale("+e+")"}connect(e,t){var n;if(n=this,this.socket&&this.socket.close(),this.ws)return this.socket=new WebSocket(this.ws),this.socket.binaryType="arraybuffer",this.socket.onopen=function(){return console.log("socket opened"),n.initConnection(e,t)},this.socket.onmessage=function(e){return n.consume(e)},this.socket.onclose=function(){return n.socket=null,n.canvas.style.cursor="auto",n.canvas&&n.resolution&&n.canvas.getContext("2d").clearRect(0,0,n.resolution.w,n.resolution.h),console.log("socket closed")}}disconnect(e){if(this.socket&&this.socket.close(),this.decoder&&e)return this.decoder.terminate()}initConnection(e,t){var n;return(n=new Uint8Array(e.length+3))[0]=32,n[1]=1,n[2]=50,t&&(t.bbp&&(n[0]=t.bbp),t.flag&&(n[1]=t.flag),t.quality&&(n[2]=t.quality)),n.set((new TextEncoder).encode(e),3),this.socket.send(this.buildCommand(1,n))}sendPointEvent(e,t,n){var s;if(this.socket)return(s=new Uint8Array(5))[0]=255&e,s[1]=e>>8,s[2]=255&t,s[3]=t>>8,s[4]=n,this.socket.send(this.buildCommand(5,s))}sendKeyEvent(e,t){var n;if(this.socket&&this.enableEvent)return(n=new Uint8Array(3))[0]=255&e,n[1]=e>>8,n[2]=t,this.socket.send(this.buildCommand(6,n))}buildCommand(e,t){var n,s;switch(s=void 0,typeof t){case"string":s=(new TextEncoder).encode(t);break;case"number":s=new Uint8Array([t]);break;default:s=t}return(n=new Uint8Array(s.length+3))[0]=e,n[2]=s.length>>8,n[1]=15&s.length,n.set(s,3),n.buffer}oncopy(e){return console.log("Get clipboard text: "+e)}onpassword(){return new Promise((function(e,t){return t("onpassword is not implemented")}))}sendTextAsClipboard(e){if(this.socket)return console.log("send ",e),this.socket.send(this.buildCommand(7,e))}oncredential(){return new Promise((function(e,t){return t("oncredential is not implemented")}))}onerror(e){return console.log("Error",e)}onresize(){return console.log("resize")}consume(e){var t,n,s,a,r,o,i;switch(t=(n=new Uint8Array(e.data))[0],o=this,t){case 254:return n=n.subarray(1,n.length-1),s=new TextDecoder("utf-8"),this.onerror(s.decode(n));case 129:return console.log("Request for password"),this.enableEvent=!1,this.onpassword().then((function(e){return o.socket.send(o.buildCommand(2,e)),o.enableEvent=!0}));case 130:return console.log("Request for login"),this.enableEvent=!1,this.oncredential().then((function(e,t){var n;return(n=new Uint8Array(e.length+t.length+1)).set((new TextEncoder).encode(e),0),n.set(["\0"],e.length),n.set((new TextEncoder).encode(t),e.length+1),o.socket.send(o.buildCommand(3,n)),o.enableEvent=!0}));case 131:return i=n[1]|n[2]<<8,r=n[3]|n[4]<<8,a=n[5],this.initCanvas(i,r,a),this.socket.send(this.buildCommand(4,1)),this.onresize();case 132:return this.decoder.postMessage(n.buffer,[n.buffer]);case 133:return n=n.subarray(1),s=new TextDecoder("utf-8"),this.oncopy(s.decode(n)),this.socket.send(this.buildCommand(4,1));default:return console.log(t)}}},window.WVNC=e}).call(this); \ No newline at end of file diff --git a/libwvnc/build/debug/package.json b/libwvnc/build/debug/package.json new file mode 100644 index 0000000..69da22a --- /dev/null +++ b/libwvnc/build/debug/package.json @@ -0,0 +1,15 @@ +{ + "pkgname": "libwvnc", + "name":"libwvnc", + "description":"libwvnc: client side VNC protocol via websocket", + "info":{ + "author": "", + "email": "" + }, + "version":"0.1.2-a", + "category":"Library", + "iconclass":"fa fa-cog", + "mimes":["none"], + "dependencies":["libjpeg@0.1.1-a"], + "locale": {} +} \ No newline at end of file diff --git a/libwvnc/build/release/libwvnc.zip b/libwvnc/build/release/libwvnc.zip new file mode 100644 index 0000000000000000000000000000000000000000..1bf22b2ae958cce33247fa382dc7918baec02d45 GIT binary patch literal 11690 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 +{ + if(!JpegImage) + { + console.error("The JPEG library is not available"); + return 0; + } + let jpeg = new JpegImage() + jpeg.parse(raw) + if(jpeg.width != msg.w || jpeg.height != msg.h) + { + console.error("Incorrect data size: expect " + msg.w*msg.h*4 + " got " + jpeg.width*jpeg.height*4); + return 0; + } + msg.pixels = new Uint8Array(msg.w*msg.h*4); + let data = jpeg.getData(msg.w, msg.h); + for(let j = 0; j < msg.h; j++) + { + for(let i = 0; i < msg.w; i++) + { + let index = j*msg.w*4 + i*4; + msg.pixels[index] = data[j*msg.w*3 + i*3]; + msg.pixels[index+1] = data[j*msg.w*3 + i*3 + 1]; + msg.pixels[index+2] = data[j*msg.w*3 + i*3 + 2]; + msg.pixels[index+3] = 255; + } + } + return msg.pixels.length; +} + +decode_raw = (raw, msg) => +{ + let size =raw.length; + if(resolution.depth == 32) + { + msg.pixels = new Uint8Array(raw); + return size; + } + if(resolution.depth != 16) + { + console.error("Unsupported depth" + resolution.depth); + return 0; + } + let bytes = resolution.depth/8; + let npixels = size / bytes; + let outsize = npixels*4; + if(outsize != msg.w*msg.h*4) + { + console.error("Incorrect data size: expect " + msg.w*msg.h*4 + " got " + outsize); + return 0; + } + msg.pixels = new Uint8Array(outsize); + let value = 0; + let px = {}; + for(let i = 0; i < npixels; i++) + { + value = 0; + for(let j=0; j < bytes; j++ ) + value = (raw[i * bytes + j] << (j*8)) | value ; + // lookup for pixel + msg.pixels[i*4] = (value & 0x1F) * (255 / 31); + msg.pixels[i*4+1] = ((value >> 5) & 0x3F) * (255 / 63); + msg.pixels[i*4+2] = ((value >> 11) & 0x1F) * (255 / 31); + msg.pixels[i*4+3] = 255; + } + return outsize; +} + +decode = (arr) => +{ + let datain = new Uint8Array(arr); + let msg = { + x: datain[1] | (datain[2] << 8), + y: datain[3] | (datain[4] << 8), + w: datain[5] | (datain[6] << 8), + h: datain[7] | (datain[8] << 8), + flag: datain[9], + pixels: undefined + } + switch (msg.flag) { + case 0x0: + decode_raw(datain.subarray(10), msg); + break; + case 0x1: + decode_jpeg(datain.subarray(10), msg); + break; + default: + console.error("Unknow flag: " + msg.flag); + } + if(msg.pixels) + { + msg.pixels = msg.pixels.buffer; + postMessage(msg, [msg.pixels]); + } +} + +onmessage = (e) => { + if(e.data.depth) + { + resolution = e.data; + } + else if(e.data.libjpeg) + { + importScripts(e.data.libjpeg); + } + else + { + decode(e.data); + } +} \ No newline at end of file diff --git a/libwvnc/main.coffee b/libwvnc/main.coffee new file mode 100644 index 0000000..b94f57d --- /dev/null +++ b/libwvnc/main.coffee @@ -0,0 +1,315 @@ +class WVNC + constructor: (args) -> + @socket = undefined + @ws = undefined + @canvas = undefined + worker = "pkg://libwvnc/decoder.js".asFileHandle().getlink() + @scale = 1.0 + @ws = args.ws if args.ws + @canvas = args.element + @canvas = document.getElementById @canvas if typeof @canvas is 'string' + libjpeg = args.libjpeg if args.libjpeg + @decoder = new Worker worker + @enableEvent = true + me = @ + @mouseMask = 0 + @decoder.postMessage {libjpeg: libjpeg} + @decoder.onmessage = (e) -> + me.process e.data + init: () -> + me = @ + return new Promise (r, e) -> + return e('Canvas is not set') if not me.canvas + # fix keyboard event problem + $(me.canvas).attr 'tabindex', '1' + me.initInputEvent() + r() + + initInputEvent: () -> + me = @ + return unless @canvas + getMousePos = (e) -> + rect = me.canvas.getBoundingClientRect() + pos= + x: Math.floor((e.clientX - rect.left) / me.scale) + y: Math.floor((e.clientY - rect.top) / me.scale) + return pos + + sendMouseLocation = (e) -> + return unless me.enableEvent + p = getMousePos e + me.sendPointEvent p.x, p.y, me.mouseMask + + return unless me.canvas + me.canvas.oncontextmenu = (e) -> + e.preventDefault() + return false + + me.canvas.onmousemove = (e) -> sendMouseLocation e + + me.canvas.onmousedown = (e) -> + state = 1 << e.button + me.mouseMask = me.mouseMask | state + sendMouseLocation e + #e.preventDefault() + + me.canvas.onmouseup = (e) -> + state = 1 << e.button + me.mouseMask = me.mouseMask & (~state) + sendMouseLocation e + #e.preventDefault() + + me.canvas.onkeydown = me.canvas.onkeyup = (e) -> + # get the key code + keycode = e.keyCode + #console.log e + switch keycode + when 8 then code = 0xFF08 #back space + when 9 then code = 0xff89 #0xFF09 # tab ? + when 13 then code = 0xFF0D # return + when 27 then code = 0xFF1B # esc + when 46 then code = 0xFFFF # delete to verify + when 38 then code = 0xFF52 # up + when 40 then code = 0xFF54 # down + when 37 then code = 0xFF51 # left + when 39 then code = 0xFF53 # right + when 91 then code = 0xFFE7 # meta left + when 93 then code = 0xFFE8 # meta right + when 16 then code = 0xFFE1 # shift left + when 17 then code = 0xFFE3 # ctrl left + when 18 then code = 0xFFE9 # alt left + when 20 then code = 0xFFE5 # capslock + when 113 then code = 0xFFBF # f2 + when 112 then code = 0xFFBE # f1 + when 114 then code = 0xFFC0 # f3 + when 115 then code = 0xFFC1 # f4 + when 116 then code = 0xFFC2 # f5 + when 117 then code = 0xFFC3 # f6 + when 118 then code = 0xFFC4 # f7 + when 119 then code = 0xFFC5 # f8 + when 120 then code = 0xFFC6 # f9 + when 121 then code = 0xFFC7 # f10 + when 122 then code = 0xFFC8 # f11 + when 123 then code = 0xFFC9 # f12 + else + code = e.key.charCodeAt(0) #if not e.ctrlKey and not e.altKey + #if ((keycode > 47 and keycode < 58) or (keycode > 64 and keycode < 91) or (keycode > 95 and keycode < 112) or (keycode > 185 and keycode < 193) or (keycode > 218 && keycode < 223)) + # code = e.key.charCodeAt(0) + #else + # code = keycode + e.preventDefault() + return unless code + if e.type is "keydown" + me.sendKeyEvent code, 1 + else if e.type is "keyup" + me.sendKeyEvent code, 0 + + # mouse wheel event + @canvas.addEventListener 'wheel', (e) -> + return unless me.enableEvent + #if (e.deltaY < 0) # up + p = getMousePos e + e.preventDefault() + if e.deltaY < 0 + me.sendPointEvent p.x, p.y, 8 + me.sendPointEvent p.x, p.y, 0 + return + me.sendPointEvent p.x, p.y, 16 + me.sendPointEvent p.x, p.y, 0 + # paste event + @canvas.onpaste = (e) -> + return unless me.enableEvent + pastedText = undefined + if window.clipboardData and window.clipboardData.getData #IE + pastedText = window.clipboardData.getData 'Text' + else if e.clipboardData and e.clipboardData.getData + pastedText = e.clipboardData.getData 'text/plain' + return false unless pastedText + e.preventDefault() + me.sendTextAsClipboard pastedText + # global event + fn = (e) => + @disconnect(true) + + window.addEventListener "unload", fn + window.addEventListener "beforeunload", fn + + initCanvas: (w, h , d) -> + me = @ + @depth = d + @canvas.width = w + @canvas.height = h + @resolution = + w: w, + h: h, + depth: @depth + @decoder.postMessage @resolution + me.canvas.style.cursor = "none" + @setScale @scale + + process: (msg) -> + if not @socket + return + data = new Uint8Array msg.pixels + #w = @buffer.width * @scale + #h = @buffer.height * @scale + ctx = @canvas.getContext "2d", { alpha: false } + imgData = ctx.createImageData msg.w, msg.h + imgData.data.set data + ctx.putImageData imgData, msg.x, msg.y + + + setScale: (n) -> + @scale = n + return unless @canvas + @canvas.style.transformOrigin = '0 0' + @canvas.style.transform = 'scale(' + n + ')' + + + connect: (url, args) -> + me = @ + @socket.close() if @socket + return unless @ws + @socket = new WebSocket @ws + @socket.binaryType = "arraybuffer" + @socket.onopen = () -> + console.log "socket opened" + me.initConnection(url, args) + + @socket.onmessage = (e) -> + me.consume e + @socket.onclose = () -> + me.socket = null + me.canvas.style.cursor = "auto" + me.canvas.getContext('2d').clearRect 0,0, me.resolution.w, me.resolution.h if me.canvas and me.resolution + console.log "socket closed" + + disconnect: (close_worker) -> + @socket.close() if @socket + @decoder.terminate() if @decoder and close_worker + + initConnection: (vncserver, params) -> + #vncserver = "192.168.1.20:5901" + data = new Uint8Array vncserver.length + 3 + data[0] = 32 # bbp + ### + flag: + 0: raw data no compress + 1: jpeg no compress + ### + data[1] = 1 + data[2] = 50 # jpeg quality + if params + data[0] = params.bbp if params.bbp + data[1] = params.flag if params.flag + data[2] = params.quality if params.quality + ## rate in milisecond + + data.set (new TextEncoder()).encode(vncserver), 3 + @socket.send(@buildCommand 0x01, data) + + sendPointEvent: (x, y, mask) -> + return unless @socket + data = new Uint8Array 5 + data[0] = x & 0xFF + data[1] = x >> 8 + data[2] = y & 0xFF + data[3] = y >> 8 + data[4] = mask + @socket.send( @buildCommand 0x05, data ) + + sendKeyEvent: (code, v) -> + #console.log code, v + return unless @socket + return unless @enableEvent + data = new Uint8Array 3 + data[0] = code & 0xFF + data[1] = code >> 8 + data[2] = v + @socket.send( @buildCommand 0x06, data ) + + buildCommand: (hex, o) -> + data = undefined + switch typeof o + when 'string' + data = (new TextEncoder()).encode(o) + when 'number' + data = new Uint8Array [o] + else + data = o + cmd = new Uint8Array data.length + 3 + cmd[0] = hex + cmd[2] = data.length >> 8 + cmd[1] = data.length & 0x0F + cmd.set data, 3 + #console.log "the command is", cmd.buffer + return cmd.buffer + + oncopy: (text) -> + console.log "Get clipboard text: " + text + + onpassword: () -> + return new Promise (resolve, reject) -> + reject("onpassword is not implemented") + + sendTextAsClipboard: (text) -> + return unless @socket + console.log "send ", text + @socket.send (@buildCommand 0x07, text) + + oncredential: () -> + return new Promise (resolve, reject) -> + reject("oncredential is not implemented") + + onerror: (m) -> + console.log "Error", m + + onresize: () -> + console.log "resize" + + consume: (e) -> + data = new Uint8Array e.data + cmd = data[0] + me = @ + switch cmd + when 0xFE #error + data = data.subarray 1, data.length - 1 + dec = new TextDecoder("utf-8") + @onerror dec.decode(data) + when 0x81 + console.log "Request for password" + @enableEvent = false + @onpassword().then (pass) -> + me.socket.send (me.buildCommand 0x02, pass) + me.enableEvent = true + when 0x82 + console.log "Request for login" + @enableEvent = false + @oncredential().then (user, pass) -> + arr = new Uint8Array user.length + pass.length + 1 + arr.set (new TextEncoder()).encode(user), 0 + arr.set ['\0'], user.length + arr.set (new TextEncoder()).encode(pass), user.length + 1 + me.socket.send(me.buildCommand 0x03, arr) + me.enableEvent = true + when 0x83 + w = data[1] | (data[2]<<8) + h = data[3] | (data[4]<<8) + depth = data[5] + @initCanvas w, h, depth + # status command for ack + @socket.send(@buildCommand 0x04, 1) + @onresize() + when 0x84 + # send data to web assembly for decoding + @decoder.postMessage data.buffer, [data.buffer] + when 0x85 + # clipboard data from server + data = data.subarray 1 + dec = new TextDecoder "utf-8" + @oncopy dec.decode data + @socket.send(@buildCommand 0x04, 1) + else + console.log cmd + +window.WVNC = WVNC \ No newline at end of file diff --git a/libwvnc/package.json b/libwvnc/package.json new file mode 100644 index 0000000..69da22a --- /dev/null +++ b/libwvnc/package.json @@ -0,0 +1,15 @@ +{ + "pkgname": "libwvnc", + "name":"libwvnc", + "description":"libwvnc: client side VNC protocol via websocket", + "info":{ + "author": "", + "email": "" + }, + "version":"0.1.2-a", + "category":"Library", + "iconclass":"fa fa-cog", + "mimes":["none"], + "dependencies":["libjpeg@0.1.1-a"], + "locale": {} +} \ No newline at end of file diff --git a/libwvnc/project.json b/libwvnc/project.json new file mode 100644 index 0000000..84df19d --- /dev/null +++ b/libwvnc/project.json @@ -0,0 +1,7 @@ +{ + "name": "libwvnc", + "css": [], + "javascripts": [], + "coffees": ["main.coffee"], + "copies": [ "decoder.js","package.json", "README.md"] +} \ No newline at end of file diff --git a/packages.json b/packages.json index fc75e10..c2fec8d 100644 --- a/packages.json +++ b/packages.json @@ -149,6 +149,16 @@ "dependencies": [], "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libjpeg/build/release/libjpeg.zip" }, + { + "pkgname": "libwvnc", + "name": "libwvnc", + "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libwvnc/README.md", + "category": "Library", + "author": "", + "version": "0.1.2-a", + "dependencies": ["libjpeg@0.1.1-a"], + "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/libwvnc/build/release/libwvnc.zip" + }, { "pkgname": "LuaPlayground", "name": "LuaPlayground", @@ -205,8 +215,8 @@ "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/RemoteDesktop/README.md", "category": "Other", "author": "", - "version": "0.1.0-a", - "dependencies": [], + "version": "0.1.5-a", + "dependencies": ["libwvnc@0.1.2-a"],"category":"Other","icon":"icon.png","mimes":["none"], "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/RemoteDesktop/build/release/RemoteDesktop.zip" }, {