Obliterate GLFW with an orbital strike

This commit is contained in:
PJB3005
2025-12-15 22:45:39 +01:00
parent b2bf5f9781
commit 095c5f58d9
54 changed files with 0 additions and 10640 deletions

View File

@@ -1,18 +0,0 @@
//
// Cursor.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Opaque handle to a GLFW cursor.
/// </summary>
public struct Cursor
{
}
}

View File

@@ -1,33 +0,0 @@
//
// ClientApi.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// The context client APIs.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintClientApi,ClientApi)"/>
public enum ClientApi
{
/// <summary>
/// No context API is created.
/// </summary>
NoApi = 0,
/// <summary>
/// OpenGL context is created.
/// </summary>
OpenGlApi = 0x00030001,
/// <summary>
/// OpenGL ES context is created.
/// </summary>
OpenGlEsApi = 0x00030002
}
}

View File

@@ -1,27 +0,0 @@
//
// ConnectedState.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Specifies connected state of devices.
/// </summary>
public enum ConnectedState
{
/// <summary>
/// Indicates that a device is connected.
/// </summary>
Connected = 0x00040001,
/// <summary>
/// Indicates that a device is disconnected.
/// </summary>
Disconnected = 0x00040002
}
}

View File

@@ -1,27 +0,0 @@
//
// ContextApi.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// The context API used to create the window context.
/// </summary>
public enum ContextApi
{
/// <summary>
/// Uses the native context API to create the window context.
/// </summary>
NativeContextApi = 0x00036001,
/// <summary>
/// Uses Egl to create the window context.
/// </summary>
EglContextApi = 0x00036002
}
}

View File

@@ -1,37 +0,0 @@
//
// CursorModeValue.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// The GLFW cursor modes.
/// See <a href="https://www.glfw.org/docs/latest/input_guide.html#cursor_mode">cursor modes</a>.
/// </summary>
public enum CursorModeValue
{
/// <summary>
/// The regular arrow cursor (or another cursor set with <see cref="GLFW.SetCursor"/>) is used
/// and cursor motion is not limited.
/// </summary>
CursorNormal = 0x00034001,
/// <summary>
/// Hides the arrow cursor when over a window.
/// </summary>
CursorHidden = 0x00034002,
/// <summary>
/// Will hide the cursor and lock it to the specified window.
/// GLFW will then take care of all the details of cursor re-centering and offset calculation
/// and providing the application with a virtual cursor position.
/// This virtual position is provided normally via both the cursor position callback and through polling.
/// </summary>
CursorDisabled = 0x00034003
}
}

View File

@@ -1,47 +0,0 @@
//
// CursorShape.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Standard cursor shapes.
/// </summary>
public enum CursorShape
{
/// <summary>
/// The standard arrow shape. Used in almost all situations.
/// </summary>
Arrow = 0x00036001,
/// <summary>
/// The I-Beam shape. Used when mousing over a place where text can be entered.
/// </summary>
IBeam = 0x00036002,
/// <summary>
/// The crosshair shape. Used when dragging and dropping.
/// </summary>
Crosshair = 0x00036003,
/// <summary>
/// The hand shape. Used when mousing over something that can be dragged around.
/// </summary>
Hand = 0x00036004,
/// <summary>
/// The horizontal resize shape. Used when mousing over something that can be horizontally resized.
/// </summary>
HResize = 0x00036005,
/// <summary>
/// The vertical resize shape. Used when mousing over something that can be vertically resized.
/// </summary>
VResize = 0x00036006
}
}

View File

@@ -1,24 +0,0 @@
//
// CursorStateAttribute.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Attribute for setting <see cref="CursorModeValue"/> of the cursor.
/// </summary>
/// <seealso cref="GLFW.SetInputMode(Window*,CursorStateAttribute,CursorModeValue)"/>
/// <seealso cref="GLFW.GetInputMode(Window*,CursorStateAttribute)"/>
public enum CursorStateAttribute
{
/// <summary>
/// Attribute for setting <see cref="CursorModeValue"/> of the cursor.
/// </summary>
Cursor = 0x00033001,
}
}

View File

@@ -1,103 +0,0 @@
//
// ErrorCode.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Error codes, used in the error callback.
/// </summary>
public enum ErrorCode
{
/// <summary>
/// Everything is running as intended. Yay!
/// </summary>
NoError = 0,
/// <summary>
/// Called a function before calling <see cref="GLFW.Init"/>. Initialize GLFW and then try again.
/// </summary>
NotInitialized = 0x00010001,
/// <summary>
/// No OpenGL/OpenGL ES context on this thread.
/// </summary>
NoContext = 0x00010002,
/// <summary>
/// Used an invalid enum value on a function.
/// </summary>
/// <remarks>
/// <para>
/// This should hopefully never happen in the bindings, due to the added type safety of C# enums VS. GLFW's native #defines
/// </para>
/// </remarks>
InvalidEnum = 0x00010003,
/// <summary>
/// Called a function with an invalid argument.
/// </summary>
/// <remarks>
/// <para>
/// This can happen if you request an OpenGL version that doesn't exist, like 2.7.
/// </para>
/// <para>
/// If you request a version of OpenGL that exists, but isn't supported by this graphics card, it will return VersionUnavailable instead.
/// </para>
/// </remarks>
InvalidValue = 0x00010004,
/// <summary>
/// A memory allocation failed on GLFW's end.
/// </summary>
/// <remarks>
/// <para>
/// Report this to the GLFW issue tracker if encountered.
/// </para>
/// </remarks>
OutOfMemory = 0x00010005,
/// <summary>
/// The requested API is not available on the system.
/// </summary>
ApiUnavailable = 0x00010006,
/// <summary>
/// The requested OpenGL version is not available on the system.
/// </summary>
VersionUnavailable = 0x00010007,
/// <summary>
/// A platform-specific error occurred that doesn't fit into any more specific category.
/// </summary>
/// <remarks>
/// <para>
/// Report this to the GLFW issue tracker if encountered.
/// </para>
/// </remarks>
PlatformError = 0x00010008,
/// <summary>
/// The requested format is unavailable.
/// </summary>
/// <remarks>
/// <para>
/// If emitted during window creation, the requested pixel format isn't available.
/// </para>
/// <para>
/// If emitted when using the clipboard, the contents of the clipboard couldn't be converted to the requested format.
/// </para>
/// </remarks>
FormatUnavailable = 0x00010009,
/// <summary>
/// There is no OpenGL/OpenGL ES context attached to this window.
/// </summary>
NoWindowContext = 0x0001000A
}
}

View File

@@ -1,46 +0,0 @@
//
// InitHint.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Initialization hints are set before <see cref="GLFW.Init"/> and affect how the library behaves until termination.
/// Hints are set with <see cref="GLFW.InitHint(InitHintBool, bool)"/>.
/// </summary>
public enum InitHintBool
{
/// <summary>
/// Used to specify whether to also expose joystick hats as buttons,
/// for compatibility with earlier versions of GLFW that did not have
/// <see cref="GLFW.GetJoystickHats"/>.
/// Set this with <see cref="GLFW.InitHint(InitHintBool, bool)"/>.
/// </summary>
JoystickHatButtons = 0x00050001,
/// <summary>
/// Used to specify whether to set the current directory to the application to the Contents/Resources
/// subdirectory of the application's bundle, if present.
/// Set this with <see cref="GLFW.InitHint(InitHintBool, bool)"/>.
/// </summary>
/// <remarks>
/// Only affects macOS; no effect on other platforms.
/// </remarks>
CocoaChdirResources = 0x00051001,
/// <summary>
/// Used to specify whether to create a basic menu bar, either from a nib or manually,
/// when the first window is created, which is when AppKit is initialized.
/// Set this with <see cref="GLFW.InitHint(InitHintBool, bool)"/>.
/// </summary>
/// <remarks>
/// Only affects macOS; no effect on other platforms.
/// </remarks>
CocoaMenubar = 0x00051002
}
}

View File

@@ -1,15 +0,0 @@
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Initialization hints are set before <see cref="GLFW.Init"/> and affect how the library behaves until termination.
/// Hints are set with <see cref="GLFW.InitHint(InitHintInt, int)"/>.
/// </summary>
/// <remarks>
/// While this enum has no members,
/// it can still be useful because it allows you to access the direct <c>glfwInitHint(int, int)</c> API.
/// In case a future version of GLFW adds an int-taking int hint and we don't handle it.
/// </remarks>
public enum InitHintInt
{
}
}

View File

@@ -1,33 +0,0 @@
//
// InputAction.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Defines event information for <see cref="GLFWCallbacks.KeyCallback"/>
/// or <see cref="GLFWCallbacks.MouseButtonCallback"/>.
/// </summary>
public enum InputAction : byte
{
/// <summary>
/// The key or mouse button was released.
/// </summary>
Release = 0,
/// <summary>
/// The key or mouse button was pressed.
/// </summary>
Press = 1,
/// <summary>
/// The key was held down until it repeated.
/// </summary>
Repeat = 2
}
}

View File

@@ -1,53 +0,0 @@
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Status of a joystick hat.
/// </summary>
public enum JoystickHats : byte
{
/// <summary>
/// Hat is centered.
/// </summary>
Centered = 0,
/// <summary>
/// Hat is pointing up.
/// </summary>
Up = 1,
/// <summary>
/// Hat is pointing right.
/// </summary>
Right = 2,
/// <summary>
/// Hat is pointing down.
/// </summary>
Down = 4,
/// <summary>
/// Hat is pointing left.
/// </summary>
Left = 8,
/// <summary>
/// Hat is pointing up and to the right.
/// </summary>
RightUp = Right | Up,
/// <summary>
/// Hat is pointing down and to the right.
/// </summary>
RightDown = Right | Down,
/// <summary>
/// Hat is pointing up and to the left.
/// </summary>
LeftUp = Left | Up,
/// <summary>
/// Hat is pointing down and to the left.
/// </summary>
LeftDown = Left | Down,
}
}

View File

@@ -1,50 +0,0 @@
//
// KeyModifiers.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
using System;
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Key modifiers, such as Shift or CTRL.
/// </summary>
[Flags]
public enum KeyModifiers : byte
{
/// <summary>
/// if one or more Shift keys were held down.
/// </summary>
Shift = 0x0001,
/// <summary>
/// If one or more Control keys were held down.
/// </summary>
Control = 0x0002,
/// <summary>
/// If one or more Alt keys were held down.
/// </summary>
Alt = 0x0004,
/// <summary>
/// If one or more Super keys were held down.
/// </summary>
Super = 0x0008,
/// <summary>
/// If caps lock is enabled.
/// </summary>
CapsLock = 0x0010,
/// <summary>
/// If num lock is enabled.
/// </summary>
NumLock = 0x0020,
}
}

View File

@@ -1,627 +0,0 @@
//
// Keys.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Specifies key codes and modifiers in US keyboard layout.
/// </summary>
public enum Keys : short
{
/// <summary>
/// An unknown key.
/// </summary>
Unknown = -1,
/// <summary>
/// The spacebar key.
/// </summary>
Space = 32,
/// <summary>
/// The apostrophe key.
/// </summary>
Apostrophe = 39 /* ' */,
/// <summary>
/// The comma key.
/// </summary>
Comma = 44 /* , */,
/// <summary>
/// The minus key.
/// </summary>
Minus = 45 /* - */,
/// <summary>
/// The period key.
/// </summary>
Period = 46 /* . */,
/// <summary>
/// The slash key.
/// </summary>
Slash = 47 /* / */,
/// <summary>
/// The 0 key.
/// </summary>
D0 = 48,
/// <summary>
/// The 1 key.
/// </summary>
D1 = 49,
/// <summary>
/// The 2 key.
/// </summary>
D2 = 50,
/// <summary>
/// The 3 key.
/// </summary>
D3 = 51,
/// <summary>
/// The 4 key.
/// </summary>
D4 = 52,
/// <summary>
/// The 5 key.
/// </summary>
D5 = 53,
/// <summary>
/// The 6 key.
/// </summary>
D6 = 54,
/// <summary>
/// The 7 key.
/// </summary>
D7 = 55,
/// <summary>
/// The 8 key.
/// </summary>
D8 = 56,
/// <summary>
/// The 9 key.
/// </summary>
D9 = 57,
/// <summary>
/// The semicolon key.
/// </summary>
Semicolon = 59 /* ; */,
/// <summary>
/// The equal key.
/// </summary>
Equal = 61 /* = */,
/// <summary>
/// The A key.
/// </summary>
A = 65,
/// <summary>
/// The B key.
/// </summary>
B = 66,
/// <summary>
/// The C key.
/// </summary>
C = 67,
/// <summary>
/// The D key.
/// </summary>
D = 68,
/// <summary>
/// The E key.
/// </summary>
E = 69,
/// <summary>
/// The F key.
/// </summary>
F = 70,
/// <summary>
/// The G key.
/// </summary>
G = 71,
/// <summary>
/// The H key.
/// </summary>
H = 72,
/// <summary>
/// The I key.
/// </summary>
I = 73,
/// <summary>
/// The J key.
/// </summary>
J = 74,
/// <summary>
/// The K key.
/// </summary>
K = 75,
/// <summary>
/// The L key.
/// </summary>
L = 76,
/// <summary>
/// The M key.
/// </summary>
M = 77,
/// <summary>
/// The N key.
/// </summary>
N = 78,
/// <summary>
/// The O key.
/// </summary>
O = 79,
/// <summary>
/// The P key.
/// </summary>
P = 80,
/// <summary>
/// The Q key.
/// </summary>
Q = 81,
/// <summary>
/// The R key.
/// </summary>
R = 82,
/// <summary>
/// The S key.
/// </summary>
S = 83,
/// <summary>
/// The T key.
/// </summary>
T = 84,
/// <summary>
/// The U key.
/// </summary>
U = 85,
/// <summary>
/// The V key.
/// </summary>
V = 86,
/// <summary>
/// The W key.
/// </summary>
W = 87,
/// <summary>
/// The X key.
/// </summary>
X = 88,
/// <summary>
/// The Y key.
/// </summary>
Y = 89,
/// <summary>
/// The Z key.
/// </summary>
Z = 90,
/// <summary>
/// The left bracket(opening bracket) key.
/// </summary>
LeftBracket = 91 /* [ */,
/// <summary>
/// The backslash.
/// </summary>
Backslash = 92 /* \ */,
/// <summary>
/// The right bracket(closing bracket) key.
/// </summary>
RightBracket = 93 /* ] */,
/// <summary>
/// The grave accent key.
/// </summary>
GraveAccent = 96 /* ` */,
/// <summary>
/// Non US keyboard layout key 1.
/// </summary>
World1 = 161 /* non-US #1 */,
/// <summary>
/// Non US keyboard layout key 2.
/// </summary>
World2 = 162 /* non-US #2 */,
/// <summary>
/// The escape key.
/// </summary>
Escape = 256,
/// <summary>
/// The enter key.
/// </summary>
Enter = 257,
/// <summary>
/// The tab key.
/// </summary>
Tab = 258,
/// <summary>
/// The backspace key.
/// </summary>
Backspace = 259,
/// <summary>
/// The insert key.
/// </summary>
Insert = 260,
/// <summary>
/// The delete key.
/// </summary>
Delete = 261,
/// <summary>
/// The right arrow key.
/// </summary>
Right = 262,
/// <summary>
/// The left arrow key.
/// </summary>
Left = 263,
/// <summary>
/// The down arrow key.
/// </summary>
Down = 264,
/// <summary>
/// The up arrow key.
/// </summary>
Up = 265,
/// <summary>
/// The page up key.
/// </summary>
PageUp = 266,
/// <summary>
/// The page down key.
/// </summary>
PageDown = 267,
/// <summary>
/// The home key.
/// </summary>
Home = 268,
/// <summary>
/// The end key.
/// </summary>
End = 269,
/// <summary>
/// The caps lock key.
/// </summary>
CapsLock = 280,
/// <summary>
/// The scroll lock key.
/// </summary>
ScrollLock = 281,
/// <summary>
/// The num lock key.
/// </summary>
NumLock = 282,
/// <summary>
/// The print screen key.
/// </summary>
PrintScreen = 283,
/// <summary>
/// The pause key.
/// </summary>
Pause = 284,
/// <summary>
/// The F1 key.
/// </summary>
F1 = 290,
/// <summary>
/// The F2 key.
/// </summary>
F2 = 291,
/// <summary>
/// The F3 key.
/// </summary>
F3 = 292,
/// <summary>
/// The F4 key.
/// </summary>
F4 = 293,
/// <summary>
/// The F5 key.
/// </summary>
F5 = 294,
/// <summary>
/// The F6 key.
/// </summary>
F6 = 295,
/// <summary>
/// The F7 key.
/// </summary>
F7 = 296,
/// <summary>
/// The F8 key.
/// </summary>
F8 = 297,
/// <summary>
/// The F9 key.
/// </summary>
F9 = 298,
/// <summary>
/// The F10 key.
/// </summary>
F10 = 299,
/// <summary>
/// The F11 key.
/// </summary>
F11 = 300,
/// <summary>
/// The F12 key.
/// </summary>
F12 = 301,
/// <summary>
/// The F13 key.
/// </summary>
F13 = 302,
/// <summary>
/// The F14 key.
/// </summary>
F14 = 303,
/// <summary>
/// The F15 key.
/// </summary>
F15 = 304,
/// <summary>
/// The F16 key.
/// </summary>
F16 = 305,
/// <summary>
/// The F17 key.
/// </summary>
F17 = 306,
/// <summary>
/// The F18 key.
/// </summary>
F18 = 307,
/// <summary>
/// The F19 key.
/// </summary>
F19 = 308,
/// <summary>
/// The F20 key.
/// </summary>
F20 = 309,
/// <summary>
/// The F21 key.
/// </summary>
F21 = 310,
/// <summary>
/// The F22 key.
/// </summary>
F22 = 311,
/// <summary>
/// The F23 key.
/// </summary>
F23 = 312,
/// <summary>
/// The F24 key.
/// </summary>
F24 = 313,
/// <summary>
/// The F25 key.
/// </summary>
F25 = 314,
/// <summary>
/// The 0 key on the key pad.
/// </summary>
KeyPad0 = 320,
/// <summary>
/// The 1 key on the key pad.
/// </summary>
KeyPad1 = 321,
/// <summary>
/// The 2 key on the key pad.
/// </summary>
KeyPad2 = 322,
/// <summary>
/// The 3 key on the key pad.
/// </summary>
KeyPad3 = 323,
/// <summary>
/// The 4 key on the key pad.
/// </summary>
KeyPad4 = 324,
/// <summary>
/// The 5 key on the key pad.
/// </summary>
KeyPad5 = 325,
/// <summary>
/// The 6 key on the key pad.
/// </summary>
KeyPad6 = 326,
/// <summary>
/// The 7 key on the key pad.
/// </summary>
KeyPad7 = 327,
/// <summary>
/// The 8 key on the key pad.
/// </summary>
KeyPad8 = 328,
/// <summary>
/// The 9 key on the key pad.
/// </summary>
KeyPad9 = 329,
/// <summary>
/// The decimal key on the key pad.
/// </summary>
KeyPadDecimal = 330,
/// <summary>
/// The divide key on the key pad.
/// </summary>
KeyPadDivide = 331,
/// <summary>
/// The multiply key on the key pad.
/// </summary>
KeyPadMultiply = 332,
/// <summary>
/// The subtract key on the key pad.
/// </summary>
KeyPadSubtract = 333,
/// <summary>
/// The add key on the key pad.
/// </summary>
KeyPadAdd = 334,
/// <summary>
/// The enter key on the key pad.
/// </summary>
KeyPadEnter = 335,
/// <summary>
/// The equal key on the key pad.
/// </summary>
KeyPadEqual = 336,
/// <summary>
/// The left shift key.
/// </summary>
LeftShift = 340,
/// <summary>
/// The left control key.
/// </summary>
LeftControl = 341,
/// <summary>
/// The left alt key.
/// </summary>
LeftAlt = 342,
/// <summary>
/// The left super key.
/// </summary>
LeftSuper = 343,
/// <summary>
/// The right shift key.
/// </summary>
RightShift = 344,
/// <summary>
/// The right control key.
/// </summary>
RightControl = 345,
/// <summary>
/// The right alt key.
/// </summary>
RightAlt = 346,
/// <summary>
/// The right super key.
/// </summary>
RightSuper = 347,
/// <summary>
/// The menu key.
/// </summary>
Menu = 348,
/// <summary>
/// The last valid key in this enum.
/// </summary>
LastKey = Menu
}
}

