Skip to content

Commit bd202f6

Browse files
committed
Implement all APIs
1 parent 34aa1c0 commit bd202f6

14 files changed

+573
-97
lines changed

sources/Core/Core/Pointers/Ptr.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,20 @@ public T[] ToArray<T>(int length)
258258
)]
259259
public static explicit operator string(Ptr ptr) => ptr.ReadToString();
260260

261+
/// <summary>
262+
/// Casts the underlying pointer to a native-sized integer.
263+
/// </summary>
264+
/// <param name="ptr">The pointer.</param>
265+
/// <returns>The integer.</returns>
266+
public static explicit operator nint(Ptr ptr) => (nint)(void*)ptr;
267+
268+
/// <summary>
269+
/// Interprets the given native-sized integer as a pointer.
270+
/// </summary>
271+
/// <param name="ptr">The integer.</param>
272+
/// <returns>The pointer.</returns>
273+
public static explicit operator Ptr(nint ptr) => (void*)ptr;
274+
261275
/// <summary>
262276
/// Creates a null ptr
263277
/// </summary>

sources/Windowing/Windowing/IDisplay.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ public interface IDisplay : IEquatable<IDisplay>
3636

3737
/// <summary>
3838
/// Gets a list of video modes known to be available when this display is <see cref="ISurfaceDisplay.Current" />.
39-
/// It may be the case that a list of video modes can't be determined until that's the case.
39+
/// It may be the case that a list of video modes can't be determined until that's the case. Furthermore, if
40+
/// <see cref="ISurfaceWindow"/> is supported, <see cref="ISurfaceWindow.State"/> needs to be
41+
/// <see cref="WindowState.ExclusiveFullscreen"/> to get access to exclusive fullscreen video modes.
42+
/// <see cref="WindowState.WindowedFullscreen"/> may be acceptable if the backend supports implicitly switching
43+
/// between windowed and exclusive fullscreen states, but this is not a requirement.
4044
/// </summary>
4145
IReadOnlyList<VideoMode>? KnownVideoModes { get; }
4246

@@ -59,4 +63,9 @@ public interface IDisplay : IEquatable<IDisplay>
5963
/// An event raised when <see cref="KnownVideoModes" /> changes.
6064
/// </summary>
6165
event Action<DisplayVideoModeAvailabilityChangeEvent>? KnownVideoModesChanged;
66+
67+
/// <summary>
68+
/// An event raised when <see cref="VideoMode" /> changes.
69+
/// </summary>
70+
public event Action<VideoModeChangeEvent>? VideoModeChanged;
6271
}

sources/Windowing/Windowing/Helper.cs renamed to sources/Windowing/Windowing/Implementations/SDL3/Helper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
global using static Silk.NET.Windowing.Helper;
4+
global using static Silk.NET.Windowing.SDL3.Helper;
55
using System.Diagnostics;
66
using System.Diagnostics.CodeAnalysis;
77
using System.Runtime.CompilerServices;
88
using Silk.NET.SDL;
99

10-
namespace Silk.NET.Windowing;
10+
namespace Silk.NET.Windowing.SDL3;
1111

