X11Framebuffer.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System;
  2. using Avalonia.Platform;
  3. namespace Avalonia.Gtk3
  4. {
  5. class X11Framebuffer : ILockedFramebuffer
  6. {
  7. private readonly IntPtr _display;
  8. private readonly IntPtr _xid;
  9. private IUnmanagedBlob _blob;
  10. public X11Framebuffer(IntPtr display, IntPtr xid, int width, int height, int factor)
  11. {
  12. _display = display;
  13. _xid = xid;
  14. Size = new PixelSize(width * factor, height * factor);
  15. RowBytes = Size.Width * 4;
  16. Dpi = new Vector(96, 96) * factor;
  17. Format = PixelFormat.Bgra8888;
  18. _blob = AvaloniaLocator.Current.GetService<IRuntimePlatform>().AllocBlob(RowBytes * Size.Height);
  19. Address = _blob.Address;
  20. }
  21. public void Dispose()
  22. {
  23. var image = new X11.XImage();
  24. int bitsPerPixel = 32;
  25. image.width = Size.Width;
  26. image.height = Size.Height;
  27. image.format = 2; //ZPixmap;
  28. image.data = Address;
  29. image.byte_order = 0;// LSBFirst;
  30. image.bitmap_unit = bitsPerPixel;
  31. image.bitmap_bit_order = 0;// LSBFirst;
  32. image.bitmap_pad = bitsPerPixel;
  33. image.depth = 24;
  34. image.bytes_per_line = RowBytes - Size.Width * 4;
  35. image.bits_per_pixel = bitsPerPixel;
  36. X11.XLockDisplay(_display);
  37. X11.XInitImage(ref image);
  38. var gc = X11.XCreateGC(_display, _xid, 0, IntPtr.Zero);
  39. X11.XPutImage(_display, _xid, gc, ref image, 0, 0, 0, 0, (uint)Size.Width, (uint)Size.Height);
  40. X11.XFreeGC(_display, gc);
  41. X11.XSync(_display, true);
  42. X11.XUnlockDisplay(_display);
  43. _blob.Dispose();
  44. }
  45. public IntPtr Address { get; }
  46. public PixelSize Size { get; }
  47. public int RowBytes { get; }
  48. public Vector Dpi { get; }
  49. public PixelFormat Format { get; }
  50. }
  51. }