View File

@@ -1,68 +0,0 @@
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Specifies the buttons of a mouse.
/// </summary>
public enum MouseButton : byte
{
/// <summary>
/// The first button.
/// </summary>
Button1 = 0,
/// <summary>
/// The second button.
/// </summary>
Button2 = 1,
/// <summary>
/// The third button.
/// </summary>
Button3 = 2,
/// <summary>
/// The fourth button.
/// </summary>
Button4 = 3,
/// <summary>
/// The fifth button.
/// </summary>
Button5 = 4,
/// <summary>
/// The sixth button.
/// </summary>
Button6 = 5,
/// <summary>
/// The seventh button.
/// </summary>
Button7 = 6,
/// <summary>
/// The eighth button.
/// </summary>
Button8 = 7,
/// <summary>
/// The left mouse button. This corresponds to <see cref="Button1"/>.
/// </summary>
Left = Button1,
/// <summary>
/// The right mouse button. This corresponds to <see cref="Button2"/>.
/// </summary>
Right = Button2,
/// <summary>
/// The middle mouse button. This corresponds to <see cref="Button3"/>.
/// </summary>
Middle = Button3,
/// <summary>
/// The highest mouse button available.
/// </summary>
Last = Button8,
}
}

View File

@@ -1,32 +0,0 @@
//
// OpenGlProfile.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// The OpenGL context profiles.
/// </summary>
public enum OpenGlProfile
{
/// <summary>
/// Used for unknown OpenGL profile or OpenGL ES.
/// </summary>
Any = 0,
/// <summary>
/// Known OpenGL Core profile.
/// </summary>
Core = 0x00032001,
/// <summary>
/// Known OpenGL compatibility profile.
/// </summary>
Compat = 0x00032002
}
}

View File

@@ -1,33 +0,0 @@
//
// ReleaseBehavior.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// The context release behaviors.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintReleaseBehavior,ReleaseBehavior)"/>
public enum ReleaseBehavior
{
/// <summary>
/// Use the default release behavior of the platform.
/// </summary>
Any = 0,
/// <summary>
/// The pipeline will be flushed whenever the context is released from being the current one.
/// </summary>
Flush = 0x00035001,
/// <summary>
/// The pipeline will not be flushed on release.
/// </summary>
None = 0x00035002
}
}

View File

@@ -1,32 +0,0 @@
//
// Robustness.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// OpenGL context robustness strategy.
/// </summary>
public enum Robustness
{
/// <summary>
/// No context robustness strategy.
/// </summary>
NoRobustness = 0,
/// <summary>
/// Robust context without a reset notification.
/// </summary>
NoResetNotification = 0x00031001,
/// <summary>
/// Lose context on reset.
/// </summary>
LoseContextOnReset = 0x00031002
}
}

View File

@@ -1,29 +0,0 @@
//
// StickyAttributes.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Attributes related to sticky keys and buttons.
/// </summary>
/// <seealso cref="GLFW.SetInputMode(Window*,StickyAttributes,bool)"/>
/// <seealso cref="GLFW.GetInputMode(Window*,StickyAttributes)"/>
public enum StickyAttributes
{
/// <summary>
/// Specify whether keyboard input should be sticky or not.
/// </summary>
StickyKeys = 0x00033002,
/// <summary>
/// Specify whether mouse button input should be sticky or not.
/// </summary>
StickyMouseButtons = 0x00033003
}
}

View File

@@ -1,96 +0,0 @@
//
// WindowAttributeSetter.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Used to get window related attributes.
/// </summary>
/// <seealso cref="GLFW.GetWindowAttrib"/>
public enum WindowAttributeGetter
{
/// <summary>
/// Indicates whether the specified window has input focus.
/// Initial input focus is controlled by the window hint with the same name
/// </summary>
Focused = WindowHintBool.Focused,
/// <summary>
/// Indicates whether the specified window is iconified,
/// whether by the user or with <see cref="GLFW.IconifyWindow"/>.
/// </summary>
Iconified = WindowHintBool.Iconified,
/// <summary>
/// Indicates whether the specified window is resizable by the user.
/// This is set on creation with the window hint with the same name.
/// </summary>
Resizable = WindowHintBool.Resizable,
/// <summary>
/// Indicates whether the specified window is visible.
/// Window visibility can be controlled with <see cref="GLFW.ShowWindow"/> and <see cref="GLFW.HideWindow"/>
/// and initial visibility is controlled by the window hint with the same name.
/// </summary>
Visible = WindowHintBool.Visible,
/// <summary>
/// Indicates whether the specified window has decorations such as a border,a close widget, etc.
/// This is set on creation with the window hint with the same name.
/// </summary>
Decorated = WindowHintBool.Decorated,
/// <summary>
/// Specifies whether the full screen window will automatically iconify and restore
/// the previous video mode on input focus loss.
/// Possible values are <c>true</c> and <c>false</c>. This hint is ignored for windowed mode windows.
/// </summary>
AutoIconify = WindowHintBool.AutoIconify,
/// <summary>
/// Indicates whether the specified window is floating, also called topmost or always-on-top.
/// This is controlled by the window hint with the same name.
/// </summary>
Floating = WindowHintBool.Floating,
/// <summary>
/// Indicates whether the specified window is maximized,
/// whether by the user or with <see cref="GLFW.MaximizeWindow"/>.
/// </summary>
Maximized = WindowHintBool.Maximized,
/// <summary>
/// Specifies whether the cursor should be centered over newly created full screen windows.
/// Possible values are <c>true</c> and <c>false</c>. This hint is ignored for windowed mode windows.
/// </summary>
CenterCursor = WindowHintBool.CenterCursor,
/// <summary>
/// Specifies whether the window framebuffer will be transparent.
/// If enabled and supported by the system, the window framebuffer alpha channel will be used
/// to combine the framebuffer with the background.
/// This does not affect window decorations. Possible values are <c>true</c> and <c>false</c>.
/// </summary>
TransparentFramebuffer = WindowHintBool.TransparentFramebuffer,
/// <summary>
/// indicates whether the cursor is currently directly over the client area of the window,
/// with no other windows between.
/// See <a href="https://www.glfw.org/docs/3.3/input_guide.html#cursor_enter">Cursor enter/leave events</a>
/// for details.
/// </summary>
Hovered = WindowHintBool.Hovered,
/// <summary>
/// Specifies whether the window will be given input focus when <see cref="GLFW.ShowWindow"/> is called.
/// Possible values are <c>true</c> and <c>false</c>.
/// </summary>
FocusOnShow = WindowHintBool.FocusOnShow,
}
}

View File

@@ -1,49 +0,0 @@
//
// WindowAttributeSetter.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Used to set window related attributes.
/// </summary>
/// <seealso cref="GLFW.SetWindowAttrib"/>
public enum WindowAttributeSetter
{
/// <summary>
/// Indicates whether the specified window is resizable by the user.
/// This is set on creation with the window hint with the same name.
/// </summary>
Resizable = WindowHintBool.Resizable,
/// <summary>
/// Indicates whether the specified window has decorations such as a border,a close widget, etc.
/// This is set on creation with the window hint with the same name.
/// </summary>
Decorated = WindowHintBool.Decorated,
/// <summary>
/// Specifies whether the full screen window will automatically iconify and restore
/// the previous video mode on input focus loss.
/// Possible values are <c>true</c> and <c>false</c>. This hint is ignored for windowed mode windows.
/// </summary>
AutoIconify = WindowHintBool.AutoIconify,
/// <summary>
/// Indicates whether the specified window is floating, also called topmost or always-on-top.
/// This is controlled by the window hint with the same name.
/// </summary>
Floating = WindowHintBool.Floating,
/// <summary>
/// Specifies whether the window will be given input focus when <see cref="GLFW.ShowWindow"/> is called.
/// Possible values are <c>true</c> and <c>false</c>.
/// </summary>
FocusOnShow = WindowHintBool.FocusOnShow
}
}

View File

@@ -1,135 +0,0 @@
//
// WindowHintBool.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Context related boolean attributes.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintBool,bool)"/>
public enum WindowHintBool
{
/// <summary>
/// Indicates whether the specified window has input focus.
/// Initial input focus is controlled by the window hint with the same name
/// </summary>
Focused = 0x00020001,
/// <summary>
/// Indicates whether the specified window is iconified,
/// whether by the user or with <see cref="GLFW.IconifyWindow"/>.
/// </summary>
Iconified = 0x00020002,
/// <summary>
/// Indicates whether the specified window is resizable by the user.
/// This is set on creation with the window hint with the same name.
/// </summary>
Resizable = 0x00020003,
/// <summary>
/// Indicates whether the specified window is visible.
/// Window visibility can be controlled with <see cref="GLFW.ShowWindow"/> and <see cref="GLFW.HideWindow"/>
/// and initial visibility is controlled by the window hint with the same name.
/// </summary>
Visible = 0x00020004,
/// <summary>
/// Indicates whether the specified window has decorations such as a border,a close widget, etc.
/// This is set on creation with the window hint with the same name.
/// </summary>
Decorated = 0x00020005,
/// <summary>
/// Specifies whether the full screen window will automatically iconify and restore
/// the previous video mode on input focus loss.
/// Possible values are <c>true</c> and <c>false</c>. This hint is ignored for windowed mode windows.
/// </summary>
AutoIconify = 0x00020006,
/// <summary>
/// Indicates whether the specified window is floating, also called topmost or always-on-top.
/// This is controlled by the window hint with the same name.
/// </summary>
Floating = 0x00020007,
/// <summary>
/// Indicates whether the specified window is maximized,
/// whether by the user or with <see cref="GLFW.MaximizeWindow"/>.
/// </summary>
Maximized = 0x00020008,
/// <summary>
/// Specifies whether the cursor should be centered over newly created full screen windows.
/// Possible values are <c>true</c> and <c>false</c>. This hint is ignored for windowed mode windows.
/// </summary>
CenterCursor = 0x00020009,
/// <summary>
/// Specifies whether the window framebuffer will be transparent.
/// If enabled and supported by the system, the window framebuffer alpha channel will be used
/// to combine the framebuffer with the background.
/// This does not affect window decorations. Possible values are <c>true</c> and <c>false</c>.
/// </summary>
TransparentFramebuffer = 0x0002000A,
/// <summary>
/// Indicates whether the cursor is currently directly over the client area of the window,
/// with no other windows between.
/// See <a href="https://www.glfw.org/docs/3.3/input_guide.html#cursor_enter">Cursor enter/leave events</a>
/// for details.
/// </summary>
Hovered = 0x0002000B,
/// <summary>
/// Specifies whether the window will be given input focus when <see cref="GLFW.ShowWindow"/> is called.
/// Possible values are <c>true</c> and <c>false</c>.
/// </summary>
FocusOnShow = 0x0002000C,
/// <summary>
/// Specifies whether the window's context is an OpenGL forward-compatible one.
/// Possible values are <c>true</c> and <c>false</c>.
/// </summary>
OpenGLForwardCompat = 0x00022006,
/// <summary>
/// Specifies whether the window's context is an OpenGL debug context.
/// Possible values are <c>true</c> and <c>false</c>.
/// </summary>
OpenGLDebugContext = 0x00022007,
/// <summary>
/// Specifies whether errors should be generated by the context.
/// If enabled, situations that would have generated errors instead cause undefined behavior.
/// </summary>
ContextNoError = 0x0002200A,
/// <summary>
/// Specifies whether to use stereoscopic rendering. This is a hard constraint.
/// </summary>
Stereo = 0x0002100C,
/// <summary>
/// Specifies whether the framebuffer should be double buffered.
/// You nearly always want to use double buffering. This is a hard constraint.
/// </summary>
DoubleBuffer = 0x00021010,
/// <summary>
/// Specifies whether the framebuffer should be sRGB capable.
/// If supported, a created OpenGL context will support the
/// <c>GL_FRAMEBUFFER_SRGB</c> enable( also called <c>GL_FRAMEBUFFER_SRGB_EXT</c>)
/// for controlling sRGB rendering and a created OpenGL ES context will always have sRGB rendering enabled.
/// </summary>
SrgbCapable = 0x0002100E,
ScaleToMonitor = 0x0002200C,
}
}

