mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
287 lines
8.9 KiB
C#
287 lines
8.9 KiB
C#
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
using SDL3;
|
|
using ET = SDL3.SDL.SDL_EventType;
|
|
|
|
namespace Robust.Client.Graphics.Clyde;
|
|
|
|
internal partial class Clyde
|
|
{
|
|
private sealed partial class Sdl3WindowingImpl
|
|
{
|
|
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
|
|
private static unsafe byte EventWatch(void* userdata, SDL.SDL_Event* sdlevent)
|
|
{
|
|
var obj = (Sdl3WindowingImpl)GCHandle.FromIntPtr((IntPtr)userdata).Target!;
|
|
|
|
obj.ProcessSdl3Event(in *sdlevent);
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void ProcessSdl3Event(in SDL.SDL_Event ev)
|
|
{
|
|
switch ((ET)ev.type)
|
|
{
|
|
case ET.SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
|
ProcessSdl3EventWindowPixelSizeChanged(in ev.window);
|
|
break;
|
|
case ET.SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
|
ProcessSdl3EventWindowDisplayScaleChanged(in ev.window);
|
|
break;
|
|
case ET.SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
|
case ET.SDL_EVENT_WINDOW_MOUSE_ENTER:
|
|
case ET.SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
|
case ET.SDL_EVENT_WINDOW_MINIMIZED:
|
|
case ET.SDL_EVENT_WINDOW_RESTORED:
|
|
case ET.SDL_EVENT_WINDOW_FOCUS_GAINED:
|
|
case ET.SDL_EVENT_WINDOW_FOCUS_LOST:
|
|
case ET.SDL_EVENT_WINDOW_MOVED:
|
|
ProcessSdl3EventWindowMisc(in ev.window);
|
|
break;
|
|
case ET.SDL_EVENT_KEY_DOWN:
|
|
case ET.SDL_EVENT_KEY_UP:
|
|
ProcessSdl3KeyEvent(in ev.key);
|
|
break;
|
|
case ET.SDL_EVENT_TEXT_INPUT:
|
|
ProcessSdl3EventTextInput(in ev.text);
|
|
break;
|
|
case ET.SDL_EVENT_TEXT_EDITING:
|
|
ProcessSdl3EventTextEditing(in ev.edit);
|
|
break;
|
|
case ET.SDL_EVENT_KEYMAP_CHANGED:
|
|
ProcessSdl3EventKeyMapChanged();
|
|
break;
|
|
case ET.SDL_EVENT_MOUSE_MOTION:
|
|
ProcessSdl3EventMouseMotion(in ev.motion);
|
|
break;
|
|
case ET.SDL_EVENT_MOUSE_BUTTON_DOWN:
|
|
case ET.SDL_EVENT_MOUSE_BUTTON_UP:
|
|
ProcessSdl3EventMouseButton(in ev.button);
|
|
break;
|
|
case ET.SDL_EVENT_MOUSE_WHEEL:
|
|
ProcessSdl3EventMouseWheel(in ev.wheel);
|
|
break;
|
|
case ET.SDL_EVENT_DISPLAY_ADDED:
|
|
WinThreadSetupMonitor(ev.display.displayID);
|
|
break;
|
|
case ET.SDL_EVENT_DISPLAY_REMOVED:
|
|
WinThreadDestroyMonitor(ev.display.displayID);
|
|
break;
|
|
case ET.SDL_EVENT_QUIT:
|
|
ProcessSdl3EventQuit();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ProcessSdl3EventQuit()
|
|
{
|
|
SendEvent(new EventQuit());
|
|
}
|
|
|
|
private void ProcessSdl3EventMouseWheel(in SDL.SDL_MouseWheelEvent ev)
|
|
{
|
|
SendEvent(new EventWheel { WindowId = ev.windowID, XOffset = ev.x, YOffset = ev.y });
|
|
}
|
|
|
|
private void ProcessSdl3EventMouseButton(in SDL.SDL_MouseButtonEvent ev)
|
|
{
|
|
var mods = SDL.SDL_GetModState();
|
|
SendEvent(new EventMouseButton
|
|
{
|
|
WindowId = ev.windowID,
|
|
Type = ev.type,
|
|
Button = ev.button,
|
|
Mods = mods
|
|
});
|
|
}
|
|
|
|
private void ProcessSdl3EventMouseMotion(in SDL.SDL_MouseMotionEvent ev)
|
|
{
|
|
SendEvent(new EventMouseMotion
|
|
{
|
|
WindowId = ev.windowID,
|
|
X = ev.x,
|
|
Y = ev.y,
|
|
XRel = ev.xrel,
|
|
YRel = ev.yrel
|
|
});
|
|
}
|
|
|
|
private unsafe void ProcessSdl3EventTextInput(in SDL.SDL_TextInputEvent ev)
|
|
{
|
|
var str = Marshal.PtrToStringUTF8((IntPtr)ev.text) ?? "";
|
|
SendEvent(new EventText { WindowId = ev.windowID, Text = str });
|
|
}
|
|
|
|
private unsafe void ProcessSdl3EventTextEditing(in SDL.SDL_TextEditingEvent ev)
|
|
{
|
|
var str = Marshal.PtrToStringUTF8((IntPtr)ev.text) ?? "";
|
|
SendEvent(new EventTextEditing
|
|
{
|
|
WindowId = ev.windowID,
|
|
Text = str,
|
|
Start = ev.start,
|
|
Length = ev.length
|
|
});
|
|
}
|
|
|
|
private void ProcessSdl3EventKeyMapChanged()
|
|
{
|
|
ReloadKeyMap();
|
|
SendEvent(new EventKeyMapChanged());
|
|
}
|
|
|
|
private void ProcessSdl3KeyEvent(in SDL.SDL_KeyboardEvent ev)
|
|
{
|
|
SendEvent(new EventKey
|
|
{
|
|
WindowId = ev.windowID,
|
|
Scancode = ev.scancode,
|
|
Type = ev.type,
|
|
Repeat = ev.repeat,
|
|
Mods = ev.mod,
|
|
});
|
|
}
|
|
|
|
private void ProcessSdl3EventWindowPixelSizeChanged(in SDL.SDL_WindowEvent ev)
|
|
{
|
|
var window = SDL.SDL_GetWindowFromID(ev.windowID);
|
|
SDL.SDL_GetWindowSize(window, out var width, out var height);
|
|
var fbW = ev.data1;
|
|
var fbH = ev.data2;
|
|
|
|
SendEvent(new EventWindowPixelSize
|
|
{
|
|
WindowId = ev.windowID,
|
|
Width = width,
|
|
Height = height,
|
|
FramebufferWidth = fbW,
|
|
FramebufferHeight = fbH,
|
|
});
|
|
}
|
|
|
|
private void ProcessSdl3EventWindowDisplayScaleChanged(in SDL.SDL_WindowEvent ev)
|
|
{
|
|
var window = SDL.SDL_GetWindowFromID(ev.windowID);
|
|
var scale = SDL.SDL_GetWindowDisplayScale(window);
|
|
|
|
SendEvent(new EventWindowContentScale { WindowId = ev.windowID, Scale = scale });
|
|
}
|
|
|
|
private void ProcessSdl3EventWindowMisc(in SDL.SDL_WindowEvent ev)
|
|
{
|
|
SendEvent(new EventWindowMisc
|
|
{
|
|
WindowId = ev.windowID,
|
|
EventId = ev.type,
|
|
Data1 = ev.data1,
|
|
Data2 = ev.data2
|
|
});
|
|
}
|
|
|
|
private abstract class EventBase;
|
|
|
|
private sealed class EventWindowCreate : EventBase
|
|
{
|
|
public required Sdl3WindowCreateResult Result;
|
|
public required TaskCompletionSource<Sdl3WindowCreateResult> Tcs;
|
|
}
|
|
|
|
private sealed class EventKey : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public SDL.SDL_Scancode Scancode;
|
|
public ET Type;
|
|
public bool Repeat;
|
|
public SDL.SDL_Keymod Mods;
|
|
}
|
|
|
|
private sealed class EventMouseMotion : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public float X;
|
|
public float Y;
|
|
public float XRel;
|
|
public float YRel;
|
|
}
|
|
|
|
private sealed class EventMouseButton : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public ET Type;
|
|
public byte Button;
|
|
public SDL.SDL_Keymod Mods;
|
|
}
|
|
|
|
private sealed class EventText : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public required string Text;
|
|
}
|
|
|
|
private sealed class EventTextEditing : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public required string Text;
|
|
public int Start;
|
|
public int Length;
|
|
}
|
|
|
|
private sealed class EventWindowPixelSize : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public int Width;
|
|
public int Height;
|
|
public int FramebufferWidth;
|
|
public int FramebufferHeight;
|
|
}
|
|
|
|
private sealed class EventWindowContentScale : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public float Scale;
|
|
}
|
|
|
|
private sealed class EventWheel : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public float XOffset;
|
|
public float YOffset;
|
|
}
|
|
|
|
// SDL_WindowEvents that don't need any handling on the window thread itself.
|
|
private sealed class EventWindowMisc : EventBase
|
|
{
|
|
public uint WindowId;
|
|
public ET EventId;
|
|
public int Data1;
|
|
public int Data2;
|
|
}
|
|
|
|
private sealed class EventMonitorSetup : EventBase
|
|
{
|
|
public int Id;
|
|
public uint DisplayId;
|
|
public required string Name;
|
|
public VideoMode CurrentMode;
|
|
public required VideoMode[] AllModes;
|
|
}
|
|
|
|
private sealed class EventMonitorDestroy : EventBase
|
|
{
|
|
public int Id;
|
|
}
|
|
|
|
private sealed class EventKeyMapChanged : EventBase;
|
|
|
|
private sealed class EventQuit : EventBase;
|
|
|
|
#if MACOS
|
|
private sealed class EventWindowDestroyed : EventBase;
|
|
#endif
|
|
}
|
|
}
|