Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions samples/ControlCatalog.Desktop/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Fonts.Inter;
using Avalonia.Headless;
using Avalonia.LinuxFramebuffer;
using Avalonia.LinuxFramebuffer.Output;
using Avalonia.LogicalTree;
using Avalonia.Platform;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
using Avalonia.Vulkan;
Expand All @@ -21,6 +23,7 @@ namespace ControlCatalog.Desktop
static class Program
{
private static bool s_useFramebuffer;
private static bool s_useDrm;

[STAThread]
static int Main(string[] args)
Expand All @@ -29,6 +32,10 @@ static int Main(string[] args)
{
s_useFramebuffer = true;
}
if (args.Contains("--drm"))
{
s_useDrm = true;
}

if (args.Contains("--wait-for-attach"))
{
Expand All @@ -51,6 +58,21 @@ double GetScaling()
return scaling;
return 1;
}
SurfaceOrientation GetOrientation()
{
var idx = Array.IndexOf(args, "--orientation");
if (idx != 0 && args.Length > idx + 1 &&
Enum.TryParse<SurfaceOrientation>(args[idx + 1], true, out var orientation))
return orientation;
return SurfaceOrientation.Rotation0;
}
string GetCard()
{
var idx = Array.IndexOf(args, "--card");
if (idx != 0 && args.Length > idx + 1)
return args[idx + 1];
return null;
}
if (s_useFramebuffer)
{
SilenceConsole();
Expand Down Expand Up @@ -106,10 +128,14 @@ void FormatMem(string metric, long bytes)
})
.StartWithClassicDesktopLifetime(args);
}
else if (args.Contains("--drm"))
else if (s_useDrm)
{
SilenceConsole();
return builder.StartLinuxDrm(args, scaling: GetScaling());
return builder.StartLinuxDrm(args, card: GetCard(), options: new DrmOutputOptions()
{
Scaling = GetScaling(),
Orientation = GetOrientation(),
});
}
else if (args.Contains("--dxgi"))
{
Expand Down Expand Up @@ -151,7 +177,7 @@ public static AppBuilder BuildAvaloniaApp()
.WithInterFont()
.AfterSetup(builder =>
{
if (!s_useFramebuffer)
if (!s_useFramebuffer && !s_useDrm)
{
builder.Instance!.AttachDevTools(new Avalonia.Diagnostics.DevToolsOptions()
{
Expand Down
18 changes: 9 additions & 9 deletions src/Android/Avalonia.Android/Platform/AndroidScreens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void Refresh(Context context)
var orientation = displayContext.Resources?.Configuration?.Orientation;
if (orientation == AndroidOrientation.Square)
naturalOrientation = ScreenOrientation.None;
else if (rotation is SurfaceOrientation.Rotation0 or SurfaceOrientation.Rotation180)
else if (rotation is global::Android.Views.SurfaceOrientation.Rotation0 or global::Android.Views.SurfaceOrientation.Rotation180)
naturalOrientation = orientation == AndroidOrientation.Landscape ?
ScreenOrientation.Landscape :
ScreenOrientation.Portrait;
Expand All @@ -73,14 +73,14 @@ public void Refresh(Context context)
CurrentOrientation = (display.Rotation, naturalOrientation) switch
{
(_, ScreenOrientation.None) => ScreenOrientation.None,
(SurfaceOrientation.Rotation0, ScreenOrientation.Landscape) => ScreenOrientation.Landscape,
(SurfaceOrientation.Rotation90, ScreenOrientation.Landscape) => ScreenOrientation.Portrait,
(SurfaceOrientation.Rotation180, ScreenOrientation.Landscape) => ScreenOrientation.LandscapeFlipped,
(SurfaceOrientation.Rotation270, ScreenOrientation.Landscape) => ScreenOrientation.PortraitFlipped,
(SurfaceOrientation.Rotation0, _) => ScreenOrientation.Portrait,
(SurfaceOrientation.Rotation90, _) => ScreenOrientation.Landscape,
(SurfaceOrientation.Rotation180, _) => ScreenOrientation.PortraitFlipped,
(SurfaceOrientation.Rotation270, _) => ScreenOrientation.LandscapeFlipped,
(global::Android.Views.SurfaceOrientation.Rotation0, ScreenOrientation.Landscape) => ScreenOrientation.Landscape,
(global::Android.Views.SurfaceOrientation.Rotation90, ScreenOrientation.Landscape) => ScreenOrientation.Portrait,
(global::Android.Views.SurfaceOrientation.Rotation180, ScreenOrientation.Landscape) => ScreenOrientation.LandscapeFlipped,
(global::Android.Views.SurfaceOrientation.Rotation270, ScreenOrientation.Landscape) => ScreenOrientation.PortraitFlipped,
(global::Android.Views.SurfaceOrientation.Rotation0, _) => ScreenOrientation.Portrait,
(global::Android.Views.SurfaceOrientation.Rotation90, _) => ScreenOrientation.Landscape,
(global::Android.Views.SurfaceOrientation.Rotation180, _) => ScreenOrientation.PortraitFlipped,
(global::Android.Views.SurfaceOrientation.Rotation270, _) => ScreenOrientation.LandscapeFlipped,
_ => ScreenOrientation.Portrait
};
}
Expand Down
6 changes: 6 additions & 0 deletions src/Avalonia.Base/Platform/ISurfaceOrientation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Avalonia.Platform;

internal interface ISurfaceOrientation
{
SurfaceOrientation Orientation { get; }
}
9 changes: 9 additions & 0 deletions src/Avalonia.Base/Platform/SurfaceOrientation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Avalonia.Platform;

public enum SurfaceOrientation
{
Rotation0,
Rotation90,
Rotation180,
Rotation270,
}
2 changes: 1 addition & 1 deletion src/Avalonia.OpenGL/GlConsts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static class GlConsts
// public const int GL_LINE_STRIP = 0x0003;
public const int GL_TRIANGLES = 0x0004;
// public const int GL_TRIANGLE_STRIP = 0x0005;
// public const int GL_TRIANGLE_FAN = 0x0006;
public const int GL_TRIANGLE_FAN = 0x0006;
// public const int GL_QUADS = 0x0007;
// public const int GL_QUAD_STRIP = 0x0008;
// public const int GL_POLYGON = 0x0009;
Expand Down
2 changes: 2 additions & 0 deletions src/Avalonia.OpenGL/GlInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ public int GetUniformLocationString(int program, string name)
[GetProcAddress("glUniform1f")]
public partial void Uniform1f(int location, float falue);

[GetProcAddress("glUniform1i")]
public partial void Uniform1i(int location, int value);

[GetProcAddress("glUniformMatrix4fv")]
public partial void UniformMatrix4fv(int location, int count, bool transpose, void* value);
Expand Down
9 changes: 8 additions & 1 deletion src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Avalonia.Media;
using Avalonia.Platform;

namespace Avalonia.LinuxFramebuffer
{
Expand All @@ -12,7 +13,13 @@ public class DrmOutputOptions
/// Default: 1.0
/// </summary>
public double Scaling { get; set; } = 1.0;


/// <summary>
/// The orientation of the screen relative to the frame buffer memory orientation
/// Default: Normal
/// </summary>
public SurfaceOrientation Orientation { get; set; } = SurfaceOrientation.Rotation0;

/// <summary>
/// If true an two cycle buffer swapping is processed at init.
/// Default: True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Avalonia.LinuxFramebuffer
{
class FramebufferToplevelImpl : ITopLevelImpl, IScreenInfoProvider
class FramebufferToplevelImpl : ITopLevelImpl, IScreenInfoProvider, ISurfaceOrientation
{
private readonly IOutputBackend _outputBackend;
private readonly IInputBackend _inputBackend;
Expand Down Expand Up @@ -81,5 +81,7 @@ public void SetFrameThemeVariant(PlatformThemeVariant themeVariant) { }

public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 1, 1);
public object? TryGetFeature(Type featureType) => null;

SurfaceOrientation ISurfaceOrientation.Orientation => _outputBackend is ISurfaceOrientation surfaceOrientation ? surfaceOrientation.Orientation : SurfaceOrientation.Rotation0;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Platform;
using static Avalonia.LinuxFramebuffer.Input.LibInput.LibInputNativeUnsafeMethods;
namespace Avalonia.LinuxFramebuffer.Input.LibInput
{
Expand Down Expand Up @@ -30,9 +32,22 @@ private IInputRoot InputRoot
private unsafe void InputThread(IntPtr ctx, LibInputBackendOptions options)
{
var fd = libinput_get_fd(ctx);
IntPtr[] devices = [.. options.Events!.Select(f => libinput_path_add_device(ctx, f)).Where(d => d != IntPtr.Zero)];
var screenOrientation = _screen is ISurfaceOrientation surfaceOrientation ? surfaceOrientation.Orientation : SurfaceOrientation.Rotation0;

float[] matrix = screenOrientation switch
{
SurfaceOrientation.Rotation90 => [0, 1, 0, -1, 0, 1],
SurfaceOrientation.Rotation180 => [-1, 0, 1, 0, -1, 1],
SurfaceOrientation.Rotation270 => [0, -1, 1, 1, 0, 0],
_ => [1, 0, 0, 0, 1, 0], // Normal
};

foreach (var device in devices)
{
libinput_device_config_calibration_set_matrix(device, matrix);
}

foreach (var f in options.Events!)
libinput_path_add_device(ctx, f);
while (true)
{
IntPtr ev;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public static IntPtr libinput_path_create_context() =>
[DllImport(LibInput)]
public extern static IntPtr libinput_path_remove_device(IntPtr device);

[DllImport(LibInput)]
public extern static int libinput_device_config_calibration_set_matrix(IntPtr device, float[] matrix);

[DllImport(LibInput)]
public extern static int libinput_get_fd(IntPtr ctx);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ public TopLevel? TopLevel
{
get
{
EnsureTopLevel();
if (_topLevel == null)
{
EnsureTopLevel();
}
return _topLevel;
}
}
Expand Down
Loading
Loading