Switch to GLFW for windowing (#914)

* Use GLFW instead of OpenTK windows

* Seems to work pretty well now.

* Fix stackalloc issue on Framework.

* Add GLFW project to sln.

* Fix package downgrade.

* Fix SLN more.

* Please work.

* Fix C# version error.
This commit is contained in:
Pieter-Jan Briers
2019-12-15 15:53:30 +01:00
committed by GitHub
parent 1899544500
commit 52e5afd277
82 changed files with 9108 additions and 931 deletions

View File

@@ -26,8 +26,6 @@ https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild
<OutputType>Library</OutputType>
<TargetFrameworkMoniker>.NETFramework, Version=v4.6.1</TargetFrameworkMoniker>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' " />
<PropertyGroup>
@@ -42,4 +40,4 @@ https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild
</Target>
<Target Name="Compile" />
<Target Name="CoreCompile" />
</Project>
</Project>

View File

@@ -6,6 +6,10 @@
<Exec Condition="'$(Platform)' == 'x64'" Command="$(Python) $(RobustToolsPath)download_swnfd.py $(Platform) $(TargetOS) $(OutputPath)" CustomErrorRegularExpression="^Error" />
<Warning Condition="'$(Platform)' != 'x64'" Text="Did not download swnfd because the platform is not set to x64. Only use this build for unit testing!" />
</Target>
<Target Name="CopyGlfw">
<Exec Condition="'$(Platform)' == 'x64'" Command="$(Python) $(RobustToolsPath)download_glfw.py $(Platform) $(TargetOS) $(OutputPath)" CustomErrorRegularExpression="^Error" />
<Warning Condition="'$(Platform)' != 'x64'" Text="Did not download GLFW because the platform is not set to x64. Only use this build for unit testing!" />
</Target>
<Target Name="CopyMiscDependencies">
<Exec Condition="'$(Platform)' == 'x64'" Command="$(Python) $(RobustToolsPath)download_misc_dependencies.py $(Platform) $(TargetOS) $(OutputPath)" CustomErrorRegularExpression="^Error" />
<Warning Condition="'$(Platform)' != 'x64'" Text="Did not download misc dependencies because the platform is not set to x64. Only use this build for unit testing!" />

View File

@@ -0,0 +1,18 @@
//
// 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

@@ -0,0 +1,33 @@
//
// 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

@@ -0,0 +1,27 @@
//
// 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

@@ -0,0 +1,27 @@
//
// 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

@@ -0,0 +1,37 @@
//
// 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

@@ -0,0 +1,47 @@
//
// 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

@@ -0,0 +1,24 @@
//
// 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

@@ -0,0 +1,103 @@
//
// 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

@@ -0,0 +1,46 @@
//
// 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

@@ -0,0 +1,15 @@
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

@@ -0,0 +1,33 @@
//
// 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
{
/// <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

@@ -0,0 +1,53 @@
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

@@ -0,0 +1,50 @@
//
// 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
{
/// <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

@@ -0,0 +1,627 @@
//
// 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
{
/// <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

@@ -0,0 +1,68 @@
namespace OpenToolkit.GraphicsLibraryFramework
{
/// <summary>
/// Specifies the buttons of a mouse.
/// </summary>
public enum MouseButton
{
/// <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

@@ -0,0 +1,32 @@
//
// 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

@@ -0,0 +1,33 @@
//
// 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

@@ -0,0 +1,32 @@
//
// 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

@@ -0,0 +1,29 @@
//
// 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

@@ -0,0 +1,96 @@
//
// 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

@@ -0,0 +1,49 @@
//
// 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

@@ -0,0 +1,133 @@
//
// 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,
}
}

View File

@@ -0,0 +1,26 @@
//
// 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

@@ -0,0 +1,24 @@
//
// 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

@@ -0,0 +1,117 @@
//
// 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

@@ -0,0 +1,29 @@
//
// 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

@@ -0,0 +1,30 @@
//
// 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

@@ -0,0 +1,25 @@
//
// 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

@@ -0,0 +1,23 @@
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

@@ -0,0 +1,171 @@
//
// 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);
}
}

View File

@@ -0,0 +1,78 @@
//
// 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)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GLFWException"/> class with the specified context
/// and the serialization information.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> associated with this exception.</param>
/// <param name="context">
/// A <see cref="StreamingContext"/> that represents the context of this exception.
/// </param>
protected GLFWException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

View File

@@ -0,0 +1,400 @@
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) =>
{
if (name != "glfw3.dll")
{
return IntPtr.Zero;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return NativeLibrary.Load("libglfw.so.3", assembly, path);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return NativeLibrary.Load("libglfw.3.dylib", assembly, path);
}
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 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 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);
}
}

View File

@@ -0,0 +1,27 @@
//
// 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

@@ -0,0 +1,37 @@
//
// 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

@@ -0,0 +1,47 @@
//
// 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

@@ -0,0 +1,23 @@
# 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

@@ -0,0 +1,18 @@
//
// 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

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\MSBuild\Robust.Properties.targets" />
<PropertyGroup>
<!-- Work around https://github.com/dotnet/project-system/issues/4314 -->
<TargetFramework>$(TargetFramework)</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>x64</Platforms>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Memory" Version="4.5.3" />
</ItemGroup>
<ItemGroup>
<Content Include="OpenToolkit.GraphicsLibraryFramework.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,5 @@
<configuration>
<!-- I actually have no idea whether this works on FreeBSD but it can't hurt to set it as such. -->
<dllmap os="linux,freebsd" dll="glfw3.dll" target="glfw.so.3" />
<dllmap os="osx" dll="glfw3.dll" target="glfw.3.dylib" />
</configuration>

View File

@@ -0,0 +1,20 @@
# 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

@@ -0,0 +1,50 @@
//
// 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

@@ -0,0 +1,29 @@
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

@@ -0,0 +1,18 @@
//
// 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
{
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -86,6 +86,7 @@ namespace Robust.Client
{
case GameController.DisplayMode.Headless:
IoCManager.Register<IClyde, ClydeHeadless>();
IoCManager.Register<IClipboardManager, ClydeHeadless>();
IoCManager.Register<IClydeAudio, ClydeHeadless>();
IoCManager.Register<IClydeInternal, ClydeHeadless>();
IoCManager.Register<IInputManager, InputManager>();
@@ -94,6 +95,7 @@ namespace Robust.Client
break;
case GameController.DisplayMode.Clyde:
IoCManager.Register<IClyde, Clyde>();
IoCManager.Register<IClipboardManager, Clyde>();
IoCManager.Register<IClydeAudio, Clyde>();
IoCManager.Register<IClydeInternal, Clyde>();
IoCManager.Register<IInputManager, ClydeInputManager>();
@@ -117,18 +119,6 @@ namespace Robust.Client
IoCManager.Register<IOverlayManagerInternal, OverlayManager>();
IoCManager.Register<IViewVariablesManager, ViewVariablesManager>();
IoCManager.Register<IViewVariablesManagerInternal, ViewVariablesManager>();
#if LINUX
IoCManager.Register<IClipboardManager, ClipboardManagerLinux>();
IoCManager.Register<IClipboardManagerInternal, ClipboardManagerLinux>();
#elif WINDOWS
IoCManager.Register<IClipboardManager, ClipboardManagerWindows>();
IoCManager.Register<IClipboardManagerInternal, ClipboardManagerWindows>();
#else
IoCManager.Register<IClipboardManager, ClipboardManagerUnsupported>();
IoCManager.Register<IClipboardManagerInternal, ClipboardManagerUnsupported>();
#endif
IoCManager.Register<ISignalHandler, ClientSignalHandler>();
IoCManager.Register<IClientConGroupController, ClientConGroupController>();
}

View File

@@ -560,12 +560,6 @@ namespace Robust.Client.Console.Commands
public bool Execute(IDebugConsole console, params string[] args)
{
var mgr = IoCManager.Resolve<IClipboardManager>();
if (!mgr.Available)
{
console.AddLine(mgr.NotAvailableReason, Color.Red);
return false;
}
mgr.SetText(args[0]);
return false;
}
@@ -580,13 +574,6 @@ namespace Robust.Client.Console.Commands
public bool Execute(IDebugConsole console, params string[] args)
{
var mgr = IoCManager.Resolve<IClipboardManager>();
if (!mgr.Available)
{
console.AddLine(mgr.NotAvailableReason, Color.Red);
return false;
}
console.AddLine(mgr.GetText());
return false;
}
}

View File

@@ -41,7 +41,6 @@ namespace Robust.Client
{
#pragma warning disable 649
[Dependency] private readonly IConfigurationManager _configurationManager;
[Dependency] private readonly IClipboardManagerInternal _clipboardManager;
[Dependency] private readonly IResourceCacheInternal _resourceCache;
[Dependency] private readonly IResourceManager _resourceManager;
[Dependency] private readonly IRobustSerializer _serializer;
@@ -82,7 +81,7 @@ namespace Robust.Client
_commandLineArgs = args;
}
public void Startup()
public bool Startup()
{
SetupLogging(_logManager);
@@ -124,11 +123,14 @@ namespace Robust.Client
_localizationManager.LoadCulture(new CultureInfo("en-US"));
// Bring display up as soon as resources are mounted.
_clyde.Initialize();
if (!_clyde.Initialize())
{
return false;
}
_clyde.SetWindowTitle("Space Station 14");
_fontManager.Initialize();
_clipboardManager.Initialize();
//identical code for server in baseserver
if (!_modLoader.TryLoadAssembly<GameShared>(_resourceManager, $"Content.Shared"))
@@ -200,6 +202,7 @@ namespace Robust.Client
}
_checkOpenGLVersion();
return true;
}
private void _checkOpenGLVersion()