1212
internal static class Helper
1313
{

sources/Windowing/Windowing/Implementations/SDL3/SdlDisplay.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ internal Ptr<DisplayMode>[] DisplayModes
9797

9898
public event Action<DisplayCoordinatesEvent>? CoordinatesChanged;
9999
public event Action<DisplayVideoModeAvailabilityChangeEvent>? KnownVideoModesChanged;
100+
public event Action<VideoModeChangeEvent>? VideoModeChanged;
100101

101102
private bool Equals(SdlDisplay other) => Id == other.Id;
102103

sources/Windowing/Windowing/Implementations/SDL3/SdlEventProcessor.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ internal static class SdlEventProcessor
99
{
1010
private static BreakneckLock _lock;
1111
private static uint _emptyEvent;
12-
private static Dictionary<int, SdlSurface>? _surfaces;
12+
private static Dictionary<uint, SdlSurface>? _surfaces;
1313

1414
// Should be called on the event thread, but given that DeliverEvent can be called on any thread, we need to lock.
15-
public static void AddSurface(int id, SdlSurface surface)
15+
public static void AddSurface(uint id, SdlSurface surface)
1616
{
1717
var taken = false;
1818
_lock.Enter(ref taken);
@@ -27,7 +27,7 @@ public static void AddSurface(int id, SdlSurface surface)
2727
}
2828

2929
// Should be called on the event thread, but given that DeliverEvent can be called on any thread, we need to lock.
30-
public static void RemoveSurface(int id)
30+
public static void RemoveSurface(uint id)
3131
{
3232
var taken = false;
3333
_lock.Enter(ref taken);
@@ -131,7 +131,16 @@ public static void DeliverEvent(ref Event @event)
131131
case (uint)EventType.WindowFocusLost:
132132
break;
133133
case (uint)EventType.WindowCloseRequested:
134+
{
135+
if (
136+
(_surfaces?.TryGetValue(@event.Window.WindowID, out var surface) ?? false)
137+
&& surface.Window is { } window
138+
)
139+
{
140+
window.IsCloseRequested = true;
141+
}
134142
break;
143+
}
135144
case (uint)EventType.WindowHitTest:
136145
break;
137146
case (uint)EventType.WindowIccprofChanged:

sources/Windowing/Windowing/Implementations/SDL3/SdlSurface.cs

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,164 @@ protected internal override void OnTick()
8282

8383
public override void Terminate()
8484
{
85+
DebugPrint();
8586
var prev = _isTerminating;
8687
_isTerminating = true;
8788
if (!prev && _isTerminating)
8889
{
90+
DebugPrint("Raising Terminating.");
8991
Terminating?.Invoke(new SurfaceLifecycleEvent(this));
9092
}
9193
}
9294

9395
public override bool TryGetPlatformInfo<TPlatformInfo>(
9496
[NotNullWhen(true)] out TPlatformInfo? info
9597
)
96-
where TPlatformInfo : default => throw new NotImplementedException();
98+
where TPlatformInfo : default
99+
{
100+
info = default;
101+
if (!Impl.IsSurfaceInitialized)
102+
{
103+
return false;
104+
}
105+
106+
var props = Sdl.GetWindowProperties(Impl.Handle);
107+
if (typeof(TPlatformInfo) == typeof(CocoaPlatformInfo))
108+
{
109+
info = (TPlatformInfo)
110+
(object)
111+
new CocoaPlatformInfo(
112+
(nint)
113+
Sdl.GetPointerProperty(props, Sdl.PropWindowCocoaWindowPointer, nullptr)
114+
);
115+
Sdl.ClearError();
116+
return true;
117+
}
118+
119+
if (typeof(TPlatformInfo) == typeof(EGLPlatformInfo))
120+
{
121+
info = (TPlatformInfo)
122+
(object)
123+
new EGLPlatformInfo(
124+
(nint)Sdl.EGLGetCurrentDisplay(),
125+
(nint)Sdl.EGLGetWindowSurface(Impl.Handle)
126+
);
127+
Sdl.ClearError();
128+
return true;
129+
}
130+
131+
if (typeof(TPlatformInfo) == typeof(UIKitPlatformInfo))
132+
{
133+
info = (TPlatformInfo)
134+
(object)
135+
new UIKitPlatformInfo(
136+
(nint)
137+
Sdl.GetPointerProperty(
138+
props,
139+
Sdl.PropWindowUikitWindowPointer,
140+
nullptr
141+
),
142+
(uint)
143+
Sdl.GetNumberProperty(
144+
props,
145+
Sdl.PropWindowUikitOpenglFramebufferNumber,
146+
0
147+
),
148+
(uint)
149+
Sdl.GetNumberProperty(
150+
props,
151+
Sdl.PropWindowUikitOpenglRenderbufferNumber,
152+
0
153+
),
154+
(uint)
155+
Sdl.GetNumberProperty(
156+
props,
157+
Sdl.PropWindowUikitOpenglResolveFramebufferNumber,
158+
0
159+
)
160+
);
161+
Sdl.ClearError();
162+
return true;
163+
}
164+
165+
if (typeof(TPlatformInfo) == typeof(VivantePlatformInfo))
166+
{
167+
info = (TPlatformInfo)
168+
(object)
169+
new VivantePlatformInfo(
170+
(nint)
171+
Sdl.GetPointerProperty(
172+
props,
173+
Sdl.PropWindowVivanteDisplayPointer,
174+
nullptr
175+
),
176+
(nint)
177+
Sdl.GetPointerProperty(
178+
props,
179+
Sdl.PropWindowVivanteWindowPointer,
180+
nullptr
181+
)
182+
);
183+
Sdl.ClearError();
184+
return true;
185+
}
186+
187+
if (typeof(TPlatformInfo) == typeof(WaylandPlatformInfo))
188+
{
189+
info = (TPlatformInfo)
190+
(object)
191+
new WaylandPlatformInfo(
192+
(nint)
193+
Sdl.GetPointerProperty(
194+
props,
195+
Sdl.PropWindowWaylandDisplayPointer,
196+
nullptr
197+
),
198+
(nint)
199+
Sdl.GetPointerProperty(
200+
props,
201+
Sdl.PropWindowWaylandDisplayPointer,
202+
nullptr
203+
)
204+
);
205+
Sdl.ClearError();
206+
return true;
207+
}
208+
209+
if (typeof(TPlatformInfo) == typeof(Win32PlatformInfo))
210+
{
211+
info = (TPlatformInfo)
212+
(object)
213+
new Win32PlatformInfo(
214+
(nint)
215+
Sdl.GetPointerProperty(props, Sdl.PropWindowWin32HwndPointer, nullptr),
216+
(nint)Sdl.GetPointerProperty(props, Sdl.PropWindowWin32HdcPointer, nullptr),
217+
(nint)
218+
Sdl.GetPointerProperty(
219+
props,
220+
Sdl.PropWindowWin32InstancePointer,
221+
nullptr
222+
)
223+
);
224+
Sdl.ClearError();
225+
return true;
226+
}
227+
228+
if (typeof(TPlatformInfo) == typeof(X11PlatformInfo))
229+
{
230+
info = (TPlatformInfo)
231+
(object)
232+
new X11PlatformInfo(
233+
(nint)
234+
Sdl.GetPointerProperty(props, Sdl.PropWindowX11DisplayPointer, nullptr),
235+
(nint)Sdl.GetNumberProperty(props, Sdl.PropWindowX11WindowNumber, 0)
236+
);
237+
Sdl.ClearError();
238+
return true;
239+
}
240+
241+
return false;
242+
}
97243

98244
public void Dispose() => Impl.Dispose();
99245

sources/Windowing/Windowing/Implementations/SDL3/SdlSurfaceComponents.Display.cs

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -166,61 +166,72 @@ public VideoMode VideoMode
166166
}
167167
set
168168
{
169-
if (_videoMode == value)
169+
var currentState = State;
170+
if (
171+
currentState
172+
is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
173+
)
170174
{
171-
return;
172-
}
175+
if (value != default)
176+
{
177+
Throw();
178+
}
173179

174-
var display = (SdlDisplay)Current;
175-
if (!display.KnownVideoModes!.Contains(value))
176-
{
177-
throw new ArgumentException(
178-
"VideoMode was not one of the valid AvailableVideoModes.",
179-
nameof(value)
180-
);
180+
return;
181181
}
182182

183-
if (!IsSurfaceInitialized)
183+
if ((_videoMode = VideoMode) == value)
184184
{
185-
_videoMode = value;
186185
return;
187186
}
188187

189-
for (var i = 0; i < display.KnownVideoModes!.Count; i++)
188+
var display = (SdlDisplay)Current;
189+
Ptr<DisplayMode> displayMode = nullptr;
190+
var found = false;
191+
for (var i = 0; i < display.KnownVideoModes?.Count; i++)
190192
{
191193
if (display.KnownVideoModes[i] != value)
192194
{
193195
continue;
194196
}
195197

196-
if (
197-
!Sdl.SetWindowFullscreenMode(
198-
Handle,
199-
(Ref<DisplayMode>)(i == 0 ? nullptr : display.DisplayModes[i - 1])
200-
)
201-
)
198+
if (i > 0)
202199
{
203-
Sdl.ThrowError();
200+
displayMode = display.DisplayModes[i - 1];
204201
}
205202

206-
_videoMode = value;
203+
found = true;
207204
break;
208205
}
209206

210-
throw new InvalidOperationException(
211-
"Mismatch between display modes enumerated from the underlying API and the current display mode "
212-
+ "reported by the underlying API."
207+
if (!found)
208+
{
209+
Throw();
210+
}
211+
212+
SetState(
213+
currentState,
214+
value == default ? WindowState.WindowedFullscreen : WindowState.ExclusiveFullscreen,
215+
(value, displayMode),
216+
display
213217
);
218+
return;
219+
static void Throw() =>
220+
throw new ArgumentException(
221+
"The given video mode is not one of the AvailableVideoModes.",
222+
nameof(value)
223+
);
214224
}
215225
}
216226

217-
public IReadOnlyList<VideoMode> AvailableVideoModes => Current.KnownVideoModes ?? [default];
227+
public IReadOnlyList<VideoMode> AvailableVideoModes =>
228+
State is not (WindowState.ExclusiveFullscreen or WindowState.WindowedFullscreen)
229+
? [default]
230+
: Current.KnownVideoModes ?? [default];
218231

219232
public event Action<DisplayChangeEvent>? CurrentDisplayChanged;
220233
public event Action<DisplayAvailabilityChangeEvent>? AvailableChanged;
221234
public event Action<DisplayVideoModeAvailabilityChangeEvent>? AvailableVideoModesChanged;
222235

223-
private void PreInitializeDisplay() { }
224-
225236
private void InitializeDisplay(uint props) { }
226237
}

0 commit comments

Comments
 (0)