X11Platform.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using Avalonia.Controls;
  5. using Avalonia.Controls.Platform;
  6. using Avalonia.FreeDesktop;
  7. using Avalonia.Input;
  8. using Avalonia.Input.Platform;
  9. using Avalonia.OpenGL;
  10. using Avalonia.Platform;
  11. using Avalonia.Rendering;
  12. using Avalonia.X11;
  13. using Avalonia.X11.Glx;
  14. using Avalonia.X11.NativeDialogs;
  15. using static Avalonia.X11.XLib;
  16. namespace Avalonia.X11
  17. {
  18. class AvaloniaX11Platform : IWindowingPlatform
  19. {
  20. private Lazy<KeyboardDevice> _keyboardDevice = new Lazy<KeyboardDevice>(() => new KeyboardDevice());
  21. public KeyboardDevice KeyboardDevice => _keyboardDevice.Value;
  22. public Dictionary<IntPtr, Action<XEvent>> Windows = new Dictionary<IntPtr, Action<XEvent>>();
  23. public XI2Manager XI2;
  24. public X11Info Info { get; private set; }
  25. public IX11Screens X11Screens { get; private set; }
  26. public IScreenImpl Screens { get; private set; }
  27. public X11PlatformOptions Options { get; private set; }
  28. public void Initialize(X11PlatformOptions options)
  29. {
  30. Options = options;
  31. XInitThreads();
  32. Display = XOpenDisplay(IntPtr.Zero);
  33. DeferredDisplay = XOpenDisplay(IntPtr.Zero);
  34. if (Display == IntPtr.Zero)
  35. throw new Exception("XOpenDisplay failed");
  36. XError.Init();
  37. Info = new X11Info(Display, DeferredDisplay);
  38. //TODO: log
  39. if (options.UseDBusMenu)
  40. DBusHelper.TryInitialize();
  41. AvaloniaLocator.CurrentMutable.BindToSelf(this)
  42. .Bind<IWindowingPlatform>().ToConstant(this)
  43. .Bind<IPlatformThreadingInterface>().ToConstant(new X11PlatformThreading(this))
  44. .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
  45. .Bind<IRenderLoop>().ToConstant(new RenderLoop())
  46. .Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Control))
  47. .Bind<IKeyboardDevice>().ToFunc(() => KeyboardDevice)
  48. .Bind<IStandardCursorFactory>().ToConstant(new X11CursorFactory(Display))
  49. .Bind<IClipboard>().ToConstant(new X11Clipboard(this))
  50. .Bind<IPlatformSettings>().ToConstant(new PlatformSettingsStub())
  51. .Bind<IPlatformIconLoader>().ToConstant(new X11IconLoader(Info))
  52. .Bind<ISystemDialogImpl>().ToConstant(new GtkSystemDialog())
  53. .Bind<IMountedVolumeInfoProvider>().ToConstant(new LinuxMountedVolumeInfoProvider());
  54. X11Screens = Avalonia.X11.X11Screens.Init(this);
  55. Screens = new X11Screens(X11Screens);
  56. if (Info.XInputVersion != null)
  57. {
  58. var xi2 = new XI2Manager();
  59. if (xi2.Init(this))
  60. XI2 = xi2;
  61. }
  62. if (options.UseGpu)
  63. {
  64. if (options.UseEGL)
  65. EglGlPlatformFeature.TryInitialize();
  66. else
  67. GlxGlPlatformFeature.TryInitialize(Info, Options.GlProfiles);
  68. }
  69. }
  70. public IntPtr DeferredDisplay { get; set; }
  71. public IntPtr Display { get; set; }
  72. public IWindowImpl CreateWindow()
  73. {
  74. return new X11Window(this, null);
  75. }
  76. public IEmbeddableWindowImpl CreateEmbeddableWindow()
  77. {
  78. throw new NotSupportedException();
  79. }
  80. }
  81. }
  82. namespace Avalonia
  83. {
  84. public class X11PlatformOptions
  85. {
  86. public bool UseEGL { get; set; }
  87. public bool UseGpu { get; set; } = true;
  88. public bool OverlayPopups { get; set; }
  89. public bool UseDBusMenu { get; set; }
  90. public bool UseDeferredRendering { get; set; } = true;
  91. public List<GlVersion> GlProfiles { get; set; } = new List<GlVersion>
  92. {
  93. new GlVersion(GlProfileType.OpenGL, 4, 0),
  94. new GlVersion(GlProfileType.OpenGL, 3, 2),
  95. new GlVersion(GlProfileType.OpenGL, 3, 0),
  96. new GlVersion(GlProfileType.OpenGLES, 3, 2),
  97. new GlVersion(GlProfileType.OpenGLES, 3, 0),
  98. new GlVersion(GlProfileType.OpenGLES, 2, 0)
  99. };
  100. public List<string> GlxRendererBlacklist { get; set; } = new List<string>
  101. {
  102. // llvmpipe is a software GL rasterizer. If it's returned by glGetString,
  103. // that usually means that something in the system is horribly misconfigured
  104. // and sometimes attempts to use GLX might cause a segfault
  105. "llvmpipe"
  106. };
  107. public string WmClass { get; set; } = Assembly.GetEntryAssembly()?.GetName()?.Name ?? "AvaloniaApplication";
  108. public bool? EnableMultiTouch { get; set; }
  109. }
  110. public static class AvaloniaX11PlatformExtensions
  111. {
  112. public static T UseX11<T>(this T builder) where T : AppBuilderBase<T>, new()
  113. {
  114. builder.UseWindowingSubsystem(() =>
  115. new AvaloniaX11Platform().Initialize(AvaloniaLocator.Current.GetService<X11PlatformOptions>() ??
  116. new X11PlatformOptions()));
  117. return builder;
  118. }
  119. public static void InitializeX11Platform(X11PlatformOptions options = null) =>
  120. new AvaloniaX11Platform().Initialize(options ?? new X11PlatformOptions());
  121. }
  122. }