View File

@@ -33,7 +33,11 @@ namespace Robust.Client
var gc = (GameController) IoCManager.Resolve<IGameController>();
gc.SetCommandLineArgs(args);
gc.Startup();
if (!gc.Startup())
{
Logger.Fatal("Failed to start game controller!");
return;
}
gc.MainLoop(mode);
Logger.Debug("Goodbye");

View File

@@ -63,9 +63,9 @@ namespace Robust.Client.Graphics.Clyde
_alContextExtensions.Add(extension);
}
Logger.DebugS("oal", "OpenAL Vendor: {0}", AL.Get(ALGetString.Vendor));
Logger.DebugS("oal", "OpenAL Renderer: {0}", AL.Get(ALGetString.Renderer));
Logger.DebugS("oal", "OpenAL Version: {0}", AL.Get(ALGetString.Version));
Logger.DebugS("clyde.oal", "OpenAL Vendor: {0}", AL.Get(ALGetString.Vendor));
Logger.DebugS("clyde.oal", "OpenAL Renderer: {0}", AL.Get(ALGetString.Renderer));
Logger.DebugS("clyde.oal", "OpenAL Version: {0}", AL.Get(ALGetString.Version));
}
private void _audioOpenDevice()
@@ -84,7 +84,7 @@ namespace Robust.Client.Graphics.Clyde
_openALDevice = Alc.OpenDevice(preferredDevice);
if (_openALDevice == IntPtr.Zero)
{
Logger.WarningS("oal", "Unable to open preferred audio device '{0}': {1}. Falling back default.",
Logger.WarningS("clyde.oal", "Unable to open preferred audio device '{0}': {1}. Falling back default.",
preferredDevice, Alc.GetError(IntPtr.Zero));
_openALDevice = Alc.OpenDevice(null);
@@ -141,7 +141,7 @@ namespace Robust.Client.Graphics.Clyde
// Clear out finalized audio sources.
while (_sourceDisposeQueue.TryDequeue(out var handle))
{
Logger.DebugS("oal", "Cleaning out source {0} which finalized in another thread.", handle);
Logger.DebugS("clyde.oal", "Cleaning out source {0} which finalized in another thread.", handle);
AL.DeleteSource(handle);
_checkAlError();
_audioSources.Remove(handle);
@@ -150,7 +150,7 @@ namespace Robust.Client.Graphics.Clyde
// Clear out finalized buffered audio sources.
while (_bufferedSourceDisposeQueue.TryDequeue(out var handle))
{
Logger.DebugS("oal", "Cleaning out buffered source {0} which finalized in another thread.", handle);
Logger.DebugS("clyde.oal", "Cleaning out buffered source {0} which finalized in another thread.", handle);
AL.DeleteSource((int) handle);
_checkAlError();
_bufferedAudioSources.Remove(handle);
@@ -196,7 +196,7 @@ namespace Robust.Client.Graphics.Clyde
var error = Alc.GetError(device);
if (error != AlcError.NoError)
{
Logger.ErrorS("oal", "[{0}:{1}] ALC error: {2}", callerMember, callerLineNumber, error);
Logger.ErrorS("clyde.oal", "[{0}:{1}] ALC error: {2}", callerMember, callerLineNumber, error);
}
}
@@ -206,7 +206,7 @@ namespace Robust.Client.Graphics.Clyde
var error = AL.GetError();
if (error != ALError.NoError)
{
Logger.ErrorS("oal", "[{0}:{1}] AL error: {2}", callerMember, callerLineNumber, error);
Logger.ErrorS("clyde.oal", "[{0}:{1}] AL error: {2}", callerMember, callerLineNumber, error);
}
}
@@ -421,7 +421,7 @@ namespace Robust.Client.Graphics.Clyde
if (_sourceStream.ChannelCount > 1 && !_didPositionWarning)
{
_didPositionWarning = true;
Logger.WarningS("oal",
Logger.WarningS("clyde.oal",
"Attempting to set position on audio source with multiple audio channels! Stream: '{0}'",
_sourceStream.Name);
}

View File

@@ -91,7 +91,7 @@ namespace Robust.Client.Graphics.Clyde
{
_drawSplash(_renderHandle);
_flushRenderHandle(_renderHandle);
_window.SwapBuffers();
SwapBuffers();
return;
}
@@ -231,7 +231,7 @@ namespace Robust.Client.Graphics.Clyde
}
// And finally, swap those buffers!
_window.SwapBuffers();
SwapBuffers();
}
private void _drawSplash(IRenderHandle handle)
@@ -438,7 +438,7 @@ namespace Robust.Client.Graphics.Clyde
ref var s = ref command.Scissor.Scissor;
// Don't forget to flip it, these coordinates have bottom left as origin.
GL.Scissor(s.Left, _window.Height - s.Bottom, s.Width, s.Height);
GL.Scissor(s.Left, _screenSize.Y - s.Bottom, s.Width, s.Height);
}
else if (oldIsScissoring)
{

View File

@@ -0,0 +1,453 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Input;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.UserInterface;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using ErrorCode = OpenToolkit.GraphicsLibraryFramework.ErrorCode;
using FrameEventArgs = Robust.Shared.Timing.FrameEventArgs;
using Image = SixLabors.ImageSharp.Image;
using Vector2 = Robust.Shared.Maths.Vector2;
using GlfwImage = OpenToolkit.GraphicsLibraryFramework.Image;
using Monitor = OpenToolkit.GraphicsLibraryFramework.Monitor;
namespace Robust.Client.Graphics.Clyde
{
internal unsafe partial class Clyde
{
// Keep delegates around to prevent GC issues.
private GLFWCallbacks.ErrorCallback _errorCallback;
private GLFWCallbacks.CharCallback _charCallback;
private GLFWCallbacks.CursorPosCallback _cursorPosCallback;
private GLFWCallbacks.KeyCallback _keyCallback;
private GLFWCallbacks.MouseButtonCallback _mouseButtonCallback;
private GLFWCallbacks.ScrollCallback _scrollCallback;
private GLFWCallbacks.WindowCloseCallback _windowCloseCallback;
private GLFWCallbacks.WindowSizeCallback _windowSizeCallback;
private bool _glfwInitialized = false;
private GraphicsContext _graphicsContext;
private Window* _glfwWindow;
private Vector2i _screenSize;
private Thread _mainThread;
private Vector2 _lastMousePos;
public override Vector2i ScreenSize => _screenSize;
public Vector2 MouseScreenPosition => _lastMousePos;
private bool InitGlfw()
{
StoreCallbacks();
GLFW.SetErrorCallback(_errorCallback);
if (!GLFW.Init())
{
Logger.FatalS("clyde.win", "Failed to initialize GLFW!");
return false;
}
_glfwInitialized = true;
var version = GLFW.GetVersionString();
Logger.DebugS("clyde.win", "GLFW initialized, version: {0}.", version);
return true;
}
private bool InitWindowing()
{
_mainThread = Thread.CurrentThread;
if (!InitGlfw())
{
return false;
}
InitWindow();
return true;
}
private void InitWindow()
{
GLFW.WindowHint(WindowHintBool.SrgbCapable, true);
GLFW.WindowHint(WindowHintInt.ContextVersionMajor, MinimumOpenGLVersion.Major);
GLFW.WindowHint(WindowHintInt.ContextVersionMinor, MinimumOpenGLVersion.Minor);
GLFW.WindowHint(WindowHintBool.OpenGLForwardCompat, true);
GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Core);
#if DEBUG
GLFW.WindowHint(WindowHintBool.OpenGLDebugContext, true);
#endif
GLFW.WindowHint(WindowHintString.X11ClassName, "SS14");
GLFW.WindowHint(WindowHintString.X11InstanceName, "SS14");
var width = _configurationManager.GetCVar<int>("display.width");
var height = _configurationManager.GetCVar<int>("display.height");
Monitor* monitor = null;
if (WindowMode == WindowMode.Fullscreen)
{
monitor = GLFW.GetPrimaryMonitor();
var mode = GLFW.GetVideoMode(monitor);
width = mode->Width;
height = mode->Height;
}
_glfwWindow = GLFW.CreateWindow(width, height, string.Empty, monitor, null);
LoadWindowIcon();
GLFW.SetCharCallback(_glfwWindow, _charCallback);
GLFW.SetKeyCallback(_glfwWindow, _keyCallback);
GLFW.SetWindowCloseCallback(_glfwWindow, _windowCloseCallback);
GLFW.SetCursorPosCallback(_glfwWindow, _cursorPosCallback);
GLFW.SetWindowSizeCallback(_glfwWindow, _windowSizeCallback);
GLFW.SetScrollCallback(_glfwWindow, _scrollCallback);
GLFW.SetMouseButtonCallback(_glfwWindow, _mouseButtonCallback);
GLFW.MakeContextCurrent(_glfwWindow);
VSyncChanged();
GLFW.GetFramebufferSize(_glfwWindow, out var fbW, out var fbH);
_screenSize = (fbW, fbH);
InitGLContext();
// Initializing OTK 3 seems to mess with the current context, so ensure it's still set.
// This took me fucking *forever* to debug because this manifested differently on nvidia drivers vs intel mesa.
// So I thought it was a calling convention issue with the calli OpenTK emits.
// Because, in my tests, I had InitGLContext() AFTER the test with a delegate-based invoke of the proc.
GLFW.MakeContextCurrent(_glfwWindow);
InitOpenGL();
}
private void LoadWindowIcon()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
// Does nothing on macOS so don't bother.
return;
}
var icons = new List<Image<Rgba32>>();
foreach (var file in _resourceCache.ContentFindFiles("/Textures/Logo/icon"))
{
if (file.Extension != "png")
{
continue;
}
using (var stream = _resourceCache.ContentFileRead(file))
{
var image = Image.Load(stream);
icons.Add(image);
}
}
SetWindowIcon(icons);
}
private void SetWindowIcon(IEnumerable<Image<Rgba32>> icons)
{
// 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();
Span<GCHandle> handles = stackalloc GCHandle[images.Count];
Span<GlfwImage> glfwImages = new 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(_glfwWindow, glfwImages);
foreach (var handle in handles)
{
handle.Free();
}
}
private void InitGLContext()
{
// Initialize the OpenTK 3 GL context with GLFW.
_graphicsContext = new GraphicsContext(new ContextHandle((IntPtr) _glfwWindow), GLFW.GetProcAddress,
() => new ContextHandle((IntPtr) GLFW.GetCurrentContext()));
}
private void ShutdownWindowing()
{
if (_glfwInitialized)
{
Logger.DebugS("clyde.win", "Terminating GLFW.");
GLFW.Terminate();
}
}
private static void OnGlfwError(ErrorCode code, string description)
{
Logger.ErrorS("clyde.win.glfw", "GLFW Error: [{0}] {1}", code, description);
}
private void OnGlfwChar(Window* window, uint codepoint)
{
_gameController.TextEntered(new TextEventArgs(codepoint));
}
private void OnGlfwCursorPos(Window* window, double x, double y)
{
var newPos = new Vector2((float) x, (float) y);
var delta = newPos - _lastMousePos;
_lastMousePos = newPos;
var ev = new MouseMoveEventArgs(delta, newPos);
_gameController.MouseMove(ev);
}
private void OnGlfwKey(Window* window, Keys key, int scanCode, InputAction action, KeyModifiers mods)
{
EmitKeyEvent(Keyboard.ConvertGlfwKey(key), action, mods);
}
private void OnGlfwMouseButton(Window* window, MouseButton button, InputAction action, KeyModifiers mods)
{
EmitKeyEvent(Mouse.MouseButtonToKey(Mouse.ConvertGlfwButton(button)), action, mods);
}
private void EmitKeyEvent(Keyboard.Key key, InputAction action, KeyModifiers mods)
{
var shift = mods.HasFlag(KeyModifiers.Shift);
var alt = mods.HasFlag(KeyModifiers.Alt);
var control = mods.HasFlag(KeyModifiers.Control);
var system = mods.HasFlag(KeyModifiers.Super);
var ev = new KeyEventArgs(
key,
action == InputAction.Repeat,
alt, control, shift, system);
switch (action)
{
case InputAction.Release:
_gameController.KeyUp(ev);
break;
case InputAction.Press:
case InputAction.Repeat:
_gameController.KeyDown(ev);
break;
default:
throw new ArgumentOutOfRangeException(nameof(action), action, null);
}
}
private void OnGlfwScroll(Window* window, double offsetX, double offsetY)
{
var ev = new MouseWheelEventArgs(((float) offsetX, (float) offsetY), _lastMousePos);
_gameController.MouseWheel(ev);
}
private void OnGlfwWindowClose(Window* window)
{
_gameController.Shutdown("Window closed");
}
private void OnGlfwWindowSize(Window* window, int width, int height)
{
var oldSize = _screenSize;
GLFW.GetFramebufferSize(window, out var fbW, out var fbH);
_screenSize = (fbW, fbH);
GL.Viewport(0, 0, fbW, fbH);
if (fbW != 0 && fbH != 0)
{
_regenerateLightRenderTarget();
}
OnWindowResized?.Invoke(new WindowResizedEventArgs(oldSize, _screenSize));
}
private void StoreCallbacks()
{
_errorCallback = OnGlfwError;
_charCallback = OnGlfwChar;
_cursorPosCallback = OnGlfwCursorPos;
_keyCallback = OnGlfwKey;
_mouseButtonCallback = OnGlfwMouseButton;
_scrollCallback = OnGlfwScroll;
_windowCloseCallback = OnGlfwWindowClose;
_windowSizeCallback = OnGlfwWindowSize;
}
public override void SetWindowTitle(string title)
{
if (title == null)
{
throw new ArgumentNullException(nameof(title));
}
GLFW.SetWindowTitle(_glfwWindow, title);
}
public void ProcessInput(FrameEventArgs frameEventArgs)
{
GLFW.PollEvents();
}
private void SwapBuffers()
{
GLFW.SwapBuffers(_glfwWindow);
}
protected override void VSyncChanged()
{
if (_glfwWindow == null)
{
return;
}
GLFW.SwapInterval(VSync ? 1 : 0);
}
protected override void WindowModeChanged()
{
if (_glfwWindow == null)
{
return;
}
if (WindowMode == WindowMode.Fullscreen)
{
var monitor = GLFW.GetPrimaryMonitor();
var mode = GLFW.GetVideoMode(monitor);
GLFW.SetWindowMonitor(_glfwWindow, GLFW.GetPrimaryMonitor(), 0, 0, mode->Width, mode->Height,
mode->RefreshRate);
}
else
{
GLFW.SetWindowMonitor(_glfwWindow, null, 0, 0, 1280, 720, 0);
}
}
string IClipboardManager.GetText()
{
return GLFW.GetClipboardString(_glfwWindow);
}
void IClipboardManager.SetText(string text)
{
GLFW.SetClipboardString(_glfwWindow, text);
}
private sealed class ClydeWindowInfo : IWindowInfo
{
public ClydeWindowInfo(Window* handle)
{
Handle = (IntPtr) handle;
}
public void Dispose()
{
// Nothing.
}
public IntPtr Handle { get; }
}
}
}
/*
var width = _configurationManager.GetCVar<int>("display.width");
var height = _configurationManager.GetCVar<int>("display.height");
_window = new GameWindow(
width,
height,
GraphicsMode.Default,
string.Empty,
GameWindowFlags.Default,
DisplayDevice.Default,
3, 3,
#if DEBUG
GraphicsContextFlags.Debug | GraphicsContextFlags.ForwardCompatible
#else
GraphicsContextFlags.ForwardCompatible
#endif
)
{
Visible = true
};
// Actually set VSync.
VSyncChanged();
WindowModeChanged();
var winSize = _window.ClientSize;
_screenSize = new Vector2i(winSize.Width, winSize.Height);
_mainThread = Thread.CurrentThread;
_window.KeyDown += (sender, eventArgs) => { _gameController.KeyDown((KeyEventArgs) eventArgs); };
_window.KeyUp += (sender, eventArgs) => { _gameController.KeyUp((KeyEventArgs) eventArgs); };
_window.Closed += _onWindowClosed;
_window.Resize += (sender, eventArgs) =>
{
var oldSize = _screenSize;
var newWinSize = _window.ClientSize;
_screenSize = new Vector2i(newWinSize.Width, newWinSize.Height);
GL.Viewport(0, 0, newWinSize.Width, newWinSize.Height);
if (newWinSize.Width != 0 && newWinSize.Height != 0)
{
_regenerateLightRenderTarget();
}
OnWindowResized?.Invoke(new WindowResizedEventArgs(oldSize, _screenSize));
};
_window.MouseDown += (sender, eventArgs) => { _gameController.KeyDown((KeyEventArgs) eventArgs); };
_window.MouseUp += (sender, eventArgs) => { _gameController.KeyUp((KeyEventArgs) eventArgs); };
_window.MouseMove += (sender, eventArgs) =>
{
MouseScreenPosition = new Vector2(eventArgs.X, eventArgs.Y);
_gameController.MouseMove((MouseMoveEventArgs) eventArgs);
};
_window.MouseWheel += (sender, eventArgs) =>
{
_gameController.MouseWheel((MouseWheelEventArgs) eventArgs);
};
_window.KeyPress += (sender, eventArgs) =>
{
// If this is a surrogate it has to be specifically handled and I'm not doing that yet.
DebugTools.Assert(!char.IsSurrogate(eventArgs.KeyChar));
_gameController.TextEntered(new TextEventArgs(eventArgs.KeyChar));
};
using (var iconFile = _resourceCache.ContentFileRead("/Textures/Logo/icon.ico"))
{
_window.Icon = new Icon(iconFile);
}
InitGLContext();
InitOpenGL();
*/

