/* * noVNC: HTML5 VNC client * Copyright (C) 2012 Joel Martin * Copyright (C) 2013 Samuel Mannehed for Cendio AB * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. * * TIGHT decoder portion: * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) */ var RFB;!function(){"use strict";RFB=function(t){t||(t={}),this._rfb_host="",this._rfb_port=5900,this._rfb_password="",this._rfb_path="",this._rfb_state="disconnected",this._rfb_version=0,this._rfb_max_version=3.8,this._rfb_auth_scheme="",this._rfb_tightvnc=!1,this._rfb_xvp_ver=0,this._encodings=[["COPYRECT",1],["TIGHT",7],["TIGHT_PNG",-260],["HEXTILE",5],["RRE",2],["RAW",0],["DesktopSize",-223],["Cursor",-239],["JPEG_quality_med",-26],["compress_hi",-247],["last_rect",-224],["xvp",-309],["ExtendedDesktopSize",-308]],this._encHandlers={},this._encNames={},this._encStats={},this._sock=null,this._display=null,this._keyboard=null,this._mouse=null,this._sendTimer=null,this._disconnTimer=null,this._msgTimer=null,this._FBU={rects:0,subrects:0,lines:0,tiles:0,bytes:0,x:0,y:0,width:0,height:0,encoding:0,subencoding:-1,background:null,zlib:[]},this._fb_Bpp=4,this._fb_depth=3,this._fb_width=0,this._fb_height=0,this._fb_name="",this._destBuff=null,this._paletteBuff=new Uint8Array(1024),this._rre_chunk_sz=100,this._timing={last_fbu:0,fbu_total:0,fbu_total_cnt:0,full_fbu_total:0,full_fbu_cnt:0,fbu_rt_start:0,fbu_rt_total:0,fbu_rt_cnt:0,pixels:0},this._supportsSetDesktopSize=!1,this._screen_id=0,this._screen_flags=0,this._mouse_buttonMask=0,this._mouse_arr=[],this._viewportDragging=!1,this._viewportDragPos={},this._viewportHasMoved=!1,Util.set_defaults(this,t,{target:"null",focusContainer:document,encrypt:!1,true_color:!0,local_cursor:!1,shared:!0,view_only:!1,xvp_password_sep:"@",disconnectTimeout:3,wsProtocols:["binary"],repeaterID:"",viewportDrag:!1,onUpdateState:function(){},onPasswordRequired:function(){},onClipboard:function(){},onBell:function(){},onFBUReceive:function(){},onFBUComplete:function(){},onFBResize:function(){},onDesktopName:function(){},onXvpInit:function(){}}),Util.Debug(">> RFB.constructor"),Object.keys(RFB.encodingHandlers).forEach(function(t){this._encHandlers[t]=RFB.encodingHandlers[t].bind(this)}.bind(this));for(var s=0;s> RFB.connect");var t;t="undefined"!=typeof UsingSocketIO?"http":this._encrypt?"wss":"ws",t+="://"+this._rfb_host+":"+this._rfb_port+"/"+this._rfb_path,Util.Info("connecting to "+t),this._sock.open(t,this._wsProtocols),Util.Debug("<< RFB.connect")},_init_vars:function(){this._FBU.rects=0,this._FBU.subrects=0,this._FBU.lines=0,this._FBU.tiles=0,this._FBU.zlibs=[],this._mouse_buttonMask=0,this._mouse_arr=[],this._rfb_tightvnc=!1;var t;for(t=0;t0&&Util.Info(" "+this._encodings[t][0]+": "+s[0]+" rects");for(Util.Info("Encoding stats since page load:"),t=0;t0&&(null===this._msgTimer?(Util.Debug("More data to process, creating timer"),this._msgTimer=setTimeout(function(){this._msgTimer=null,this._handle_message()}.bind(this),10)):Util.Debug("More data to process, existing timer"));break;default:this._init_msg()}},_handleKeyPress:function(t,s){this._view_only||(RFB.messages.keyEvent(this._sock,t,s),this._sock.flush())},_handleMouseButton:function(t,s,i,e){if(i?this._mouse_buttonMask|=e:this._mouse_buttonMask^=e,this._viewportDrag){if(i&&!this._viewportDragging)return this._viewportDragging=!0,void(this._viewportDragPos={x:t,y:s});this._viewportDragging=!1,this._viewportHasMoved||this._view_only||RFB.messages.pointerEvent(this._sock,this._display.absX(t),this._display.absY(s),e),this._viewportHasMoved=!1}this._view_only||"normal"===this._rfb_state&&RFB.messages.pointerEvent(this._sock,this._display.absX(t),this._display.absY(s),this._mouse_buttonMask)},_handleMouseMove:function(t,s){if(this._viewportDragging){var i=this._viewportDragPos.x-t,e=this._viewportDragPos.y-s,r=10*(window.devicePixelRatio||1);return void((this._viewportHasMoved||Math.abs(i)>r||Math.abs(e)>r)&&(this._viewportHasMoved=!0,this._viewportDragPos={x:t,y:s},this._display.viewportChangePos(i,e)))}this._view_only||"normal"===this._rfb_state&&RFB.messages.pointerEvent(this._sock,this._display.absX(t),this._display.absY(s),this._mouse_buttonMask)},_negotiate_protocol_version:function(){if(this._sock.rQlen()<12)return this._fail("Incomplete protocol version");var t=this._sock.rQshiftStr(12).substr(4,7);Util.Info("Server ProtocolVersion: "+t);var s=0;switch(t){case"000.000":s=1;break;case"003.003":case"003.006":case"003.889":this._rfb_version=3.3;break;case"003.007":this._rfb_version=3.7;break;case"003.008":case"004.000":case"004.001":this._rfb_version=3.8;break;default:return this._fail("Invalid server version "+t)}if(s){for(var i=this._repeaterID;i.length<250;)i+="\0";return this._sock.send_string(i),!0}this._rfb_version>this._rfb_max_version&&(this._rfb_version=this._rfb_max_version),this._sendTimer=setInterval(this._sock.flush.bind(this._sock),50);var e="00"+parseInt(this._rfb_version,10)+".00"+10*this._rfb_version%10;this._sock.send_string("RFB "+e+"\n"),this._updateState("Security","Sent ProtocolVersion: "+e)},_negotiate_security:function(){if(this._rfb_version>=3.7){var t=this._sock.rQshift8();if(this._sock.rQwait("security type",t,1))return!1;if(0===t){var s=this._sock.rQshift32(),i=this._sock.rQshiftStr(s);return this._fail("Security failure: "+i)}this._rfb_auth_scheme=0;var e=this._sock.rQshiftBytes(t);Util.Debug("Server security types: "+e);for(var r=0;rthis._rfb_auth_scheme&&(e[r]<=16||22==e[r])&&(this._rfb_auth_scheme=e[r]);if(0===this._rfb_auth_scheme)return this._fail("Unsupported security types: "+e);this._sock.send([this._rfb_auth_scheme])}else{if(this._sock.rQwait("security scheme",4))return!1;this._rfb_auth_scheme=this._sock.rQshift32()}return this._updateState("Authentication","Authenticating using scheme: "+this._rfb_auth_scheme),this._init_msg()},_negotiate_xvp_auth:function(){var t=this._xvp_password_sep,s=this._rfb_password.split(t);if(s.length<3)return this._updateState("password","XVP credentials required (user"+t+"target"+t+"password) -- got only "+this._rfb_password),this._onPasswordRequired(this),!1;var i=String.fromCharCode(s[0].length)+String.fromCharCode(s[1].length)+s[0]+s[1];return this._sock.send_string(i),this._rfb_password=s.slice(2).join(t),this._rfb_auth_scheme=2,this._negotiate_authentication()},_negotiate_std_vnc_auth:function(){if(0===this._rfb_password.length)return this._updateState("password","Password Required"),this._onPasswordRequired(this),!1;if(this._sock.rQwait("auth challenge",16))return!1;var t=Array.prototype.slice.call(this._sock.rQshiftBytes(16)),s=RFB.genDES(this._rfb_password,t);return this._sock.send(s),this._updateState("SecurityResult"),!0},_negotiate_tight_tunnels:function(t){for(var s={0:{vendor:"TGHT",signature:"NOTUNNEL"}},i={},e=0;e0&&this._sock.rQwait("tunnel capabilities",16*t,4))return!1;if(this._rfb_tightvnc=!0,t>0)return this._negotiate_tight_tunnels(t),!1}if(this._sock.rQwait("sub auth count",4))return!1;var s=this._sock.rQshift32();if(this._sock.rQwait("sub auth capabilities",16*s,4))return!1;for(var i={STDVNOAUTH__:1,STDVVNCAUTH_:2},e=[],r=0;r=3.8?(this._updateState("SecurityResult"),!0):(this._updateState("ClientInitialisation","No auth required"),this._init_msg());case 22:return this._negotiate_xvp_auth();case 2:return this._negotiate_std_vnc_auth();case 16:return this._negotiate_tight_auth();default:return this._fail("Unsupported auth scheme: "+this._rfb_auth_scheme)}},_handle_security_result:function(){if(this._sock.rQwait("VNC auth response ",4))return!1;switch(this._sock.rQshift32()){case 0:return this._updateState("ClientInitialisation","Authentication OK"),this._init_msg();case 1:if(this._rfb_version>=3.8){var t=this._sock.rQshift32();if(this._sock.rQwait("SecurityResult reason",t,8))return!1;var s=this._sock.rQshiftStr(t);return this._fail(s)}return this._fail("Authentication failure");case 2:return this._fail("Too many auth attempts")}},_negotiate_server_init:function(){if(this._sock.rQwait("server initialization",24))return!1;this._fb_width=this._sock.rQshift16(),this._fb_height=this._sock.rQshift16(),this._destBuff=new Uint8Array(this._fb_width*this._fb_height*4);var t=this._sock.rQshift8(),s=this._sock.rQshift8(),i=this._sock.rQshift8(),e=this._sock.rQshift8(),r=this._sock.rQshift16(),_=this._sock.rQshift16(),h=this._sock.rQshift16(),n=this._sock.rQshift8(),o=this._sock.rQshift8(),a=this._sock.rQshift8();this._sock.rQskipBytes(3);var c=this._sock.rQshift32();if(this._sock.rQwait("server init name",c,24))return!1;if(this._fb_name=Util.decodeUTF8(this._sock.rQshiftStr(c)),this._rfb_tightvnc){if(this._sock.rQwait("TightVNC extended server init header",8,24+c))return!1;var l=this._sock.rQshift16(),f=this._sock.rQshift16(),u=this._sock.rQshift16();this._sock.rQskipBytes(2);var d=16*(l+f+u);if(this._sock.rQwait("TightVNC extended server init header",d,32+c))return!1;this._sock.rQskipBytes(16*l),this._sock.rQskipBytes(16*f),this._sock.rQskipBytes(16*u)}Util.Info("Screen: "+this._fb_width+"x"+this._fb_height+", bpp: "+t+", depth: "+s+", big_endian: "+i+", true_color: "+e+", red_max: "+r+", green_max: "+_+", blue_max: "+h+", red_shift: "+n+", green_shift: "+o+", blue_shift: "+a),0!==i&&Util.Warn("Server native endian is not little endian"),16!==n&&Util.Warn("Server native red-shift is not 16"),0!==a&&Util.Warn("Server native blue-shift is not 0"),this._onDesktopName(this,this._fb_name),this._true_color&&"Intel(r) AMT KVM"===this._fb_name&&(Util.Warn("Intel AMT KVM only supports 8/16 bit depths. Disabling true color"),this._true_color=!1),this._display.set_true_color(this._true_color),this._display.resize(this._fb_width,this._fb_height),this._onFBResize(this,this._fb_width,this._fb_height),this._keyboard.grab(),this._mouse.grab(),this._true_color?(this._fb_Bpp=4,this._fb_depth=3):(this._fb_Bpp=1,this._fb_depth=1),RFB.messages.pixelFormat(this._sock,this._fb_Bpp,this._fb_depth,this._true_color),RFB.messages.clientEncodings(this._sock,this._encodings,this._local_cursor,this._true_color),RFB.messages.fbUpdateRequests(this._sock,this._display.getCleanDirtyReset(),this._fb_width,this._fb_height),this._timing.fbu_rt_start=(new Date).getTime(),this._timing.pixels=0,this._sock.flush(),this._encrypt?this._updateState("normal","Connected (encrypted) to: "+this._fb_name):this._updateState("normal","Connected (unencrypted) to: "+this._fb_name)},_init_msg:function(){switch(this._rfb_state){case"ProtocolVersion":return this._negotiate_protocol_version();case"Security":return this._negotiate_security();case"Authentication":return this._negotiate_authentication();case"SecurityResult":return this._handle_security_result();case"ClientInitialisation":return this._sock.send([this._shared?1:0]),this._updateState("ServerInitialisation","Authentication OK"),!0;case"ServerInitialisation":return this._negotiate_server_init()}},_handle_set_colour_map_msg:function(){Util.Debug("SetColorMapEntries"),this._sock.rQskip8();var t=this._sock.rQshift16(),s=this._sock.rQshift16();if(this._sock.rQwait("SetColorMapEntries",6*s,6))return!1;for(var i=0;i0?0:this._sock.rQshift8()){case 0:var s=this._framebufferUpdate();return s&&(RFB.messages.fbUpdateRequests(this._sock,this._display.getCleanDirtyReset(),this._fb_width,this._fb_height),this._sock.flush()),s;case 1:return this._handle_set_colour_map_msg();case 2:return Util.Debug("Bell"),this._onBell(this),!0;case 3:return this._handle_server_cut_text();case 250:return this._handle_xvp_msg();default:return this._fail("Disconnected: illegal server message type "+t),Util.Debug("sock.rQslice(0, 30): "+this._sock.rQslice(0,30)),!0}},_framebufferUpdate:function(){var t,s=!0;if(0===this._FBU.rects){if(this._sock.rQwait("FBU header",3,1))return!1;this._sock.rQskip8(),this._FBU.rects=this._sock.rQshift16(),this._FBU.bytes=0,this._timing.cur_fbu=0,this._timing.fbu_rt_start>0&&(t=(new Date).getTime(),Util.Info("First FBU latency: "+(t-this._timing.fbu_rt_start)))}for(;this._FBU.rects>0;){if("normal"!==this._rfb_state)return!1;if(this._sock.rQwait("FBU",this._FBU.bytes))return!1;if(0===this._FBU.bytes){if(this._sock.rQwait("rect header",12))return!1;var i=this._sock.rQshiftBytes(12);if(this._FBU.x=(i[0]<<8)+i[1],this._FBU.y=(i[2]<<8)+i[3],this._FBU.width=(i[4]<<8)+i[5],this._FBU.height=(i[6]<<8)+i[7],this._FBU.encoding=parseInt((i[8]<<24)+(i[9]<<16)+(i[10]<<8)+i[11],10),this._onFBUReceive(this,{x:this._FBU.x,y:this._FBU.y,width:this._FBU.width,height:this._FBU.height,encoding:this._FBU.encoding,encodingName:this._encNames[this._FBU.encoding]}),!this._encNames[this._FBU.encoding])return this._fail("Disconnected: unsupported encoding "+this._FBU.encoding),!1}this._timing.last_fbu=(new Date).getTime();var e=this._encHandlers[this._FBU.encoding];try{s=e()}catch(t){console.log("missed "+this._FBU.encoding+": "+e),s=this._encHandlers[this._FBU.encoding]()}if(t=(new Date).getTime(),this._timing.cur_fbu+=t-this._timing.last_fbu,s&&(this._encStats[this._FBU.encoding][0]++,this._encStats[this._FBU.encoding][1]++,this._timing.pixels+=this._FBU.width*this._FBU.height),this._timing.pixels>=this._fb_width*this._fb_height&&((this._FBU.width===this._fb_width&&this._FBU.height===this._fb_height||this._timing.fbu_rt_start>0)&&(this._timing.full_fbu_total+=this._timing.cur_fbu,this._timing.full_fbu_cnt++,Util.Info("Timing of full FBU, curr: "+this._timing.cur_fbu+", total: "+this._timing.full_fbu_total+", cnt: "+this._timing.full_fbu_cnt+", avg: "+this._timing.full_fbu_total/this._timing.full_fbu_cnt)),this._timing.fbu_rt_start>0)){var r=t-this._timing.fbu_rt_start;this._timing.fbu_rt_total+=r,this._timing.fbu_rt_cnt++,Util.Info("full FBU round-trip, cur: "+r+", total: "+this._timing.fbu_rt_total+", cnt: "+this._timing.fbu_rt_cnt+", avg: "+this._timing.fbu_rt_total/this._timing.fbu_rt_cnt),this._timing.fbu_rt_start=0}if(!s)return s}return this._onFBUComplete(this,{x:this._FBU.x,y:this._FBU.y,width:this._FBU.width,height:this._FBU.height,encoding:this._FBU.encoding,encodingName:this._encNames[this._FBU.encoding]}),!0}},Util.make_properties(RFB,[["target","wo","dom"],["focusContainer","wo","dom"],["encrypt","rw","bool"],["true_color","rw","bool"],["local_cursor","rw","bool"],["shared","rw","bool"],["view_only","rw","bool"],["xvp_password_sep","rw","str"],["disconnectTimeout","rw","int"],["wsProtocols","rw","arr"],["repeaterID","rw","str"],["viewportDrag","rw","bool"],["onUpdateState","rw","func"],["onPasswordRequired","rw","func"],["onClipboard","rw","func"],["onBell","rw","func"],["onFBUReceive","rw","func"],["onFBUComplete","rw","func"],["onFBResize","rw","func"],["onDesktopName","rw","func"],["onXvpInit","rw","func"]]),RFB.prototype.set_local_cursor=function(t){!t||t in{0:1,no:1,false:1}?(this._local_cursor=!1,this._display.disableLocalCursor()):this._display.get_cursor_uri()?this._local_cursor=!0:(Util.Warn("Browser does not support local cursor"),this._display.disableLocalCursor())},RFB.prototype.get_display=function(){return this._display},RFB.prototype.get_keyboard=function(){return this._keyboard},RFB.prototype.get_mouse=function(){return this._mouse},RFB.messages={keyEvent:function(t,s,i){var e=t._sQ,r=t._sQlen;e[r]=4,e[r+1]=i,e[r+2]=0,e[r+3]=0,e[r+4]=s>>24,e[r+5]=s>>16,e[r+6]=s>>8,e[r+7]=s,t._sQlen+=8},pointerEvent:function(t,s,i,e){var r=t._sQ,_=t._sQlen;r[_]=5,r[_+1]=e,r[_+2]=s>>8,r[_+3]=s,r[_+4]=i>>8,r[_+5]=i,t._sQlen+=6},clientCutText:function(t,s){var i=t._sQ,e=t._sQlen;i[e]=6,i[e+1]=0,i[e+2]=0,i[e+3]=0;var r=s.length;i[e+4]=r>>24,i[e+5]=r>>16,i[e+6]=r>>8,i[e+7]=r;for(var _=0;_>8,_[h+3]=s,_[h+4]=i>>8,_[h+5]=i,_[h+6]=1,_[h+7]=0,_[h+8]=e>>24,_[h+9]=e>>16,_[h+10]=e>>8,_[h+11]=e,_[h+12]=0,_[h+13]=0,_[h+14]=0,_[h+15]=0,_[h+16]=s>>8,_[h+17]=s,_[h+18]=i>>8,_[h+19]=i,_[h+20]=r>>24,_[h+21]=r>>16,_[h+22]=r>>8,_[h+23]=r,t._sQlen+=24},pixelFormat:function(t,s,i,e){var r=t._sQ,_=t._sQlen;r[_]=0,r[_+1]=0,r[_+2]=0,r[_+3]=0,r[_+4]=8*s,r[_+5]=8*i,r[_+6]=0,r[_+7]=e?1:0,r[_+8]=0,r[_+9]=255,r[_+10]=0,r[_+11]=255,r[_+12]=0,r[_+13]=255,r[_+14]=16,r[_+15]=8,r[_+16]=0,r[_+17]=0,r[_+18]=0,r[_+19]=0,t._sQlen+=20},clientEncodings:function(t,s,i,e){var r=t._sQ,_=t._sQlen;r[_]=2,r[_+1]=0;var h,n=_+4,o=0;for(h=0;h>24,r[n+1]=a>>16,r[n+2]=a>>8,r[n+3]=a,n+=4,o++}else Util.Warn("Skipping tight as it is only supported with true color");else Util.Debug("Skipping Cursor pseudo-encoding");r[_+2]=o>>8,r[_+3]=o,t._sQlen+=n-_},fbUpdateRequests:function(t,s,i,e){var r,_,h=s.cleanBox;h.w>0&&h.h>0&&(r=void 0===h.w?i:h.w,_=void 0===h.h?e:h.h,RFB.messages.fbUpdateRequest(t,1,h.x,h.y,r,_));for(var n=0;n>8&255,h[n+3]=255&i,h[n+4]=e>>8&255,h[n+5]=255&e,h[n+6]=r>>8&255,h[n+7]=255&r,h[n+8]=_>>8&255,h[n+9]=255&_,t._sQlen+=10}},RFB.genDES=function(t,s){for(var i=[],e=0;e0?this._FBU.bytes=this._FBU.width*this._fb_Bpp:(this._FBU.rects--,this._FBU.bytes=0),!0},COPYRECT:function(){return this._FBU.bytes=4,!this._sock.rQwait("COPYRECT",4)&&(this._display.copyImage(this._sock.rQshift16(),this._sock.rQshift16(),this._FBU.x,this._FBU.y,this._FBU.width,this._FBU.height),this._FBU.rects--,this._FBU.bytes=0,!0)},RRE:function(){var t;if(0===this._FBU.subrects){if(this._FBU.bytes=4+this._fb_Bpp,this._sock.rQwait("RRE",4+this._fb_Bpp))return!1;this._FBU.subrects=this._sock.rQshift32(),t=this._sock.rQshiftBytes(this._fb_Bpp),this._display.fillRect(this._FBU.x,this._FBU.y,this._FBU.width,this._FBU.height,t)}for(;this._FBU.subrects>0&&this._sock.rQlen()>=this._fb_Bpp+8;){t=this._sock.rQshiftBytes(this._fb_Bpp);var s=this._sock.rQshift16(),i=this._sock.rQshift16(),e=this._sock.rQshift16(),r=this._sock.rQshift16();this._display.fillRect(this._FBU.x+s,this._FBU.y+i,e,r,t),this._FBU.subrects--}if(this._FBU.subrects>0){var _=Math.min(this._rre_chunk_sz,this._FBU.subrects);this._FBU.bytes=(this._fb_Bpp+8)*_}else this._FBU.rects--,this._FBU.bytes=0;return!0},HEXTILE:function(){var t=this._sock.get_rQ(),s=this._sock.get_rQi();for(0===this._FBU.tiles&&(this._FBU.tiles_x=Math.ceil(this._FBU.width/16),this._FBU.tiles_y=Math.ceil(this._FBU.height/16),this._FBU.total_tiles=this._FBU.tiles_x*this._FBU.tiles_y,this._FBU.tiles=this._FBU.total_tiles);this._FBU.tiles>0;){if(this._FBU.bytes=1,this._sock.rQwait("HEXTILE subencoding",this._FBU.bytes))return!1;var i=t[s];if(i>30)return this._fail("Disconnected: illegal hextile subencoding "+i),!1;var e=0,r=this._FBU.total_tiles-this._FBU.tiles,_=r%this._FBU.tiles_x,h=Math.floor(r/this._FBU.tiles_x),n=this._FBU.x+16*_,o=this._FBU.y+16*h,a=Math.min(16,this._FBU.x+this._FBU.width-n),c=Math.min(16,this._FBU.y+this._FBU.height-o);if(1&i)this._FBU.bytes+=a*c*this._fb_Bpp;else if(2&i&&(this._FBU.bytes+=this._fb_Bpp),4&i&&(this._FBU.bytes+=this._fb_Bpp),8&i){if(this._FBU.bytes++,this._sock.rQwait("hextile subrects header",this._FBU.bytes))return!1;e=t[s+this._FBU.bytes-1],this._FBU.bytes+=16&i?e*(this._fb_Bpp+2):2*e}if(this._sock.rQwait("hextile",this._FBU.bytes))return!1;if(this._FBU.subencoding=t[s],s++,0===this._FBU.subencoding)1&this._FBU.lastsubencoding?Util.Debug(" Ignoring blank after RAW"):this._display.fillRect(n,o,a,c,this._FBU.background);else if(1&this._FBU.subencoding)this._display.blitImage(n,o,a,c,t,s),s+=this._FBU.bytes-1;else{if(2&this._FBU.subencoding&&(1==this._fb_Bpp?this._FBU.background=t[s]:this._FBU.background=[t[s],t[s+1],t[s+2],t[s+3]],s+=this._fb_Bpp),4&this._FBU.subencoding&&(1==this._fb_Bpp?this._FBU.foreground=t[s]:this._FBU.foreground=[t[s],t[s+1],t[s+2],t[s+3]],s+=this._fb_Bpp),this._display.startTile(n,o,a,c,this._FBU.background),8&this._FBU.subencoding){e=t[s],s++;for(var l=0;l>4,p=15&u,b=t[s];s++;var g=1+(b>>4),B=1+(15&b);this._display.subTile(d,p,g,B,f)}}this._display.finishTile()}this._sock.set_rQi(s),this._FBU.lastsubencoding=this._FBU.subencoding,this._FBU.bytes=0,this._FBU.tiles--}return 0===this._FBU.tiles&&this._FBU.rects--,!0},getTightCLength:function(t){var s=1,i=0;return i+=127&t[0],128&t[0]&&(s++,i+=(127&t[1])<<7,128&t[1]&&(s++,i+=t[2]<<14)),[s,i]},display_tight:function(t){if(1===this._fb_depth&&this._fail("Tight protocol handler only implements true color mode"),this._FBU.bytes=1,this._sock.rQwait("TIGHT compression-control",this._FBU.bytes))return!1;var s,i,e,r,_=0,h=-1,n=function(t,s){for(var i=0;i<4;i++)_>>i&1&&(this._FBU.zlibs[i].reset(),console.debug("RESET!"),Util.Info("Reset zlib stream "+i));return this._FBU.zlibs[h].inflate(t,!0,s)}.bind(this),o=function(t,s,i,e){for(var r=this._destBuff,_=Math.floor((i+7)/8),h=Math.floor(i/8),n=0;n=0;o--)c=4*(n*i+8*a+7-o),l=3*(t[n*_+a]>>o&1),r[c]=s[l],r[c+1]=s[l+1],r[c+2]=s[l+2],r[c+3]=255;for(o=7;o>=8-i%8;o--)c=4*(n*i+8*a+7-o),l=3*(t[n*_+a]>>o&1),r[c]=s[l],r[c+1]=s[l+1],r[c+2]=s[l+2],r[c+3]=255}return r}.bind(this),a=function(t,s,i,e){for(var r=this._destBuff,_=i*e*4,h=0,n=0;h<_;h+=4,n++){var o=3*t[n];r[h]=s[o],r[h+1]=s[o+1],r[h+2]=s[o+2],r[h+3]=255}return r}.bind(this),c=this._sock.get_rQi(),l=this._sock.rQwhole(),f=function(){var t=l[c+2]+1,_=t*this._fb_depth;if(this._FBU.bytes+=_,this._sock.rQwait("TIGHT palette "+s,this._FBU.bytes))return!1;var h=t<=2?1:8,f=Math.floor((this._FBU.width*h+7)/8),u=!1;if(f*this._FBU.height<12)u=!0,e=0,r=f*this._FBU.height;else{var d=c+3+_;e=1,r=0,r+=127&l[d],128&l[d]&&(e++,r+=(127&l[d+1])<<7,128&l[d+1]&&(e++,r+=l[d+2]<<14))}if(this._FBU.bytes+=e+r,this._sock.rQwait("TIGHT "+s,this._FBU.bytes))return!1;this._sock.rQskipBytes(3),this._sock.rQshiftTo(this._paletteBuff,_),this._sock.rQskipBytes(e),i=u?this._sock.rQshiftBytes(r):n(this._sock.rQshiftBytes(r),f*this._FBU.height);var p;return 2==t?(p=o(i,this._paletteBuff,this._FBU.width,this._FBU.height),this._display.blitRgbxImage(this._FBU.x,this._FBU.y,this._FBU.width,this._FBU.height,p,0,!1)):(p=a(i,this._paletteBuff,this._FBU.width,this._FBU.height),this._display.blitRgbxImage(this._FBU.x,this._FBU.y,this._FBU.width,this._FBU.height,p,0,!1)),!0}.bind(this),u=function(){var t=!1,_=this._FBU.width*this._FBU.height*this._fb_depth;if(_<12)t=!0,e=0,r=_;else{var h=c+1;e=1,r=0,r+=127&l[h],128&l[h]&&(e++,r+=(127&l[h+1])<<7,128&l[h+1]&&(e++,r+=l[h+2]<<14))}return this._FBU.bytes=1+e+r,!this._sock.rQwait("TIGHT "+s,this._FBU.bytes)&&(this._sock.rQshiftBytes(1+e),i=t?this._sock.rQshiftBytes(r):n(this._sock.rQshiftBytes(r),_),this._display.blitRgbImage(this._FBU.x,this._FBU.y,this._FBU.width,this._FBU.height,i,0,!1),!0)}.bind(this),d=this._sock.rQpeek8();if(_=15&d,d>>=4,h=3&d,8===d)s="fill";else if(9===d)s="jpeg";else if(10===d)s="png";else if(4&d)s="filter";else{if(!(d<4))return this._fail("Illegal tight compression received, ctl: "+d);s="copy"}if(t&&("filter"===s||"copy"===s))return this._fail("filter/copy received in tightPNG mode");switch(s){case"fill": this._FBU.bytes+=this._fb_depth;break;case"jpeg":case"png":this._FBU.bytes+=3;break;case"filter":this._FBU.bytes+=2}if(this._sock.rQwait("TIGHT "+s,this._FBU.bytes))return!1;switch(s){case"fill":this._display.fillRect(this._FBU.x,this._FBU.y,this._FBU.width,this._FBU.height,[l[c+3],l[c+2],l[c+1]],!1),this._sock.rQskipBytes(4);break;case"png":case"jpeg":var p=c+1;if(e=1,r=0,r+=127&l[p],128&l[p]&&(e++,r+=(127&l[p+1])<<7,128&l[p+1]&&(e++,r+=l[p+2]<<14)),this._FBU.bytes=1+e+r,this._sock.rQwait("TIGHT "+s,this._FBU.bytes))return!1;this._sock.rQskipBytes(1+e);var b=new Image;b.src="data: image/"+s+RFB.extract_data_uri(this._sock.rQshiftBytes(r)),this._display.renderQ_push({type:"img",img:b,x:this._FBU.x,y:this._FBU.y}),b=null;break;case"filter":var g=l[c+1];if(1!==g)throw new Error("Unsupported tight subencoding received, filter: "+g);if(!f())return!1;break;case"copy":if(!u())return!1}return this._FBU.bytes=0,this._FBU.rects--,!0},TIGHT:function(){return this._encHandlers.display_tight(!1)},TIGHT_PNG:function(){return this._encHandlers.display_tight(!0)},last_rect:function(){return this._FBU.rects=0,!0},handle_FB_resize:function(){return this._fb_width=this._FBU.width,this._fb_height=this._FBU.height,this._destBuff=new Uint8Array(this._fb_width*this._fb_height*4),this._display.resize(this._fb_width,this._fb_height),this._onFBResize(this,this._fb_width,this._fb_height),this._timing.fbu_rt_start=(new Date).getTime(),this._FBU.bytes=0,this._FBU.rects-=1,!0},ExtendedDesktopSize:function(){if(this._FBU.bytes=1,this._sock.rQwait("ExtendedDesktopSize",this._FBU.bytes))return!1;this._supportsSetDesktopSize=!0;var t=this._sock.rQpeek8();if(this._FBU.bytes=4+16*t,this._sock.rQwait("ExtendedDesktopSize",this._FBU.bytes))return!1;this._sock.rQskipBytes(1),this._sock.rQskipBytes(3);for(var s=0;s> set_cursor");var t=this._FBU.x,s=this._FBU.y,i=this._FBU.width,e=this._FBU.height,r=i*e*this._fb_Bpp,_=Math.floor((i+7)/8)*e;return this._FBU.bytes=r+_,!this._sock.rQwait("cursor encoding",this._FBU.bytes)&&(this._display.changeCursor(this._sock.rQshiftBytes(r),this._sock.rQshiftBytes(_),t,s,i,e),this._FBU.bytes=0,this._FBU.rects--,Util.Debug("<< set_cursor"),!0)},JPEG_quality_lo:function(){Util.Error("Server sent jpeg_quality pseudo-encoding")},compress_lo:function(){Util.Error("Server sent compress level pseudo-encoding")}}}();