View File

@@ -1,26 +0,0 @@
//
// WindowHintClientApi.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Context related client API attribute.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintClientApi,ClientApi)"/>
public enum WindowHintClientApi
{
/// <summary>
/// Indicates the client API provided by the window's context;
/// either <see cref="GraphicsLibraryFramework.ClientApi.OpenGlApi"/>,
/// <see cref="GraphicsLibraryFramework.ClientApi.OpenGlEsApi"/> or
/// <see cref="GraphicsLibraryFramework.ClientApi.NoApi"/>.
/// </summary>
ClientApi = 0x00022001,
}
}

View File

@@ -1,24 +0,0 @@
//
// WindowHintContextApi.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Used to specify the context creation API.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintContextApi,ContextApi)"/>
public enum WindowHintContextApi
{
/// <summary>
/// Indicates the context creation API used to create the window's context;
/// either <see cref="ContextApi.NativeContextApi"/> or <see cref="ContextApi.EglContextApi"/>.
/// </summary>
ContextCreationApi = 0x0002200B,
}
}

View File

@@ -1,117 +0,0 @@
//
// WindowHintInt.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Context related attributes.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintInt,int)"/>
public enum WindowHintInt
{
/// <summary>
/// Indicate the client API version(major part) of the window's context.
/// </summary>
ContextVersionMajor = 0x00022002,
/// <summary>
/// Indicate the client API version(minor part) of the window's context.
/// </summary>
ContextVersionMinor = 0x00022003,
/// <summary>
/// Indicate the client API version(revision part) of the window's context.
/// </summary>
ContextRevision = 0x00022004,
/// <summary>
/// Specify the desired bit depths of the red component of the default framebuffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
RedBits = 0x00021001,
/// <summary>
/// Specify the desired bit depths of the green component of the default framebuffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
GreenBits = 0x00021002,
/// <summary>
/// Specify the desired bit depths of the blue component of the default framebuffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
BlueBits = 0x00021003,
/// <summary>
/// Specify the desired bit depths of the alpha component of the default framebuffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
AlphaBits = 0x00021004,
/// <summary>
/// Specify the desired bit depths of the depth component of the default framebuffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
DepthBits = 0x00021005,
/// <summary>
/// Specify the desired bit depths of the stencil component of the default framebuffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
StencilBits = 0x00021006,
/// <summary>
/// Specify the desired bit depths of the red component of the accumulation buffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
/// <remarks>Accumulation buffers are a legacy OpenGL feature and should not be used in new code.</remarks>
AccumRedBits = 0x00021007,
/// <summary>
/// Specify the desired bit depths of the green component of the accumulation buffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
/// <remarks>Accumulation buffers are a legacy OpenGL feature and should not be used in new code.</remarks>
AccumGreenBits = 0x00021008,
/// <summary>
/// Specify the desired bit depths of the blue component of the accumulation buffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
/// <remarks>Accumulation buffers are a legacy OpenGL feature and should not be used in new code.</remarks>
AccumBlueBits = 0x00021009,
/// <summary>
/// Specify the desired bit depths of the alpha component of the accumulation buffer.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
/// <remarks>Accumulation buffers are a legacy OpenGL feature and should not be used in new code.</remarks>
AccumAlphaBits = 0x0002100A,
/// <summary>
/// Specifies the desired number of auxiliary buffers.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
/// <remarks>Auxiliary buffers are a legacy OpenGL feature and should not be used in new code.</remarks>
AuxBuffers = 0x0002100B,
/// <summary>
/// Specifies the desired number of samples to use for multisampling. Zero disables multisampling.
/// <see cref="GLFW.DontCare"/> means the application has no preference.
/// </summary>
Samples = 0x0002100D,
/// <summary>
/// Specifies the desired refresh rate for full screen windows.
/// If set to <see cref="GLFW.DontCare"/>,
/// the highest available refresh rate will be used. This hint is ignored for windowed mode windows.
/// </summary>
RefreshRate = 0x0002100F,
}
}

View File

@@ -1,29 +0,0 @@
//
// WindowHintOpenGlProfile.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Used to set the OpenGlProfile attribute.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintOpenGlProfile,OpenGlProfile)"/>
public enum WindowHintOpenGlProfile
{
/// <summary>
/// Indicates the OpenGL profile used by the context.
/// This is <see cref="GraphicsLibraryFramework.OpenGlProfile.Core"/>
/// or <see cref="GraphicsLibraryFramework.OpenGlProfile.Compat"/>
/// if the context uses a known profile, or <see cref="GraphicsLibraryFramework.OpenGlProfile.Any"/>
/// if the OpenGL profile is unknown or the context is an OpenGL ES context.
/// Note that the returned profile may not match the profile bits of the context flags,
/// as GLFW will try other means of detecting the profile when no bits are set. TODO: enum for missing crefs
/// </summary>
OpenGlProfile = 0x00022008,
}
}

View File

@@ -1,30 +0,0 @@
//
// WindowHintReleaseBehavior.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Used to specify the release behavior used by the local context.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintReleaseBehavior,ReleaseBehavior)"/>
public enum WindowHintReleaseBehavior
{
/// <summary>
/// Specifies the release behavior to be used by the context.
/// Possible values are one of <see cref="ReleaseBehavior.Any"/>,
/// <see cref="ReleaseBehavior.Flush"/> or <see cref="ReleaseBehavior.None"/>.
/// If the behavior is <see cref="ReleaseBehavior"/>, the default behavior
/// of the context creation API will be used.
/// If the behavior is <see cref="ReleaseBehavior.Flush"/>, the pipeline will be flushed
/// whenever the context is released from being the current one.
/// If the behavior is <see cref="ReleaseBehavior.None"/>, the pipeline will not be flushed on release.
/// </summary>
ContextReleaseBehavior = 0x00022009,
}
}

View File

@@ -1,25 +0,0 @@
//
// WindowHintRobustness.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Used to set context robustness attribute.
/// </summary>
/// <seealso cref="GLFW.WindowHint(WindowHintRobustness,Robustness)"/>
public enum WindowHintRobustness
{
/// <summary>
/// Indicates the robustness strategy used by the context.
/// This is <see cref="Robustness.LoseContextOnReset"/> or <see cref="Robustness.NoResetNotification"/>
/// if the window's context supports robustness, or <see cref="Robustness.NoRobustness"/> otherwise.
/// </summary>
ContextRobustness = 0x00022005,
}
}

View File

@@ -1,23 +0,0 @@
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Window hints for the WindowHintString function.
/// </summary>
public enum WindowHintString
{
/// <summary>
/// Sets the frame name on Cocoa. On any other platform, this does nothing.
/// </summary>
CocoaFrameName = 0x00023002,
/// <summary>
/// Sets the class name on X11. On any other platform, this does nothing.
/// </summary>
X11ClassName = 0x00024001,
/// <summary>
/// Sets the instance name on X11. on any other platform, this does nothing.
/// </summary>
X11InstanceName = 0x00024002,
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,180 +0,0 @@
//
// GLFWCallbacks.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
using System;
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Class containing GLFW related callbacks.
/// </summary>
public static unsafe class GLFWCallbacks
{
/// <summary>
/// The function signature for Unicode character callback functions.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="codepoint">The Unicode code point of the character.</param>
/// <seealso cref="GLFW.SetCharCallback"/>
public delegate void CharCallback(Window* window, uint codepoint);
/// <summary>
/// The function signature for Unicode character with modifiers callback functions.
/// It is called for each input character, regardless of what modifier keys are held down.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="codepoint">The Unicode code point of the character.</param>
/// <param name="modifiers">Bit field describing which modifier keys were held down.</param>
/// <seealso cref="GLFW.SetCharModsCallback"/>
public delegate void CharModsCallback(Window* window, uint codepoint, KeyModifiers modifiers);
/// <summary>
/// The function signature for cursor enter/leave callback functions.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="entered"><c>true</c> if the cursor entered the window's client area, or <c>false</c> if it left it.</param>
/// <seealso cref="GLFW.SetCursorEnterCallback"/>
public delegate void CursorEnterCallback(Window* window, bool entered);
/// <summary>
/// The function signature for cursor position callback functions.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="x">The new cursor x-coordinate, relative to the left edge of the client area.</param>
/// <param name="y">The new cursor y-coordinate, relative to the top edge of the client area.</param>
/// <seealso cref="GLFW.SetCursorPosCallback"/>
public delegate void CursorPosCallback(Window* window, double x, double y);
/// <summary>
/// The function signature for file drop callbacks.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="count">The number of dropped files.</param>
/// <param name="paths">The UTF-8 encoded file and/or directory path names.</param>
/// <seealso cref="GLFW.SetDropCallback"/>
public delegate void DropCallback(Window* window, int count, byte** paths);
/// <summary>
/// The function signature for joystick configuration callback functions.
/// </summary>
/// <param name="joystick">The joystick that was connected or disconnected.</param>
/// <param name="state">
/// One of <see cref="ConnectedState.Connected"/> or <see cref="ConnectedState.Disconnected"/>.
/// </param>
/// <seealso cref="GLFW.SetJoystickCallback"/>
public delegate void JoystickCallback(int joystick, ConnectedState state);
/// <summary>
/// The function signature for keyboard key callback functions.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="key">The keyboard key that was pressed or released.</param>
/// <param name="scanCode">The system-specific scancode of the key.</param>
/// <param name="action">The <see cref="InputAction"/> for that <paramref name="key"/>.</param>
/// <param name="mods">Bit field describing which modifier keys were held down.</param>
/// <seealso cref="GLFW.SetKeyCallback"/>
public delegate void KeyCallback(Window* window, Keys key, int scanCode, InputAction action, KeyModifiers mods);
/// <summary>
/// The function signature for mouse button callback functions.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="button">The mouse button that was pressed or released.</param>
/// <param name="action">One of <see cref="InputAction.Press"/> or <see cref="InputAction.Release"/>.</param>
/// <param name="mods">Bit field describing which modifier keys were held down.</param>
/// <seealso cref="GLFW.SetMouseButtonCallback"/>
public delegate void MouseButtonCallback(Window* window, MouseButton button, InputAction action, KeyModifiers mods); // TODO: Make enums for int params in callback
/// <summary>
/// The function signature for scroll callback functions.
/// </summary>
/// <param name="window">The window that received the event.</param>
/// <param name="offsetX">The scroll offset along the x-axis.</param>
/// <param name="offsetY">The scroll offset along the y-axis.</param>
/// <seealso cref="GLFW.SetScrollCallback"/>
public delegate void ScrollCallback(Window* window, double offsetX, double offsetY);
/// <summary>
/// The function signature for monitor configuration callback functions.
/// </summary>
/// <param name="monitor">The monitor that was connected or disconnected.</param>
/// <param name="state">
/// One <see cref="ConnectedState.Connected"/> of or <see cref="ConnectedState.Disconnected"/>.
/// </param>
/// <seealso cref="GLFW.SetMonitorCallback"/>
public delegate void MonitorCallback(Monitor* monitor, ConnectedState state);
/// <summary>
/// The function signature for window close callback functions.
/// </summary>
/// <param name="window">The window that the user attempted to close.</param>
/// <seealso cref="GLFW.SetWindowCloseCallback"/>
public delegate void WindowCloseCallback(Window* window);
/// <summary>
/// The function signature for window focus callback functions.
/// </summary>
/// <param name="window">The window that gained or lost input focus.</param>
/// <param name="focused"><c>true</c> if the window was given input focus, or <c>false</c> if it lost it.</param>
/// <seealso cref="GLFW.SetWindowFocusCallback"/>
public delegate void WindowFocusCallback(Window* window, bool focused);
/// <summary>
/// The function signature for window iconify/restore callback functions.
/// </summary>
/// <param name="window">The window that was iconified or restored.</param>
/// <param name="iconified"><c>true</c> if the window was iconified(minimized), or <c>false</c> if it was restored.</param>
/// <seealso cref="GLFW.SetWindowIconifyCallback"/>
public delegate void WindowIconifyCallback(Window* window, bool iconified);
/// <summary>
/// The function signature for window position callback functions.
/// </summary>
/// <param name="window">The window that was moved.</param>
/// <param name="x">
/// The new x-coordinate, in screen coordinates, of the upper-left corner of the client area of the window.
/// </param>
/// <param name="y">
/// The new y-coordinate, in screen coordinates, of the upper-left corner of the client area of the window.
/// </param>
/// <seealso cref="GLFW.SetWindowPosCallback"/>
public delegate void WindowPosCallback(Window* window, int x, int y);
/// <summary>
/// The function signature for window size callback functions.
/// </summary>
/// <param name="window">The window that was resized.</param>
/// <param name="width">The new width, in screen coordinates, of the window.</param>
/// <param name="height">The new height, in screen coordinates, of the window.</param>
/// <seealso cref="GLFW.SetWindowSizeCallback"/>
public delegate void WindowSizeCallback(Window* window, int width, int height);
/// <summary>
/// The function signature for error callback functions.
/// </summary>
/// <param name="error">An error code.</param>
/// <param name="description">A UTF-8 encoded string describing the error.</param>
public delegate void ErrorCallback(ErrorCode error, string description);
/// <summary>
/// The function signature for window refresh functions.
/// </summary>
/// <param name="window">The window that needs to be refreshed.</param>
public delegate void WindowRefreshCallback(Window* window);
/// <summary>
/// This is the function pointer type for window content scale callbacks.
/// </summary>
/// <param name="window">The window whose content scale changed. </param>
/// <param name="xscale">The new x-axis content scale of the window. </param>
/// <param name="yscale">The new y-axis content scale of the window.</param>
/// <seealso cref="GLFW.SetWindowContentScaleCallback"/>
public delegate void WindowContentScaleCallback(Window* window, float xscale, float yscale);
}
}

View File