View File

@@ -29,29 +29,29 @@ using Matrix3 = Robust.Shared.Maths.Matrix3;
using Vector2 = Robust.Shared.Maths.Vector2;
using Vector3 = Robust.Shared.Maths.Vector3;
using FrameEventArgs = Robust.Shared.Timing.FrameEventArgs;
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
namespace Robust.Client.Graphics.Clyde
{
/// <summary>
/// Responsible for most things rendering on OpenGL mode.
/// </summary>
internal sealed partial class Clyde : DisplayManager, IClydeInternal, IClydeAudio, IDisposable
internal sealed partial class Clyde : ClydeBase, IClydeInternal, IClydeAudio, IDisposable
{
#pragma warning disable 649
[Shared.IoC.Dependency] private readonly IResourceCache _resourceCache;
[Shared.IoC.Dependency] private readonly IEyeManager _eyeManager;
[Shared.IoC.Dependency] private readonly IMapManager _mapManager;
[Shared.IoC.Dependency] private readonly IOverlayManager _overlayManager;
[Shared.IoC.Dependency] private readonly IComponentManager _componentManager;
[Shared.IoC.Dependency] private readonly IUserInterfaceManagerInternal _userInterfaceManager;
[Shared.IoC.Dependency] private readonly IClydeTileDefinitionManager _tileDefinitionManager;
[Shared.IoC.Dependency] private readonly ILightManager _lightManager;
[Dependency] private readonly IResourceCache _resourceCache;
[Dependency] private readonly IEyeManager _eyeManager;
[Dependency] private readonly IMapManager _mapManager;
[Dependency] private readonly IOverlayManager _overlayManager;
[Dependency] private readonly IComponentManager _componentManager;
[Dependency] private readonly IUserInterfaceManagerInternal _userInterfaceManager;
[Dependency] private readonly IClydeTileDefinitionManager _tileDefinitionManager;
[Dependency] private readonly ILightManager _lightManager;
#pragma warning restore 649
private static readonly Version MinimumOpenGLVersion = new Version(3, 3);
private Vector2i _screenSize;
private GameWindow _window;
//private GameWindow _window;
private const int ProjViewBindingIndex = 0;
private const int UniformConstantsBindingIndex = 1;
@@ -90,7 +90,6 @@ namespace Robust.Client.Graphics.Clyde
// Thread the window is instantiated on.
// OpenGL is allergic to multi threading so we need to check this.
private Thread _mainThread;
private bool _drawingSplash;
private ShaderProgram _currentProgram;
@@ -98,17 +97,6 @@ namespace Robust.Client.Graphics.Clyde
private ClydeDebugStats _debugStats;
public override Vector2i ScreenSize
{
get => _screenSize;
set
{
_window.Size = new Size(value.X, value.Y);
var s = _window.ClientSize;
_screenSize = new Vector2i(s.Width, s.Height);
}
}
private readonly HashSet<string> OpenGLExtensions = new HashSet<string>();
private bool HasKHRDebug => HasExtension("GL_KHR_debug");
@@ -118,18 +106,18 @@ namespace Robust.Client.Graphics.Clyde
private bool _disposing;
private bool _lite;
public override void SetWindowTitle(string title)
{
_window.Title = title;
}
public override void Initialize(bool lite = false)
public override bool Initialize(bool lite = false)
{
_debugStats = new ClydeDebugStats();
_lite = lite;
_initWindow();
if (!InitWindowing())
{
return false;
}
_initializeAudio();
ReloadConfig();
return true;
}
public void FrameProcess(FrameEventArgs eventArgs)
@@ -139,17 +127,11 @@ namespace Robust.Client.Graphics.Clyde
ClearDeadShaderInstances();
}
public void ProcessInput(FrameEventArgs frameEventArgs)
{
_window.ProcessEvents();
}
public void Ready()
{
_drawingSplash = false;
}
public Vector2 MouseScreenPosition { get; private set; }
public IClydeDebugInfo DebugInfo { get; private set; }
public IClydeDebugStats DebugStats => _debugStats;
@@ -178,81 +160,7 @@ namespace Robust.Client.Graphics.Clyde
public override event Action<WindowResizedEventArgs> OnWindowResized;
private void _initWindow()
{
var width = _configurationManager.GetCVar<int>("display.width");
var height = _configurationManager.GetCVar<int>("display.height");
_window = new GameWindow(
width,
height,
GraphicsMode.Default,
string.Empty,
GameWindowFlags.Default,
DisplayDevice.Default,
3, 3,
#if DEBUG
GraphicsContextFlags.Debug | GraphicsContextFlags.ForwardCompatible
#else
GraphicsContextFlags.ForwardCompatible
#endif
)
{
Visible = true
};
// Actually set VSync.
VSyncChanged();
WindowModeChanged();
var winSize = _window.ClientSize;
_screenSize = new Vector2i(winSize.Width, winSize.Height);
_mainThread = Thread.CurrentThread;
_window.KeyDown += (sender, eventArgs) => { _gameController.KeyDown((KeyEventArgs) eventArgs); };
_window.KeyUp += (sender, eventArgs) => { _gameController.KeyUp((KeyEventArgs) eventArgs); };
_window.Closed += _onWindowClosed;
_window.Resize += (sender, eventArgs) =>
{
var oldSize = _screenSize;
var newWinSize = _window.ClientSize;
_screenSize = new Vector2i(newWinSize.Width, newWinSize.Height);
GL.Viewport(0, 0, newWinSize.Width, newWinSize.Height);
if (newWinSize.Width != 0 && newWinSize.Height != 0)
{
_regenerateLightRenderTarget();
}
OnWindowResized?.Invoke(new WindowResizedEventArgs(oldSize, _screenSize));
};
_window.MouseDown += (sender, eventArgs) => { _gameController.KeyDown((KeyEventArgs) eventArgs); };
_window.MouseUp += (sender, eventArgs) => { _gameController.KeyUp((KeyEventArgs) eventArgs); };
_window.MouseMove += (sender, eventArgs) =>
{
MouseScreenPosition = new Vector2(eventArgs.X, eventArgs.Y);
_gameController.MouseMove((MouseMoveEventArgs) eventArgs);
};
_window.MouseWheel += (sender, eventArgs) =>
{
_gameController.MouseWheel((MouseWheelEventArgs) eventArgs);
};
_window.KeyPress += (sender, eventArgs) =>
{
// If this is a surrogate it has to be specifically handled and I'm not doing that yet.
DebugTools.Assert(!char.IsSurrogate(eventArgs.KeyChar));
_gameController.TextEntered(new TextEventArgs(eventArgs.KeyChar));
};
using (var iconFile = _resourceCache.ContentFileRead("/Textures/Logo/icon.ico"))
{
_window.Icon = new Icon(iconFile);
}
_initOpenGL();
}
private void _initOpenGL()
private void InitOpenGL()
{
_loadExtensions();
@@ -261,9 +169,9 @@ namespace Robust.Client.Graphics.Clyde
var vendor = GL.GetString(StringName.Vendor);
var renderer = GL.GetString(StringName.Renderer);
var version = GL.GetString(StringName.Version);
Logger.DebugS("ogl", "OpenGL Vendor: {0}", vendor);
Logger.DebugS("ogl", "OpenGL Renderer: {0}", renderer);
Logger.DebugS("ogl", "OpenGL Version: {0}", version);
Logger.DebugS("clyde.ogl", "OpenGL Vendor: {0}", vendor);
Logger.DebugS("clyde.ogl", "OpenGL Renderer: {0}", renderer);
Logger.DebugS("clyde.ogl", "OpenGL Version: {0}", version);
_loadVendorSettings(vendor, renderer, version);
var major = GL.GetInteger(GetPName.MajorVersion);
@@ -406,7 +314,7 @@ namespace Robust.Client.Graphics.Clyde
{
if (!HasKHRDebug)
{
Logger.DebugS("ogl", "KHR_debug not present, OpenGL debug logging not enabled.");
Logger.DebugS("clyde.ogl", "KHR_debug not present, OpenGL debug logging not enabled.");
return;
}
@@ -550,35 +458,10 @@ namespace Robust.Client.Graphics.Clyde
public void Dispose()
{
_disposing = true;
_window.Dispose();
ShutdownWindowing();
_shutdownAudio();
}
public IntPtr GetNativeWindowHandle()
{
return _window.WindowInfo.Handle;
}
protected override void VSyncChanged()
{
if (_window == null)
{
return;
}
_window.VSync = VSync ? VSyncMode.On : VSyncMode.Off;
}
protected override void WindowModeChanged()
{
if (_window == null)
{
return;
}
_window.WindowState = WindowMode == WindowMode.Fullscreen ? WindowState.Fullscreen : WindowState.Normal;
}
protected override void HighResLightsChanged(bool newValue)
{
_quartResLights = !newValue;
@@ -599,18 +482,6 @@ namespace Robust.Client.Graphics.Clyde
}
}
private void _onWindowClosed(object sender, EventArgs args)
{
if (_disposing)
{
// OpenTK seems to fire Closed when closing the window via Dispose on Windows.
// So uh, ignore it.
return;
}
_gameController.Shutdown("Window closed");
}
[StructLayout(LayoutKind.Sequential)]
[PublicAPI]
private readonly struct Vertex2D

View File

@@ -13,10 +13,10 @@ namespace Robust.Client.Graphics.Clyde
/// <summary>
/// Hey look, it's Clyde's evil twin brother!
/// </summary>
internal sealed class ClydeHeadless : DisplayManager, IClydeInternal, IClydeAudio
internal sealed class ClydeHeadless : ClydeBase, IClydeInternal, IClydeAudio
{
// Would it make sense to report a fake resolution like 720p here so code doesn't break? idk.
public override Vector2i ScreenSize { get; set; } = (1280, 720);
public override Vector2i ScreenSize { get; } = (1280, 720);
public ShaderInstance InstanceShader(ClydeHandle handle)
{
@@ -32,9 +32,9 @@ namespace Robust.Client.Graphics.Clyde
// Nada.
}
public override void Initialize(bool lite = false)
public override bool Initialize(bool lite = false)
{
// Nada.
return true;
}
#pragma warning disable CS0067
@@ -109,9 +109,14 @@ namespace Robust.Client.Graphics.Clyde
return DummyBufferedAudioSource.Instance;
}
public IntPtr GetNativeWindowHandle()
public string GetText()
{
return default;
return string.Empty;
}
public void SetText(string text)
{
// Nada.
}
private class DummyAudioSource : IClydeAudioSource

View File

@@ -18,7 +18,7 @@ namespace Robust.Client.Graphics
/// <summary>
/// Manages the game window, resolutions, fullscreen mode, VSync, etc...
/// </summary>
internal abstract class DisplayManager : IPostInjectInit
internal abstract class ClydeBase : IPostInjectInit
{
private const string CVarVSync = "display.vsync";
private const string CVarWindowMode = "display.windowmode";
@@ -41,9 +41,9 @@ namespace Robust.Client.Graphics
_configurationManager.RegisterCVar("audio.device", "");
}
public abstract Vector2i ScreenSize { get; set; }
public abstract Vector2i ScreenSize { get; }
public abstract void SetWindowTitle(string title);
public abstract void Initialize(bool lite=false);
public abstract bool Initialize(bool lite=false);
protected virtual void ReloadConfig()
{

View File

@@ -7,10 +7,23 @@ using Robust.Shared.Maths;
namespace Robust.Client.Input
{
public abstract class InputEventArgs : EventArgs
{
public bool Handled { get; private set; }
/// <summary>
/// Mark this event as handled.
/// </summary>
public void Handle()
{
Handled = true;
}
}
/// <summary>
/// Generic input event that has modifier keys like control.
/// </summary>
public abstract class ModifierInputEventArgs : EventArgs
public abstract class ModifierInputEventArgs : InputEventArgs
{
/// <summary>
/// Whether the alt key (⌥ Option on MacOS) is held.
@@ -32,8 +45,6 @@ namespace Robust.Client.Input
/// </summary>
public bool System { get; }
public bool Handled { get; private set; }
protected ModifierInputEventArgs(bool alt, bool control, bool shift, bool system)
{
Alt = alt;
@@ -41,14 +52,6 @@ namespace Robust.Client.Input
Shift = shift;
System = system;
}
/// <summary>
/// Mark this event as handled.
/// </summary>
public void Handle()
{
Handled = true;
}
}
public class TextEventArgs : EventArgs
@@ -79,41 +82,17 @@ namespace Robust.Client.Input
Key = key;
IsRepeat = repeat;
}
public static explicit operator KeyEventArgs(OpenTK.Input.KeyboardKeyEventArgs args)
{
return new KeyEventArgs(Keyboard.ConvertOpenTKKey(args.Key), args.IsRepeat, args.Alt, args.Control, args.Shift, false);
}
public static explicit operator KeyEventArgs(OpenTK.Input.MouseButtonEventArgs args)
{
return new KeyEventArgs(Mouse.MouseButtonToKey(Mouse.ConvertOpenTKButton(args.Button)), false,
false, false, false, false);
}
}
public abstract class MouseEventArgs : ModifierInputEventArgs
public abstract class MouseEventArgs : InputEventArgs
{
/// <summary>
/// <c>InputEventMouse.button_mask</c> in Godot.
/// Which mouse buttons are currently held maybe?
/// </summary>
public Mouse.ButtonMask ButtonMask { get; }
/// <summary>
/// Position of the mouse relative to the screen.
/// </summary>
public Vector2 Position { get; }
protected MouseEventArgs(Mouse.ButtonMask buttonMask,
Vector2 position,
bool alt,
bool control,
bool shift,
bool system)
: base(alt, control, shift, system)
protected MouseEventArgs(Vector2 position)
{
ButtonMask = buttonMask;
Position = position;
}
}
@@ -125,66 +104,11 @@ namespace Robust.Client.Input
/// </summary>
public Mouse.Button Button { get; }
/// <summary>
/// True if this action was a double click.
/// Can't be true if this was a release event.
/// </summary>
public bool DoubleClick { get; }
public ClickType ClickType
{
get
{
ClickType type = ClickType.None;
switch (Button)
{
case Mouse.Button.Left:
type = ClickType.Left;
break;
case Mouse.Button.Right:
type = ClickType.Right;
break;
case Mouse.Button.Middle:
type = ClickType.Middle;
break;
default:
return type;
}
if (Alt)
type |= ClickType.Alt;
if (Control)
type |= ClickType.Cntrl;
if (Shift)
type |= ClickType.Shift;
if (System)
type |= ClickType.System;
return type;
}
}
// ALL the parameters!
public MouseButtonEventArgs(Mouse.Button button,
bool doubleClick,
Mouse.ButtonMask buttonMask,
Vector2 position,
bool alt,
bool control,
bool shift,
bool system)
: base(buttonMask, position, alt, control, shift, system)
public MouseButtonEventArgs(Mouse.Button button, Vector2 position)
: base(position)
{
Button = button;
DoubleClick = doubleClick;
}
public static explicit operator MouseButtonEventArgs(OpenTK.Input.MouseButtonEventArgs inputEvent)
{
return new MouseButtonEventArgs(
Mouse.ConvertOpenTKButton(inputEvent.Button),
false, Mouse.ButtonMask.None,
new Vector2(inputEvent.X, inputEvent.Y),
false, false, false, false);
}
}
@@ -196,29 +120,11 @@ namespace Robust.Client.Input
public Vector2 Delta { get; }
// ALL the parameters!
public MouseWheelEventArgs(Vector2 delta,
Mouse.ButtonMask buttonMask,
Vector2 position,
bool alt,
bool control,
bool shift,
bool system)
: base(buttonMask, position, alt, control, shift, system)
public MouseWheelEventArgs(Vector2 delta, Vector2 position)
: base(position)
{
Delta = delta;
}
public static explicit operator MouseWheelEventArgs(OpenTK.Input.MouseWheelEventArgs inputEvent)
{
return new MouseWheelEventArgs(
// OpenTK 3 doesn't support horizontal scrolling.
// This is a necessary feature, so the events do have the API.
// Eventually when we switch to OpenTK 4 this will be fixed.
(0, inputEvent.DeltaPrecise),
Mouse.ButtonMask.None,
new Vector2(inputEvent.X, inputEvent.Y),
false, false, false, false);
}
}
public class MouseMoveEventArgs : MouseEventArgs
@@ -228,35 +134,11 @@ namespace Robust.Client.Input
/// </summary>
public Vector2 Relative { get; }
// TODO: Godot's docs aren't exactly clear on what this is.
// Speed how?
/// <summary>
/// The speed of the movement.
/// </summary>
public Vector2 Speed { get; }
// ALL the parameters!
public MouseMoveEventArgs(Vector2 relative,
Vector2 speed,
Mouse.ButtonMask buttonMask,
Vector2 position,
bool alt,
bool control,
bool shift,
bool system)
: base(buttonMask, position, alt, control, shift, system)
public MouseMoveEventArgs(Vector2 relative, Vector2 position)
: base(position)
{
Relative = relative;
Speed = speed;
}
public static explicit operator MouseMoveEventArgs(OpenTK.Input.MouseMoveEventArgs inputEvent)
{
return new MouseMoveEventArgs(
new Vector2(inputEvent.XDelta, inputEvent.YDelta),
Vector2.Zero, Mouse.ButtonMask.None,
new Vector2(inputEvent.X, inputEvent.Y),
false, false, false, false);
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using TKKey = OpenTK.Input.Key;
using TKButton = OpenTK.Input.MouseButton;
using System.Collections.Generic;
using GlfwKey = OpenToolkit.GraphicsLibraryFramework.Keys;
using GlfwButton = OpenToolkit.GraphicsLibraryFramework.MouseButton;
namespace Robust.Client.Input
{
@@ -24,25 +23,12 @@ namespace Robust.Client.Input
LastButton,
}
/// <summary>
/// Represents mouse buttons, but in bitflag form.
/// </summary>
[Flags]
public enum ButtonMask
{
// These match Godot's
None = 0,
Left = 1,
Middle = 2,
Right = 4,
}
public static Keyboard.Key MouseButtonToKey(Button button)
{
return _mouseKeyMap[button];
}
public static Button ConvertOpenTKButton(OpenTK.Input.MouseButton button)
public static Button ConvertGlfwButton(GlfwButton button)
{
return _openTKButtonMap[button];
}
@@ -61,17 +47,16 @@ namespace Robust.Client.Input
{Button.LastButton, Keyboard.Key.Unknown},
};
private static readonly Dictionary<TKButton, Button> _openTKButtonMap = new Dictionary<TKButton, Button>
private static readonly Dictionary<GlfwButton, Button> _openTKButtonMap = new Dictionary<GlfwButton, Button>
{
{TKButton.Left, Button.Left},
{TKButton.Middle, Button.Middle},
{TKButton.Right, Button.Right},
{TKButton.Button1, Button.Button4},
{TKButton.Button2, Button.Button5},
{TKButton.Button3, Button.Button6},
{TKButton.Button4, Button.Button7},
{TKButton.Button5, Button.Button8},
{TKButton.Button6, Button.Button9},
{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},
};
}
@@ -151,13 +136,11 @@ namespace Robust.Client.Input
SemiColon,
Comma,
Period,
Quote,
Apostrophe,
Slash,
BackSlash,
Tilde,
Equal,
Dash,
Space,
Return,
NumpadEnter,
@@ -169,13 +152,12 @@ namespace Robust.Client.Input
Home,
Insert,
Delete,
Plus,
Minus,
Asterisk,
NumpadAdd,
NumpadSubtract,
NumpadDivide,
NumpadMultiply,
NumpadDecimal,
Left,
Right,
Up,
@@ -198,9 +180,9 @@ namespace Robust.Client.Input
Pause,
}
internal static Key ConvertOpenTKKey(TKKey key)
internal static Key ConvertGlfwKey(GlfwKey key)
{
if (OpenTKKeyMap.TryGetValue(key, out var result))
if (_glfwKeyMap.TryGetValue(key, out var result))
{
return result;
}
@@ -208,113 +190,111 @@ namespace Robust.Client.Input
return Key.Unknown;
}
private static readonly Dictionary<TKKey, Key> OpenTKKeyMap = new Dictionary<OpenTK.Input.Key, Key>
private static readonly Dictionary<GlfwKey, Key> _glfwKeyMap = new Dictionary<GlfwKey, Key>
{
// TODO: Missing keys OpenTK has but we don't:
// Scroll Lock, Caps Lock, Print Screen, Num Lock, Clear, Sleep, F keys above 15, NonUSBackSlash, LastKey.
{TKKey.Unknown, Key.Unknown},
{TKKey.LShift, Key.Shift},
{TKKey.RShift, Key.Shift},
{TKKey.LControl, Key.Control},
{TKKey.RControl, Key.Control},
{TKKey.LAlt, Key.Alt},
{TKKey.RAlt, Key.Alt},
{TKKey.LWin, Key.LSystem},
{TKKey.RWin, Key.RSystem},
{TKKey.Menu, Key.Menu},
{TKKey.F1, Key.F1},
{TKKey.F2, Key.F2},
{TKKey.F3, Key.F3},
{TKKey.F4, Key.F4},
{TKKey.F5, Key.F5},
{TKKey.F6, Key.F6},
{TKKey.F7, Key.F7},
{TKKey.F8, Key.F8},
{TKKey.F9, Key.F9},
{TKKey.F10, Key.F10},
{TKKey.F11, Key.F11},
{TKKey.F12, Key.F12},
{TKKey.F13, Key.F13},
{TKKey.F14, Key.F14},
{TKKey.F15, Key.F15},
{TKKey.Up, Key.Up},
{TKKey.Down, Key.Down},
{TKKey.Left, Key.Left},
{TKKey.Right, Key.Right},
{TKKey.Enter, Key.Return},
{TKKey.Escape, Key.Escape},
{TKKey.Space, Key.Space},
{TKKey.Tab, Key.Tab},
{TKKey.Back, Key.BackSpace},
{TKKey.Insert, Key.Insert},
{TKKey.Delete, Key.Delete},
{TKKey.PageUp, Key.PageUp},
{TKKey.PageDown, Key.PageDown},
{TKKey.Home, Key.Home},
{TKKey.End, Key.End},
{TKKey.Pause, Key.Pause},
{TKKey.Keypad0, Key.NumpadNum0},
{TKKey.Keypad1, Key.NumpadNum1},
{TKKey.Keypad2, Key.NumpadNum2},
{TKKey.Keypad3, Key.NumpadNum3},
{TKKey.Keypad4, Key.NumpadNum4},
{TKKey.Keypad5, Key.NumpadNum5},
{TKKey.Keypad6, Key.NumpadNum6},
{TKKey.Keypad7, Key.NumpadNum7},
{TKKey.Keypad8, Key.NumpadNum8},
{TKKey.Keypad9, Key.NumpadNum9},
{TKKey.KeypadDivide, Key.NumpadDivide},
{TKKey.KeypadMultiply, Key.NumpadMultiply},
{TKKey.KeypadMinus, Key.Minus},
{TKKey.KeypadAdd, Key.NumpadAdd},
{TKKey.KeypadEnter, Key.NumpadEnter},
{TKKey.A, Key.A},
{TKKey.B, Key.B},
{TKKey.C, Key.C},
{TKKey.D, Key.D},
{TKKey.E, Key.E},
{TKKey.F, Key.F},
{TKKey.G, Key.G},
{TKKey.H, Key.H},
{TKKey.I, Key.I},
{TKKey.J, Key.J},
{TKKey.K, Key.K},
{TKKey.L, Key.L},
{TKKey.M, Key.M},
{TKKey.N, Key.N},
{TKKey.O, Key.O},
{TKKey.P, Key.P},
{TKKey.Q, Key.Q},
{TKKey.R, Key.R},
{TKKey.S, Key.S},
{TKKey.T, Key.T},
{TKKey.U, Key.U},
{TKKey.V, Key.V},
{TKKey.W, Key.W},
{TKKey.X, Key.X},
{TKKey.Y, Key.Y},
{TKKey.Z, Key.Z},
{TKKey.Number0, Key.Num0},
{TKKey.Number1, Key.Num1},
{TKKey.Number2, Key.Num2},
{TKKey.Number3, Key.Num3},
{TKKey.Number4, Key.Num4},
{TKKey.Number5, Key.Num5},
{TKKey.Number6, Key.Num6},
{TKKey.Number7, Key.Num7},
{TKKey.Number8, Key.Num8},
{TKKey.Number9, Key.Num9},
{TKKey.Tilde, Key.Tilde},
{TKKey.Minus, Key.Minus},
{TKKey.Plus, Key.Plus},
{TKKey.LBracket, Key.LBracket},
{TKKey.RBracket, Key.RBracket},
{TKKey.Semicolon, Key.SemiColon},
{TKKey.Quote, Key.Quote},
{TKKey.Comma, Key.Comma},
{TKKey.Period, Key.Period},
{TKKey.Slash, Key.Slash},
{TKKey.BackSlash, Key.BackSlash},
{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.Pause, Key.Pause},
};
}
}

