/// <summary>Read an update rectangle from the server.</summary> /// <returns>A CCR task enumerator</returns> private async Task ReadRectangle() { var packet = new byte[12]; using (var cancellation = new CancellationTokenSource()) { cancellation.CancelAfter(DefaultTimeout); await this.ReadPacketAsync(packet, cancellation.Token); } var left = (packet[0] << 8) | packet[1]; var top = (packet[2] << 8) | packet[3]; var width = (packet[4] << 8) | packet[5]; var height = (packet[6] << 8) | packet[7]; var encoding = ConvertBigEndianU32(packet, 8); if (encoding != 0) { throw new InvalidDataException("Unexpected encoding"); } byte[] pixels; var size = width * height; switch (this.pixelFormat.BitsPerPixel) { case 8: pixels = new byte[size]; break; case 16: pixels = new byte[size * 2]; break; case 32: pixels = new byte[size * 4]; break; default: throw new InvalidDataException(); } var rectangle = new Rectangle(left, top, width, height, pixels); using (var cancellation = new CancellationTokenSource()) { cancellation.CancelAfter(DefaultTimeout); await this.ReadPacketAsync(pixels, cancellation.Token); } this.onRectangle(rectangle); }
/// <summary>Draws an update rectangle into the current frame buffer.</summary> /// <param name="rectangle">The rectangle to update.</param> private void OnRectangle(Rectangle rectangle) { if (!this.hasRectangle) { this.hasRectangle = true; this.FinishConnecting(); } var dest = this.frameBufferBitmap.PixelBuffer; var width = this.frameBufferBitmap.PixelWidth; var height = this.frameBufferBitmap.PixelHeight; var leftOffset = rectangle.Left * 4; var scan = rectangle.Width * 4; var src = WindowsRuntimeBufferExtensions.AsBuffer(rectangle.Pixels); for (int y = 0; y < rectangle.Height; y++) { var destOffset = ((y + rectangle.Top) * width * 4) + leftOffset; var srcOffset = y * scan; src.CopyTo((uint)srcOffset, dest, (uint)destOffset, (uint)scan); } this.frameBufferBitmap.Invalidate(); }
/// <summary>Handles an update to a rectangle in the frame buffer</summary> /// <remarks>This assumes that the rectangle is completely within the /// frame buffer dimensions and that the pixel format is BGR32</remarks> /// <param name="update">The update information</param> private void HandleRectangle(Rectangle update) { var rect = new Int32Rect( update.Left, update.Top, update.Width, update.Height); var array = update.Pixels; this.DoInvoke(() => this.Framebuffer.WritePixels( rect, array, rect.Width * 4, 0)); }