public VncReadMessageBody ReadServerMessage() { if (m_readingServerMessage) { return(null); } m_readingServerMessage = true; try { var readBody = VncComm.ReadServerMessage(m_readStream, m_serverInitBody.ServerPixelFormat.BytesPerPixel, m_serverInitBody.ServerPixelFormat.BigEndianFlag); // Set after WriteFramebufferUpdateRequest to prevent the excess data VncReadMessageBody retBody = null; var messageType = (VncEnum.MessageTypeServerToClient)readBody[0]; if (messageType == VncEnum.MessageTypeServerToClient.FramebufferUpdate) { var encodeList = VncEncodeFactory.CreateVncEncodeFromBinary(readBody, m_serverInitBody.ServerPixelFormat.BytesPerPixel, m_serverInitBody.ServerPixelFormat.BigEndianFlag, m_zrleReader); // Draw to canvas lock (CanvasLock) { foreach (var e in encodeList) { // Draw to canvas IVncPixelGetter pixelGetter = (e.EncodeType == VncEnum.EncodeType.ZRLE) ? m_pixelGetterZrle : m_pixelGetterNormal; e.Draw(pixelGetter, m_canvas); } } retBody = new VncReadMessageBody(messageType, encodeList, null); } else if (messageType == VncEnum.MessageTypeServerToClient.SetColorMapEntries) { var colorMap = new VncSetColorMapEntriesBody(readBody); m_pixelGetterNormal.SetColorMap(colorMap); retBody = new VncReadMessageBody(messageType, null, colorMap); } onRead(new VncReadEventArgs(readBody, retBody)); return(retBody); } catch (Exception a_ex) { cleanupForDisconnect(a_ex); onDisconnected(new VncCauseEventArgs(a_ex)); return(null); } finally { m_readingServerMessage = false; } }
protected static void writePixelColor(IVncPixelGetter a_pixelGetter, byte[] a_body, int a_basePos, MemoryStream a_output) { var bgr = a_pixelGetter.GetPixelVec3b(a_body, a_basePos); a_output.WriteByte(bgr.Item2); a_output.WriteByte(bgr.Item1); a_output.WriteByte(bgr.Item0); a_output.WriteByte(255); }
public override void Draw(IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { Scalar background = (Scalar)a_pixelGetter.GetPixelVec3b(Background, 0); a_mat.Rectangle(new Rect(X, Y, Width, Height), background, -1 /* Fill */); foreach (var v in Subrectangle) { Scalar pixelValue = (Scalar)a_pixelGetter.GetPixelVec3b(v.PixelBinary, 0); a_mat.Rectangle(new Rect(X + v.X, Y + v.Y, v.Width, v.Height), pixelValue, -1 /* Fill */); } }
public void DrawHexTile(int a_x, int a_y, int a_width, int a_height, IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { Scalar background = (Scalar)a_pixelGetter.GetPixelVec3b(Background, 0); a_mat.Rectangle(new Rect(a_x, a_y, a_width, a_height), background, -1 /* Fill */); foreach (var v in Subrects) { Scalar color = (Scalar)a_pixelGetter.GetPixelVec3b(v.SubrectsColor, 0); a_mat.Rectangle(new Rect(a_x + v.X, a_y + v.Y, v.Width, v.Height), color, -1 /* Fill */); } }
public override void Draw(IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { var indexer = a_mat.GetIndexer(); int byteSize = a_pixelGetter.GetPixelByteSize(); int offset = m_offset; for (int y = Y; y < Y + Height; ++y) { for (int x = X; x < X + Width; ++x) { indexer[y, x] = a_pixelGetter.GetPixelVec3b(m_pixelData, offset); offset += byteSize; } } }
public void DrawHexTile(int a_x, int a_y, int a_width, int a_height, IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { var indexer = a_mat.GetIndexer(); int byteSize = a_pixelGetter.GetPixelByteSize(); int offset = Offset; for (int y = a_y; y < a_y + a_height; ++y) { for (int x = a_x; x < a_x + a_width; ++x) { indexer[y, x] = a_pixelGetter.GetPixelVec3b(RawPixel, offset); offset += byteSize; } } }
public override void Draw(IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { int tile = 0; for (int y = Y; y < Y + Height; y += 16) { int h = (Y + Height - y) > 16 ? 16 : (Y + Height - y); for (int x = X; x < X + Width; x += 16) { int w = (X + Width - x) > 16 ? 16 : (X + Width - x); Hextile[tile].DrawHexTile(x, y, w, h, a_pixelGetter, a_mat); ++tile; } } }
public override void Draw(IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { Rect srcRect = new Rect(SrcX, SrcY, Width, Height); Rect dstRect = new Rect(X, Y, Width, Height); if (srcRect.IntersectsWith(dstRect)) { using (var src = a_mat.Clone(srcRect)) using (var dst = new MatOfByte3(a_mat, dstRect)) { src.CopyTo(dst); } } else { using (var src = new MatOfByte3(a_mat, srcRect)) using (var dst = new MatOfByte3(a_mat, dstRect)) { src.CopyTo(dst); } } }
public abstract void Draw(IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat);
public bool ConnectVnc() { Connecting = true; try { m_tcpClient = new TcpClient(); m_tcpClient.Connect(ClientConfig.Address, ClientConfig.Port); m_readStream = m_readStreamCreator(m_tcpClient.Client); m_writeStream = m_writeStreamCreator(m_tcpClient.Client); // ZRLE encoding uses one zlib stream during connection. // Therefore, it generates at the timing of VNC connection. m_zrleReader?.Dispose(); m_zrleReader = new ZrleDataReader(); //----------------------- // Handshake //----------------------- // Server -> (ProtocolVersion) -> Client var version = VncComm.ReadProtocolVersion(m_readStream, ClientConfig.ForceVersion); // Server <- (ProtocolVersion) <- Client VncComm.WriteProtocolVersion(m_writeStream, version); // (Security) if (version == VncEnum.Version.Version33) { // Server -> (Security) -> Client var securityType = VncComm.ReadSecurityType(m_readStream); if (securityType != VncEnum.SecurityType.None && securityType != VncEnum.SecurityType.VNCAuthentication) { throw new SecurityException($"VNC Version is 3.3. Security type is {securityType}."); } if (securityType == VncEnum.SecurityType.VNCAuthentication) { // Server -> (VNC Authentication Challenge) -> Client var challenge = VncComm.ReadVncChallange(m_readStream); // Server <- (VNC Authentication Response) <- Client byte[] response = encryptChallenge(ClientConfig.Password, challenge); VncComm.WriteVncResponse(m_writeStream, response); // Server -> (Security Result) -> Client VncComm.ReadSecurityResult(m_readStream, version); // Result is checked in method. So don't check here, } } else { // Server -> (SecurityTypes) -> Client var securityTypes = VncComm.ReadSecurityTypes(m_readStream); if (securityTypes.Contains(VncEnum.SecurityType.None)) { // Server <- (SecurityType) <- Client VncComm.WriteSecurityType(m_writeStream, VncEnum.SecurityType.None); if (version == VncEnum.Version.Version38) { // Server -> (Security Result) -> Client VncComm.ReadSecurityResult(m_readStream, version); } } else if (securityTypes.Contains(VncEnum.SecurityType.VNCAuthentication)) { // Server <- (SecurityType) <- Client VncComm.WriteSecurityType(m_writeStream, VncEnum.SecurityType.VNCAuthentication); // Server -> (VNC Authentication Challenge) -> Client var challenge = VncComm.ReadVncChallange(m_readStream); // Server <- (VNC Authentication Response) <- Client byte[] response = encryptChallenge(ClientConfig.Password, challenge); VncComm.WriteVncResponse(m_writeStream, response); // Server -> (Security Result) -> Client VncComm.ReadSecurityResult(m_readStream, version); } else { throw new SecurityException($"Unknown security-types. Server can use [{string.Join(",", securityTypes)}]."); } } //----------------------- // Initial Message //----------------------- // Server <- (ClientInit) <- Client VncComm.WriteClientInit(m_writeStream, VncEnum.SharedFlag.Share); // Server -> (ServerInit) -> Client m_serverInitBody = VncComm.ReadServerInit(m_readStream); //----------------------- // InitialSettings //----------------------- // Server <- (SetEncodings) <- Client VncComm.WriteSetEncodings(m_writeStream, ClientConfig.Encodings); // Server <- (SetPixelFormat) <- Client if (ClientConfig.IsColourSpecified) { var pixelFormat = new PixelFormat(ClientConfig.SpecifiedColour.BytesPerPixel, ClientConfig.SpecifiedColour.Depth, m_serverInitBody.ServerPixelFormat.BigEndianFlag, ClientConfig.SpecifiedColour.TrueColorFlag, ClientConfig.SpecifiedColour.RedMax, ClientConfig.SpecifiedColour.GreenMax, ClientConfig.SpecifiedColour.BlueMax, ClientConfig.SpecifiedColour.RedShift, ClientConfig.SpecifiedColour.GreenShift, ClientConfig.SpecifiedColour.BlueShift); m_serverInitBody = new VncServerInitBody(m_serverInitBody.FramebufferWidth, m_serverInitBody.FramebufferHeight, pixelFormat, m_serverInitBody.NameString); VncComm.WriteSetPixelFormat(m_writeStream, m_serverInitBody.ServerPixelFormat); } //----------------------- // Refresh Framebuffer //----------------------- // Server <- (Refresh Framebuffer) <- Client VncComm.WriteFramebufferUpdateRequest(m_writeStream, VncEnum.FramebufferUpdateRequestIncremental.UpdateAll, 0, 0, m_serverInitBody.FramebufferWidth, m_serverInitBody.FramebufferHeight); // Create Data m_pixelGetterNormal = VncPixelGetterFactory.CreateVncPixelGetter(m_serverInitBody.ServerPixelFormat, VncEnum.EncodeType.Raw); m_pixelGetterZrle = VncPixelGetterFactory.CreateVncPixelGetter(m_serverInitBody.ServerPixelFormat, VncEnum.EncodeType.ZRLE); m_canvas?.Dispose(); m_canvas = new MatOfByte3(m_serverInitBody.FramebufferHeight, m_serverInitBody.FramebufferWidth); // Successful connection m_connected = true; onConnected(); } catch (Exception a_ex) { cleanupForDisconnect(a_ex); onConnectFailed(new VncCauseEventArgs(a_ex)); } finally { Connecting = false; } return(m_connected); }
public override void Draw(IVncPixelGetter a_pixelGetter, MatOfByte3 a_mat) { if (m_unzippedData == null) { m_unzippedData = m_zrleReader.Read(m_zlibData, m_offset, m_length); } int readPos = 0; for (int y = Y; y < Y + Height; y += 64) { int h = (Y + Height - y) > 64 ? 64 : (Y + Height - y); for (int x = X; x < X + Width; x += 64) { int w = (X + Width - x) > 64 ? 64 : (X + Width - x); int subencodingType = m_unzippedData[readPos++]; if (subencodingType == 0) { var indexer = a_mat.GetIndexer(); int byteSize = a_pixelGetter.GetPixelByteSize(); for (int posY = y; posY < y + h; ++posY) { for (int posX = x; posX < x + w; ++posX) { indexer[posY, posX] = a_pixelGetter.GetPixelVec3b(m_unzippedData, readPos); readPos += byteSize; } } } else if (subencodingType == 1) { Scalar background = (Scalar)a_pixelGetter.GetPixelVec3b(m_unzippedData, readPos); readPos += a_pixelGetter.GetPixelByteSize(); a_mat.Rectangle(new Rect(x, y, w, h), background, -1 /* Fill */); } else if (2 <= subencodingType && subencodingType <= 16) { Vec3b[] palette = new Vec3b[subencodingType]; for (int i = 0; i < subencodingType; ++i) { palette[i] = a_pixelGetter.GetPixelVec3b(m_unzippedData, readPos); readPos += a_pixelGetter.GetPixelByteSize(); } var indexer = a_mat.GetIndexer(); int byteSize = a_pixelGetter.GetPixelByteSize(); int[] ppa = createPackedPixelsArray(w, h, m_unzippedData, readPos, subencodingType); for (int i = 0, posY = y; posY < y + h; ++posY) { for (int posX = x; posX < x + w; ++posX) { indexer[posY, posX] = palette[ppa[i]]; ++i; } } readPos += getPackedPixelsBytesSize(w, h, subencodingType); } else if (17 <= subencodingType && subencodingType <= 127) { throw new NotSupportedException($"SubencodingType ({subencodingType}) is not supported."); } else if (subencodingType == 128) { var indexer = a_mat.GetIndexer(); int posX = x; int posY = y; int totalLen = 0; int size = w * h; while (totalLen < size) { Vec3b pixel = a_pixelGetter.GetPixelVec3b(m_unzippedData, readPos); readPos += a_pixelGetter.GetPixelByteSize(); // count length int b; int len = 1; do { b = m_unzippedData[readPos++]; len += b; } while (b == 255); // set pixel for (int i = 0; i < len; ++i) { indexer[posY, posX] = pixel; // to next position ++posX; if (posX >= x + w) { posX = x; ++posY; } } totalLen += len; } } else if (subencodingType == 129) { throw new NotSupportedException($"SubencodingType ({subencodingType}) is not supported."); } else if (130 <= subencodingType && subencodingType <= 255) { // create palette int paletteSize = subencodingType - 128; Vec3b[] palette = new Vec3b[paletteSize]; for (int i = 0; i < paletteSize; ++i) { palette[i] = a_pixelGetter.GetPixelVec3b(m_unzippedData, readPos); readPos += a_pixelGetter.GetPixelByteSize(); } var indexer = a_mat.GetIndexer(); int posX = x; int posY = y; int totalLen = 0; int size = w * h; while (totalLen < size) { int paletteIndex = m_unzippedData[readPos++]; if ((paletteIndex & 0b10000000) == 0) { // length is 1 indexer[posY, posX] = palette[paletteIndex]; ++totalLen; // to next position ++posX; if (posX >= x + w) { posX = x; ++posY; } } else { int b; int len = 1; do { b = m_unzippedData[readPos++]; len += b; } while (b == 255); for (int i = 0; i < len; ++i) { indexer[posY, posX] = palette[paletteIndex & 0x7F]; // to next position ++posX; if (posX >= x + w) { posX = x; ++posY; } } totalLen += len; } } }