View File

@@ -7,6 +7,7 @@ using Robust.Client.Graphics;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Graphics.Shaders;
using Robust.Client.Interfaces.Input;
using Robust.Client.Interfaces.UserInterface;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
@@ -15,7 +16,7 @@ namespace Robust.Client.Interfaces.Graphics
{
public interface IClyde
{
Vector2i ScreenSize { get; set; }
Vector2i ScreenSize { get; }
void SetWindowTitle(string title);
event Action<WindowResizedEventArgs> OnWindowResized;
@@ -39,7 +40,7 @@ namespace Robust.Client.Interfaces.Graphics
IClydeBufferedAudioSource CreateBufferedAudioSource(int buffers);
}
internal interface IClydeInternal : IClyde
internal interface IClydeInternal : IClyde, IClipboardManager
{
// Basic main loop hooks.
void Render();
@@ -47,7 +48,7 @@ namespace Robust.Client.Interfaces.Graphics
void ProcessInput(FrameEventArgs frameEventArgs);
// Init.
void Initialize(bool lite=false);
bool Initialize(bool lite = false);
void Ready();
ClydeHandle LoadShader(ParsedShader shader, string name = null);
@@ -66,12 +67,6 @@ namespace Robust.Client.Interfaces.Graphics
IClydeDebugInfo DebugInfo { get; }
IClydeDebugStats DebugStats { get; }
/// <summary>
/// Gets the platform specific window handle exposed by OpenTK.
/// Seriously please avoid using this unless absolutely necessary.
/// </summary>
IntPtr GetNativeWindowHandle();
}
public interface IClydeAudioSource : IDisposable

View File

@@ -12,7 +12,7 @@ namespace Robust.Client.Interfaces
{
void SetCommandLineArgs(CommandLineArgs args);
bool LoadConfigAndUserData { get; set; }
void Startup();
bool Startup();
void MainLoop(GameController.DisplayMode mode);
string ContentRootDir { get; set; }
void KeyDown(KeyEventArgs keyEvent);

View File

@@ -2,15 +2,7 @@ namespace Robust.Client.Interfaces.UserInterface
{
public interface IClipboardManager
{
bool Available { get; }
string NotAvailableReason { get; }
string GetText();
void SetText(string text);
}
internal interface IClipboardManagerInternal : IClipboardManager
{
void Initialize();
}
}

View File

@@ -24,7 +24,6 @@
<PackageReference Include="SixLabors.Core" Version="1.0.0-beta0007" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0006" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0006" />
<PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.0'" Include="System.Drawing.Common" Version="4.6.0" />
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Memory" Version="4.5.3" />
<PackageReference Include="YamlDotNet" Version="6.1.2" />
<PackageReference Include="OpenTK" Version="3.1.0" />
@@ -32,6 +31,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
<ProjectReference Include="..\OpenToolkit.GraphicsLibraryFramework\OpenToolkit.GraphicsLibraryFramework.csproj" />
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />
</ItemGroup>
@@ -52,5 +52,5 @@
</EmbeddedResource>
</ItemGroup>
<Import Project="..\MSBuild\Robust.Engine.targets" />
<Target Name="RobustAfterBuild" DependsOnTargets="CopyMiscDependencies;CopySwnfd" AfterTargets="Build" />
<Target Name="RobustAfterBuild" DependsOnTargets="CopyMiscDependencies;CopySwnfd;CopyGlfw" AfterTargets="Build" />
</Project>

View File

@@ -1,89 +0,0 @@
using System;
using System.Diagnostics;
using Robust.Client.Interfaces.UserInterface;
using Robust.Shared.Utility;
namespace Robust.Client.UserInterface
{
internal sealed class ClipboardManagerLinux : IClipboardManagerInternal
{
public bool Available { get; private set; }
public string NotAvailableReason =>
// ReSharper disable once StringLiteralTypo
"Clipboard support on Linux is done with the 'xclip' utility. Please install it.";
public string GetText()
{
if (!Available)
{
throw new NotSupportedException();
}
var startInfo = new ProcessStartInfo
{
FileName = "xclip",
Arguments = "-o -selection clipboard",
RedirectStandardOutput = true,
StandardOutputEncoding = EncodingHelpers.UTF8,
UseShellExecute = false,
};
var process = Process.Start(startInfo);
DebugTools.AssertNotNull(process);
process.WaitForExit();
return process.StandardOutput.ReadToEnd();
}
public void SetText(string text)
{
if (!Available)
{
throw new NotSupportedException();
}
var startInfo = new ProcessStartInfo
{
FileName = "xclip",
Arguments = "-i -selection clipboard",
RedirectStandardInput = true,
UseShellExecute = false,
};
var process = Process.Start(startInfo);
DebugTools.AssertNotNull(process);
process.StandardInput.Write(text);
process.StandardInput.Close();
process.WaitForExit();
}
public async void Initialize()
{
try
{
var process = Process.Start(
new ProcessStartInfo
{
FileName = "xclip",
Arguments = "-version",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
});
if (process == null)
{
Available = false;
return;
}
await process.WaitForExitAsync();
Available = process.ExitCode == 0;
}
catch (Exception)
{
Available = false;
}
}
}
}

View File

@@ -1,26 +0,0 @@
using System;
using Robust.Client.Interfaces.UserInterface;
namespace Robust.Client.UserInterface
{
internal sealed class ClipboardManagerUnsupported : IClipboardManagerInternal
{
public bool Available => false;
public string NotAvailableReason => "Sorry, the clipboard is not supported on your platform.";
public string GetText()
{
throw new NotSupportedException();
}
public void SetText(string text)
{
throw new NotSupportedException();
}
public void Initialize()
{
// Nothing.
}
}
}

View File

@@ -1,213 +0,0 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.UserInterface;
using Robust.Shared.IoC;
namespace Robust.Client.UserInterface
{
// Yay Windows API!
sealed class ClipboardManagerWindows : IClipboardManagerInternal
{
[Dependency]
#pragma warning disable 649
private readonly IClydeInternal _clyde;
#pragma warning restore 649
public bool Available => true;
public string NotAvailableReason => "";
public string GetText()
{
var windowHandle = _clyde.GetNativeWindowHandle();
if (!OpenClipboard(windowHandle))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
if (IsClipboardFormatAvailable(CF_UNICODETEXT))
{
var dataHandle = GetClipboardData(CF_UNICODETEXT);
if (dataHandle == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
var ptr = GlobalLock(dataHandle);
if (ptr == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
var str = Marshal.PtrToStringUni(ptr);
return str;
}
finally
{
GlobalUnlock(dataHandle);
}
}
if (IsClipboardFormatAvailable(CF_TEXT))
{
var dataHandle = GetClipboardData(CF_TEXT);
if (dataHandle == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
var ptr = GlobalLock(dataHandle);
if (ptr == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
var str = Marshal.PtrToStringAnsi(ptr);
return str;
}
finally
{
GlobalUnlock(dataHandle);
}
}
// Clipboard data isn't available as string, guess we just say it's empty.
return "";
}
finally
{
CloseClipboard();
}
}
public void SetText(string text)
{
void DoSetData(int allocLength, uint format, Func<string, IntPtr> allocHGlobal)
{
// Allocate global data for the clipboard contents.
var alloc = GlobalAlloc(GMEM_MOVEABLE, (UIntPtr)allocLength);
var clipboardSet = false;
try
{
// Copy data into global allocation.
var ptr = GlobalLock(alloc);
if (ptr == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try
{
var uniPtr = allocHGlobal(text);
try
{
unsafe
{
Buffer.MemoryCopy((void*)uniPtr, (void*)ptr, allocLength, allocLength);
}
}
finally
{
Marshal.FreeHGlobal(uniPtr);
}
}
finally
{
GlobalUnlock(alloc);
}
// Set clipboard to global allocation.
var clip = SetClipboardData(format, alloc);
if (clip == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
clipboardSet = true;
}
finally
{
if (!clipboardSet)
{
// If clipboardSet is false we didn't hand the data off to the clipboard and an error occured.
// In that case, try to avoid a memory leak by freeing the data.
GlobalFree(alloc);
}
}
}
var windowHandle = _clyde.GetNativeWindowHandle();
if (!OpenClipboard(windowHandle))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
EmptyClipboard();
try
{
DoSetData(text.Length * 2 + 1, CF_UNICODETEXT, Marshal.StringToHGlobalUni);
DoSetData(text.Length + 1, CF_TEXT, Marshal.StringToHGlobalAnsi);
}
finally
{
CloseClipboard();
}
}
public void Initialize()
{
// Nothing.
}
private const uint CF_UNICODETEXT = 13;
private const uint CF_TEXT = 1;
private const uint GMEM_MOVEABLE = 2;
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GlobalFree(IntPtr hMem);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GlobalLock(IntPtr hMem);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GlobalUnlock(IntPtr hMem);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsClipboardFormatAvailable(uint format);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseClipboard();
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EmptyClipboard();
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetClipboardData(uint uFormat);
}
}

View File

@@ -1,5 +1,4 @@
using Robust.Client.Input;
using Robust.Client.Utility;
using Robust.Shared.Input;
using Robust.Shared.Map;
using Robust.Shared.Maths;
@@ -123,19 +122,13 @@ namespace Robust.Client.UserInterface
}
}
public abstract class GUIMouseEventArgs : ModifierInputEventArgs
public abstract class GUIMouseEventArgs : InputEventArgs
{
/// <summary>
/// The control spawning this event.
/// </summary>
public Control SourceControl { get; internal set; }
/// <summary>
/// <c>InputEventMouse.button_mask</c> in Godot.
/// Which mouse buttons are currently held maybe?
/// </summary>
public Mouse.ButtonMask ButtonMask { get; }
/// <summary>
/// Position of the mouse, relative to the screen.
/// </summary>
@@ -151,19 +144,12 @@ namespace Robust.Client.UserInterface
public Vector2 RelativePixelPosition { get; internal set; }
protected GUIMouseEventArgs(Control sourceControl,
Mouse.ButtonMask buttonMask,
Vector2 globalPosition,
Vector2 globalPixelPosition,
Vector2 relativePosition,
Vector2 relativePixelPosition,
bool alt,
bool control,
bool shift,
bool system)
: base(alt, control, shift, system)
Vector2 relativePixelPosition)
{
SourceControl = sourceControl;
ButtonMask = buttonMask;
GlobalPosition = globalPosition;
RelativePosition = relativePosition;
RelativePixelPosition = relativePixelPosition;
@@ -178,30 +164,16 @@ namespace Robust.Client.UserInterface
/// </summary>
public Vector2 Relative { get; }
// TODO: Godot's docs aren't exactly clear on what this is.
// Speed how?
/// <summary>
/// The speed of the movement.
/// </summary>
public Vector2 Speed { get; }
// ALL the parameters!
public GUIMouseMoveEventArgs(Vector2 relative,
Vector2 speed,
Control sourceControl,
Mouse.ButtonMask buttonMask,
Vector2 globalPosition,
Vector2 globalPixelPosition,
Vector2 relativePosition,
Vector2 relativePixelPosition,
bool alt,
bool control,
bool shift,
bool system)
: base(sourceControl, buttonMask, globalPosition, globalPixelPosition, relativePosition, relativePixelPosition, alt, control, shift, system)
Vector2 relativePixelPosition)
: base(sourceControl, globalPosition, globalPixelPosition, relativePosition, relativePixelPosition)
{
Relative = relative;
Speed = speed;
}
}
@@ -211,16 +183,11 @@ namespace Robust.Client.UserInterface
public GUIMouseWheelEventArgs(Vector2 delta,
Control sourceControl,
Mouse.ButtonMask buttonMask,
Vector2 globalPosition,
Vector2 globalPixelPosition,
Vector2 relativePosition,
Vector2 relativePixelPosition,
bool alt,
bool control,
bool shift,
bool system)
: base(sourceControl, buttonMask, globalPosition, globalPixelPosition, relativePosition, relativePixelPosition, alt, control, shift, system)
Vector2 relativePixelPosition)
: base(sourceControl, globalPosition, globalPixelPosition, relativePosition, relativePixelPosition)
{
Delta = delta;
}

View File

@@ -333,12 +333,6 @@ namespace Robust.Client.UserInterface.Controls
if (Editable)
{
var clipboard = IoCManager.Resolve<IClipboardManager>();
if (!clipboard.Available)
{
UserInterfaceManager.Popup(clipboard.NotAvailableReason, "Clipboard not available!");
return;
}
InsertAtCursor(clipboard.GetText());
}
}