@@ -1,65 +0,0 @@
//
// GLFWException.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
using System;
using System.Runtime.Serialization;
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Represents errors that occur within GLFW.
/// </summary>
[Serializable]
public class GLFWException : Exception
{
/// <summary>
/// Gets the underlying GLFW-error code.
/// </summary>
public ErrorCode ErrorCode { get; }
/// <summary>
/// Initializes a new instance of the <see cref="GLFWException"/> class.
/// </summary>
public GLFWException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GLFWException"/> class with the specified detailed description.
/// </summary>
/// <param name="message">A detailed description of the error.</param>
public GLFWException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GLFWException"/> class
/// with the specified detailed description and GLFW error code.
/// </summary>
/// <param name="message">A detailed description of the error.</param>
/// <param name="errorCode">The GLFW error code causing the exception.</param>
public GLFWException(string message, ErrorCode errorCode)
: base(message)
{
ErrorCode = errorCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="GLFWException"/> class with the specified detailed description
/// and the specified exception.
/// </summary>
/// <param name="message">A detailed description of the error.</param>
/// <param name="innerException">A reference to the inner exception that is the cause of this exception.</param>
public GLFWException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

View File

@@ -1,414 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace OpenToolkit.GraphicsLibraryFramework
{
internal static unsafe class GLFWNative
{
private const string LibraryName = "glfw3.dll";
public const int GLFW_TRUE = 1;
public const int GLFW_FALSE = 0;
#if NETCOREAPP
static GLFWNative()
{
// Register DllImport resolver so that the correct dynamic library is loaded on all platforms.
// On net472, we rely on Mono's DllMap for this. See the .dll.config file.
NativeLibrary.SetDllImportResolver(typeof(GLFWNative).Assembly, (name, assembly, path) =>
{
// Please keep in sync with what Robust.Shared/DllMapHelper.cs does.
if (name != "glfw3.dll")
{
return IntPtr.Zero;
}
string rName = null;
if (OperatingSystem.IsLinux() || OperatingSystem.IsFreeBSD()) rName = "libglfw.so.3";
else if (OperatingSystem.IsMacOS()) rName = "libglfw.3.dylib";
if ((rName != null) && NativeLibrary.TryLoad(rName, assembly, path, out var handle))
return handle;
return IntPtr.Zero;
});
}
#endif
[DllImport(LibraryName)]
public static extern int glfwInit();
[DllImport(LibraryName)]
public static extern void glfwTerminate();
[DllImport(LibraryName)]
public static extern void glfwInitHint(int hint, int value);
[DllImport(LibraryName)]
public static extern void glfwGetVersion(int* major, int* minor, int* revision);
[DllImport(LibraryName)]
public static extern byte* glfwGetVersionString();
[DllImport(LibraryName)]
public static extern ErrorCode glfwGetError(byte** description);
[DllImport(LibraryName)]
public static extern Monitor** glfwGetMonitors(int* count);
[DllImport(LibraryName)]
public static extern void glfwGetMonitorPos(Monitor* monitor, int* x, int* y);
[DllImport(LibraryName)]
public static extern void glfwGetMonitorPhysicalSize(Monitor* monitor, int* width, int* height);
[DllImport(LibraryName)]
public static extern void glfwGetMonitorContentScale(Monitor* monitor, float* xscale, float* yscale);
[DllImport(LibraryName)]
public static extern byte* glfwGetMonitorName(Monitor* monitor);
[DllImport(LibraryName)]
public static extern void glfwSetMonitorUserPointer(Monitor* monitor, void* pointer);
[DllImport(LibraryName)]
public static extern void* glfwGetMonitorUserPointer(Monitor* monitor);
[DllImport(LibraryName)]
public static extern VideoMode* glfwGetVideoModes(Monitor* monitor, int* count);
[DllImport(LibraryName)]
public static extern void glfwSetGamma(Monitor* monitor, float gamma);
[DllImport(LibraryName)]
public static extern GammaRamp* glfwGetGammaRamp(Monitor* monitor);
[DllImport(LibraryName)]
public static extern void glfwSetGammaRamp(Monitor* monitor, GammaRamp* ramp);
[DllImport(LibraryName)]
public static extern void glfwDefaultWindowHints();
[DllImport(LibraryName)]
public static extern void glfwWindowHintString(int hint, byte* value);
[DllImport(LibraryName)]
public static extern void glfwSetWindowSizeLimits(Window* window, int minwidth, int minheight, int maxwidth, int maxheight);
[DllImport(LibraryName)]
public static extern void glfwSetWindowAspectRatio(Window* window, int numer, int denom);
[DllImport(LibraryName)]
public static extern void glfwGetWindowFrameSize(Window* window, int* left, int* top, int* right, int* bottom);
[DllImport(LibraryName)]
public static extern void glfwGetWindowContentScale(Window* window, float* xscale, float* yscale);
[DllImport(LibraryName)]
public static extern float glfwGetWindowOpacity(Window* window);
[DllImport(LibraryName)]
public static extern void glfwSetWindowOpacity(Window* window, float opacity);
[DllImport(LibraryName)]
public static extern void glfwRequestWindowAttention(Window* window);
[DllImport(LibraryName)]
public static extern void glfwSetWindowAttrib(Window* window, WindowAttributeSetter attrib, int value);
[DllImport(LibraryName)]
public static extern int glfwRawMouseMotionSupported();
[DllImport(LibraryName)]
public static extern byte* glfwGetKeyName(Keys key, int scancode);
[DllImport(LibraryName)]
public static extern int glfwGetKeyScancode(Keys key);
[DllImport(LibraryName)]
public static extern InputAction glfwGetKey(Window* window, Keys key);
[DllImport(LibraryName)]
public static extern InputAction glfwGetMouseButton(Window* window, MouseButton button);
[DllImport(LibraryName)]
public static extern void glfwGetCursorPos(Window* window, double* xpos, double* ypos);
[DllImport(LibraryName)]
public static extern void glfwSetCursorPos(Window* window, double xpos, double ypos);
[DllImport(LibraryName)]
public static extern Cursor* glfwCreateCursor(Image* image, int xhot, int yhot);
[DllImport(LibraryName)]
public static extern Cursor* glfwCreateStandardCursor(CursorShape shape);
[DllImport(LibraryName)]
public static extern void glfwDestroyCursor(Cursor* cursor);
[DllImport(LibraryName)]
public static extern void glfwSetCursor(Window* window, Cursor* cursor);
[DllImport(LibraryName)]
public static extern int glfwJoystickPresent(int jid);
[DllImport(LibraryName)]
public static extern float* glfwGetJoystickAxes(int jid, int* count);
[DllImport(LibraryName)]
public static extern InputAction* glfwGetJoystickButtons(int jid, int* count);
[DllImport(LibraryName)]
public static extern JoystickHats* glfwGetJoystickHats(int jid, int* count);
[DllImport(LibraryName)]
public static extern byte* glfwGetJoystickName(int jid);
[DllImport(LibraryName)]
public static extern byte* glfwGetJoystickGUID(int jid);
[DllImport(LibraryName)]
public static extern void glfwSetJoystickUserPointer(int jid, void* ptr);
[DllImport(LibraryName)]
public static extern void* glfwGetJoystickUserPointer(int jid);
[DllImport(LibraryName)]
public static extern int glfwJoystickIsGamepad(int jid);
[DllImport(LibraryName)]
public static extern int glfwUpdateGamepadMappings(byte* newMapping);
[DllImport(LibraryName)]
public static extern byte* glfwGetGamepadName(int jid);
[DllImport(LibraryName)]
public static extern int glfwGetGamepadState(int jid, GamepadState* state);
[DllImport(LibraryName)]
public static extern double glfwGetTime();
[DllImport(LibraryName)]
public static extern void glfwSetTime(double time);
[DllImport(LibraryName)]
public static extern long glfwGetTimerValue();
[DllImport(LibraryName)]
public static extern long glfwGetTimerFrequency();
[DllImport(LibraryName)]
public static extern Window* glfwGetCurrentContext();
[DllImport(LibraryName)]
public static extern void glfwSwapBuffers(Window* window);
[DllImport(LibraryName)]
public static extern int glfwExtensionSupported(byte* extensionName);
[DllImport(LibraryName)]
public static extern IntPtr glfwGetProcAddress(byte* procame);
[DllImport(LibraryName)]
public static extern Window* glfwCreateWindow(int width, int height, byte* title, Monitor* monitor, Window* share);
[DllImport(LibraryName)]
public static extern Monitor* glfwGetPrimaryMonitor();
[DllImport(LibraryName)]
public static extern void glfwDestroyWindow(Window* window);
[DllImport(LibraryName)]
public static extern void glfwFocusWindow(Window* window);
[DllImport(LibraryName)]
public static extern void glfwGetFramebufferSize(Window* window, int* width, int* height);
[DllImport(LibraryName)]
public static extern CursorModeValue glfwGetInputMode(Window* window, CursorStateAttribute mode);
[DllImport(LibraryName)]
public static extern int glfwGetInputMode(Window* window, StickyAttributes mode);
[DllImport(LibraryName)]
public static extern void glfwRestoreWindow(Window* window);
[DllImport(LibraryName)]
public static extern VideoMode* glfwGetVideoMode(Monitor* monitor);
[DllImport(LibraryName)]
public static extern int glfwGetWindowAttrib(Window* window, WindowAttributeGetter attribute);
[DllImport(LibraryName)]
public static extern void glfwGetWindowSize(Window* window, int* width, int* height);
[DllImport(LibraryName)]
public static extern void glfwGetWindowPos(Window* window, int* x, int* y);
[DllImport(LibraryName)]
public static extern Monitor* glfwGetWindowMonitor(Window* window);
[DllImport(LibraryName)]
public static extern void glfwHideWindow(Window* window);
[DllImport(LibraryName)]
public static extern void glfwIconifyWindow(Window* window);
[DllImport(LibraryName)]
public static extern void glfwMakeContextCurrent(Window* window);
[DllImport(LibraryName)]
public static extern void glfwMaximizeWindow(Window* window);
[DllImport(LibraryName)]
public static extern void glfwPollEvents();
[DllImport(LibraryName)]
public static extern void glfwPostEmptyEvent();
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintInt hint, int value);
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintBool hint, int value);
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintClientApi hint, ClientApi value);
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintReleaseBehavior hint, ReleaseBehavior value);
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintContextApi hint, ContextApi value);
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintRobustness hint, Robustness value);
[DllImport(LibraryName)]
public static extern void glfwWindowHint(WindowHintOpenGlProfile hint, OpenGlProfile value);
[DllImport(LibraryName)]
public static extern int glfwWindowShouldClose(Window* window);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetCharCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetCharModsCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetCursorEnterCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetCursorPosCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetDropCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetErrorCallback(IntPtr callback);
[DllImport(LibraryName)]
public static extern void glfwSetInputMode(Window* window, CursorStateAttribute mode, CursorModeValue value);
[DllImport(LibraryName)]
public static extern void glfwSetInputMode(Window* window, StickyAttributes mode, int value);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetJoystickCallback(IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetKeyCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetScrollCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetMonitorCallback(IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetMouseButtonCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowCloseCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowFocusCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern void glfwSetWindowIcon(Window* window, int count, Image* images);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowIconifyCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowContentScaleCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern void glfwSetWindowTitle(Window* window, byte* title);
[DllImport(LibraryName)]
public static extern void glfwShowWindow(Window* window);
[DllImport(LibraryName)]
public static extern void glfwSetWindowSize(Window* window, int width, int height);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowSizeCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern void glfwSetWindowShouldClose(Window* window, int value);
[DllImport(LibraryName)]
public static extern void glfwSetWindowMonitor(Window* window, Monitor* monitor, int x, int y, int width, int height, int refreshRate);
[DllImport(LibraryName)]
public static extern void glfwSetWindowPos(Window* window, int x, int y);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowPosCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowRefreshCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern void glfwSwapInterval(int interval);
[DllImport(LibraryName)]
public static extern void glfwWaitEvents();
[DllImport(LibraryName)]
public static extern void glfwWaitEventsTimeout(double timeout);
[DllImport(LibraryName)]
public static extern byte* glfwGetClipboardString(Window* window);
[DllImport(LibraryName)]
public static extern void glfwSetClipboardString(Window* window, byte* data);
[DllImport(LibraryName)]
public static extern int glfwVulkanSupported();
[DllImport(LibraryName)]
public static extern byte** glfwGetRequiredInstanceExtensions(uint* count);
[DllImport(LibraryName)]
public static extern IntPtr glfwGetInstanceProcAddress(VkHandle instance, byte* procName);
[DllImport(LibraryName)]
public static extern int glfwGetPhysicalDevicePresentationSupport(VkHandle instance, VkHandle device, int queueFamily);
[DllImport(LibraryName)]
public static extern int glfwCreateWindowSurface(VkHandle instance, Window* window, void* allocator, VkHandle surface);
[DllImport(LibraryName)]
public static extern uint glfwGetX11Window(Window* window);
[DllImport(LibraryName)]
public static extern IntPtr glfwGetX11Display(Window* window);
[DllImport(LibraryName)]
public static extern IntPtr glfwGetWin32Window(Window* window);
}
}

View File

@@ -1,27 +0,0 @@
//
// GamepadState.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// This describes the input state of a gamepad.
/// </summary>
public struct GamepadState
{
/// <summary>
/// State of each of the 15 gamepad buttons, equal to <see cref="InputAction.Press"/> or <see cref="InputAction.Release"/>.
/// </summary>
public unsafe fixed byte Buttons[15];
/// <summary>
/// State of each of the 6 gamepad axes, ranging from -1.0 to 1.0.
/// </summary>
public unsafe fixed float Axes[6];
}
}

View File

@@ -1,37 +0,0 @@
//
// GammaRamp.cs
//
// Copyright (C) 2019 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Gamma ramp for a <see cref="Monitor"/>.
/// </summary>
public unsafe struct GammaRamp
{
/// <summary>
/// Red components of the gamma ramp.
/// </summary>
public ushort* Red;
/// <summary>
/// Green components of the gamma ramp.
/// </summary>
public ushort* Green;
/// <summary>
/// Blue components of the gamma ramp.
/// </summary>
public ushort* Blue;
/// <summary>
/// Length of the arrays.
/// </summary>
public uint Size;
}
}

View File

@@ -1,47 +0,0 @@
//
// Image.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
using System;
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Contains GLFW Image data.
/// </summary>
public unsafe struct Image
{
/// <summary>
/// Initializes a new instance of the <see cref="Image"/> struct.
/// </summary>
/// <param name="width">The width of the image in pixels.</param>
/// <param name="height">The height of the image in pixels.</param>
/// <param name="pixels"><see cref="IntPtr"/> pointing to the RGBA pixel data of the image.</param>
public Image(int width, int height, byte* pixels)
{
Width = width;
Height = height;
Pixels = pixels;
}
/// <summary>
/// The width, in pixels, of this <see cref="Image"/>.
/// </summary>
public int Width;
/// <summary>
/// The height, in pixels, of this <see cref="Image"/>.
/// </summary>
public int Height;
/// <summary>
/// A <see cref="byte"/> pointer pointing to the RGBA pixel data.
/// </summary>
public byte* Pixels;
}
}

View File

@@ -1,23 +0,0 @@
# MIT License
Copyright (c) 2006-2019 Stefanos Apostolopoulos for the Open Toolkit project.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
#### Third party licenses may be applicable. These have been disclosed in [THIRD_PARTIES.md](THIRD_PARTIES.md)

View File

@@ -1,18 +0,0 @@
//
// Monitor.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Opaque handle to a GLFW monitor.
/// </summary>
public struct Monitor
{
}
}

View File

@@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>9.0</LangVersion>
<SkipRobustAnalyzer>true</SkipRobustAnalyzer>
</PropertyGroup>
<Import Project="..\MSBuild\Robust.Properties.targets" />
</Project>

View File

@@ -1,20 +0,0 @@
# Third parties
## AdvancedDLSupport
> OpenTK uses AdvancedDLSupport for native interoperability. To enable compatibility with the LGPLv3 License, Firwood has given us a licensing exception.
* Read the [license grant](AdvancedDLSupport-LICENSE.pdf).
* Read the [license summary](Short-LICENSE.md) for an easy-to-understand version.
## OpenEXR
> OpenTK.Half offers Half-to-Single and Single-to-Half conversions based on OpenEXR source code, which is covered by the following license:
Copyright (c) 2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Industrial Light & Magic nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,50 +0,0 @@
//
// VideoMode.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
using System.Runtime.InteropServices;
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Replicated handle to a GLFW VideoMode.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VideoMode
{
/// <summary>
/// The width, in screen coordinates, of the <see cref="VideoMode"/>.
/// </summary>
public int Width;
/// <summary>
/// The height, in screen coordinates, of the <see cref="VideoMode"/>.
/// </summary>
public int Height;
/// <summary>
/// The bit depth of the red channel of the <see cref="VideoMode"/>.
/// </summary>
public int RedBits;
/// <summary>
/// The bit depth of the green channel of the <see cref="VideoMode"/>.
/// </summary>
public int GreenBits;
/// <summary>
/// The bit depth of the blue channel of the <see cref="VideoMode"/>.
/// </summary>
public int BlueBits;
/// <summary>
/// The refresh rate, in Hz, of the <see cref="VideoMode"/>.
/// </summary>
public int RefreshRate;
}
}

View File

