/// <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; }
/// <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(VncHost rfb, Framebuffer framebuffer) { Debug.Assert(rfb != null, "RfbProtocol object must be non-null"); Debug.Assert(framebuffer != null, "Framebuffer object must be non-null"); this.rfb = rfb; this.framebuffer = framebuffer; }
public VncServer(string password, int port, string name, int w, int h) { _password = password; _port = port; _name = name; //Size screenSize = ScreenSize(); fb = new Framebuffer(w,h); // (screenSize.Width, screenSize.Height); fb.BitsPerPixel = 32; fb.Depth = 24; fb.BigEndian = false; fb.TrueColor = true; fb.RedShift = 16; fb.GreenShift = 8; fb.BlueShift = 0; fb.RedMax = fb.GreenMax = fb.BlueMax = 0xFF; fb.DesktopName = name; }
public VncServer(string password, int port, string name) { Password = password; Port = port; Name = name; Size screenSize = ScreenSize(); fb = new Framebuffer(screenSize.Width, screenSize.Height) { BitsPerPixel = 32, Depth = 24, BigEndian = false, TrueColor = true, RedShift = 16, GreenShift = 8, BlueShift = 0, BlueMax = 0xFF, GreenMax = 0xFF, RedMax = 0xFF, DesktopName = name }; }
/// <summary> /// Writes the server's Initialization message, specifically the Framebuffer's properties. /// </summary> /// <param name="fb">The framebuffer that is sent.</param> public void WriteServerInit(Framebuffer fb) { try { writer.Write(Convert.ToUInt16(fb.Width)); writer.Write(Convert.ToUInt16(fb.Height)); writer.Write(fb.ToPixelFormat()); writer.Write(Convert.ToUInt32(fb.DesktopName.Length)); writer.Write(GetBytes(fb.DesktopName)); writer.Flush(); } catch (IOException ex) { Console.WriteLine(ex.Message); Close(); } }
/// <summary> /// Creates the encoded pixel data in a form of an EncodedRectangle with the preferred encoding. /// </summary> private void DoFrameBufferUpdate(Framebuffer fb, bool incremental, int x, int y, int width, int height) { // Console.WriteLine("X: " + x + " Y: " + y + " W: " + fb.Width + " H: " + fb.Height); int w = fb.Width; int h = fb.Height; if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { Console.WriteLine("Neg:" + x + ":" + y + ":" + width + ":" + height); return; } if (x + width > w) { Console.WriteLine("Too wide"); return; } if (y + height > h) { Console.WriteLine("Too high"); return; } // Console.WriteLine("Bounds OK!"); List<EncodedRectangle> lst = new List<EncodedRectangle>(); //List<byte[]> lstHash = new List<byte[]>(); try { //Console.WriteLine("Framebuffer: "); //fb.Print(); //Console.ReadLine(); System.Diagnostics.Stopwatch tip = System.Diagnostics.Stopwatch.StartNew(); EncodedRectangleFactory factory = new EncodedRectangleFactory(this, fb); /* int i = width / 4; int j = height / 4; int m = 0; Rectangle lRect = Rectangle.Empty; for (int k = 0; k < 4; k++) for (m = 0; m < 4; m++) { lRect = new Rectangle(); lRect.X = (i * k); lRect.Y = (j * m); lRect.Width = i; lRect.Height = j; //lRect = PixelGrabber.AlignRectangle(lRect, width, height); EncodedRectangle localRect = factory.Build(lRect, GetPreferredEncoding()); localRect.Encode(); lst.Add(localRect); } */ EncodedRectangle localRect = factory.Build(new Rectangle(x,y,width, height), GetPreferredEncoding()); localRect.Encode(); lst.Add(localRect); // Console.WriteLine("Encoding took: " + tip.Elapsed); } catch (Exception localException) { Console.WriteLine(localException.StackTrace.ToString()); if (localException is IOException) { this.Close(); return; } } if (lst.Count != 0) WriteFrameBufferUpdate(lst.ToArray()); }
/// <summary> /// Receives a mouse movement or button press/release from the client. /// </summary> public void ReadPointerEvent(Framebuffer fb) { try { byte buttonMask = reader.ReadByte(); ushort X = reader.ReadUInt16(); ushort Y = reader.ReadUInt16(); if (fb.DoMouseEvent != null) fb.DoMouseEvent(buttonMask, X, Y); /*new Thread(delegate() { */ //Robot.PointerEvent(buttonMask, X, Y); // TODO: MOUSE /*}).Start();*/ } catch (IOException ex) { Console.WriteLine(ex.Message); this.Close(); return; } }
/// <summary> /// Receives a key press or release event from the client. /// </summary> public void ReadKeyEvent(Framebuffer fb) { try { bool pressed = (reader.ReadByte() == 1); ReadPadding(2); uint keysym = reader.ReadUInt32(); if (fb.DoKeyEvent != null) fb.DoKeyEvent(pressed, keysym); //Do KeyEvent //new Thread(delegate() { //Robot.KeyEvent(pressed, Convert.ToInt32(keysym)); // TODO: KEYS //}).Start(); } catch (IOException ex) { Console.WriteLine(ex.Message); this.Close(); return; } }
public void Start() { if (String.IsNullOrEmpty(Name)) throw new ArgumentNullException("Name", "The VNC Server Name cannot be empty."); if (Port == 0) throw new ArgumentNullException("Port", "The VNC Server port cannot be zero."); Console.WriteLine("Started VNC Server at port: " + Port); host = new VncHost(Port, Name, new ScreenHandler(new Rectangle(0, 0, ScreenSize().Width, ScreenSize().Height), true)); host.WriteProtocolVersion(); Console.WriteLine("Wrote Protocol Version"); host.ReadProtocolVersion(); Console.WriteLine("Read Protocol Version"); Console.WriteLine("Awaiting Authentication"); if (!host.WriteAuthentication(Password)) { Console.WriteLine("Authentication failed !"); host.Close(); //Start(); } else { Console.WriteLine("Authentication successfull !"); bool share = host.ReadClientInit(); Console.WriteLine("Share: " + share); Console.WriteLine("Server name: " + fb.DesktopName); host.WriteServerInit(fb); while ((host.isRunning)) { switch (host.ReadServerMessageType()) { case VncHost.ClientMessages.SetPixelFormat: Console.WriteLine("Read SetPixelFormat"); Framebuffer f = host.ReadSetPixelFormat(fb.Width, fb.Height); if (f != null) fb = f; break; case VncHost.ClientMessages.ReadColorMapEntries: Console.WriteLine("Read ReadColorMapEntry"); host.ReadColorMapEntry(); break; case VncHost.ClientMessages.SetEncodings: Console.WriteLine("Read SetEncodings"); host.ReadSetEncodings(); break; case VncHost.ClientMessages.FramebufferUpdateRequest: Console.WriteLine("Read FrameBufferUpdateRequest"); host.ReadFrameBufferUpdateRequest(fb); break; case VncHost.ClientMessages.KeyEvent: Console.WriteLine("Read KeyEvent"); host.ReadKeyEvent(); break; case VncHost.ClientMessages.PointerEvent: Console.WriteLine("Read PointerEvent"); host.ReadPointerEvent(); break; case VncHost.ClientMessages.ClientCutText: Console.WriteLine("Read CutText"); host.ReadClientCutText(); break; } } //if (!host.isRunning) //Start(); } }
/// <summary> /// Converts an integer pixel into a byte array /// </summary> /// <param name="pixel">The pixel represented as an integer value</param> /// <param name="fb">The framebuffer that should be used</param> /// <returns>A byte array containing the pixels BGRA data.</returns> public static byte[] GrabBytes(int pixel, Framebuffer fb) { int b = 0; byte[] bytes = null; switch (fb.BitsPerPixel) { case 32: bytes = new byte[4]; bytes[b++] = (byte)(pixel & 0xFF); //B bytes[b++] = (byte)((pixel >> 8) & 0xFF); //G bytes[b++] = (byte)((pixel >> 16) & 0xFF); //R bytes[b++] = (byte)((pixel >> 24) & 0xFF); //A break; case 16: bytes = new byte[2]; bytes[b++] = (byte)(pixel & 0xFF); //B bytes[b++] = (byte)((pixel >> 8) & 0xFF); //G break; case 8: bytes = new byte[1]; bytes[b++] = (byte)(pixel & 0xFF); //B break; } return bytes; }
public void Start() { if (string.IsNullOrEmpty(Name)) { throw new ArgumentNullException("Name", "The VNC Server Name cannot be empty."); } if (Port == 0) { throw new ArgumentNullException("Port", "The VNC Server port cannot be zero."); } if (ProxyPort == 0) { throw new ArgumentNullException("ProxyPort", "You must set a proxy port."); } new Thread(() => { Console.WriteLine("Started VNC Server at port: " + Port + " and proxy port at: " + ProxyPort); //proxy = new VncProxy(Path, ProxyPort, Port); //proxy.StartWebsockify(); host = new VncHost(Port, Name, new ScreenHandler(new Rectangle(0, 0, ScreenSize().Width, ScreenSize().Height), true)); host.WriteProtocolVersion(); Console.WriteLine("Wrote Protocol Version"); host.ReadProtocolVersion(); Console.WriteLine("Read Protocol Version"); Console.WriteLine("Awaiting Authentication"); if (!host.WriteAuthentication(Password)) { Console.WriteLine("Authentication failed !"); Stop(); //Start(); } else { Console.WriteLine("Authentication successfull !"); var share = host.ReadClientInit(); Console.WriteLine("Share: " + share); Console.WriteLine("Server name: " + fb.DesktopName); host.WriteServerInit(fb); while (host.isRunning) { switch (host.ReadServerMessageType()) { case VncHost.ClientMessages.SetPixelFormat: Console.WriteLine("Read SetPixelFormat"); var f = host.ReadSetPixelFormat(fb.Width, fb.Height); if (f != null) { fb = f; } break; case VncHost.ClientMessages.ReadColorMapEntries: Console.WriteLine("Read ReadColorMapEntry"); host.ReadColorMapEntry(); break; case VncHost.ClientMessages.SetEncodings: Console.WriteLine("Read SetEncodings"); host.ReadSetEncodings(); break; case VncHost.ClientMessages.FramebufferUpdateRequest: Console.WriteLine("Read FrameBufferUpdateRequest"); host.ReadFrameBufferUpdateRequest(fb); break; case VncHost.ClientMessages.KeyEvent: Console.WriteLine("Read KeyEvent"); host.ReadKeyEvent(); break; case VncHost.ClientMessages.PointerEvent: Console.WriteLine("Read PointerEvent"); host.ReadPointerEvent(); break; case VncHost.ClientMessages.ClientCutText: Console.WriteLine("Read CutText"); host.ReadClientCutText(); break; } } if (!host.isRunning) { Console.WriteLine("Stopping Websockify"); } //proxy.StopWebsockify(); //Start(); } }).Start(); }
/// <summary> /// Creates the encoded pixel data in a form of an EncodedRectangle with the preferred encoding. /// </summary> private void DoFrameBufferUpdate(Framebuffer fb, bool incremental, int x, int y, int width, int height) { //if (incremental) // return; Trace.WriteLine("X: " + x + " Y: " + y + " W: " + fb.Width + " H: " + fb.Height); var w = fb.Width; var h = fb.Height; if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { Trace.WriteLine("Neg:" + x + ":" + y + ":" + width + ":" + height); return; } if (x + width > w) { Trace.WriteLine("Too wide"); return; } if (y + height > h) { Trace.WriteLine("Too high"); return; } Trace.WriteLine("Bounds OK!"); var rectangles = new HashSet<EncodedRectangle>(); try { var tip = Stopwatch.StartNew(); var factory = new EncodedRectangleFactory(this, fb); var localRect = factory.Build(new Rectangle2(x, y, width, height), GetPreferredEncoding()); localRect.Encode(); rectangles.Add(localRect); Trace.WriteLine("Encoding took: " + tip.Elapsed); } catch (Exception localException) { Console.WriteLine(localException.StackTrace); if (localException is IOException) { Close(); return; } } if (rectangles.Count != 0) WriteFrameBufferUpdate(rectangles); }
public virtual void Start() { if (String.IsNullOrEmpty(Name)) { throw new ArgumentNullException("Name", "The VNC Server Name cannot be empty."); } if (Port == 0) { throw new ArgumentNullException("Port", "The VNC Server port cannot be zero."); } Console.WriteLine("Started VNC Server at port: " + Port); host = new VncHost(Port, Name, new ScreenHandler(new Rectangle(0, 0, ScreenSize().Width, ScreenSize().Height), true)); host.Start(this); host.WriteProtocolVersion(); Console.WriteLine("Wrote Protocol Version"); host.ReadProtocolVersion(); Console.WriteLine("Read Protocol Version"); Console.WriteLine("Awaiting Authentication"); if (!host.WriteAuthentication(Password)) { Console.WriteLine("Authentication failed !"); #if DEBUG //Start(); if (!Debugger.IsAttached) { host.Close(); return; } #else host.Close(); return; #endif } // else { Console.WriteLine("Authentication successfull !"); bool share = host.ReadClientInit(); Console.WriteLine("Share: " + share); Console.WriteLine("Server name: " + fb.DesktopName); host.WriteServerInit(fb); if (!host.isRunning) { Console.WriteLine("host.isRunning = false"); return; } while ((host.isRunning)) { switch (host.ReadServerMessageType()) { case VncHost.ClientMessages.Error: break; case VncHost.ClientMessages.SetPixelFormat: Console.WriteLine("Read SetPixelFormat"); Framebuffer f = host.ReadSetPixelFormat(fb.Width, fb.Height); if (f != null) { fb = f; } break; case VncHost.ClientMessages.ReadColorMapEntries: Console.WriteLine("Read ReadColorMapEntry"); host.ReadColorMapEntry(); break; case VncHost.ClientMessages.SetEncodings: Console.WriteLine("Read SetEncodings"); host.ReadSetEncodings(); break; case VncHost.ClientMessages.FramebufferUpdateRequest: Console.WriteLine("Read FrameBufferUpdateRequest"); host.ReadFrameBufferUpdateRequest(fb); break; case VncHost.ClientMessages.KeyEvent: Console.WriteLine("Read KeyEvent"); host.ReadKeyEvent(); break; case VncHost.ClientMessages.PointerEvent: Console.WriteLine("Read PointerEvent"); host.ReadPointerEvent(); break; case VncHost.ClientMessages.ClientCutText: Console.WriteLine("Read CutText"); host.ReadClientCutText(); break; } } //if (!host.isRunning) //Start(); } }
/// <summary> /// Converts an array of pixels represented as integers into a byte array of pixel data. /// </summary> /// <param name="pixels">The pixel array represented as integers.</param> /// <param name="rectangle">A sub-rectangle of the pixels which we should extract</param> /// <param name="pf">The Framebuffer that should be used.</param> /// <returns></returns> public static byte[] GrabPixels(int[] pixels, Rectangle rectangle, Framebuffer fb) { // Encode as bytes int x = rectangle.X; int y = rectangle.Y; int w = rectangle.Width; int h = rectangle.Height; byte[] bytes = null; int b = 0; int i = 0; int s = 0; int pixel; int size = rectangle.Width * rectangle.Height; int scanline = rectangle.Width; int offsetX = rectangle.X; int offsetY = rectangle.Y; int jump = scanline - w; int p = (y - offsetY) * w + x - offsetX; switch (fb.BitsPerPixel) { case 32: bytes = new byte[size << 2]; for (; i < size; i++, s++, p++) { if (s == w) { s = 0; p += jump; } int tmp = pixels[p]; pixel = fb.TranslatePixel(tmp); //pixel = pixels[p]; bytes[b++] = (byte)(pixel & 0xFF); //B bytes[b++] = (byte)((pixel >> 8) & 0xFF); //G bytes[b++] = (byte)((pixel >> 16) & 0xFF); //R bytes[b++] = (byte)((pixel >> 24) & 0xFF); //A } break; case 24: bytes = new byte[size << 2]; for (; i < size; i++, s++, p++) { if (s == w) { s = 0; p += jump; } pixel = fb.TranslatePixel(pixels[p]); bytes[b++] = (byte)(pixel & 0xFF); //B bytes[b++] = (byte)((pixel >> 8) & 0xFF); //G bytes[b++] = (byte)((pixel >> 16) & 0xFF); //R } break; case 16: bytes = new byte[size << 1]; for (; i < size; i++, s++, p++) { if (s == w) { s = 0; p += jump; } pixel = fb.TranslatePixel(pixels[p]); bytes[b++] = (byte)(pixel & 0xFF); //B bytes[b++] = (byte)((pixel >> 8) & 0xFF); //G } break; case 8: bytes = new byte[size]; for (; i < size; i++, s++, p++) { if (s == w) { s = 0; p += jump; } bytes[i] = (byte)fb.TranslatePixel(pixels[p]); //B } break; } return bytes; }
/// <summary> /// Reads a request for an update of the area specified by (x, y, w, h). /// <param name="fb">The server's current Framebuffer.</param> /// </summary> public void ReadFrameBufferUpdateRequest(Framebuffer fb) { try { bool incremental = Convert.ToBoolean((int)(reader.ReadByte())); ushort x = reader.ReadUInt16(); ushort y = reader.ReadUInt16(); ushort width = reader.ReadUInt16(); ushort height = reader.ReadUInt16(); //Console.WriteLine("FrameBufferUpdateRequest on x: " + x + " y: " + y + " w: " + width + " h:" + height); /*new Thread(delegate() { */ DoFrameBufferUpdate(fb, incremental, x, y, width, height); /*}).Start();*/ } catch (IOException ex) { Console.WriteLine(ex.Message); Close(); } }
/// <summary> /// Creates the encoded pixel data in a form of an EncodedRectangle with the preferred encoding. /// </summary> private void DoFrameBufferUpdate(Framebuffer fb, bool incremental, int x, int y, int width, int height) { //if (incremental) // return; Trace.WriteLine("X: " + x + " Y: " + y + " W: " + fb.Width + " H: " + fb.Height); int w = fb.Width; int h = fb.Height; if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { Trace.WriteLine("Neg:" + x + ":" + y + ":" + width + ":" + height); return; } if (x + width > w) { Trace.WriteLine("Too wide"); return; } if (y + height > h) { Trace.WriteLine("Too high"); return; } Trace.WriteLine("Bounds OK!"); HashSet<EncodedRectangle> rectangles = new HashSet<EncodedRectangle>(); try { Stopwatch tip = Stopwatch.StartNew(); EncodedRectangleFactory factory = new EncodedRectangleFactory(this, fb); ICollection<QuadNode> list = screenHandler.GetChange(); Trace.WriteLine(list.Count + " rectangles to encode"); foreach (QuadNode iter in list) { Trace.WriteLine(iter.ToString()); EncodedRectangle localRect = factory.Build(iter, GetPreferredEncoding()); localRect.Encode(); rectangles.Add(localRect); } Trace.WriteLine("Encoding took: " + tip.Elapsed); } catch (Exception localException) { Console.WriteLine(localException.StackTrace); if (localException is IOException) { Close(); return; } } if (rectangles.Count != 0) WriteFrameBufferUpdate(rectangles); }
/// <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."); var buffer = new Framebuffer(width, height); buffer.BitsPerPixel = Convert.ToInt32(b[0]); buffer.Depth = Convert.ToInt32(b[1]); buffer.BigEndian = b[2] != 0; buffer.TrueColor = b[3] != 0; buffer.RedMax = Convert.ToInt32(b[5] | b[4] << 8); buffer.GreenMax = Convert.ToInt32(b[7] | b[6] << 8); buffer.BlueMax = Convert.ToInt32(b[9] | b[8] << 8); buffer.RedShift = Convert.ToInt32(b[10]); buffer.GreenShift = Convert.ToInt32(b[11]); buffer.BlueShift = Convert.ToInt32(b[12]); // Last 3 bytes are padding, ignore return buffer; }