View File

@@ -284,12 +284,10 @@ namespace Robust.Client.UserInterface
if (target != null)
{
var guiArgs = new GUIMouseMoveEventArgs(mouseMoveEventArgs.Relative / UIScale,
mouseMoveEventArgs.Speed / UIScale, target,
mouseMoveEventArgs.ButtonMask, mouseMoveEventArgs.Position / UIScale, mouseMoveEventArgs.Position,
target,
mouseMoveEventArgs.Position / UIScale, mouseMoveEventArgs.Position,
mouseMoveEventArgs.Position / UIScale - target.GlobalPosition,
mouseMoveEventArgs.Position - target.GlobalPixelPosition,
mouseMoveEventArgs.Alt,
mouseMoveEventArgs.Control, mouseMoveEventArgs.Shift, mouseMoveEventArgs.System);
mouseMoveEventArgs.Position - target.GlobalPixelPosition);
_doMouseGuiInput(target, guiArgs, (c, ev) => c.MouseMove(ev));
}
@@ -305,10 +303,9 @@ namespace Robust.Client.UserInterface
args.Handle();
var guiArgs = new GUIMouseWheelEventArgs(args.Delta, control, Mouse.ButtonMask.None,
var guiArgs = new GUIMouseWheelEventArgs(args.Delta, control,
args.Position / UIScale, args.Position,
args.Position / UIScale - control.GlobalPosition, args.Position - control.GlobalPixelPosition, args.Alt,
args.Control, args.Shift, args.System);
args.Position / UIScale - control.GlobalPosition, args.Position - control.GlobalPixelPosition);
_doMouseGuiInput(control, guiArgs, (c, ev) => c.MouseWheel(ev), true);
}

