Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SDL3-CS #6374

Merged
merged 3 commits into from
Sep 16, 2024
Merged
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
2 changes: 1 addition & 1 deletion osu.Framework.Android/osu.Framework.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<ProjectReference Include="..\osu.Framework\osu.Framework.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.SDL3-CS.Android" Version="2024.807.1" />
<PackageReference Include="ppy.SDL3-CS.Android" Version="2024.916.0" />
<PackageReference Include="Xamarin.AndroidX.Window" Version="1.2.0.1" PrivateAssets="compile" />
</ItemGroup>
</Project>
7 changes: 3 additions & 4 deletions osu.Framework/Platform/SDL3/SDL3Clipboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,14 @@ private static unsafe bool trySetData(string mimeType, Func<ReadOnlyMemory<byte>
// TODO: support multiple mime types in a single callback
fixed (byte* ptr = Encoding.UTF8.GetBytes(mimeType + '\0'))
{
int ret = SDL_SetClipboardData(&dataCallback, &cleanupCallback, objectHandle.Handle, &ptr, 1);

if (ret < 0)
if (SDL_SetClipboardData(&dataCallback, &cleanupCallback, objectHandle.Handle, &ptr, 1) == SDL_bool.SDL_FALSE)
{
objectHandle.Dispose();
Logger.Log($"Failed to set clipboard data callback. SDL error: {SDL_GetError()}");
return false;
}

return ret == 0;
return true;
}
}

Expand Down
24 changes: 19 additions & 5 deletions osu.Framework/Platform/SDL3/SDL3Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ protected SDL3Window(GraphicsSurfaceType surfaceType, string appName)

SDL_SetHint(SDL_HINT_APP_NAME, appName);

if (SDL_Init(SDL_InitFlags.SDL_INIT_VIDEO | SDL_InitFlags.SDL_INIT_GAMEPAD) < 0)
if (SDL_Init(SDL_InitFlags.SDL_INIT_VIDEO | SDL_InitFlags.SDL_INIT_GAMEPAD) == SDL_bool.SDL_FALSE)
{
throw new InvalidOperationException($"Failed to initialise SDL: {SDL_GetError()}");
}
Expand Down Expand Up @@ -320,23 +320,23 @@ protected void HandleEventFromWatch(SDL_Event evt)
}

[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static int eventFilter(IntPtr userdata, SDL_Event* eventPtr)
private static SDL_bool eventFilter(IntPtr userdata, SDL_Event* eventPtr)
{
var handle = new ObjectHandle<SDL3Window>(userdata);
if (handle.GetTarget(out SDL3Window window))
window.HandleEventFromFilter(*eventPtr);

return 1;
return SDL_bool.SDL_TRUE;
}

[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static int eventWatch(IntPtr userdata, SDL_Event* eventPtr)
private static SDL_bool eventWatch(IntPtr userdata, SDL_Event* eventPtr)
{
var handle = new ObjectHandle<SDL3Window>(userdata);
if (handle.GetTarget(out SDL3Window window))
window.HandleEventFromWatch(*eventPtr);

return 1;
return SDL_bool.SDL_TRUE;
}

private bool firstDraw = true;
Expand Down Expand Up @@ -573,6 +573,20 @@ protected virtual void HandleEvent(SDL_Event e)
case SDL_EventType.SDL_EVENT_DROP_COMPLETE:
handleDropEvent(e.drop);
break;

case SDL_EventType.SDL_EVENT_PEN_DOWN:
case SDL_EventType.SDL_EVENT_PEN_UP:
handlePenTouchEvent(e.ptouch);
break;

case SDL_EventType.SDL_EVENT_PEN_BUTTON_DOWN:
case SDL_EventType.SDL_EVENT_PEN_BUTTON_UP:
handlePenButtonEvent(e.pbutton);
break;

case SDL_EventType.SDL_EVENT_PEN_MOTION:
handlePenMotionEvent(e.pmotion);
break;
}
}

Expand Down
114 changes: 108 additions & 6 deletions osu.Framework/Platform/SDL3/SDL3Window_Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public bool RelativeMouseMode
throw new InvalidOperationException($"Cannot set {nameof(RelativeMouseMode)} to true when the cursor is not hidden via {nameof(CursorState)}.");