@@ -1,29 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// A handle to a Vulkan object.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct VkHandle
{
/// <summary>
/// The actual value of the Vulkan handle.
/// </summary>
public IntPtr Handle;
/// <summary>
/// Initializes a new instance of the <see cref="VkHandle"/> struct.
/// </summary>
/// <param name="handle">
/// The native Vulkan handle.
/// This is NOT a pointer to a field containing the handle, this is the actual handle itself.
/// </param>
public VkHandle(IntPtr handle)
{
Handle = handle;
}
}
}

View File

@@ -1,18 +0,0 @@
//
// Window.cs
//
// Copyright (C) 2018 OpenTK
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Opaque handle to a GLFW window.
/// </summary>
public struct Window
{
}
}

View File

@@ -102,18 +102,11 @@ namespace Robust.Client.Graphics.Clyde
_windowingThread = Thread.CurrentThread;
// Default to SDL3 on ARM64. GLFW is not feature complete there (lacking file dialog implementation)
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
_cfg.SetCVar(CVars.DisplayWindowingApi, "sdl3");
var windowingApi = _cfg.GetCVar(CVars.DisplayWindowingApi);
IWindowingImpl winImpl;
switch (windowingApi)
{
case "glfw":
winImpl = new GlfwWindowingImpl(this, _deps);
break;
case "sdl3":
winImpl = new Sdl3WindowingImpl(this, _deps);
break;

View File

@@ -1,188 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Utility;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using GlfwImage = OpenToolkit.GraphicsLibraryFramework.Image;
namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private sealed unsafe partial class GlfwWindowingImpl
{
private readonly Dictionary<ClydeHandle, WinThreadCursorReg> _winThreadCursors = new();
private readonly Dictionary<StandardCursorShape, CursorImpl> _standardCursors = new();
public ICursor CursorGetStandard(StandardCursorShape shape)
{
return _standardCursors[shape];
}
public ICursor CursorCreate(Image<Rgba32> image, Vector2i hotSpot)
{
var cloneImg = new Image<Rgba32>(image.Width, image.Height);
image.GetPixelSpan().CopyTo(cloneImg.GetPixelSpan());
var id = _clyde.AllocRid();
SendCmd(new CmdCursorCreate(cloneImg, hotSpot, id));
return new CursorImpl(this, id, false);
}
private void WinThreadCursorCreate(CmdCursorCreate cmd)
{
var (img, (hotX, hotY), id) = cmd;
fixed (Rgba32* pixPtr = img.GetPixelSpan())
{
var gImg = new GlfwImage(img.Width, img.Height, (byte*) pixPtr);
var ptr = GLFW.CreateCursor(gImg, hotX, hotY);
_winThreadCursors.Add(id, new WinThreadCursorReg {Ptr = ptr});
}
img.Dispose();
}
public void CursorSet(WindowReg window, ICursor? cursor)
{
CheckWindowDisposed(window);
var reg = (GlfwWindowReg) window;
if (reg.Cursor == cursor)
{
// Nothing has to be done!
return;
}
if (cursor == null)
{
reg.Cursor = null;
SendCmd(new CmdWinCursorSet((nint) reg.GlfwWindow, default));
return;
}
var impl = (CursorImpl) cursor;
DebugTools.Assert(impl.Owner == this);
if (impl.Id == default)
{
throw new ObjectDisposedException(nameof(cursor));
}
reg.Cursor = impl;
SendCmd(new CmdWinCursorSet((nint) reg.GlfwWindow, impl.Id));
}
private void WinThreadWinCursorSet(CmdWinCursorSet cmd)
{
var window = (Window*) cmd.Window;
Cursor* ptr = null;
if (cmd.Cursor != default)
ptr = _winThreadCursors[cmd.Cursor].Ptr;
#if DEBUG
if (_win32Experience)
{
// Based on a true story.
Thread.Sleep(15);
}
#endif
GLFW.SetCursor(window, ptr);
}
private void WinThreadCursorDestroy(CmdCursorDestroy cmd)
{
var cursorReg = _winThreadCursors[cmd.Cursor];
GLFW.DestroyCursor(cursorReg.Ptr);
_winThreadCursors.Remove(cmd.Cursor);
}
private void InitCursors()
{
// Gets ran on window thread don't worry about it.
void AddStandardCursor(StandardCursorShape standardShape, CursorShape shape)
{
var id = _clyde.AllocRid();
var ptr = GLFW.CreateStandardCursor(shape);
var impl = new CursorImpl(this, id, true);
_standardCursors.Add(standardShape, impl);
_winThreadCursors.Add(id, new WinThreadCursorReg {Ptr = ptr});
}
AddStandardCursor(StandardCursorShape.Arrow, CursorShape.Arrow);
AddStandardCursor(StandardCursorShape.IBeam, CursorShape.IBeam);
AddStandardCursor(StandardCursorShape.Crosshair, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.Hand, CursorShape.Hand);
AddStandardCursor(StandardCursorShape.HResize, CursorShape.HResize);
AddStandardCursor(StandardCursorShape.VResize, CursorShape.VResize);
AddStandardCursor(StandardCursorShape.Progress, CursorShape.Arrow);
AddStandardCursor(StandardCursorShape.NWSEResize, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.NESWResize, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.Move, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.NotAllowed, CursorShape.Arrow);
AddStandardCursor(StandardCursorShape.NWResize, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.NResize, CursorShape.VResize);
AddStandardCursor(StandardCursorShape.NEResize, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.EResize, CursorShape.HResize);
AddStandardCursor(StandardCursorShape.SEResize, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.SResize, CursorShape.VResize);
AddStandardCursor(StandardCursorShape.SWResize, CursorShape.Crosshair);
AddStandardCursor(StandardCursorShape.WResize, CursorShape.HResize);
}
private sealed class CursorImpl : ICursor
{
private readonly bool _standard;
public GlfwWindowingImpl Owner { get; }
public ClydeHandle Id { get; private set; }
public CursorImpl(GlfwWindowingImpl clyde, ClydeHandle id, bool standard)
{
_standard = standard;
Owner = clyde;
Id = id;
}
~CursorImpl()
{
DisposeImpl();
}
private void DisposeImpl()
{
Owner.SendCmd(new CmdCursorDestroy(Id));
Id = default;
}
public void Dispose()
{
if (_standard)
{
throw new InvalidOperationException("Can't dispose standard cursor shape.");
}
GC.SuppressFinalize(this);
DisposeImpl();
}
}
public sealed class WinThreadCursorReg
{
public Cursor* Ptr;
}
}
}
}

View File

@@ -1,271 +0,0 @@
using System;
using System.Numerics;
using System.Text;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Input;
using Robust.Shared.Map;
namespace Robust.Client.Graphics.Clyde
{
partial class Clyde
{
private partial class GlfwWindowingImpl
{
public void ProcessEvents(bool single=false)
{
while (_eventReader.TryRead(out var ev))
{
try
{
ProcessEvent(ev);
}
catch (Exception e)
{
_sawmill.Error($"Caught exception in windowing event ({ev.GetType()}):\n{e}");
}
if (single)
break;
}
}
// Block waiting on the windowing -> game thread channel.
// I swear to god do not use this unless you know what you are doing.
private void WaitEvents()
{
_eventReader.WaitToReadAsync().AsTask().Wait();
}
private void ProcessEvent(EventBase evb)
{
switch (evb)
{
case EventMouseButton mb:
ProcessEventMouseButton(mb);
break;
case EventCursorPos cp:
ProcessEventCursorPos(cp);
break;
case EventCursorEnter ev:
ProcessEventCursorEnter(ev);
break;
case EventScroll s:
ProcessEventScroll(s);
break;
case EventKey k:
ProcessEventKey(k);
break;
case EventChar c:
ProcessEventChar(c);
break;
case EventMonitorSetup ms:
ProcessSetupMonitor(ms);
break;
case EventMonitorDestroy md:
ProcessEventDestroyMonitor(md);
break;
case EventWindowCreate wCreate:
FinishWindowCreate(wCreate);
break;
case EventWindowClose wc:
ProcessEventWindowClose(wc);
break;
case EventWindowFocus wf:
ProcessEventWindowFocus(wf);
break;
case EventWindowSize ws:
ProcessEventWindowSize(ws);
break;
case EventWindowPos wp:
ProcessEventWindowPos(wp);
break;
case EventWindowIconify wi:
ProcessEventWindowIconify(wi);
break;
case EventWindowContentScale cs:
ProcessEventWindowContentScale(cs);
break;
case EventSetFullscreenAck:
ProcessEventSetFullscreenAck();
break;
default:
_sawmill.Error($"Unknown GLFW event type: {evb.GetType()}");
break;
}
}
private void ProcessEventChar(EventChar ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg is not { TextInputActive: true })
return;
_clyde.SendText(new TextEnteredEventArgs(new Rune(ev.CodePoint).ToString()));
}
private void ProcessEventCursorPos(EventCursorPos ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
var newPos = new Vector2((float) ev.XPos, (float) ev.YPos) * windowReg.PixelRatio;
var delta = newPos - windowReg.LastMousePos;
windowReg.LastMousePos = newPos;
_clyde._currentHoveredWindow = windowReg;
_clyde.SendMouseMove(new MouseMoveEventArgs(delta, new ScreenCoordinates(newPos, windowReg.Id)));
}
private void ProcessEventCursorEnter(EventCursorEnter ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
if (ev.Entered)
{
_clyde._currentHoveredWindow = windowReg;
}
else if (_clyde._currentHoveredWindow == windowReg)
{
_clyde._currentHoveredWindow = null;
}
_clyde.SendMouseEnterLeave(new MouseEnterLeaveEventArgs(windowReg.Handle, ev.Entered));
}
private void ProcessEventKey(EventKey ev)
{
EmitKeyEvent(ConvertGlfwKey(ev.Key), ev.Action, ev.Mods, ev.ScanCode);
}
private void EmitKeyEvent(Keyboard.Key key, InputAction action, KeyModifiers mods, int scanCode)
{
var shift = (mods & KeyModifiers.Shift) != 0;
var alt = (mods & KeyModifiers.Alt) != 0;
var control = (mods & KeyModifiers.Control) != 0;
var system = (mods & KeyModifiers.Super) != 0;
var ev = new KeyEventArgs(
key,
action == InputAction.Repeat,
alt, control, shift, system,
scanCode);
switch (action)
{
case InputAction.Release:
_clyde.SendKeyUp(ev);
break;
case InputAction.Press:
case InputAction.Repeat:
_clyde.SendKeyDown(ev);
break;
default:
throw new ArgumentOutOfRangeException(nameof(action), action, null);
}
}
private void ProcessEventMouseButton(EventMouseButton ev)
{
EmitKeyEvent(Mouse.MouseButtonToKey(ConvertGlfwButton(ev.Button)), ev.Action, ev.Mods, default);
}
private void ProcessEventScroll(EventScroll ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
var eventArgs = new MouseWheelEventArgs(
new((float) ev.XOffset, (float) ev.YOffset),
new ScreenCoordinates(windowReg.LastMousePos, windowReg.Id));
_clyde.SendScroll(eventArgs);
}
private void ProcessEventWindowClose(EventWindowClose ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
_clyde.SendCloseWindow(windowReg, new WindowRequestClosedEventArgs(windowReg.Handle));
}
private void ProcessEventWindowSize(EventWindowSize ev)
{
var window = ev.Window;
var width = ev.Width;
var height = ev.Height;
var fbW = ev.FramebufferWidth;
var fbH = ev.FramebufferHeight;
var windowReg = FindWindow(window);
if (windowReg == null)
return;
var oldSize = windowReg.FramebufferSize;
windowReg.FramebufferSize = (fbW, fbH);
windowReg.WindowSize = (width, height);
if (fbW == 0 || fbH == 0 || width == 0 || height == 0)
return;
windowReg.PixelRatio = windowReg.FramebufferSize / windowReg.WindowSize;
_clyde.SendWindowResized(windowReg, oldSize);
}
private void ProcessEventWindowPos(EventWindowPos ev)
{
var window = ev.Window;
var x = ev.X;
var y = ev.Y;
var windowReg = FindWindow(window);
if (windowReg == null)
return;
windowReg.WindowPos = (x, y);
}
private void ProcessEventWindowContentScale(EventWindowContentScale ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
windowReg.WindowScale = new Vector2(ev.XScale, ev.YScale);
_clyde.SendWindowContentScaleChanged(new WindowContentScaleEventArgs(windowReg.Handle));
}
private void ProcessEventWindowIconify(EventWindowIconify ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
windowReg.IsMinimized = ev.Iconified;
}
private void ProcessEventWindowFocus(EventWindowFocus ev)
{
var windowReg = FindWindow(ev.Window);
if (windowReg == null)
return;
windowReg.IsFocused = ev.Focused;
_clyde.SendWindowFocus(new WindowFocusedEventArgs(ev.Focused, windowReg.Handle));
}
private void ProcessEventSetFullscreenAck()
{
// As far as I can tell, sometimes entering fullscreen just disables vsync.
// Hilarious!
_clyde._glContext?.UpdateVSync();
}
}
}
}

View File