View File

@@ -26,7 +26,6 @@ namespace Robust.Lite
private IGameLoop _mainLoop;
#pragma warning disable 649
[Dependency] private readonly IClipboardManagerInternal _clipboardManager;
[Dependency] private readonly IClydeInternal _clyde;
[Dependency] private readonly IConfigurationManager _configurationManager;
[Dependency] private readonly IEyeManager _eyeManager;
@@ -56,7 +55,7 @@ namespace Robust.Lite
_mainLoop.Running = false;
}
public void Startup()
public bool Startup()
{
throw new NotSupportedException();
}
@@ -97,7 +96,6 @@ namespace Robust.Lite
}
_fontManager.Initialize();
_clipboardManager.Initialize();
_eyeManager.Initialize();

View File

@@ -1,17 +0,0 @@
using System;
namespace Robust.Shared.Input
{
[Flags]
public enum ClickType
{
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Middle = 1 << 2,
Alt = 1 << 3,
Shift = 1 << 4,
Cntrl = 1 << 5,
System = 1 << 6,
}
}

View File

@@ -7,4 +7,5 @@
[assembly: InternalsVisibleTo("Robust.Client")]
[assembly: InternalsVisibleTo("Robust.Lite")]
[assembly: InternalsVisibleTo("Robust.UnitTesting")]
[assembly: InternalsVisibleTo("OpenToolkit.GraphicsLibraryFramework")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Gives access to Castle(Moq)

View File

@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
namespace Robust.Shared.Utility
{
@@ -33,5 +34,26 @@ namespace Robust.Shared.Utility
return EncodingHelpers.UTF8.GetString(ptr, length);
}
public static unsafe IntPtr StringToCoTaskMemUTF8(string str)
{
if (str == null)
{
return IntPtr.Zero;
}
var maxByteLength = System.Text.Encoding.UTF8.GetMaxByteCount(str.Length);
var ptr = (byte*)Marshal.AllocCoTaskMem(maxByteLength + 1);
int actualLen;
fixed (char* pChar = str)
{
actualLen = System.Text.Encoding.UTF8.GetBytes(pChar, str.Length, ptr, maxByteLength);
}
ptr[actualLen] = 0;
return (IntPtr)ptr;
}
}
}