relativeMouseMode = value;
ScheduleCommand(() => SDL_SetRelativeMouseMode(value ? SDL_bool.SDL_TRUE : SDL_bool.SDL_FALSE));
ScheduleCommand(() => SDL_SetWindowRelativeMouseMode(SDLWindowHandle, value ? SDL_bool.SDL_TRUE : SDL_bool.SDL_FALSE));
updateCursorConfinement();
}
}
Expand Down Expand Up @@ -151,7 +151,9 @@ private void enqueueJoystickButtonInput(JoystickButton button, bool isPressed)

private PointF previousPolledPoint = PointF.Empty;

private SDL_MouseButtonFlags pressedButtons;
private SDL_MouseButtonFlags mousePressedButtons;

private SDL_MouseButtonFlags penPressedButtons;

private void pollMouse()
{
Expand All @@ -170,7 +172,7 @@ private void pollMouse()
}

// a button should be released if it was pressed and its current global state differs (its bit in globalButtons is set to 0)
SDL_MouseButtonFlags buttonsToRelease = pressedButtons & (globalButtons ^ pressedButtons);
SDL_MouseButtonFlags buttonsToRelease = mousePressedButtons & (globalButtons ^ mousePressedButtons) & ~penPressedButtons;

// the outer if just optimises for the common case that there are no buttons to release.
if (buttonsToRelease != 0)
Expand All @@ -180,6 +182,8 @@ private void pollMouse()
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_RMASK)) MouseUp?.Invoke(MouseButton.Right);
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_X1MASK)) MouseUp?.Invoke(MouseButton.Button1);
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_X2MASK)) MouseUp?.Invoke(MouseButton.Button2);

mousePressedButtons &= ~buttonsToRelease;
}
}

Expand Down Expand Up @@ -437,20 +441,32 @@ private void handleMouseButtonEvent(SDL_MouseButtonEvent evtButton)
switch (evtButton.type)
{
case SDL_EventType.SDL_EVENT_MOUSE_BUTTON_DOWN:
pressedButtons |= mask;
if (penPressedButtons.HasFlagFast(mask))
{
Logger.Log("Mouse tried pressing a button already pressed by tablet!", level: LogLevel.Debug);
return;
}

mousePressedButtons |= mask;
MouseDown?.Invoke(button);
break;

case SDL_EventType.SDL_EVENT_MOUSE_BUTTON_UP:
pressedButtons &= ~mask;
if (!mousePressedButtons.HasFlagFast(mask))
{
Logger.Log("Mouse tried releasing a button already released by tablet!", level: LogLevel.Debug);
return;
}

mousePressedButtons &= ~mask;
MouseUp?.Invoke(button);
break;
}
}

private void handleMouseMotionEvent(SDL_MouseMotionEvent evtMotion)
{
if (SDL_GetRelativeMouseMode() == SDL_bool.SDL_FALSE)
if (SDL_GetWindowRelativeMouseMode(SDLWindowHandle) == SDL_bool.SDL_FALSE)
MouseMove?.Invoke(new Vector2(evtMotion.x * Scale, evtMotion.y * Scale));
else
MouseMoveRelative?.Invoke(new Vector2(evtMotion.xrel * Scale, evtMotion.yrel * Scale));
Expand Down Expand Up @@ -494,6 +510,55 @@ private void handleKeyboardEvent(SDL_KeyboardEvent evtKey)

private void handleKeymapChangedEvent() => KeymapChanged?.Invoke();

private void handlePenMotionEvent(SDL_PenMotionEvent evtPenMotion)
{
MouseMove?.Invoke(new Vector2(evtPenMotion.x * Scale, evtPenMotion.y * Scale));
}

private void handlePenTouchEvent(SDL_PenTouchEvent evtPenTouch)
{
if (evtPenTouch.eraser == SDL_bool.SDL_TRUE)
return;

handlePenPressEvent(0, evtPenTouch.down == SDL_bool.SDL_TRUE);
}

private void handlePenButtonEvent(SDL_PenButtonEvent evtPenButton)
{
handlePenPressEvent(evtPenButton.button, evtPenButton.down == SDL_bool.SDL_TRUE);
}

private void handlePenPressEvent(byte penButton, bool pressed)
{
mouseButtonFromPen(pressed, penButton, out MouseButton button, out SDL_MouseButtonFlags mask);

if (mask == 0)
return;

if (pressed)
{
if (mousePressedButtons.HasFlagFast(mask))
{
Logger.Log("Tablet tried pressing a button already pressed by mouse!", level: LogLevel.Debug);
return;
}

penPressedButtons |= mask;
MouseDown?.Invoke(button);
}
else
{
if (!penPressedButtons.HasFlagFast(mask))
{
Logger.Log("Tablet tried releasing a button already released by mouse!", level: LogLevel.Debug);
return;
}

penPressedButtons &= ~mask;
MouseUp?.Invoke(button);
}
}

private MouseButton mouseButtonFromEvent(SDLButton button)
{
switch (button)
Expand All @@ -519,6 +584,43 @@ private MouseButton mouseButtonFromEvent(SDLButton button)
}
}