@@ -1,236 +0,0 @@
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Robust.Shared;
using System.Threading;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Input;
using Robust.Shared.Localization;
using GlfwKey = OpenToolkit.GraphicsLibraryFramework.Keys;
using GlfwButton = OpenToolkit.GraphicsLibraryFramework.MouseButton;
using static Robust.Client.Input.Mouse;
using static Robust.Client.Input.Keyboard;
using Robust.Shared.IoC;
using Robust.Shared.Configuration;
namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private sealed partial class GlfwWindowingImpl
{
// TODO: to avoid having to ask the windowing thread, key names are cached.
// This means they don't update correctly if the user switches keyboard mode. RIP.
private readonly Dictionary<Key, string> _printableKeyNameMap = new();
private void InitKeyMap()
{
_printableKeyNameMap.Clear();
// From GLFW's source code: this is the actual list of "printable" keys
// that GetKeyName returns something for.
CacheKey(Keys.KeyPadEqual);
for (var k = Keys.KeyPad0; k <= Keys.KeyPadAdd; k++)
{
CacheKey(k);
}
for (var k = Keys.Apostrophe; k <= Keys.World2; k++)
{
CacheKey(k);
}
void CacheKey(GlfwKey key)
{
var rKey = ConvertGlfwKey(key);
if (rKey == Key.Unknown)
return;
var name = GLFW.GetKeyName(key, 0);
if (!string.IsNullOrEmpty(name))
_printableKeyNameMap.Add(rKey, name);
}
}
public string? KeyGetName(Keyboard.Key key)
{
if (_printableKeyNameMap.TryGetValue(key, out var name))
return name;
return null;
}
public static Button ConvertGlfwButton(GlfwButton button)
{
return MouseButtonMap[button];
}
private static readonly FrozenDictionary<GlfwButton, Button> MouseButtonMap = new Dictionary<GlfwButton, Button>()
{
{GlfwButton.Left, Button.Left},
{GlfwButton.Middle, Button.Middle},
{GlfwButton.Right, Button.Right},
{GlfwButton.Button4, Button.Button4},
{GlfwButton.Button5, Button.Button5},
{GlfwButton.Button6, Button.Button6},
{GlfwButton.Button7, Button.Button7},
{GlfwButton.Button8, Button.Button8},
}.ToFrozenDictionary();
private static readonly FrozenDictionary<GlfwKey, Key> KeyMap;
private static readonly FrozenDictionary<Key, GlfwKey> KeyMapReverse;
internal static Key ConvertGlfwKey(GlfwKey key)
{
if (KeyMap.TryGetValue(key, out var result))
{
return result;
}
return Key.Unknown;
}
internal static GlfwKey ConvertGlfwKeyReverse(Key key)
{
if (KeyMapReverse.TryGetValue(key, out var result))
{
return result;
}
return GlfwKey.Unknown;
}
static GlfwWindowingImpl()
{
KeyMap = new Dictionary<GlfwKey, Key>
{
{GlfwKey.A, Key.A},
{GlfwKey.B, Key.B},
{GlfwKey.C, Key.C},
{GlfwKey.D, Key.D},
{GlfwKey.E, Key.E},
{GlfwKey.F, Key.F},
{GlfwKey.G, Key.G},
{GlfwKey.H, Key.H},
{GlfwKey.I, Key.I},
{GlfwKey.J, Key.J},
{GlfwKey.K, Key.K},
{GlfwKey.L, Key.L},
{GlfwKey.M, Key.M},
{GlfwKey.N, Key.N},
{GlfwKey.O, Key.O},
{GlfwKey.P, Key.P},
{GlfwKey.Q, Key.Q},
{GlfwKey.R, Key.R},
{GlfwKey.S, Key.S},
{GlfwKey.T, Key.T},
{GlfwKey.U, Key.U},
{GlfwKey.V, Key.V},
{GlfwKey.W, Key.W},
{GlfwKey.X, Key.X},
{GlfwKey.Y, Key.Y},
{GlfwKey.Z, Key.Z},
{GlfwKey.D0, Key.Num0},
{GlfwKey.D1, Key.Num1},
{GlfwKey.D2, Key.Num2},
{GlfwKey.D3, Key.Num3},
{GlfwKey.D4, Key.Num4},
{GlfwKey.D5, Key.Num5},
{GlfwKey.D6, Key.Num6},
{GlfwKey.D7, Key.Num7},
{GlfwKey.D8, Key.Num8},
{GlfwKey.D9, Key.Num9},
{GlfwKey.KeyPad0, Key.NumpadNum0},
{GlfwKey.KeyPad1, Key.NumpadNum1},
{GlfwKey.KeyPad2, Key.NumpadNum2},
{GlfwKey.KeyPad3, Key.NumpadNum3},
{GlfwKey.KeyPad4, Key.NumpadNum4},
{GlfwKey.KeyPad5, Key.NumpadNum5},
{GlfwKey.KeyPad6, Key.NumpadNum6},
{GlfwKey.KeyPad7, Key.NumpadNum7},
{GlfwKey.KeyPad8, Key.NumpadNum8},
{GlfwKey.KeyPad9, Key.NumpadNum9},
{GlfwKey.Escape, Key.Escape},
{GlfwKey.LeftControl, Key.Control},
{GlfwKey.RightControl, Key.Control},
{GlfwKey.RightShift, Key.Shift},
{GlfwKey.LeftShift, Key.Shift},
{GlfwKey.LeftAlt, Key.Alt},
{GlfwKey.RightAlt, Key.Alt},
{GlfwKey.LeftSuper, Key.LSystem},
{GlfwKey.RightSuper, Key.RSystem},
{GlfwKey.Menu, Key.Menu},
{GlfwKey.LeftBracket, Key.LBracket},
{GlfwKey.RightBracket, Key.RBracket},
{GlfwKey.Semicolon, Key.SemiColon},
{GlfwKey.Comma, Key.Comma},
{GlfwKey.Period, Key.Period},
{GlfwKey.Apostrophe, Key.Apostrophe},
{GlfwKey.Slash, Key.Slash},
{GlfwKey.Backslash, Key.BackSlash},
{GlfwKey.GraveAccent, Key.Tilde},
{GlfwKey.Equal, Key.Equal},
{GlfwKey.Space, Key.Space},
{GlfwKey.Enter, Key.Return},
{GlfwKey.KeyPadEnter, Key.NumpadEnter},
{GlfwKey.Backspace, Key.BackSpace},
{GlfwKey.Tab, Key.Tab},
{GlfwKey.PageUp, Key.PageUp},
{GlfwKey.PageDown, Key.PageDown},
{GlfwKey.End, Key.End},
{GlfwKey.Home, Key.Home},
{GlfwKey.Insert, Key.Insert},
{GlfwKey.Delete, Key.Delete},
{GlfwKey.Minus, Key.Minus},
{GlfwKey.KeyPadAdd, Key.NumpadAdd},
{GlfwKey.KeyPadSubtract, Key.NumpadSubtract},
{GlfwKey.KeyPadDivide, Key.NumpadDivide},
{GlfwKey.KeyPadMultiply, Key.NumpadMultiply},
{GlfwKey.KeyPadDecimal, Key.NumpadDecimal},
{GlfwKey.Left, Key.Left},
{GlfwKey.Right, Key.Right},
{GlfwKey.Up, Key.Up},
{GlfwKey.Down, Key.Down},
{GlfwKey.F1, Key.F1},
{GlfwKey.F2, Key.F2},
{GlfwKey.F3, Key.F3},
{GlfwKey.F4, Key.F4},
{GlfwKey.F5, Key.F5},
{GlfwKey.F6, Key.F6},
{GlfwKey.F7, Key.F7},
{GlfwKey.F8, Key.F8},
{GlfwKey.F9, Key.F9},
{GlfwKey.F10, Key.F10},
{GlfwKey.F11, Key.F11},
{GlfwKey.F12, Key.F12},
{GlfwKey.F13, Key.F13},
{GlfwKey.F14, Key.F14},
{GlfwKey.F15, Key.F15},
{GlfwKey.F16, Key.F16},
{GlfwKey.F17, Key.F17},
{GlfwKey.F18, Key.F18},
{GlfwKey.F19, Key.F19},
{GlfwKey.F20, Key.F20},
{GlfwKey.F21, Key.F21},
{GlfwKey.F22, Key.F22},
{GlfwKey.F23, Key.F23},
{GlfwKey.F24, Key.F24},
{GlfwKey.Pause, Key.Pause},
{GlfwKey.World1, Key.World1},
{GlfwKey.CapsLock, Key.CapsLock}
}.ToFrozenDictionary();
var keyMapReverse = new Dictionary<Key, GlfwKey>();
foreach (var (key, value) in KeyMap)
{
keyMapReverse[value] = key;
}
KeyMapReverse = keyMapReverse.ToFrozenDictionary();
}
}
}
}

View File

@@ -1,131 +0,0 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Shared.Utility;
using GlfwVideoMode = OpenToolkit.GraphicsLibraryFramework.VideoMode;
namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private sealed unsafe partial class GlfwWindowingImpl
{
// TODO: GLFW doesn't have any events for complex monitor config changes,
// so we need some way to reload stuff if e.g. the primary monitor changes.
// Still better than SDL2 though which doesn't acknowledge monitor changes at all.
// Monitors are created at GLFW's will,
// so we need to make SURE monitors keep existing while operating on them.
// because, you know, async. Don't want a use-after-free.
private readonly Dictionary<int, WinThreadMonitorReg> _winThreadMonitors = new();
// Can't use ClydeHandle because it's 64 bit.
private int _nextMonitorId = 1;
private readonly Dictionary<int, GlfwMonitorReg> _monitors = new();
private void InitMonitors()
{
var monitors = GLFW.GetMonitorsRaw(out var count);
for (var i = 0; i < count; i++)
{
WinThreadSetupMonitor(monitors[i]);
}
var primaryMonitor = GLFW.GetPrimaryMonitor();
var up = GLFW.GetMonitorUserPointer(primaryMonitor);
_clyde._primaryMonitorId = (int) up;
ProcessEvents();
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void WinThreadSetupMonitor(Monitor* monitor)
{
var id = _nextMonitorId++;
DebugTools.Assert(GLFW.GetMonitorUserPointer(monitor) == null,
"GLFW window already has user pointer??");
var name = GLFW.GetMonitorName(monitor);
var videoMode = GLFW.GetVideoMode(monitor);
var modesPtr = GLFW.GetVideoModesRaw(monitor, out var modeCount);
var modes = new VideoMode[modeCount];
for (var i = 0; i < modes.Length; i++)
{
modes[i] = ConvertVideoMode(modesPtr[i]);
}
GLFW.SetMonitorUserPointer(monitor, (void*) id);
_winThreadMonitors.Add(id, new WinThreadMonitorReg {Ptr = monitor});
SendEvent(new EventMonitorSetup(id, name, ConvertVideoMode(*videoMode), modes));
}
private static VideoMode ConvertVideoMode(in GlfwVideoMode mode)
{
return new()
{
Width = (ushort) mode.Width,
Height = (ushort) mode.Height,
RedBits = (byte) mode.RedBits,
RefreshRate = (ushort) mode.RefreshRate,
GreenBits = (byte) mode.GreenBits,
BlueBits = (byte) mode.BlueBits,
};
}
private void ProcessSetupMonitor(EventMonitorSetup ev)
{
var impl = new MonitorHandle(
ev.Id,
ev.Name,
(ev.CurrentMode.Width, ev.CurrentMode.Height),
ev.CurrentMode.RefreshRate,
ev.AllModes);
_clyde._monitorHandles.Add(ev.Id, impl);
_monitors[ev.Id] = new GlfwMonitorReg
{
Id = ev.Id,
Handle = impl
};
}
private void WinThreadDestroyMonitor(Monitor* monitor)
{
var ptr = (int) GLFW.GetMonitorUserPointer(monitor);
if (ptr == 0)
{
var name = GLFW.GetMonitorName(monitor);
_sawmill.Warning($"Monitor '{name}' had no user pointer set??");
return;
}
_winThreadMonitors.Remove(ptr);
GLFW.SetMonitorUserPointer(monitor, null);
SendEvent(new EventMonitorDestroy(ptr));
}
private void ProcessEventDestroyMonitor(EventMonitorDestroy ev)
{
_monitors.Remove(ev.Id);
_clyde._monitorHandles.Remove(ev.Id);
}
private sealed class GlfwMonitorReg : MonitorReg
{
public int Id;
}
private sealed class WinThreadMonitorReg
{
public Monitor* Ptr;
}
}
}
}

View File

@@ -1,225 +0,0 @@
using System.Threading.Tasks;
using OpenToolkit.GraphicsLibraryFramework;
namespace Robust.Client.Graphics.Clyde
{
partial class Clyde
{
private unsafe partial class GlfwWindowingImpl
{
// Keep delegates around to prevent GC issues.
private GLFWCallbacks.ErrorCallback? _errorCallback;
private GLFWCallbacks.MonitorCallback? _monitorCallback;
private GLFWCallbacks.CharCallback? _charCallback;
private GLFWCallbacks.CursorPosCallback? _cursorPosCallback;
private GLFWCallbacks.CursorEnterCallback? _cursorEnterCallback;
private GLFWCallbacks.KeyCallback? _keyCallback;
private GLFWCallbacks.MouseButtonCallback? _mouseButtonCallback;
private GLFWCallbacks.ScrollCallback? _scrollCallback;
private GLFWCallbacks.WindowCloseCallback? _windowCloseCallback;
private GLFWCallbacks.WindowPosCallback? _windowPosCallback;
private GLFWCallbacks.WindowSizeCallback? _windowSizeCallback;
private GLFWCallbacks.WindowContentScaleCallback? _windowContentScaleCallback;
private GLFWCallbacks.WindowIconifyCallback? _windowIconifyCallback;
private GLFWCallbacks.WindowFocusCallback? _windowFocusCallback;
private void StoreCallbacks()
{
_errorCallback = OnGlfwError;
_monitorCallback = OnGlfwMonitor;
_charCallback = OnGlfwChar;
_cursorPosCallback = OnGlfwCursorPos;
_cursorEnterCallback = OnGlfwCursorEnter;
_keyCallback = OnGlfwKey;
_mouseButtonCallback = OnGlfwMouseButton;
_scrollCallback = OnGlfwScroll;
_windowCloseCallback = OnGlfwWindowClose;
_windowSizeCallback = OnGlfwWindowSize;
_windowPosCallback = OnGlfwWindowPos;
_windowContentScaleCallback = OnGlfwWindowContentScale;
_windowIconifyCallback = OnGlfwWindowIconify;
_windowFocusCallback = OnGlfwWindowFocus;
}
private void SetupGlobalCallbacks()
{
GLFW.SetMonitorCallback(_monitorCallback);
}
private void OnGlfwMonitor(Monitor* monitor, ConnectedState state)
{
if (state == ConnectedState.Connected)
WinThreadSetupMonitor(monitor);
else
WinThreadDestroyMonitor(monitor);
}
private void OnGlfwChar(Window* window, uint codepoint)
{
SendEvent(new EventChar((nint) window, codepoint));
}
private void OnGlfwCursorPos(Window* window, double x, double y)
{
// System.Console.WriteLine($"{(nint)window:X16}: {x},{y}");
SendEvent(new EventCursorPos((nint) window, x, y));
}
private void OnGlfwCursorEnter(Window* window, bool entered)
{
// System.Console.WriteLine($"{(nint)window:X16}: {entered}");
SendEvent(new EventCursorEnter((nint) window, entered));
}
private void OnGlfwKey(Window* window, Keys key, int scanCode, InputAction action, KeyModifiers mods)
{
SendEvent(new EventKey((nint) window, key, scanCode, action, mods));
}
private void OnGlfwMouseButton(Window* window, MouseButton button, InputAction action, KeyModifiers mods)
{
SendEvent(new EventMouseButton((nint) window, button, action, mods));
}
private void OnGlfwScroll(Window* window, double offsetX, double offsetY)
{
SendEvent(new EventScroll((nint) window, offsetX, offsetY));
}
private void OnGlfwWindowClose(Window* window)
{
SendEvent(new EventWindowClose((nint) window));
}
private void OnGlfwWindowSize(Window* window, int width, int height)
{
GLFW.GetFramebufferSize(window, out var fbW, out var fbH);
SendEvent(new EventWindowSize((nint) window, width, height, fbW, fbH));
}
private void OnGlfwWindowPos(Window* window, int x, int y)
{
SendEvent(new EventWindowPos((nint) window, x, y));
}
private void OnGlfwWindowContentScale(Window* window, float xScale, float yScale)
{
SendEvent(new EventWindowContentScale((nint) window, xScale, yScale));
}
private void OnGlfwWindowIconify(Window* window, bool iconified)
{
SendEvent(new EventWindowIconify((nint) window, iconified));
}
private void OnGlfwWindowFocus(Window* window, bool focused)
{
SendEvent(new EventWindowFocus((nint) window, focused));
}
// NOTE: events do not correspond 1:1 to GLFW events
// This is because they need to pack all the data required
// for the game-thread event handling.
private abstract record EventBase;
private record EventMouseButton(
nint Window,
MouseButton Button,
InputAction Action,
KeyModifiers Mods
) : EventBase;
private record EventCursorPos(
nint Window,
double XPos,
double YPos
) : EventBase;
private record EventCursorEnter(
nint Window,
bool Entered
) : EventBase;
private record EventScroll(
nint Window,
double XOffset,
double YOffset
) : EventBase;
private record EventKey(
nint Window,
Keys Key,
int ScanCode,
InputAction Action,
KeyModifiers Mods
) : EventBase;
private record EventChar
(
nint Window,
uint CodePoint
) : EventBase;
private record EventWindowClose
(
nint Window
) : EventBase;
private record EventWindowCreate(
GlfwWindowCreateResult Result,
TaskCompletionSource<GlfwWindowCreateResult> Tcs
) : EventBase;
private record EventWindowSize
(
nint Window,
int Width,
int Height,
int FramebufferWidth,
int FramebufferHeight
) : EventBase;
private record EventWindowPos
(
nint Window,
int X,
int Y
) : EventBase;
private record EventWindowContentScale
(
nint Window,
float XScale,
float YScale
) : EventBase;
private record EventWindowIconify
(
nint Window,
bool Iconified
) : EventBase;
private record EventWindowFocus
(
nint Window,
bool Focused
) : EventBase;
private record EventMonitorSetup
(
int Id,
string Name,
VideoMode CurrentMode,
VideoMode[] AllModes
) : EventBase;
private record EventMonitorDestroy
(
int Id
) : EventBase;
private sealed record EventSetFullscreenAck : EventBase;
}
}
}

View File