View File

@@ -17,14 +17,13 @@ namespace Robust.UnitTesting
public bool LoadConfigAndUserData { get; set; } = true;
public void Startup()
public bool Startup()
{
return true;
}
public void MainLoop(GameController.DisplayMode mode)
{
}
public string ContentRootDir { get; set; }

View File

@@ -19,60 +19,46 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Robust.Client", "Robust.Cli
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Robust.Shared.Maths", "Robust.Shared.Maths\Robust.Shared.Maths.csproj", "{93F23A82-00C5-4572-964E-E7C9457726D4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenToolkit.GraphicsLibraryFramework", "OpenToolkit.GraphicsLibraryFramework\OpenToolkit.GraphicsLibraryFramework.csproj", "{52710F44-4240-4140-9B33-F36EBD9D3FC2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{59250BAF-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Debug|x86.Build.0 = Debug|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|Any CPU
{59250BAF-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|Any CPU
{B04AAE71-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|x64
{B04AAE71-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|x64
{B04AAE71-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|x64
{B04AAE71-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|x64
{B04AAE71-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|x64
{B04AAE71-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|x64
{0529F740-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|x64
{0529F740-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|x64
{0529F740-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|x64
{0529F740-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|x64
{0529F740-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|x64
{0529F740-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|x64
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Debug|x64.ActiveCfg = Debug|x64
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Debug|x64.Build.0 = Debug|x64
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Debug|x86.ActiveCfg = Debug|x64
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|x64.ActiveCfg = Release|x64
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|x64.Build.0 = Release|x64
{F0ADA779-40B8-4F7E-BA6C-CDB19F3065D9}.Release|x86.ActiveCfg = Release|x64
{D0DA124B-5580-4345-A02B-9F051F78915F}.Debug|x64.ActiveCfg = Debug|x64
{D0DA124B-5580-4345-A02B-9F051F78915F}.Debug|x64.Build.0 = Debug|x64
{D0DA124B-5580-4345-A02B-9F051F78915F}.Debug|x86.ActiveCfg = Debug|x86
{D0DA124B-5580-4345-A02B-9F051F78915F}.Debug|x86.Build.0 = Debug|x86
{D0DA124B-5580-4345-A02B-9F051F78915F}.Release|x64.ActiveCfg = Release|x64
{D0DA124B-5580-4345-A02B-9F051F78915F}.Release|x64.Build.0 = Release|x64
{D0DA124B-5580-4345-A02B-9F051F78915F}.Release|x86.ActiveCfg = Release|x86
{D0DA124B-5580-4345-A02B-9F051F78915F}.Release|x86.Build.0 = Release|x86
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Debug|x64.ActiveCfg = Debug|x64
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Debug|x64.Build.0 = Debug|x64
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Debug|x86.ActiveCfg = Debug|x64
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|x64.ActiveCfg = Release|x64
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|x64.Build.0 = Release|x64
{83429BD6-6358-4B18-BE51-401DF8EA2673}.Release|x86.ActiveCfg = Release|x64
{93F23A82-00C5-4572-964E-E7C9457726D4}.Debug|x64.ActiveCfg = Debug|x64
{93F23A82-00C5-4572-964E-E7C9457726D4}.Debug|x64.Build.0 = Debug|x64
{93F23A82-00C5-4572-964E-E7C9457726D4}.Debug|x86.ActiveCfg = Debug|x64
{93F23A82-00C5-4572-964E-E7C9457726D4}.Release|x64.ActiveCfg = Release|x64
{93F23A82-00C5-4572-964E-E7C9457726D4}.Release|x64.Build.0 = Release|x64
{93F23A82-00C5-4572-964E-E7C9457726D4}.Release|x86.ActiveCfg = Release|x64
{52710F44-4240-4140-9B33-F36EBD9D3FC2}.Release|x64.ActiveCfg = Release|x64
{52710F44-4240-4140-9B33-F36EBD9D3FC2}.Release|x64.Build.0 = Release|x64
{52710F44-4240-4140-9B33-F36EBD9D3FC2}.Debug|x64.ActiveCfg = Debug|x64
{52710F44-4240-4140-9B33-F36EBD9D3FC2}.Debug|x64.Build.0 = Debug|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

76
Tools/download_glfw.py Normal file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/env python3
import os
import sys
import urllib.request
import shutil
CURRENT_VERSION = "3.3"
RELEASES_ROOT = "https://github.com/space-wizards/build-dependencies/raw/master/natives/glfw/3.3/"
WINDOWS_FILENAME = "glfw3.dll"
MACOS_FILENAME = "libglfw.3.dylib"
LINUX_FILENAME = "libglfw.so.3"
WINDOWS_TARGET_FILENAME = "glfw3.dll"
MACOS_TARGET_FILENAME = "libglfw.3.dylib"
LINUX_TARGET_FILENAME = "libglfw.so.3"
def main():
platform = sys.argv[1]
target_os = sys.argv[2]
# Hah good luck passing something containing a space to the Exec MSBuild Task.
target_dir = " ".join(sys.argv[3:])
if platform != "x64":
print("Error: Unable to download GLFW for any platform outside x64. "
"If you REALLY want x86 support for some misguided reason, I'm not providing it.")
exit(1)
repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
dependencies_dir = os.path.join(repo_dir, "Dependencies", "glfw")
version_file = os.path.join(dependencies_dir, "VERSION")
os.makedirs(dependencies_dir, exist_ok=True)
existing_version = "?"
if os.path.exists(version_file):
with open(version_file, "r") as f:
existing_version = f.read().strip()
if existing_version != CURRENT_VERSION:
for x in os.listdir(dependencies_dir):
os.remove(x)
with open(version_file, "w") as f:
f.write(CURRENT_VERSION)
filename = None
target_filename = None
if target_os == "Windows":
filename = WINDOWS_FILENAME
target_filename = WINDOWS_TARGET_FILENAME
elif target_os == "Linux":
filename = LINUX_FILENAME
target_filename = LINUX_TARGET_FILENAME
elif target_os == "MacOS":
filename = MACOS_FILENAME
target_filename = MACOS_TARGET_FILENAME
else:
print("Error: Unknown platform target:", target_os)
exit(2)
dependency_path = os.path.join(dependencies_dir, filename)
if not os.path.exists(dependency_path):
urllib.request.urlretrieve(RELEASES_ROOT + filename, dependency_path)
target_file_path = os.path.join(target_dir, target_filename)
if not os.path.exists(target_file_path) or \
os.stat(dependency_path).st_mtime > os.stat(target_file_path).st_mtime:
shutil.copy2(dependency_path, target_file_path)
if __name__ == '__main__':
main()