private void mouseButtonFromPen(bool pressed, byte penButton, out MouseButton button, out SDL_MouseButtonFlags buttonFlag)
{
switch (penButton)
{
case 0:
button = MouseButton.Left;
buttonFlag = SDL_MouseButtonFlags.SDL_BUTTON_LMASK;
break;

case 1:
button = MouseButton.Right;
buttonFlag = SDL_MouseButtonFlags.SDL_BUTTON_RMASK;
break;

case 2:
button = MouseButton.Middle;
buttonFlag = SDL_MouseButtonFlags.SDL_BUTTON_MMASK;
break;

case 3:
button = MouseButton.Button1;
buttonFlag = SDL_MouseButtonFlags.SDL_BUTTON_X1MASK;
break;

case 4:
button = MouseButton.Button2;
buttonFlag = SDL_MouseButtonFlags.SDL_BUTTON_X2MASK;
break;

default:
Logger.Log($"unknown pen button index: {penButton}, ignoring...");
button = MouseButton.Button3;
buttonFlag = 0;
break;
}
}

#endregion

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions osu.Framework/Platform/SDL3/SDL3Window_Windowing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ private static unsafe bool tryGetDisplayFromSDL(int displayIndex, SDL_DisplayID

SDL_Rect rect;

if (SDL_GetDisplayBounds(displayID, &rect) < 0)
if (SDL_GetDisplayBounds(displayID, &rect) == SDL_bool.SDL_FALSE)
{
Logger.Log($"Failed to get display bounds for display at index ({displayIndex}). SDL Error: {SDL_GetError()}");
display = null;
Expand Down Expand Up @@ -874,14 +874,14 @@ private static unsafe SDL_DisplayMode getClosestDisplayMode(SDL_Window* windowHa

SDL_DisplayMode mode;

if (SDL_GetClosestFullscreenDisplayMode(displayID, size.Width, size.Height, requestedMode.RefreshRate, SDL_bool.SDL_TRUE, &mode) == 0)
if (SDL_GetClosestFullscreenDisplayMode(displayID, size.Width, size.Height, requestedMode.RefreshRate, SDL_bool.SDL_TRUE, &mode) == SDL_bool.SDL_TRUE)
return mode;

Logger.Log(
$"Unable to get preferred display mode (try #1/2). Target display: {display.Index}, mode: {size.Width}x{size.Height}@{requestedMode.RefreshRate}. SDL error: {SDL3Extensions.GetAndClearError()}");

// fallback to current display's native bounds
if (SDL_GetClosestFullscreenDisplayMode(displayID, display.Bounds.Width, display.Bounds.Height, 0f, SDL_bool.SDL_TRUE, &mode) != 0)
if (SDL_GetClosestFullscreenDisplayMode(displayID, display.Bounds.Width, display.Bounds.Height, 0f, SDL_bool.SDL_TRUE, &mode) == SDL_bool.SDL_TRUE)
return mode;

Logger.Log(
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/osu.Framework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<PackageReference Include="ppy.osuTK.NS20" Version="1.0.211" />
<PackageReference Include="StbiSharp" Version="1.1.0" />
<PackageReference Include="ppy.SDL2-CS" Version="1.0.741-alpha" />
<PackageReference Include="ppy.SDL3-CS" Version="2024.807.1" />
<PackageReference Include="ppy.SDL3-CS" Version="2024.916.0" />
<PackageReference Include="ppy.osu.Framework.SourceGeneration" Version="2023.720.0" />

<!-- DO NOT use ProjectReference for native packaging project.
Expand Down
Loading