@@ -1,303 +0,0 @@
using System;
using System.Threading.Channels;
using System.Threading.Tasks;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Shared;
using Robust.Shared.Maths;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private sealed partial class GlfwWindowingImpl
{
private bool _windowingRunning;
private ChannelWriter<CmdBase> _cmdWriter = default!;
private ChannelReader<CmdBase> _cmdReader = default!;
private ChannelReader<EventBase> _eventReader = default!;
private ChannelWriter<EventBase> _eventWriter = default!;
//
// Let it be forever recorded that I started work on windowing thread separation
// because win32 SetCursor was taking 15ms spinwaiting inside the kernel.
//
//
// To avoid stutters and solve some other problems like smooth window resizing,
// we (by default) use a separate thread for windowing.
//
// Types like WindowReg are considered to be part of the "game" thread
// and should **NOT** be directly updated/accessed from the windowing thread.
//
// Got that?
//
//
// The windowing -> game channel is bounded so that the OS properly detects the game as locked
// up when it actually locks up. The other way around is not bounded to avoid deadlocks.
// This also means that all operations like clipboard reading, window creation, etc....
// have to be asynchronous.
//
public void EnterWindowLoop()
{
_windowingRunning = true;
while (_windowingRunning)
{
// glfwPostEmptyEvent is broken on macOS and crashes when not called from the main thread
// (despite what the docs claim, and yes this makes it useless).
// Because of this, we just forego it and use glfwWaitEventsTimeout on macOS instead.
if (OperatingSystem.IsMacOS())
GLFW.WaitEventsTimeout(0.008);
else
GLFW.WaitEvents();
while (_cmdReader.TryRead(out var cmd) && _windowingRunning)
{
ProcessGlfwCmd(cmd);
}
}
}
public void PollEvents()
{
GLFW.PollEvents();
}
private void ProcessGlfwCmd(CmdBase cmdb)
{
switch (cmdb)
{
case CmdTerminate:
_windowingRunning = false;
_eventWriter.Complete();
break;
case CmdWinSetTitle cmd:
WinThreadWinSetTitle(cmd);
break;
case CmdWinSetMonitor cmd:
WinThreadWinSetMonitor(cmd);
break;
case CmdWinSetSize cmd:
WinThreadWinSetSize(cmd);
break;
case CmdWinSetVisible cmd:
WinThreadWinSetVisible(cmd);
break;
case CmdWinRequestAttention cmd:
WinThreadWinRequestAttention(cmd);
break;
case CmdWinSetFullscreen cmd:
WinThreadWinSetFullscreen(cmd);
break;
case CmdWinCreate cmd:
WinThreadWinCreate(cmd);
break;
case CmdWinDestroy cmd:
WinThreadWinDestroy(cmd);
break;
case CmdSetClipboard cmd:
WinThreadSetClipboard(cmd);
break;
case CmdGetClipboard cmd:
WinThreadGetClipboard(cmd);
break;
case CmdCursorCreate cmd:
WinThreadCursorCreate(cmd);
break;
case CmdCursorDestroy cmd:
WinThreadCursorDestroy(cmd);
break;
case CmdWinCursorSet cmd:
WinThreadWinCursorSet(cmd);
break;
case CmdRunAction cmd:
cmd.Action();
break;
}
}
public void TerminateWindowLoop()
{
SendCmd(new CmdTerminate());
_cmdWriter.Complete();
// Drain command queue ignoring it until the window thread confirms completion.
#pragma warning disable RA0004
while (_eventReader.WaitToReadAsync().AsTask().Result)
#pragma warning restore RA0004
{
_eventReader.TryRead(out _);
}
}
private void InitChannels()
{
var cmdChannel = Channel.CreateUnbounded<CmdBase>(new UnboundedChannelOptions
{
SingleReader = true,
// Finalizers can write to this in some cases.
SingleWriter = false
});
_cmdReader = cmdChannel.Reader;
_cmdWriter = cmdChannel.Writer;
var bufferSize = _cfg.GetCVar(CVars.DisplayInputBufferSize);
var eventChannel = Channel.CreateBounded<EventBase>(new BoundedChannelOptions(bufferSize)
{
FullMode = BoundedChannelFullMode.Wait,
SingleReader = true,
SingleWriter = true,
// For unblocking continuations.
AllowSynchronousContinuations = true
});
_eventReader = eventChannel.Reader;
_eventWriter = eventChannel.Writer;
}
private void SendCmd(CmdBase cmd)
{
if (_clyde._threadWindowApi)
{
_cmdWriter.TryWrite(cmd);
// Post empty event to unstuck WaitEvents if necessary.
if (!OperatingSystem.IsMacOS())
GLFW.PostEmptyEvent();
}
else
{
ProcessGlfwCmd(cmd);
}
}
private void SendEvent(EventBase ev)
{
if (_clyde._threadWindowApi)
{
var task = _eventWriter.WriteAsync(ev);
if (!task.IsCompletedSuccessfully)
{
task.AsTask().Wait();
}
}
else
{
ProcessEvent(ev);
}
}
public void RunOnWindowThread(Action action)
{
SendCmd(new CmdRunAction(action));
}
private abstract record CmdBase;
private sealed record CmdTerminate : CmdBase;
private sealed record CmdWinSetTitle(
nint Window,
string Title
) : CmdBase;
private sealed record CmdWinSetMonitor(
nint Window,
int MonitorId,
int X, int Y,
int W, int H,
int RefreshRate
) : CmdBase;
private sealed record CmdWinMaximize(
nint Window
) : CmdBase;
private sealed record CmdWinSetFullscreen(
nint Window
) : CmdBase;
private sealed record CmdWinSetSize(
nint Window,
int W, int H
) : CmdBase;
private sealed record CmdWinSetVisible(
nint Window,
bool Visible
) : CmdBase;
private sealed record CmdWinRequestAttention(
nint Window
) : CmdBase;
private sealed record CmdWinCreate(
GLContextSpec? GLSpec,
WindowCreateParameters Parameters,
nint ShareWindow,
nint OwnerWindow,
TaskCompletionSource<GlfwWindowCreateResult> Tcs
) : CmdBase;
private sealed record CmdWinDestroy(
nint Window,
bool hadOwner
) : CmdBase;
private sealed record GlfwWindowCreateResult(
GlfwWindowReg? Reg,
(string Desc, ErrorCode Code)? Error
);
private sealed record CmdSetClipboard(
nint Window,
string Text
) : CmdBase;
private sealed record CmdGetClipboard(
nint Window,
TaskCompletionSource<string> Tcs
) : CmdBase;
private sealed record CmdWinCursorSet(
nint Window,
ClydeHandle Cursor
) : CmdBase;
private sealed record CmdCursorCreate(
Image<Rgba32> Bytes,
Vector2i Hotspot,
ClydeHandle Cursor
) : CmdBase;
private sealed record CmdCursorDestroy(
ClydeHandle Cursor
) : CmdBase;
private sealed record CmdRunAction(
Action Action
) : CmdBase;
}
}
}

View File

