/// <summary> /// Finish setting-up protocol with VNC Host. Should be called after Connect and Authenticate (if password required). /// </summary> public void Initialize() { // Finish initializing protocol with host rfb.WriteClientInitialisation(false); buffer = rfb.ReadServerInit(); rfb.WriteSetPixelFormat(buffer); // just use the server's framebuffer format rfb.WriteSetEncodings(new uint[] { RfbProtocol.ZRLE_ENCODING, RfbProtocol.HEXTILE_ENCODING, // RfbProtocol.CORRE_ENCODING, // CoRRE is buggy in some hosts, so don't bother using RfbProtocol.RRE_ENCODING, RfbProtocol.COPYRECT_ENCODING, RfbProtocol.RAW_ENCODING }); // Create an EncodedRectangleFactory so that EncodedRectangles can be built according to set pixel layout factory = new EncodedRectangleFactory(rfb, buffer); }
/// <summary> /// Sends the format to be used by the server when sending Framebuffer Updates. See RFB Doc v. 3.8 section 6.3.1. /// </summary> /// <param name="buffer">A Framebuffer telling the server how to encode pixel data. Typically this will be the same one sent by the server during initialization.</param> public void WriteSetPixelFormat(Framebuffer buffer) { writer.Write(SET_PIXEL_FORMAT); WritePadding(3); writer.Write(buffer.ToPixelFormat()); // 16-byte Pixel Format writer.Flush(); }
/// <summary> /// Given the dimensions and 16-byte PIXEL_FORMAT record from the VNC Host, deserialize this into a Framebuffer object. /// </summary> /// <param name="b">The 16-byte PIXEL_FORMAT record.</param> /// <param name="width">The width in pixels of the remote desktop.</param> /// <param name="height">The height in pixels of the remote desktop.</param> /// <param name="bitsPerPixel">The number of Bits Per Pixel for the Framebuffer--one of 8, 16, or 32.</param> /// <param name="depth">The Colour Depth of the Framebuffer--one of 3, 6, 8 or 16.</param> /// <returns>Returns a Framebuffer object matching the specification of b[].</returns> public static Framebuffer FromPixelFormat(byte[] b, int width, int height, int bitsPerPixel, int depth) { if (b.Length != 16) { throw new ArgumentException("Length of b must be 16 bytes."); } var buffer = new Framebuffer(width, height); if ((bitsPerPixel == 16) && (depth == 16)) { buffer.BitsPerPixel = 16; buffer.Depth = 16; buffer.BigEndian = b[2] != 0; buffer.TrueColour = false; buffer.RedMax = 31; buffer.GreenMax = 63; buffer.BlueMax = 31; buffer.RedShift = 11; buffer.GreenShift = 5; buffer.BlueShift = 0; } else if ((bitsPerPixel) == 16 && (depth == 8)) { buffer.BitsPerPixel = 16; buffer.Depth = 8; buffer.BigEndian = b[2] != 0; buffer.TrueColour = false; buffer.RedMax = 31; buffer.GreenMax = 63; buffer.BlueMax = 31; buffer.RedShift = 11; buffer.GreenShift = 5; buffer.BlueShift = 0; } else if ((bitsPerPixel) == 8 && (depth == 8)) { buffer.BitsPerPixel = 8; buffer.BigEndian = b[2] != 0; buffer.TrueColour = false; buffer.Depth = 8; buffer.RedMax = 7; buffer.GreenMax = 7; buffer.BlueMax = 3; buffer.RedShift = 0; buffer.GreenShift = 3; buffer.BlueShift = 6; } else if ((bitsPerPixel) == 8 && (depth == 6)) { buffer.BitsPerPixel = 8; buffer.Depth = 6; buffer.BigEndian = b[2] != 0; buffer.TrueColour = false; buffer.RedMax = 3; buffer.GreenMax = 3; buffer.BlueMax = 3; buffer.RedShift = 4; buffer.GreenShift = 2; buffer.BlueShift = 0; } else if ((bitsPerPixel == 8) && (depth == 3)) { buffer.BitsPerPixel = 8; buffer.Depth = 3; buffer.BigEndian = b[2] != 0; buffer.TrueColour = false; buffer.RedMax = 1; buffer.GreenMax = 1; buffer.BlueMax = 1; buffer.RedShift = 2; buffer.GreenShift = 1; buffer.BlueShift = 0; } else { buffer.BitsPerPixel = b[0]; buffer.Depth = b[1]; buffer.BigEndian = b[2] != 0; buffer.TrueColour = b[3] != 0; buffer.RedMax = b[5] | b[4] << 8; buffer.GreenMax = b[7] | b[6] << 8; buffer.BlueMax = b[9] | b[8] << 8; buffer.RedShift = b[10]; buffer.GreenShift = b[11]; buffer.BlueShift = b[12]; } // Last 3 bytes are padding, ignore return(buffer); }
/// <summary> /// Given the dimensions and 16-byte PIXEL_FORMAT record from the VNC Host, deserialize this into a Framebuffer object. /// </summary> /// <param name="b">The 16-byte PIXEL_FORMAT record.</param> /// <param name="width">The width in pixels of the remote desktop.</param> /// <param name="height">The height in pixles of the remote desktop.</param> /// <returns>Returns a Framebuffer object matching the specification of b[].</returns> public static Framebuffer FromPixelFormat(byte[] b, int width, int height) { if (b.Length != 16) throw new ArgumentException("Length of b must be 16 bytes."); Framebuffer buffer = new Framebuffer(width, height); buffer.BitsPerPixel = (int) b[0]; buffer.Depth = (int) b[1]; buffer.BigEndian = (b[2] != 0); buffer.TrueColour = (b[3] != 0); buffer.RedMax = (int) (b[5] | b[4] << 8); buffer.GreenMax = (int) (b[7] | b[6] << 8); buffer.BlueMax = (int) (b[9] | b[8] << 8); buffer.RedShift = (int) b[10]; buffer.GreenShift = (int) b[11]; buffer.BlueShift = (int) b[12]; // Last 3 bytes are padding, ignore return buffer; }
/// <summary> /// Creates an instance of the EncodedRectangleFactory using the connected RfbProtocol object and associated Framebuffer object. /// </summary> /// <param name="rfb">An RfbProtocol object that will be passed to any created EncodedRectangle objects. Must be non-null, already initialized, and connected.</param> /// <param name="framebuffer">A Framebuffer object which will be used by any created EncodedRectangle objects in order to decode and draw rectangles locally.</param> public EncodedRectangleFactory(RfbProtocol rfb, Framebuffer framebuffer) { System.Diagnostics.Debug.Assert(rfb != null, "RfbProtocol object must be non-null"); System.Diagnostics.Debug.Assert(framebuffer != null, "Framebuffer object must be non-null"); this.rfb = rfb; this.framebuffer = framebuffer; }