@@ -1,759 +0,0 @@
using System;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Utility;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using SixLabors.ImageSharp.PixelFormats;
using TerraFX.Interop.Windows;
using TerraFX.Interop.Xlib;
using GlfwImage = OpenToolkit.GraphicsLibraryFramework.Image;
using Monitor = OpenToolkit.GraphicsLibraryFramework.Monitor;
using Window = OpenToolkit.GraphicsLibraryFramework.Window;
using X11Window = TerraFX.Interop.Xlib.Window;
namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private sealed unsafe partial class GlfwWindowingImpl
{
private int _nextWindowId = 1;
public void WindowSetTitle(WindowReg window, string title)
{
CheckWindowDisposed(window);
if (title == null)
{
throw new ArgumentNullException(nameof(title));
}
var reg = (GlfwWindowReg) window;
SendCmd(new CmdWinSetTitle((nint) reg.GlfwWindow, title));
}
private void WinThreadWinSetTitle(CmdWinSetTitle cmd)
{
GLFW.SetWindowTitle((Window*) cmd.Window, cmd.Title);
}
public void WindowSetMonitor(WindowReg window, IClydeMonitor monitor)
{
CheckWindowDisposed(window);
var winReg = (GlfwWindowReg) window;
var monitorImpl = (MonitorHandle) monitor;
SendCmd(new CmdWinSetMonitor(
(nint) winReg.GlfwWindow,
monitorImpl.Id,
0, 0,
monitorImpl.Size.X, monitorImpl.Size.Y,
monitorImpl.RefreshRate));
}
private void WinThreadWinSetMonitor(CmdWinSetMonitor cmd)
{
Monitor* monitorPtr;
if (cmd.MonitorId == 0)
{
monitorPtr = null;
}
else if (_winThreadMonitors.TryGetValue(cmd.MonitorId, out var monitorReg))
{
monitorPtr = monitorReg.Ptr;
}
else
{
return;
}
GLFW.SetWindowMonitor(
(Window*) cmd.Window,
monitorPtr,
cmd.X, cmd.Y,
cmd.W, cmd.H,
cmd.RefreshRate
);
}
public void WindowSetSize(WindowReg window, Vector2i size)
{
var reg = (GlfwWindowReg) window;
SendCmd(new CmdWinSetSize((nint) reg.GlfwWindow, size.X, size.Y));
}
public void WindowSetVisible(WindowReg window, bool visible)
{
var reg = (GlfwWindowReg) window;
reg.IsVisible = visible;
SendCmd(new CmdWinSetVisible((nint) reg.GlfwWindow, visible));
}
private void WinThreadWinSetSize(CmdWinSetSize cmd)
{
var win = (Window*) cmd.Window;
GLFW.SetWindowSize(win, cmd.W, cmd.H);
}
private void WinThreadWinSetVisible(CmdWinSetVisible cmd)
{
var win = (Window*) cmd.Window;
if (cmd.Visible)
{
GLFW.ShowWindow(win);
}
else
{
GLFW.HideWindow(win);
}
}
public void WindowRequestAttention(WindowReg window)
{
CheckWindowDisposed(window);
var reg = (GlfwWindowReg) window;
SendCmd(new CmdWinRequestAttention((nint) reg.GlfwWindow));
}
private void WinThreadWinRequestAttention(CmdWinRequestAttention cmd)
{
var win = (Window*) cmd.Window;
GLFW.RequestWindowAttention(win);
}
public void WindowSwapBuffers(WindowReg window)
{
CheckWindowDisposed(window);
var reg = (GlfwWindowReg) window;
GLFW.SwapBuffers(reg.GlfwWindow);
}
public void UpdateMainWindowMode()
{
if (_clyde._mainWindow == null)
return;
var win = (GlfwWindowReg) _clyde._mainWindow;
if (_clyde._windowMode == WindowMode.Fullscreen)
{
win.PrevWindowSize = win.WindowSize;
win.PrevWindowPos = win.WindowPos;
SendCmd(new CmdWinSetFullscreen((nint) win.GlfwWindow));
}
else
{
SendCmd(new CmdWinSetMonitor(
(nint) win.GlfwWindow,
0,
win.PrevWindowPos.X, win.PrevWindowPos.Y,
win.PrevWindowSize.X, win.PrevWindowSize.Y,
0
));
}
}
private void WinThreadWinSetFullscreen(CmdWinSetFullscreen cmd)
{
var ptr = (Window*) cmd.Window;
//GLFW.GetWindowSize(ptr, out var w, out var h);
//GLFW.GetWindowPos(ptr, out var x, out var y);
var monitor = MonitorForWindow(ptr);
var mode = GLFW.GetVideoMode(monitor);
GLFW.SetWindowMonitor(
ptr,
monitor,
0, 0,
mode->Width, mode->Height,
mode->RefreshRate);
SendEvent(new EventSetFullscreenAck());
}
// glfwGetWindowMonitor only works for fullscreen windows.
// Picks the monitor with the top-left corner of the window.
private Monitor* MonitorForWindow(Window* window)
{
GLFW.GetWindowPos(window, out var winPosX, out var winPosY);
var monitors = GLFW.GetMonitorsRaw(out var count);
for (var i = 0; i < count; i++)
{
var monitor = monitors[i];
GLFW.GetMonitorPos(monitor, out var monPosX, out var monPosY);
var videoMode = GLFW.GetVideoMode(monitor);
var box = Box2i.FromDimensions(monPosX, monPosY, videoMode->Width, videoMode->Height);
if (box.Contains(winPosX, winPosY))
return monitor;
}
// Fallback
return GLFW.GetPrimaryMonitor();
}
public uint? WindowGetX11Id(WindowReg window)
{
CheckWindowDisposed(window);
var reg = (GlfwWindowReg) window;
try
{
return GLFW.GetX11Window(reg.GlfwWindow);
}
catch (EntryPointNotFoundException)
{
return null;
}
}
public nint? WindowGetX11Display(WindowReg window)
{
CheckWindowDisposed(window);
var reg = (GlfwWindowReg) window;
try
{
return GLFW.GetX11Display(reg.GlfwWindow);
}
catch (EntryPointNotFoundException)
{
return null;
}
}
public nint? WindowGetWin32Window(WindowReg window)
{
if (!OperatingSystem.IsWindows())
return null;
var reg = (GlfwWindowReg) window;
try
{
return GLFW.GetWin32Window(reg.GlfwWindow);
}
catch (EntryPointNotFoundException)
{
return null;
}
}
public (WindowReg?, string? error) WindowCreate(
GLContextSpec? spec,
WindowCreateParameters parameters,
WindowReg? share,
WindowReg? owner)
{
Window* sharePtr = null;
if (share is GlfwWindowReg glfwReg)
sharePtr = glfwReg.GlfwWindow;
Window* ownerPtr = null;
if (owner is GlfwWindowReg glfwOwnerReg)
ownerPtr = glfwOwnerReg.GlfwWindow;
var task = SharedWindowCreate(
spec,
parameters,
sharePtr,
ownerPtr);
// Block the main thread (to avoid stuff like texture uploads being problematic).
WaitWindowCreate(task);
#pragma warning disable RA0004
var (reg, errorResult) = task.Result;
#pragma warning restore RA0004
if (reg != null)
{
reg.Owner = reg.Handle;
return (reg, null);
}
var (desc, errCode) = errorResult!.Value;
return (null, (string)$"[{errCode}]: {desc}");
}
public void WindowDestroy(WindowReg window)
{
var reg = (GlfwWindowReg) window;
SendCmd(new CmdWinDestroy((nint) reg.GlfwWindow, window.Owner != null));
}
private void WaitWindowCreate(Task<GlfwWindowCreateResult> windowTask)
{
while (!windowTask.IsCompleted)
{
// Keep processing events until the window task gives either an error or success.
WaitEvents();
ProcessEvents(single: true);
}
}
private Task<GlfwWindowCreateResult> SharedWindowCreate(
GLContextSpec? glSpec,
WindowCreateParameters parameters,
Window* share, Window* owner)
{
//
// IF YOU'RE WONDERING WHY THIS IS TASK-BASED:
// I originally wanted this to be async so we could avoid blocking the main thread
// while the OS takes its stupid 100~ms just to initialize a fucking GL context.
// This doesn't *work* because
// we have to release the GL context while the shared context is being created.
// (at least on WGL, I didn't test other platforms and I don't care to.)
// Not worth it to avoid a main thread blockage by allowing Clyde to temporarily release the GL context,
// because rendering would be locked up *anyways*.
//
// Basically what I'm saying is that everything about OpenGL is a fucking mistake
// and I should get on either Veldrid or Vulkan some time.
// Probably Veldrid tbh.
//
// Yes we ping-pong this TCS through the window thread and back, deal with it.
var tcs = new TaskCompletionSource<GlfwWindowCreateResult>();
SendCmd(new CmdWinCreate(
glSpec,
parameters,
(nint) share,
(nint) owner,
tcs));
return tcs.Task;
}
private static void FinishWindowCreate(EventWindowCreate ev)
{
var (res, tcs) = ev;
tcs.TrySetResult(res);
}
private void WinThreadWinCreate(CmdWinCreate cmd)
{
var (glSpec, parameters, share, owner, tcs) = cmd;
var window = CreateGlfwWindowForRenderer(glSpec, parameters, (Window*) share, (Window*) owner);
if (window == null)
{
var err = GLFW.GetError(out var desc);
SendEvent(new EventWindowCreate(new GlfwWindowCreateResult(null, (desc, err)), tcs));
return;
}
// We can't invoke the TCS directly from the windowing thread because:
// * it'd hit the synchronization context,
// which would make (blocking) main window init more annoying.
// * it'd not be synchronized to other incoming window events correctly which might be icky.
// So we send the TCS back to the game thread
// which processes events in the correct order and has better control of stuff during init.
var reg = WinThreadSetupWindow(window);
SendEvent(new EventWindowCreate(new GlfwWindowCreateResult(reg, null), tcs));
}
private static void WinThreadWinDestroy(CmdWinDestroy cmd)
{
var window = (Window*) cmd.Window;
if (OperatingSystem.IsWindows() && cmd.hadOwner)
{
// On Windows, closing the child window causes the owner to be minimized, apparently.
// Clear owner on close to avoid this.
var hWnd = (HWND) GLFW.GetWin32Window(window);
DebugTools.Assert(hWnd != HWND.NULL);
Windows.SetWindowLongPtrW(
hWnd,
GWLP.GWLP_HWNDPARENT,
0);
}
GLFW.DestroyWindow((Window*) cmd.Window);
}
private Window* CreateGlfwWindowForRenderer(
GLContextSpec? spec,
WindowCreateParameters parameters,
Window* contextShare,
Window* ownerWindow)
{
GLFW.WindowHint(WindowHintString.X11ClassName, "RobustToolbox");
GLFW.WindowHint(WindowHintString.X11InstanceName, "RobustToolbox");
GLFW.WindowHint(WindowHintBool.ScaleToMonitor, true);
if (spec == null)
{
// No OpenGL context requested.
GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.NoApi);
}
else
{
var s = spec.Value;
#if DEBUG
GLFW.WindowHint(WindowHintBool.OpenGLDebugContext, true);
#endif
GLFW.WindowHint(WindowHintInt.ContextVersionMajor, s.Major);
GLFW.WindowHint(WindowHintInt.ContextVersionMinor, s.Minor);
GLFW.WindowHint(WindowHintBool.OpenGLForwardCompat, s.Profile != GLContextProfile.Compatibility);
GLFW.WindowHint(WindowHintBool.SrgbCapable, true);
switch (s.Profile)
{
case GLContextProfile.Compatibility:
GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Any);
GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.OpenGlApi);
break;
case GLContextProfile.Core:
GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Core);
GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.OpenGlApi);
break;
case GLContextProfile.Es:
GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Any);
GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.OpenGlEsApi);
break;
}
GLFW.WindowHint(WindowHintContextApi.ContextCreationApi,
s.CreationApi == GLContextCreationApi.Egl
? ContextApi.EglContextApi
: ContextApi.NativeContextApi);
if (s.CreationApi == GLContextCreationApi.Egl)
WsiShared.EnsureEglAvailable();
}
Monitor* monitor = null;
if (parameters.Monitor != null &&
_winThreadMonitors.TryGetValue(parameters.Monitor.Id, out var monitorReg))
{
monitor = monitorReg.Ptr;
var mode = GLFW.GetVideoMode(monitor);
// Set refresh rate to monitor's so that GLFW doesn't manually select one.
GLFW.WindowHint(WindowHintInt.RefreshRate, mode->RefreshRate);
}
else
{
GLFW.WindowHint(WindowHintInt.RefreshRate, -1);
}
GLFW.WindowHint(WindowHintBool.Visible, false);
GLFW.WindowHint(WindowHintInt.RedBits, 8);
GLFW.WindowHint(WindowHintInt.GreenBits, 8);
GLFW.WindowHint(WindowHintInt.BlueBits, 8);
GLFW.WindowHint(WindowHintInt.AlphaBits, 8);
GLFW.WindowHint(WindowHintInt.StencilBits, 8);
GLFW.WindowHint(WindowHintBool.Decorated, (parameters.Styles & OSWindowStyles.NoTitleBar) == 0);
var window = GLFW.CreateWindow(
parameters.Width, parameters.Height,
parameters.Title,
parameters.Fullscreen ? monitor : null,
contextShare);
// Check if window failed to create.
if (window == null)
return null;
if (parameters.Maximized)
{
GLFW.GetMonitorPos(monitor, out var x, out var y);
GLFW.SetWindowPos(window, x, y);
GLFW.MaximizeWindow(window);
}
if ((parameters.Styles & OSWindowStyles.NoTitleOptions) != 0)
{
if (OperatingSystem.IsWindows())
{
var hWnd = (HWND) GLFW.GetWin32Window(window);
WsiShared.SetWindowStyleNoTitleOptionsWindows(hWnd);
}
else if (OperatingSystem.IsLinux())
{
try
{
var x11Window = (X11Window)GLFW.GetX11Window(window);
var x11Display = (Display*) GLFW.GetX11Display(window);
WsiShared.SetWindowStyleNoTitleOptionsX11(x11Display, x11Window);
}
catch (EntryPointNotFoundException)
{
_sawmill.Warning("OSWindowStyles.NoTitleOptions not implemented on this windowing manager");
}
}
else
{
_sawmill.Warning("OSWindowStyles.NoTitleOptions not implemented on this platform");
}
}
if (ownerWindow != null)
{
if (OperatingSystem.IsWindows())
{
var hWnd = (HWND) GLFW.GetWin32Window(window);
var ownerHWnd = (HWND) GLFW.GetWin32Window(ownerWindow);
DebugTools.Assert(hWnd != HWND.NULL);
Windows.SetWindowLongPtrW(
hWnd,
GWLP.GWLP_HWNDPARENT,
ownerHWnd);
}
else if (OperatingSystem.IsLinux())
{
try
{
var x11Display = (Display*) GLFW.GetX11Display(window);
var thisWindow = (X11Window)GLFW.GetX11Window(window);
var parentWindow = (X11Window)GLFW.GetX11Window(ownerWindow);
DebugTools.Assert(thisWindow != X11Window.NULL);
DebugTools.Assert(parentWindow != X11Window.NULL);
#pragma warning disable CA1806
Xlib.XSetTransientForHint(x11Display, thisWindow, parentWindow);
#pragma warning restore CA1806
}
catch (EntryPointNotFoundException)
{
_sawmill.Warning("owner windows not implemented on this windowing manager");
}
}
else
{
_sawmill.Warning("owner windows not implemented on this platform");
}
if (parameters.StartupLocation == WindowStartupLocation.CenterOwner)
{
// TODO: Maybe include window frames in size calculations here?
// Figure out frame sizes of both windows.
GLFW.GetWindowPos(ownerWindow, out var ownerX, out var ownerY);
GLFW.GetWindowSize(ownerWindow, out var ownerW, out var ownerH);
// Re-fetch this in case DPI scaling is changing it I guess.
GLFW.GetWindowSize(window, out var thisW, out var thisH);
GLFW.SetWindowPos(window, ownerX + (ownerW - thisW) / 2, ownerY + (ownerH - thisH) / 2);
}
}
if (OperatingSystem.IsWindows())
WsiShared.WindowsSharedWindowCreate((HWND) GLFW.GetWin32Window(window), _cfg);
if (parameters.Visible)
{
GLFW.ShowWindow(window);
}
return window;
}
private GlfwWindowReg WinThreadSetupWindow(Window* window)
{
var reg = new GlfwWindowReg
{
GlfwWindow = window,
Id = new WindowId(_nextWindowId++)
};
var handle = new WindowHandle(_clyde, reg);
reg.Handle = handle;
LoadWindowIcon(window);
GLFW.SetCharCallback(window, _charCallback);
GLFW.SetKeyCallback(window, _keyCallback);
GLFW.SetWindowCloseCallback(window, _windowCloseCallback);
GLFW.SetCursorPosCallback(window, _cursorPosCallback);
GLFW.SetCursorEnterCallback(window, _cursorEnterCallback);
GLFW.SetWindowSizeCallback(window, _windowSizeCallback);
GLFW.SetWindowPosCallback(window, _windowPosCallback);
GLFW.SetScrollCallback(window, _scrollCallback);
GLFW.SetMouseButtonCallback(window, _mouseButtonCallback);
GLFW.SetWindowContentScaleCallback(window, _windowContentScaleCallback);
GLFW.SetWindowIconifyCallback(window, _windowIconifyCallback);
GLFW.SetWindowFocusCallback(window, _windowFocusCallback);
GLFW.GetFramebufferSize(window, out var fbW, out var fbH);
reg.FramebufferSize = (fbW, fbH);
GLFW.GetWindowContentScale(window, out var scaleX, out var scaleY);
reg.WindowScale = new Vector2(scaleX, scaleY);
GLFW.GetWindowSize(window, out var w, out var h);
reg.PrevWindowSize = reg.WindowSize = (w, h);
GLFW.GetWindowPos(window, out var x, out var y);
reg.PrevWindowPos = (x, y);
reg.PixelRatio = reg.FramebufferSize / (Vector2) reg.WindowSize;
return reg;
}
private GlfwWindowReg? FindWindow(nint window) => FindWindow((Window*) window);
private GlfwWindowReg? FindWindow(Window* window)
{
foreach (var windowReg in _clyde._windows)
{
var glfwReg = (GlfwWindowReg) windowReg;
if (glfwReg.GlfwWindow == window)
{
return glfwReg;
}
}
return null;
}
public Task<string> ClipboardGetText(WindowReg mainWindow)
{
var tcs = new TaskCompletionSource<string>();
SendCmd(new CmdGetClipboard((nint) ((GlfwWindowReg) mainWindow).GlfwWindow, tcs));
return tcs.Task;
}
private static void WinThreadGetClipboard(CmdGetClipboard cmd)
{
var clipboard = GLFW.GetClipboardString((Window*) cmd.Window) ?? "";
// Don't have to care about synchronization I don't think so just fire this immediately.
cmd.Tcs.TrySetResult(clipboard);
}
public void ClipboardSetText(WindowReg mainWindow, string text)
{
SendCmd(new CmdSetClipboard((nint) ((GlfwWindowReg) mainWindow).GlfwWindow, text));
}
private static void WinThreadSetClipboard(CmdSetClipboard cmd)
{
GLFW.SetClipboardString((Window*) cmd.Window, cmd.Text);
}
public void LoadWindowIcon(Window* window)
{
var icons = _clyde.LoadWindowIcons().ToArray();
// Done if no icon (e.g., macOS)
if (icons.Length == 0)
return;
// Turn each image into a byte[] so we can actually pin their contents.
// Wish I knew a clean way to do this without allocations.
var images = icons
.Select(i => (MemoryMarshal.Cast<Rgba32, byte>(i.GetPixelSpan()).ToArray(), i.Width, i.Height))
.ToList();
// ReSharper disable once SuggestVarOrType_Elsewhere
Span<GCHandle> handles = stackalloc GCHandle[images.Count];
Span<GlfwImage> glfwImages = stackalloc GlfwImage[images.Count];
for (var i = 0; i < images.Count; i++)
{
var image = images[i];
handles[i] = GCHandle.Alloc(image.Item1, GCHandleType.Pinned);
var addrOfPinnedObject = (byte*) handles[i].AddrOfPinnedObject();
glfwImages[i] = new GlfwImage(image.Width, image.Height, addrOfPinnedObject);
}
GLFW.SetWindowIcon(window, glfwImages);
foreach (var handle in handles)
{
handle.Free();
}
}
public void GLMakeContextCurrent(WindowReg? window)
{
if (window != null)
{
CheckWindowDisposed(window);
var reg = (GlfwWindowReg)window;
GLFW.MakeContextCurrent(reg.GlfwWindow);
}
else
{
GLFW.MakeContextCurrent(null);
}
}
public void GLSwapInterval(WindowReg reg, int interval)
{
GLFW.SwapInterval(interval);
}
public void* GLGetProcAddress(string procName)
{
return (void*) GLFW.GetProcAddress(procName);
}
public void TextInputSetRect(WindowReg reg, UIBox2i rect, int cursor)
{
// Not supported on GLFW.
}
public void TextInputStart(WindowReg reg)
{
// Not properly supported on GLFW.
((GlfwWindowReg)reg).TextInputActive = true;
}
public void TextInputStop(WindowReg reg)
{
// Not properly supported on GLFW.
((GlfwWindowReg)reg).TextInputActive = false;
}
private void CheckWindowDisposed(WindowReg reg)
{
if (reg.IsDisposed)
throw new ObjectDisposedException("Window disposed");
}
private sealed class GlfwWindowReg : WindowReg
{
public Window* GlfwWindow;
// Kept around to avoid it being GCd.
public CursorImpl? Cursor;
// While GLFW does not provide proper IME APIs, we can at least emulate SDL3's StartTextInput() system.
// This will ensure some level of consistency between the backends.
public bool TextInputActive;
}
}
}
}

View File

@@ -1,129 +0,0 @@
using System;
using System.Runtime.Serialization;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Input;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.IoC;
using Robust.Shared.Log;
namespace Robust.Client.Graphics.Clyde
{
internal partial class Clyde
{
private sealed partial class GlfwWindowingImpl : IWindowingImpl
{
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
private readonly Clyde _clyde;
private readonly ISawmill _sawmill;
private readonly ISawmill _sawmillGlfw;
private bool _glfwInitialized;
#if DEBUG
private bool _win32Experience;
#endif
public GlfwWindowingImpl(Clyde clyde, IDependencyCollection deps)
{
_clyde = clyde;
deps.InjectDependencies(this, true);
_sawmill = _logManager.GetSawmill("clyde.win");
_sawmillGlfw = _logManager.GetSawmill("clyde.win.glfw");
}
public bool Init()
{
#if DEBUG
_cfg.OnValueChanged(CVars.DisplayWin32Experience, b => _win32Experience = b, true);
#endif
_cfg.OnValueChanged(CVars.DisplayUSQWERTYHotkeys, ReInitKeyMap);
InitChannels();
if (!InitGlfw())
{
return false;
}
SetupGlobalCallbacks();
InitMonitors();
InitCursors();
InitKeyMap();
return true;
}
public void Shutdown()
{
if (_glfwInitialized)
{
_sawmill.Debug("Terminating GLFW.");
_cfg.UnsubValueChanged(CVars.DisplayUSQWERTYHotkeys, ReInitKeyMap);
GLFW.Terminate();
}
}
public void FlushDispose()
{
// Not currently used
}
public string GetDescription()
{
return $"GLFW {GLFW.GetVersionString()}";
}
private void ReInitKeyMap(bool onValueChanged)
{
InitKeyMap();
_inputManager.InputModeChanged();
}
private bool InitGlfw()
{
StoreCallbacks();
GLFW.SetErrorCallback(_errorCallback);
if (!GLFW.Init())
{
var err = GLFW.GetError(out var desc);
_sawmill.Fatal($"Failed to initialize GLFW! [{err}] {desc}");
return false;
}
_glfwInitialized = true;
var version = GLFW.GetVersionString();
_sawmill.Debug("GLFW initialized, version: {0}.", version);
return true;
}
private void OnGlfwError(ErrorCode code, string description)
{
_sawmillGlfw.Error("GLFW Error: [{0}] {1}", code, description);
}
[Serializable]
[Virtual]
public class GlfwException : Exception
{
public GlfwException()
{
}
public GlfwException(string message) : base(message)
{
}
public GlfwException(string message, Exception inner) : base(message, inner)
{
}
}
}
}
}

View File

@@ -42,7 +42,6 @@
<ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
<ProjectReference Include="..\OpenToolkit.GraphicsLibraryFramework\OpenToolkit.GraphicsLibraryFramework.csproj" />
<ProjectReference Include="..\Robust.LoaderApi\Robust.LoaderApi\Robust.LoaderApi.csproj" />
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />

View File

@@ -88,7 +88,6 @@
<BuildType Solution="Tools|*" Project="Release"/>
</Project>
<Project Path="Lidgren.Network/Lidgren.Network.csproj"/>
<Project Path="OpenToolkit.GraphicsLibraryFramework/OpenToolkit.GraphicsLibraryFramework.csproj"/>
<Project Path="Robust.Client.Injectors/Robust.Client.Injectors.csproj">
<BuildType Solution="DebugOpt|*" Project="Debug"/>
<BuildType Solution="Tools|*" Project="Release"/>