Skip to content
Browse files

Merge pull request #151 from thefiddler/kms

[KMS] Implement Linux/KMS platform
  • Loading branch information...
2 parents c1c6b42 + 00b5174 commit 17aa8051f6646b9005131739bc5cfc3518b417bf @thefiddler thefiddler committed Jul 18, 2014
Showing with 4,758 additions and 135 deletions.
  1. +23 −4 Source/Examples/OpenTK/Test/TestResolutionChanges.cs
  2. +1 −1 Source/OpenTK/Configuration.cs
  3. +20 −0 Source/OpenTK/DisplayDevice.cs
  4. +3 −0 Source/OpenTK/Graphics/GraphicsBindingsBase.cs
  5. +13 −6 Source/OpenTK/Input/MouseState.cs
  6. +25 −3 Source/OpenTK/OpenTK.csproj
  7. +151 −0 Source/OpenTK/Platform/DeviceCollection.cs
  8. +27 −16 Source/OpenTK/Platform/Egl/Egl.cs
  9. +18 −4 Source/OpenTK/Platform/Egl/EglContext.cs
  10. +9 −0 Source/OpenTK/Platform/Egl/EglGraphicsMode.cs
  11. +32 −2 Source/OpenTK/Platform/Egl/EglUnixContext.cs
  12. +2 −2 Source/OpenTK/Platform/Egl/EglWindowInfo.cs
  13. +3 −1 Source/OpenTK/Platform/Factory.cs
  14. +209 −0 Source/OpenTK/Platform/Linux/Bindings/Drm.cs
  15. +452 −0 Source/OpenTK/Platform/Linux/Bindings/Evdev.cs
  16. +278 −0 Source/OpenTK/Platform/Linux/Bindings/Gbm.cs
  17. +46 −0 Source/OpenTK/Platform/Linux/Bindings/Kms.cs
  18. +330 −0 Source/OpenTK/Platform/Linux/Bindings/LibInput.cs
  19. +178 −0 Source/OpenTK/Platform/Linux/Bindings/Libc.cs
  20. +65 −0 Source/OpenTK/Platform/Linux/Bindings/Poll.cs
  21. +170 −0 Source/OpenTK/Platform/Linux/Bindings/Terminal.cs
  22. +46 −0 Source/OpenTK/Platform/Linux/Bindings/Udev.cs
  23. +76 −0 Source/OpenTK/Platform/Linux/DefaultCursor.cs
  24. +413 −0 Source/OpenTK/Platform/Linux/LinuxDisplayDriver.cs
  25. +248 −0 Source/OpenTK/Platform/Linux/LinuxFactory.cs
  26. +303 −0 Source/OpenTK/Platform/Linux/LinuxGraphicsContext.cs
  27. +717 −0 Source/OpenTK/Platform/Linux/LinuxInput.cs
  28. +25 −94 Source/OpenTK/Platform/{X11/X11Joystick.cs → Linux/LinuxJoystick.cs}
  29. +268 −0 Source/OpenTK/Platform/Linux/LinuxKeyboardTTY.cs
  30. +549 −0 Source/OpenTK/Platform/Linux/LinuxNativeWindow.cs
  31. +56 −0 Source/OpenTK/Platform/Linux/LinuxWindowInfo.cs
  32. +1 −1 Source/OpenTK/Platform/X11/X11Input.cs
  33. +1 −1 Source/OpenTK/Platform/X11/XI2Input.cs
View
27 Source/Examples/OpenTK/Test/TestResolutionChanges.cs
@@ -23,16 +23,35 @@ public static void Main()
DisplayDevice dev = DisplayDevice.GetDisplay(DisplayIndex.First + i);
if (dev != null)
{
- Trace.WriteLine(dev.ToString());
- MessageBox.Show(dev.ToString());
+ Print(dev.ToString());
+
dev.ChangeResolution(dev.SelectResolution(640, 480, 32, 60.0f));
Thread.Sleep(1000);
- MessageBox.Show(dev.ToString());
+ Print(dev.ToString());
+
dev.RestoreResolution();
Thread.Sleep(1000);
- MessageBox.Show(dev.ToString());
+ Print(dev.ToString());
+ }
+ }
+ }
+
+ static void Print(string msg)
+ {
+ Trace.WriteLine(msg);
+
+ // Also display a MessageBox when running on a platform
+ // with WinForms support.
+ try
+ {
+ if (Configuration.RunningOnWindows || Configuration.RunningOnX11 || Configuration.RunningOnMacOS)
+ {
+ MessageBox.Show(msg);
}
}
+ catch
+ {
+ }
}
}
}
View
2 Source/OpenTK/Configuration.cs
@@ -95,7 +95,7 @@ public static bool RunningOnSdl2
#region public static bool RunningOnLinux
- /// <summary>Gets a System.Boolean indicating whether OpenTK is running on an X11 platform.</summary>
+ /// <summary>Gets a System.Boolean indicating whether OpenTK is running on the Linux kernel.</summary>
public static bool RunningOnLinux { get { return runningOnLinux; } }
#endregion
View
20 Source/OpenTK/DisplayDevice.cs
@@ -351,6 +351,26 @@ internal DisplayResolution OriginalResolution
#endregion
+ #region FromPoint
+
+ internal static DisplayDevice FromPoint(int x, int y)
+ {
+ for (DisplayIndex i = DisplayIndex.First; i < DisplayIndex.Sixth; i++)
+ {
+ DisplayDevice display = DisplayDevice.GetDisplay(i);
+ if (display != null)
+ {
+ if (display.Bounds.Contains(x, y))
+ {
+ return display;
+ }
+ }
+ }
+ return null;
+ }
+
+ #endregion
+
#endregion
#region --- Private Methods ---
View
3 Source/OpenTK/Graphics/GraphicsBindingsBase.cs
@@ -26,6 +26,7 @@
#endregion
using System;
+using System.Diagnostics;
using System.Runtime.InteropServices;
namespace OpenTK.Graphics
@@ -84,6 +85,8 @@ protected override IntPtr GetAddress(string funcname)
// validation necessary.)
internal override void LoadEntryPoints()
{
+ Debug.Print("Loading entry points for {0}", GetType().FullName);
+
IGraphicsContext context = GraphicsContext.CurrentContext;
if (context == null)
throw new GraphicsContextMissingException();
View
19 Source/OpenTK/Input/MouseState.cs
@@ -38,7 +38,8 @@ public struct MouseState : IEquatable<MouseState>
{
#region Fields
- int x, y;
+ internal const int MaxButtons = 16; // we are storing in an ushort
+ Vector2 position;
MouseScroll scroll;
ushort buttons;
bool is_connected;
@@ -101,7 +102,7 @@ public float WheelPrecise
}
/// <summary>
- /// Gets a <see cref="OpenTK.Input.MouseScrollWheel"/> instance,
+ /// Gets a <see cref="OpenTK.Input.MouseScroll"/> instance,
/// representing the current state of the mouse scroll wheel.
/// </summary>
public MouseScroll Scroll
@@ -114,17 +115,17 @@ public MouseScroll Scroll
/// </summary>
public int X
{
- get { return x; }
- internal set { x = value; }
+ get { return (int)Math.Round(position.X); }
+ internal set { position.X = value; }
}
/// <summary>
/// Gets an integer representing the absolute y position of the pointer, in window pixel coordinates.
/// </summary>
public int Y
{
- get { return y; }
- internal set { y = value; }
+ get { return (int)Math.Round(position.Y); }
+ internal set { position.Y = value; }
}
/// <summary>
@@ -272,6 +273,12 @@ public override string ToString()
#region Internal Members
+ internal Vector2 Position
+ {
+ get { return position; }
+ set { position = value; }
+ }
+
internal bool ReadBit(int offset)
{
ValidateOffset(offset);
View
28 Source/OpenTK/OpenTK.csproj
@@ -343,9 +343,6 @@
<Compile Include="Platform\X11\X11WindowInfo.cs">
<SubType>Code</SubType>
</Compile>
- <Compile Include="Platform\X11\X11Joystick.cs">
- <SubType>Code</SubType>
- </Compile>
<Compile Include="Platform\X11\Functions.cs">
<SubType>Code</SubType>
</Compile>
@@ -806,6 +803,27 @@
<Compile Include="Platform\X11\XI2Input.cs" />
<Compile Include="Platform\X11\XI2MouseKeyboard.cs" />
<Compile Include="Platform\MacOS\Cocoa\NSFloat.cs" />
+ <Compile Include="Platform\Linux\Bindings\Drm.cs" />
+ <Compile Include="Platform\Linux\LinuxFactory.cs" />
+ <Compile Include="Platform\Linux\LinuxNativeWindow.cs" />
+ <Compile Include="Platform\Linux\Bindings\Gbm.cs" />
+ <Compile Include="Platform\Linux\LinuxDisplayDriver.cs" />
+ <Compile Include="Platform\Linux\LinuxJoystick.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Platform\Linux\Bindings\Libc.cs" />
+ <Compile Include="Platform\Linux\LinuxWindowInfo.cs" />
+ <Compile Include="Platform\Linux\LinuxGraphicsContext.cs" />
+ <Compile Include="Platform\Linux\Bindings\Poll.cs" />
+ <Compile Include="Platform\Linux\LinuxKeyboardTTY.cs" />
+ <Compile Include="Platform\Linux\Bindings\Udev.cs" />
+ <Compile Include="Platform\Linux\Bindings\LibInput.cs" />
+ <Compile Include="Platform\Linux\LinuxInput.cs" />
+ <Compile Include="Platform\Linux\Bindings\Terminal.cs" />
+ <Compile Include="Platform\DeviceCollection.cs" />
+ <Compile Include="Platform\Linux\Bindings\Evdev.cs" />
+ <Compile Include="Platform\Linux\DefaultCursor.cs" />
+ <Compile Include="Platform\Linux\Bindings\Kms.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
@@ -836,4 +854,8 @@
</MonoDevelop>
</ProjectExtensions>
<ItemGroup />
+ <ItemGroup>
+ <Folder Include="Platform\Linux\" />
+ <Folder Include="Platform\Linux\Bindings\" />
+ </ItemGroup>
</Project>
View
151 Source/OpenTK/Platform/DeviceCollection.cs
@@ -0,0 +1,151 @@
+#region License
+//
+// DeviceCollection.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace OpenTK.Platform
+{
+ // Holds a collection of hardware devices with an associated id.
+ // Note: 'id' refers to a unique hardware-specific device identifier.
+ // Note: 'index' refers to the offset of the device in the Devices array.
+ // Indices are allocated sequentially as devices are added to the system.
+ // If a device is removed, its index will be reused for the next device
+ // that is added.
+ class DeviceCollection<T> : IEnumerable<T>
+ {
+ readonly Dictionary<int, int> Map = new Dictionary<int, int>();
+ readonly List<T> Devices = new List<T>();
+
+ #region IEnumerable<T> Members
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ return Devices.GetEnumerator();
+ }
+
+ #endregion
+
+ #region IEnumerable implementation
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+
+ #region Public Members
+
+ public void Add(int id, T device)
+ {
+ if (!Map.ContainsKey(id))
+ {
+ int index = GetIndex();
+ Map.Add(id, index);
+ }
+
+ Devices[Map[id]] = device;
+ }
+
+ public void Remove(int id)
+ {
+ if (!TryRemove(id))
+ {
+ Debug.Print("Invalid DeviceCollection<{0}> id: {1}", typeof(T).FullName, id);
+ }
+ }
+
+ public bool TryRemove(int id)
+ {
+ if (!Map.ContainsKey(id))
+ {
+ return false;
+ }
+
+ Devices[Map[id]] = default(T);
+ Map.Remove(id);
+ return true;
+ }
+
+ public T FromIndex(int index)
+ {
+ if (index >= 0 && index < Devices.Count)
+ {
+ return Devices[index];
+ }
+ else
+ {
+ return default(T);
+ }
+ }
+
+ public T FromHardwareId(int id)
+ {
+ if (Map.ContainsKey(id))
+ {
+ return FromIndex(Map[id]);
+ }
+ else
+ {
+ return default(T);
+ }
+ }
+
+ public int Count
+ {
+ get { return Map.Count; }
+ }
+
+ #endregion
+
+ #region Private Members
+
+ // Return the index of the first empty slot in Devices.
+ // If no empty slot exists, append a new one and return
+ // that index.
+ int GetIndex()
+ {
+ for (int i = 0; i < Devices.Count; i++)
+ {
+ if (Devices[i] == null)
+ {
+ return i;
+ }
+ }
+
+ Devices.Add(default(T));
+ return Devices.Count - 1;
+ }
+
+ #endregion
+ }
+}
+
View
43 Source/OpenTK/Platform/Egl/Egl.cs
@@ -41,6 +41,13 @@ namespace OpenTK.Platform.Egl
using EGLSurface = IntPtr;
using EGLClientBuffer = IntPtr;
+ enum RenderApi
+ {
+ ES = Egl.OPENGL_ES_API,
+ GL = Egl.OPENGL_API,
+ VG = Egl.OPENVG_API
+ }
+
[Flags]
enum RenderableFlags
{
@@ -50,6 +57,24 @@ enum RenderableFlags
VG = Egl.OPENVG_BIT,
}
+ enum ErrorCode
+ {
+ SUCCESS = 12288,
+ NOT_INITIALIZED = 12289,
+ BAD_ACCESS = 12290,
+ BAD_ALLOC = 12291,
+ BAD_ATTRIBUTE = 12292,
+ BAD_CONFIG = 12293,
+ BAD_CONTEXT = 12294,
+ BAD_CURRENT_SURFACE = 12295,
+ BAD_DISPLAY = 12296,
+ BAD_MATCH = 12297,
+ BAD_NATIVE_PIXMAP = 12298,
+ BAD_NATIVE_WINDOW = 12299,
+ BAD_PARAMETER = 12300,
+ BAD_SURFACE = 12301,
+ }
+
static partial class Egl
{
public const int VERSION_1_0 = 1;
@@ -60,20 +85,6 @@ static partial class Egl
public const int FALSE = 0;
public const int TRUE = 1;
public const int DONT_CARE = -1;
- public const int SUCCESS = 12288;
- public const int NOT_INITIALIZED = 12289;
- public const int BAD_ACCESS = 12290;
- public const int BAD_ALLOC = 12291;
- public const int BAD_ATTRIBUTE = 12292;
- public const int BAD_CONFIG = 12293;
- public const int BAD_CONTEXT = 12294;
- public const int BAD_CURRENT_SURFACE = 12295;
- public const int BAD_DISPLAY = 12296;
- public const int BAD_MATCH = 12297;
- public const int BAD_NATIVE_PIXMAP = 12298;
- public const int BAD_NATIVE_WINDOW = 12299;
- public const int BAD_PARAMETER = 12300;
- public const int BAD_SURFACE = 12301;
public const int CONTEXT_LOST = 12302;
public const int BUFFER_SIZE = 12320;
public const int ALPHA_SIZE = 12321;
@@ -178,7 +189,7 @@ static partial class Egl
public const int ALPHA_FORMAT_PRE = VG_ALPHA_FORMAT_PRE;
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetError")]
- public static extern int GetError();
+ public static extern ErrorCode GetError();
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")]
public static extern EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
@@ -225,7 +236,7 @@ static partial class Egl
[DllImportAttribute("libEGL.dll", EntryPoint = "eglBindAPI")]
[return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool BindAPI(int api);
+ public static extern bool BindAPI(RenderApi api);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryAPI")]
public static extern int QueryAPI();
View
22 Source/OpenTK/Platform/Egl/EglContext.cs
@@ -35,9 +35,9 @@ abstract class EglContext : EmbeddedGraphicsContext
{
#region Fields
- readonly RenderableFlags Renderable;
+ protected readonly RenderableFlags Renderable;
+ protected EglWindowInfo WindowInfo;
- EglWindowInfo WindowInfo;
IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } }
int swap_interval = 1; // Default interval is defined as 1 in EGL.
@@ -60,7 +60,20 @@ abstract class EglContext : EmbeddedGraphicsContext
// Select an EGLConfig that matches the desired mode. We cannot use the 'mode'
// parameter directly, since it may have originated on a different system (e.g. GLX)
// and it may not support the desired renderer.
- Renderable = major > 1 ? RenderableFlags.ES2 : RenderableFlags.ES;
+
+ Renderable = RenderableFlags.GL;
+ if ((flags & GraphicsContextFlags.Embedded) != 0)
+ {
+ Renderable = major > 1 ? RenderableFlags.ES2 : RenderableFlags.ES;
+ }
+
+ RenderApi api = (Renderable & RenderableFlags.GL) != 0 ? RenderApi.GL : RenderApi.ES;
+ Debug.Print("[EGL] Binding {0} rendering API.", api);
+ if (!Egl.BindAPI(api))
+ {
+ Debug.Print("[EGL] Failed to bind rendering API. Error: {0}", Egl.GetError());
+ }
+
Mode = new EglGraphicsMode().SelectGraphicsMode(window,
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
@@ -133,7 +146,8 @@ public override int SwapInterval
if (Egl.SwapInterval(WindowInfo.Display, value))
swap_interval = value;
else
- Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", WindowInfo.Display, value);
+ Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed. Error: {2}",
+ WindowInfo.Display, value, Egl.GetError());
}
}
View
9 Source/OpenTK/Platform/Egl/EglGraphicsMode.cs
@@ -35,6 +35,15 @@ namespace OpenTK.Platform.Egl
class EglGraphicsMode
{
public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
+ GraphicsMode mode, RenderableFlags flags)
+ {
+ return SelectGraphicsMode(window,
+ mode.ColorFormat, mode.Depth, mode.Stencil,
+ mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
+ flags);
+ }
+
+ public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
ColorFormat color, int depth, int stencil,
int samples, ColorFormat accum, int buffers, bool stereo,
RenderableFlags renderable_flags)
View
34 Source/OpenTK/Platform/Egl/EglUnixContext.cs
@@ -28,14 +28,16 @@
#endregion
using System;
+using System.Diagnostics;
using OpenTK.Graphics;
namespace OpenTK.Platform.Egl
{
class EglUnixContext : EglContext
{
- readonly IntPtr ES1 = OpenTK.Platform.X11.DL.Open("libGLESv1_CM", X11.DLOpenFlags.Lazy);
- readonly IntPtr ES2 = OpenTK.Platform.X11.DL.Open("libGLESv2", X11.DLOpenFlags.Lazy);
+ IntPtr ES1 = OpenTK.Platform.X11.DL.Open("libGLESv1_CM", X11.DLOpenFlags.Lazy);
+ IntPtr ES2 = OpenTK.Platform.X11.DL.Open("libGLESv2", X11.DLOpenFlags.Lazy);
+ IntPtr GL = OpenTK.Platform.X11.DL.Open("libGL", X11.DLOpenFlags.Lazy);
public EglUnixContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
int major, int minor, GraphicsContextFlags flags)
@@ -59,6 +61,10 @@ protected override IntPtr GetStaticAddress(IntPtr function, RenderableFlags rend
{
return X11.DL.Symbol(ES2, function);
}
+ else if ((renderable & RenderableFlags.GL) != 0 && GL != IntPtr.Zero)
+ {
+ return X11.DL.Symbol(GL, function);
+ }
return IntPtr.Zero;
}
@@ -72,8 +78,32 @@ protected override void Dispose(bool manual)
{
X11.DL.Close(ES2);
}
+ if (GL != IntPtr.Zero)
+ {
+ X11.DL.Close(GL);
+ }
+
+ GL = ES1 = ES2 = IntPtr.Zero;
base.Dispose(manual);
}
+
+ public override void LoadAll()
+ {
+ // Modern unices can use EGL to create
+ // both GL and ES contexts, so we need
+ // to load all entry points. This is
+ // especially true on KMS, Wayland and Mir.
+
+ Stopwatch time = Stopwatch.StartNew();
+
+ new OpenTK.Graphics.OpenGL.GL().LoadEntryPoints();
+ new OpenTK.Graphics.OpenGL4.GL().LoadEntryPoints();
+ new OpenTK.Graphics.ES11.GL().LoadEntryPoints();
+ new OpenTK.Graphics.ES20.GL().LoadEntryPoints();
+ new OpenTK.Graphics.ES30.GL().LoadEntryPoints();
+
+ Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
+ }
}
}
View
4 Source/OpenTK/Platform/Egl/EglWindowInfo.cs
@@ -75,7 +75,7 @@ public EglWindowInfo(IntPtr handle, IntPtr display, IntPtr surface)
#region Public Members
- public IntPtr Handle { get { return handle; } private set { handle = value; } }
+ public IntPtr Handle { get { return handle; } set { handle = value; } }
public IntPtr Display { get { return display; } private set { display = value; } }
@@ -87,7 +87,7 @@ public void CreateWindowSurface(IntPtr config)
if (Surface==IntPtr.Zero)
{
throw new GraphicsContextException(String.Format(
- "[Error] Failed to create EGL window surface, error {0}.", Egl.GetError()));
+ "[EGL] Failed to create window surface, error {0}.", Egl.GetError()));
}
}
View
4 Source/OpenTK/Platform/Factory.cs
@@ -54,6 +54,7 @@ static Factory()
// Create regular platform backend
if (Configuration.RunningOnSdl2) Default = new SDL2.Sdl2Factory();
else if (Configuration.RunningOnX11) Default = new X11.X11Factory();
+ else if (Configuration.RunningOnLinux) Default = new Linux.LinuxFactory();
else if (Configuration.RunningOnWindows) Default = new Windows.WinFactory();
else if (Configuration.RunningOnMacOS) Default = new MacOS.MacOSFactory();
else Default = new UnsupportedPlatform();
@@ -70,7 +71,8 @@ static Factory()
}
else if (Egl.Egl.IsSupported)
{
- if (Configuration.RunningOnX11) Embedded = new Egl.EglX11PlatformFactory();
+ if (Configuration.RunningOnLinux) Embedded = Default;
+ else if (Configuration.RunningOnX11) Embedded = new Egl.EglX11PlatformFactory();
else if (Configuration.RunningOnWindows) Embedded = new Egl.EglWinPlatformFactory();
else if (Configuration.RunningOnMacOS) Embedded = new Egl.EglMacPlatformFactory();
else Embedded = new UnsupportedPlatform();
View
209 Source/OpenTK/Platform/Linux/Bindings/Drm.cs
@@ -0,0 +1,209 @@
+#region License
+//
+// Drm.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace OpenTK.Platform.Linux
+{
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ delegate void VBlankCallback(int fd,
+ int sequence,
+ int tv_sec,
+ int tv_usec,
+ IntPtr user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ delegate void PageFlipCallback(int fd,
+ int sequence,
+ int tv_sec,
+ int tv_usec,
+ IntPtr user_data);
+
+ class Drm
+ {
+ const string lib = "libdrm";
+
+ [DllImport(lib, EntryPoint = "drmHandleEvent", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int HandleEvent(int fd, ref EventContext evctx);
+
+ [DllImport(lib, EntryPoint = "drmModeAddFB", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ModeAddFB(int fd, int width, int height, byte depth,
+ byte bpp, int pitch, int bo_handle,
+ out int buf_id);
+
+ [DllImport(lib, EntryPoint = "drmModeRmFB", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ModeRmFB(int fd, int bufferId);
+
+ [DllImport(lib, EntryPoint = "drmModeFreeCrtc", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ModeFreeCrtc(IntPtr ptr);
+
+ [DllImport(lib, EntryPoint = "drmModeGetCrtc", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr ModeGetCrtc(int fd, int crtcId);
+
+ [DllImport(lib, EntryPoint = "drmModeFreeConnector", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ModeFreeConnector(IntPtr ptr);
+
+ [DllImport(lib, EntryPoint = "drmModeFreeEncoder", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ModeFreeEncoder(IntPtr ptr);
+
+ [DllImport(lib, EntryPoint = "drmModeGetConnector", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr ModeGetConnector(int fd, int connector_id);
+
+ [DllImport(lib, EntryPoint = "drmModeGetEncoder", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr ModeGetEncoder(int fd, int encoder_id);
+
+ [DllImport(lib, EntryPoint = "drmModeGetResources", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr ModeGetResources(int fd);
+
+ [DllImport(lib, EntryPoint = "drmModePageFlip", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int ModePageFlip(int fd, int crtc_id, int fb_id,
+ PageFlipFlags flags, IntPtr user_data);
+
+ [DllImport(lib, EntryPoint = "drmModeSetCrtc", CallingConvention = CallingConvention.Cdecl)]
+ unsafe public static extern int ModeSetCrtc(int fd, int crtcId, int bufferId,
+ int x, int y, int* connectors, int count, ModeInfo* mode);
+
+ [DllImport(lib, EntryPoint = "drmModeSetCursor2", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetCursor(int fd, int crtcId, int bo_handle, int width, int height, int hot_x, int hot_y);
+
+ [DllImport(lib, EntryPoint = "drmModeMoveCursor", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int MoveCursor(int fd, int crtcId, int x, int y);
+
+ }
+
+ enum ModeConnection
+ {
+ Connected = 1,
+ Disconnected = 2,
+ Unknown = 3
+ }
+
+ enum ModeSubPixel
+ {
+ Unknown = 1,
+ HorizontalRgb = 2,
+ HorizontalBgr = 3,
+ VerticalRgb = 4,
+ VerticalBgr = 5,
+ None = 6
+ }
+
+ [Flags]
+ enum PageFlipFlags
+ {
+ FlipEvent = 0x01,
+ FlipAsync = 0x02,
+ FlipFlags = FlipEvent | FlipAsync
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct EventContext
+ {
+ public int version;
+ public IntPtr vblank_handler;
+ public IntPtr page_flip_handler;
+
+ public static readonly int Version = 2;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ unsafe struct ModeConnector
+ {
+ public int connector_id;
+ public int encoder_id;
+ public int connector_type;
+ public int connector_type_id;
+ public ModeConnection connection;
+ public int mmWidth, mmHeight;
+ public ModeSubPixel subpixel;
+
+ public int count_modes;
+ public ModeInfo* modes;
+
+ public int count_props;
+ public int *props;
+ public long *prop_values;
+
+ public int count_encoders;
+ public int *encoders;
+ }
+
+ struct ModeCrtc
+ {
+ public int crtc_id;
+ public int buffer_id;
+
+ public int x, y;
+ public int width, height;
+ public int mode_valid;
+ public ModeInfo mode;
+
+ public int gamma_size;
+ }
+
+ struct ModeEncoder
+ {
+ public int encoder_id;
+ public int encoder_type;
+ public int crtc_id;
+ public int possible_crtcs;
+ public int possible_clones;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ unsafe struct ModeInfo
+ {
+ public uint clock;
+ public ushort hdisplay, hsync_start, hsync_end, htotal, hskew;
+ public ushort vdisplay, vsync_start, vsync_end, vtotal, vscan;
+
+ public int vrefresh; // refresh rate * 1000
+
+ public uint flags;
+ public uint type;
+ public fixed sbyte name[32];
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ unsafe struct ModeRes
+ {
+ public int count_fbs;
+ public int* fbs;
+ public int count_crtcs;
+ public int* crtcs;
+ public int count_connectors;
+ public int* connectors;
+ public int count_encoders;
+ public int* encoders;
+ public int min_width, max_width;
+ public int min_height, max_height;
+ }
+}
+
View
452 Source/OpenTK/Platform/Linux/Bindings/Evdev.cs
@@ -0,0 +1,452 @@
+#region License
+//
+// Evdev.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Diagnostics;
+using OpenTK.Input;
+
+namespace OpenTK.Platform.Linux
+{
+ // Bindings for linux/input.h
+ class Evdev
+ {
+ #region KeyMap
+
+ public static readonly Key[] KeyMap = new Key[]
+ {
+ // 0-7
+ Key.Unknown,
+ Key.Escape,
+ Key.Number1,
+ Key.Number2,
+ Key.Number3,
+ Key.Number4,
+ Key.Number5,
+ Key.Number6,
+ // 8-15
+ Key.Number7,
+ Key.Number8,
+ Key.Number9,
+ Key.Number0,
+ Key.Minus,
+ Key.Plus,
+ Key.BackSpace,
+ Key.Tab,
+ // 16-23
+ Key.Q,
+ Key.W,
+ Key.E,
+ Key.R,
+ Key.T,
+ Key.Y,
+ Key.U,
+ Key.I,
+ // 24-31
+ Key.O,
+ Key.P,
+ Key.BracketLeft,
+ Key.BracketRight,
+ Key.Enter,
+ Key.ControlLeft,
+ Key.A,
+ Key.S,
+ // 32-39
+ Key.D,
+ Key.F,
+ Key.G,
+ Key.H,
+ Key.J,
+ Key.K,
+ Key.L,
+ Key.Semicolon,
+ // 40-47
+ Key.Quote,
+ Key.Tilde,
+ Key.ShiftLeft,
+ Key.BackSlash, //Key.Execute,
+ Key.Z,
+ Key.X,
+ Key.C,
+ Key.V, //Key.Help,
+ // 48-55
+ Key.B,
+ Key.N,
+ Key.M,
+ Key.Comma,
+ Key.Period,
+ Key.Slash,
+ Key.ShiftRight,
+ Key.KeypadMultiply,
+ // 56-63
+ Key.AltLeft,
+ Key.Space,
+ Key.CapsLock,
+ Key.F1,
+ Key.F2,
+ Key.F3,
+ Key.F4,
+ Key.F5,
+ // 64-71
+ Key.F6,
+ Key.F7,
+ Key.F8,
+ Key.F9,
+ Key.F10,
+ Key.NumLock,
+ Key.ScrollLock,
+ Key.Keypad7,
+ // 72-79
+ Key.Keypad8,
+ Key.Keypad9,
+ Key.KeypadSubtract,
+ Key.Keypad4,
+ Key.Keypad5,
+ Key.Keypad6,
+ Key.KeypadPlus,
+ Key.Keypad1,
+ // 80-87
+ Key.Keypad2,
+ Key.Keypad3,
+ Key.Keypad0,
+ Key.KeypadPeriod,
+ Key.Unknown,
+ Key.Unknown, // zenkakuhankaku
+ Key.Unknown, // 102ND
+ Key.F11,
+ // 88-95
+ Key.F12,
+ Key.Unknown, // ro
+ Key.Unknown, // katakana
+ Key.Unknown, // hiragana
+ Key.Unknown, // henkan
+ Key.Unknown, // katakanahiragana
+ Key.Unknown, // muhenkan
+ Key.Unknown, // kpjpcomma
+ // 96-103
+ Key.KeypadEnter,
+ Key.ControlRight,
+ Key.KeypadDivide,
+ Key.Unknown, // sysrq
+ Key.AltRight,
+ Key.Unknown, // linefeed
+ Key.Home,
+ Key.Up,
+ // 104-111
+ Key.PageUp,
+ Key.Left,
+ Key.Right,
+ Key.End,
+ Key.Down,
+ Key.PageDown,
+ Key.Insert,
+ Key.Delete,
+ // 112-119
+ Key.Unknown, // macro
+ Key.Unknown, // mute
+ Key.Unknown, // volumedown
+ Key.Unknown, // volumeup
+ Key.Unknown, // power
+ Key.Unknown, // kpequal
+ Key.Unknown, // kpplusminus
+ Key.Pause,
+ // 120-127
+ Key.Unknown, // scale
+ Key.Unknown, // kpcomma
+ Key.Unknown, // hangeul / hanguel
+ Key.Unknown, // hanja
+ Key.Unknown, // yen
+ Key.WinLeft,
+ Key.WinRight,
+ Key.Unknown, // compose
+ // 128-135
+ Key.Unknown, // stop
+ Key.Unknown, // again
+ Key.Unknown, // props
+ Key.Unknown, // undo
+ Key.Unknown, // front
+ Key.Unknown, // copy
+ Key.Unknown, // open
+ Key.Unknown, // paste
+ // 136-143
+ Key.Unknown, // find
+ Key.Unknown, // cut
+ Key.Unknown, // help
+ Key.Unknown, // menu
+ Key.Unknown, // calc
+ Key.Unknown, // setup
+ Key.Unknown, // sleep
+ Key.Unknown, // wakeup
+ // 144-151
+ Key.Unknown, // file
+ Key.Unknown, // send file
+ Key.Unknown, // delete file
+ Key.Unknown, // xfer
+ Key.Unknown, // prog1
+ Key.Unknown, // prog2
+ Key.Unknown, // www
+ Key.Unknown, // msdos
+ // 152-159
+ Key.Unknown, // coffee / screenlock
+ Key.Unknown, // direction
+ Key.Unknown, // cycle windows
+ Key.Unknown, // mail
+ Key.Unknown, // bookmarks
+ Key.Unknown, // computer
+ Key.Back,
+ Key.Unknown, // forward
+ // 160-167
+ Key.Unknown, // close cd
+ Key.Unknown, // eject cd
+ Key.Unknown, // eject/close cd
+ Key.Unknown, // next song
+ Key.Unknown, // play/pause
+ Key.Unknown, // previous song
+ Key.Unknown, // stop cd
+ Key.Unknown, // record
+ // 168-175
+ Key.Unknown, // rewind
+ Key.Unknown, // phone
+ Key.Unknown, // iso
+ Key.Unknown, // config
+ Key.Unknown, // homepage
+ Key.Unknown, // refresh
+ Key.Unknown, // exit
+ Key.Unknown, // move,
+ // 176-183
+ Key.Unknown, // edit,
+ Key.Unknown, // scroll up,
+ Key.Unknown, // scroll down,
+ Key.Unknown, // kp left paren,
+ Key.Unknown, // kp right paren,
+ Key.Unknown, // new,
+ Key.Unknown, // redo,
+ Key.F13,
+ // 184-191
+ Key.F14,
+ Key.F15,
+ Key.F16,
+ Key.F17,
+ Key.F18,
+ Key.F19,
+ Key.F20,
+ Key.F21,
+ // 192-199
+ Key.F22,
+ Key.F23,
+ Key.F24,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ // 200-207
+ Key.Unknown, // play cd
+ Key.Unknown, // pause cd
+ Key.Unknown, // prog3
+ Key.Unknown, // prog4
+ Key.Unknown, // dashboard
+ Key.Unknown, // suspend
+ Key.Unknown, // close
+ Key.Unknown, // play
+ // 208-215
+ Key.Unknown, // fast forward
+ Key.Unknown, // bass boost
+ Key.Unknown, // print
+ Key.Unknown, // hp
+ Key.Unknown, // camera
+ Key.Unknown, // sound
+ Key.Unknown, // question
+ Key.Unknown, // email
+ // 216-223
+ Key.Unknown, // chat
+ Key.Unknown, // search
+ Key.Unknown, // connect
+ Key.Unknown, // finance
+ Key.Unknown, // sport
+ Key.Unknown, // shop
+ Key.Unknown, // alt erase
+ Key.Unknown, // cancel
+ // 224-231
+ Key.Unknown, // brightness down
+ Key.Unknown, // brightness up
+ Key.Unknown, // media
+ Key.Unknown, // switch video mode
+ Key.Unknown, // dillum toggle
+ Key.Unknown, // dillum down
+ Key.Unknown, // dillum up
+ Key.Unknown, // send
+ // 232-239
+ Key.Unknown, // reply
+ Key.Unknown, // forward email
+ Key.Unknown, // save
+ Key.Unknown, // documents
+ Key.Unknown, // battery
+ Key.Unknown, // bluetooth
+ Key.Unknown, // wlan
+ Key.Unknown, // uwb
+ // 240-247
+ Key.Unknown,
+ Key.Unknown, // video next
+ Key.Unknown, // video prev
+ Key.Unknown, // brightness cycle
+ Key.Unknown, // brightness zero
+ Key.Unknown, // display off
+ Key.Unknown, // wwan / wimax
+ Key.Unknown, // rfkill
+ // 248-255
+ Key.Unknown, // mic mute
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown,
+ Key.Unknown, // reserved
+ };
+
+ #endregion
+
+ public static MouseButton GetMouseButton(EvdevButton button)
+ {
+ switch (button)
+ {
+ case EvdevButton.LEFT:
+ return MouseButton.Left;
+ case EvdevButton.RIGHT:
+ return MouseButton.Right;
+ case EvdevButton.MIDDLE:
+ return MouseButton.Middle;
+ case EvdevButton.BTN0:
+ return MouseButton.Button1;
+ case EvdevButton.BTN1:
+ return MouseButton.Button2;
+ case EvdevButton.BTN2:
+ return MouseButton.Button3;
+ case EvdevButton.BTN3:
+ return MouseButton.Button4;
+ case EvdevButton.BTN4:
+ return MouseButton.Button5;
+ case EvdevButton.BTN5:
+ return MouseButton.Button6;
+ case EvdevButton.BTN6:
+ return MouseButton.Button7;
+ case EvdevButton.BTN7:
+ return MouseButton.Button8;
+ case EvdevButton.BTN8:
+ return MouseButton.Button9;
+ default:
+ Debug.Print("[Input] Unknown EvdevButton {0}", button);
+ return MouseButton.Left;
+ }
+ }
+ }
+
+ enum EvdevButton : uint
+ {
+ MISC = 0x100,
+ BTN0 = 0x100,
+ BTN1 = 0x101,
+ BTN2 = 0x102,
+ BTN3 = 0x103,
+ BTN4 = 0x104,
+ BTN5 = 0x105,
+ BTN6 = 0x106,
+ BTN7 = 0x107,
+ BTN8 = 0x108,
+ BTN9 = 0x109,
+
+ MOUSE = 0x110,
+ LEFT = 0x110,
+ RIGHT = 0x111,
+ MIDDLE = 0x112,
+ SIDE = 0x113,
+ EXTRA = 0x114,
+ FORWARD = 0x115,
+ BACK = 0x116,
+ TASK = 0x117,
+
+ JOYSTICK = 0x120,
+ TRIGGER = 0x120,
+ THUMB = 0x121,
+ THUMB2 = 0x122,
+ TOP = 0x123,
+ TOP2 = 0x124,
+ PINKIE = 0x125,
+ BASE = 0x126,
+ BASE2 = 0x127,
+ BASE3 = 0x128,
+ BASE4 = 0x129,
+ BASE5 = 0x12a,
+ BASE6 = 0x12b,
+ DEAD = 0x12f,
+
+ GAMEPAD = 0x130,
+ SOUTH = 0x130,
+ A = SOUTH,
+ EAST = 0x131,
+ B = EAST,
+ C = 0x132,
+ NORTH = 0x133,
+ X = NORTH,
+ WEST = 0x134,
+ Y = WEST,
+ Z = 0x135,
+ TL = 0x136,
+ TR = 0x137,
+ TL2 = 0x138,
+ TR2 = 0x139,
+ SELECT = 0x13a,
+ START = 0x13b,
+ MODE = 0x13c,
+ THUMBL = 0x13d,
+ THUMBR = 0x13e,
+
+ DIGI = 0x140,
+ TOOL_PEN = 0x140,
+ TOOL_RUBBER = 0x141,
+ TOOL_BRUSH = 0x142,
+ TOOL_PENCIL = 0x143,
+ TOOL_AIRBRUSH = 0x144,
+ TOOL_FINGER = 0x145,
+ TOOL_MOUSE = 0x146,
+ TOOL_LENS = 0x147,
+ TOOL_QUINTTAP = 0x148, // Five fingers on trackpad
+ TOUCH = 0x14a,
+ STYLUS = 0x14b,
+ STYLUS2 = 0x14c,
+ TOOL_DOUBLETAP = 0x14d,
+ TOOL_TRIPLETAP = 0x14e,
+ TOOL_QUADTAP = 0x14f, // Four fingers on trackpad
+
+ WHEEL = 0x150,
+ GEAR_DOWN = 0x150,
+ GEAR_UP = 0x151,
+ }
+}
+
View
278 Source/OpenTK/Platform/Linux/Bindings/Gbm.cs
@@ -0,0 +1,278 @@
+#region License
+//
+// Gbm.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace OpenTK.Platform.Linux
+{
+ using Device = IntPtr; // struct gbm_device*
+ using Surface = IntPtr;
+ using BufferObjectHandle = IntPtr;
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ delegate void DestroyUserDataCallback(BufferObject bo, IntPtr data);
+
+ class Gbm
+ {
+ const string lib = "gbm";
+
+ [DllImport(lib, EntryPoint = "gbm_bo_create", CallingConvention = CallingConvention.Cdecl)]
+ public static extern BufferObject CreateBuffer(Device gbm, int width, int height, SurfaceFormat format, SurfaceFlags flags);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_destroy", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void DestroyBuffer(BufferObject bo);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_write", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int BOWrite(IntPtr bo, IntPtr buf, IntPtr count);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_get_device", CallingConvention = CallingConvention.Cdecl)]
+ public static extern Device BOGetDevice(IntPtr bo);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_get_handle", CallingConvention = CallingConvention.Cdecl)]
+ public static extern BufferObjectHandle BOGetHandle(IntPtr bo);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_get_height", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int BOGetHeight(IntPtr bo);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_get_width", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int BOGetWidth(IntPtr bo);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_get_stride", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int BOGetStride(IntPtr bo);
+
+ [DllImport(lib, EntryPoint = "gbm_bo_set_user_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void BOSetUserData(IntPtr bo, IntPtr data, DestroyUserDataCallback callback);
+
+ [DllImport(lib, EntryPoint = "gbm_create_device", CallingConvention = CallingConvention.Cdecl)]
+ public static extern Device CreateDevice(int fd);
+
+ [DllImport(lib, EntryPoint = "gbm_device_destroy", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void DestroyDevice(Device gbm);
+
+ [DllImport(lib, EntryPoint = "gbm_device_get_fd", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int DeviceGetFD(IntPtr gbm);
+
+ [DllImport(lib, EntryPoint = "gbm_surface_create", CallingConvention = CallingConvention.Cdecl)]
+ public static extern Surface CreateSurface(Device gbm, int width, int height, SurfaceFormat format, SurfaceFlags flags);
+
+ [DllImport(lib, EntryPoint = "gbm_surface_destroy", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void DestroySurface(IntPtr surface);
+
+ [DllImport(lib, EntryPoint = "gbm_device_is_format_supported", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool IsFormatSupported(Device gbm, SurfaceFormat format, SurfaceFlags usage);
+
+ [DllImport(lib, EntryPoint = "gbm_surface_lock_front_buffer", CallingConvention = CallingConvention.Cdecl)]
+ public static extern BufferObject LockFrontBuffer(Surface surface);
+
+ [DllImport(lib, EntryPoint = "gbm_surface_release_buffer", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ReleaseBuffer(Surface surface, BufferObject buffer);
+ }
+
+ enum SurfaceFormat
+ {
+ BigEndian = 1 << 31,
+ C8 = ((int)('C') | ((int)('8') << 8) | ((int)(' ') << 16) | ((int)(' ') << 24)),
+
+ RGB332 = ((int)('R') | ((int)('G') << 8) | ((int)('B') << 16) | ((int)('8') << 24)),
+ BGR233 = ((int)('B') | ((int)('G') << 8) | ((int)('R') << 16) | ((int)('8') << 24)),
+
+ XRGB4444 = ((int)('X') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ XBGR4444 = ((int)('X') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ RGBX4444 = ((int)('R') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ BGRX4444 = ((int)('B') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+
+ ARGB4444 = ((int)('A') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ ABGR4444 = ((int)('A') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ RGBA4444 = ((int)('R') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ BGRA4444 = ((int)('B') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+
+ XRGB1555 = ((int)('X') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+ XBGR1555 = ((int)('X') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+ RGBX5551 = ((int)('R') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+ BGRX5551 = ((int)('B') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+
+ ARGB1555 = ((int)('A') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+ ABGR1555 = ((int)('A') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+ RGBA5551 = ((int)('R') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+ BGRA5551 = ((int)('B') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
+
+ RGB565 = ((int)('R') | ((int)('G') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
+ BGR565 = ((int)('B') | ((int)('G') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
+
+ RGB888 = ((int)('R') | ((int)('G') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ BGR888 = ((int)('B') | ((int)('G') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+
+ XRGB8888 = ((int)('X') | ((int)('R') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ XBGR8888 = ((int)('X') | ((int)('B') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ RGBX8888 = ((int)('R') | ((int)('X') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ BGRX8888 = ((int)('B') | ((int)('X') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+
+ ARGB8888 = ((int)('A') | ((int)('R') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ ABGR8888 = ((int)('A') | ((int)('B') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ RGBA8888 = ((int)('R') | ((int)('A') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ BGRA8888 = ((int)('B') | ((int)('A') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+
+ XRGB2101010 = ((int)('X') | ((int)('R') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+ XBGR2101010 = ((int)('X') | ((int)('B') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+ RGBX1010102 = ((int)('R') | ((int)('X') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+ BGRX1010102 = ((int)('B') | ((int)('X') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+
+ ARGB2101010 = ((int)('A') | ((int)('R') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+ ABGR2101010 = ((int)('A') | ((int)('B') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+ RGBA1010102 = ((int)('R') | ((int)('A') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+ BGRA1010102 = ((int)('B') | ((int)('A') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
+
+ YUYV = ((int)('Y') | ((int)('U') << 8) | ((int)('Y') << 16) | ((int)('V') << 24)),
+ YVYU = ((int)('Y') | ((int)('V') << 8) | ((int)('Y') << 16) | ((int)('U') << 24)),
+ UYVY = ((int)('U') | ((int)('Y') << 8) | ((int)('V') << 16) | ((int)('Y') << 24)),
+ VYUY = ((int)('V') | ((int)('Y') << 8) | ((int)('U') << 16) | ((int)('Y') << 24)),
+
+ AYUV = ((int)('A') | ((int)('Y') << 8) | ((int)('U') << 16) | ((int)('V') << 24)),
+
+ NV12 = ((int)('N') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ NV21 = ((int)('N') | ((int)('V') << 8) | ((int)('2') << 16) | ((int)('1') << 24)),
+ NV16 = ((int)('N') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
+ NV61 = ((int)('N') | ((int)('V') << 8) | ((int)('6') << 16) | ((int)('1') << 24)),
+
+ YUV410 = ((int)('Y') | ((int)('U') << 8) | ((int)('V') << 16) | ((int)('9') << 24)),
+ YVU410 = ((int)('Y') | ((int)('V') << 8) | ((int)('U') << 16) | ((int)('9') << 24)),
+ YUV411 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('1') << 24)),
+ YVU411 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('1') << 24)),
+ YUV420 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ YVU420 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
+ YUV422 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
+ YVU422 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
+ YUV444 = ((int)('Y') | ((int)('U') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ YVU444 = ((int)('Y') | ((int)('V') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
+ }
+
+ [Flags]
+ enum SurfaceFlags
+ {
+ Scanout = (1 << 0),
+ Cursor64x64 = (1 << 1),
+ Rendering = (1 << 2),
+ Write = (1 << 3),
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct BufferObject : IEquatable<BufferObject>
+ {
+ IntPtr buffer;
+
+ public static readonly BufferObject Zero =
+ default(BufferObject);
+
+ public int Write(byte[] data)
+ {
+ unsafe
+ {
+ fixed (byte* pdata = data)
+ {
+ return Gbm.BOWrite(buffer, (IntPtr)pdata, (IntPtr)data.Length);
+ }
+ }
+ }
+
+ public void SetUserData(IntPtr data, DestroyUserDataCallback destroyFB)
+ {
+ Gbm.BOSetUserData(buffer, data, destroyFB);
+ }
+
+ public Device Device
+ {
+ get { return Gbm.BOGetDevice(buffer); }
+ }
+
+ public int Handle
+ {
+ get { return Gbm.BOGetHandle(buffer).ToInt32(); }
+ }
+
+ public int Width
+ {
+ get { return Gbm.BOGetWidth(buffer); }
+ }
+
+ public int Height
+ {
+ get { return Gbm.BOGetHeight(buffer); }
+ }
+
+ public int Stride
+ {
+ get { return Gbm.BOGetStride(buffer); }
+ }
+
+ public void Dispose()
+ {
+ Gbm.DestroyBuffer(this);
+ buffer = IntPtr.Zero;
+ }
+
+ public static bool operator ==(BufferObject left, BufferObject right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(BufferObject left, BufferObject right)
+ {
+ return !left.Equals(right);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return
+ obj is BufferObject &&
+ this.Equals((BufferObject)obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return buffer.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return string.Format("[BufferObject: {0}]", buffer);
+ }
+
+ #region IEquatable implementation
+
+ public bool Equals(BufferObject other)
+ {
+ return buffer == other.buffer;
+ }
+
+ #endregion
+ }
+}
+
View
46 Source/OpenTK/Platform/Linux/Bindings/Kms.cs
@@ -0,0 +1,46 @@
+#region License
+//
+// Kms.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace OpenTK.Platform.Linux
+{
+ class Kms
+ {
+ const string lib = "libkms";
+
+ [DllImport(lib, EntryPoint = "kms_bo_map", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int MapBuffer(IntPtr bo, out IntPtr @out);
+
+ [DllImport(lib, EntryPoint = "kms_bo_unmap", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int UnmapBuffer(IntPtr bo);
+ }
+}
+
View
330 Source/OpenTK/Platform/Linux/Bindings/LibInput.cs
@@ -0,0 +1,330 @@
+#region License
+//
+// LibInput.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// 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.
+//
+#endregion
+
+#pragma warning disable 0169, 0219
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace OpenTK.Platform.Linux
+{
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ delegate int OpenRestrictedCallback(IntPtr path, int flags, IntPtr data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ delegate void CloseRestrictedCallback(int fd, IntPtr data);
+
+ class LibInput
+ {
+ internal const string lib = "libinput";
+
+ [DllImport(lib, EntryPoint = "libinput_udev_create_for_seat", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr CreateContext(InputInterface @interface,
+ IntPtr user_data, IntPtr udev, string seat_id);
+
+ [DllImport(lib, EntryPoint = "libinput_destroy", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void DestroyContext(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_event_destroy", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void DestroyEvent(IntPtr @event);
+
+ [DllImport(lib, EntryPoint = "libinput_device_get_sysname", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr DeviceGetNameInternal(IntPtr device);
+ public static string DeviceGetName(IntPtr device)
+ {
+ unsafe
+ {
+ return new string((sbyte*)DeviceGetNameInternal(device));
+ }
+ }
+
+ [DllImport(lib, EntryPoint = "libinput_device_get_user_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr DeviceGetData(IntPtr device);
+
+ [DllImport(lib, EntryPoint = "libinput_device_set_user_data", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void DeviceSetData(IntPtr device, IntPtr user_data);
+
+ [DllImport(lib, EntryPoint = "libinput_device_get_output_name", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr DeviceGetOutputNameInternal(IntPtr device);
+ public static string DeviceGetOutputName(IntPtr device)
+ {
+ unsafe
+ {
+ sbyte* pname = (sbyte*)DeviceGetOutputNameInternal(device);
+ return pname == null ? String.Empty : new string(pname);
+ }
+ }
+
+ [DllImport(lib, EntryPoint = "libinput_device_get_seat", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr DeviceGetSeat(IntPtr device);
+
+ [DllImport(lib, EntryPoint = "libinput_device_has_capability", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool DeviceHasCapability(IntPtr device, DeviceCapability capability);
+
+ [DllImport(lib, EntryPoint = "libinput_dispatch", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Dispatch(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_event_get_device", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr GetDevice(IntPtr @event);
+
+ [DllImport(lib, EntryPoint = "libinput_get_event", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr GetEvent(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_event_get_keyboard_event", CallingConvention = CallingConvention.Cdecl)]
+ public static extern KeyboardEvent GetKeyboardEvent(IntPtr @event);
+
+ [DllImport(lib, EntryPoint = "libinput_event_get_pointer_event", CallingConvention = CallingConvention.Cdecl)]
+ public static extern PointerEvent GetPointerEvent(IntPtr @event);
+
+ [DllImport(lib, EntryPoint = "libinput_event_get_type", CallingConvention = CallingConvention.Cdecl)]
+ public static extern InputEventType GetEventType(IntPtr @event);
+
+ [DllImport(lib, EntryPoint = "libinput_get_fd", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetFD(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_next_event_type", CallingConvention = CallingConvention.Cdecl)]
+ public static extern InputEventType NextEventType(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_resume", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void Resume(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_suspend", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void Suspend(IntPtr libinput);
+
+ [DllImport(lib, EntryPoint = "libinput_seat_get_logical_name", CallingConvention = CallingConvention.Cdecl)]
+ static extern public IntPtr SeatGetLogicalNameInternal(IntPtr seat);
+ public static string SeatGetLogicalName(IntPtr seat)
+ {
+ unsafe
+ {
+ return new string((sbyte*)SeatGetLogicalNameInternal(seat));
+ }
+ }
+
+ [DllImport(lib, EntryPoint = "libinput_seat_get_physical_name", CallingConvention = CallingConvention.Cdecl)]
+ static extern public IntPtr SeatGetPhysicalNameInternal(IntPtr seat);
+ public static string SeatGetPhysicalName(IntPtr seat)
+ {
+ unsafe
+ {
+ return new string((sbyte*)SeatGetPhysicalNameInternal(seat));
+ }
+ }
+ }
+
+ enum DeviceCapability
+ {
+ Keyboard = 0,
+ Mouse,
+ Touch
+ }
+
+ enum InputEventType
+ {
+ None = 0,
+
+ DeviceAdded,
+ DeviceRemoved,
+
+ KeyboardKey = 300,
+
+ PointerMotion = 400,
+ PointerMotionAbsolute,
+ PointerButton,
+ PointerAxis,
+
+ TouchDown = 500,
+ TouchUP,
+ TouchMotion,
+ TouchCancel,
+
+ /// \internal
+ /// <summary>
+ /// Signals the end of a set of touchpoints at one device sample
+ /// time. This event has no coordinate information attached.
+ /// </summary>
+ TouchFrame
+ }
+
+ enum ButtonState
+ {
+ Released = 0,
+ Pressed = 1
+ }
+
+ enum KeyState
+ {
+ Released = 0,
+ Pressed = 1
+ }
+
+ enum PointerAxis
+ {
+ VerticalScroll = 0,
+ HorizontalScroll = 1
+ }
+
+ struct Fixed24
+ {
+ internal readonly int Value;
+
+ public static implicit operator double(Fixed24 n)
+ {
+ long l = ((1023L + 44L) << 52) + (1L << 51) + n.Value;
+ unsafe
+ {
+ double d = *(double*)&l;
+ return d - (3L << 43);
+ }
+ }
+
+ public static implicit operator float(Fixed24 n)
+ {
+ return (float)(double)n;
+ }
+
+ public static explicit operator int(Fixed24 n)
+ {
+ return n.Value >> 8;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ class InputInterface
+ {
+ internal readonly IntPtr open;
+ internal readonly IntPtr close;
+
+ public InputInterface(
+ OpenRestrictedCallback open_restricted,
+ CloseRestrictedCallback close_restricted)
+ {
+ if (open_restricted == null || close_restricted == null)
+ throw new ArgumentNullException();
+
+ open = Marshal.GetFunctionPointerForDelegate(open_restricted);
+ close = Marshal.GetFunctionPointerForDelegate(close_restricted);
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct KeyboardEvent
+ {
+ IntPtr @event;
+
+ public IntPtr BaseEvent { get { return GetBaseEvent(@event); } }
+ public IntPtr Event { get { return @event; } }
+ public uint Time { get { return GetTime(@event); } }
+ public uint Key { get { return GetKey(@event); } }
+ public uint KeyCount { get { return GetSeatKeyCount(@event); } }
+ public KeyState KeyState { get { return GetKeyState(@event); } }
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_time", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetTime(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_base_event", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr GetBaseEvent(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_seat_key_count", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetSeatKeyCount(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetKey(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key_state", CallingConvention = CallingConvention.Cdecl)]
+ static extern KeyState GetKeyState(IntPtr @event);
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct PointerEvent
+ {
+ IntPtr @event;
+
+ public IntPtr BaseEvent { get { return GetBaseEvent(@event); } }
+ public IntPtr Event { get { return @event; } }
+ public uint Time { get { return GetTime(@event); } }
+ public EvdevButton Button { get { return (EvdevButton)GetButton(@event); } }
+ public uint ButtonCount { get { return GetButtonCount(@event); } }
+ public ButtonState ButtonState { get { return GetButtonState(@event); } }
+ public PointerAxis Axis { get { return GetAxis(@event); } }
+ public Fixed24 AxisValue { get { return GetAxisValue(@event); } }
+ public Fixed24 DeltaX { get { return GetDX(@event); } }
+ public Fixed24 DeltaY { get { return GetDY(@event); } }
+ public Fixed24 X { get { return GetAbsX(@event); } }
+ public Fixed24 Y { get { return GetAbsY(@event); } }
+ public Fixed24 TransformedX(int width) { return GetAbsXTransformed(@event, width); }
+ public Fixed24 TransformedY(int height) { return GetAbsYTransformed(@event, height); }
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_time", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetTime(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_base_event", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr GetBaseEvent(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_seat_key_count", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetSeatKeyCount(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_button", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetButton(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_seat_button_count", CallingConvention = CallingConvention.Cdecl)]
+ static extern uint GetButtonCount(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_button_state", CallingConvention = CallingConvention.Cdecl)]
+ static extern ButtonState GetButtonState(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_axis", CallingConvention = CallingConvention.Cdecl)]
+ static extern PointerAxis GetAxis(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_axis_value", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetAxisValue(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_dx", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetDX(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_dy", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetDY(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_x", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetAbsX(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_y", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetAbsY(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_x_transformed", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetAbsXTransformed(IntPtr @event, int width);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_y_transformed", CallingConvention = CallingConvention.Cdecl)]
+ static extern Fixed24 GetAbsYTransformed(IntPtr @event, int height);
+ }
+}
+
View
178 Source/OpenTK/Platform/Linux/Bindings/Libc.cs
@@ -0,0 +1,178 @@
+#region License
+//
+// Linux.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace OpenTK.Platform.Linux
+{
+ partial class Libc
+ {
+ const string lib = "libc";
+
+ [DllImport(lib)]
+ public static extern int dup(int file);
+
+ [DllImport(lib)]
+ public static extern int dup2(int file1, int file2);
+
+ [DllImport(lib)]
+ public static extern int ioctl(int d, JoystickIoctlCode request, ref int data);
+
+ [DllImport(lib)]
+ public static extern int ioctl(int d, JoystickIoctlCode request, StringBuilder data);
+
+ [DllImport(lib)]
+ public static extern int ioctl(int d, EvdevIoctlCode request, out EvdevInputId data);
+
+ [DllImport(lib)]
+ public static extern int ioctl(int d, KeyboardIoctlCode request, ref IntPtr data);
+
+ [DllImport(lib)]
+ public static extern int ioctl(int d, KeyboardIoctlCode request, int data);
+
+ [DllImport(lib)]
+ public static extern int open([MarshalAs(UnmanagedType.LPStr)]string pathname, OpenFlags flags);
+
+ [DllImport(lib)]
+ public static extern int open(IntPtr pathname, OpenFlags flags);
+
+ [DllImport(lib)]
+ public static extern int close(int fd);
+
+ [DllImport(lib)]
+ unsafe public static extern IntPtr read(int fd, void* buffer, UIntPtr count);
+
+ public static int read(int fd, out byte b)
+ {
+ unsafe
+ {
+ fixed (byte* pb = &b)
+ {
+ return read(fd, pb, (UIntPtr)1).ToInt32();
+ }
+ }
+ }
+
+ public static int read(int fd, out short s)
+ {
+ unsafe
+ {
+ fixed (short* ps = &s)
+ {
+ return read(fd, ps, (UIntPtr)2).ToInt32();
+ }
+ }
+ }
+
+ [DllImport(lib)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool isatty(int fd);
+ }
+
+ enum ErrorNumber
+ {
+ Interrupted = 4,
+ Again = 11,
+ InvalidValue = 22,
+ }
+
+ [Flags]
+ enum OpenFlags
+ {
+ ReadOnly = 0x0000,
+ WriteOnly = 0x0001,
+ ReadWrite = 0x0002,
+ NonBlock = 0x0800,
+ CloseOnExec = 0x0080000
+ }
+
+ enum EvdevIoctlCode : uint
+ {
+ Id = ((byte)'E' << 8) | (0x02 << 0) //EVIOCGID, which is _IOR('E', 0x02, struct input_id)
+ }
+
+ [Flags]
+ enum JoystickEventType : byte
+ {
+ Button = 0x01, // button pressed/released
+ Axis = 0x02, // joystick moved
+ Init = 0x80 // initial state of device
+ }
+
+ enum JoystickIoctlCode : uint
+ {
+ Version = 0x80046a01,
+ Axes = 0x80016a11,
+ Buttons = 0x80016a12,
+ Name128 = (2u << 30) | (0x6A << 8) | (0x13 << 0) | (128 << 16) //JSIOCGNAME(128), which is _IOC(_IO_READ, 'j', 0x13, len)
+ }
+
+ enum KeyboardIoctlCode
+ {
+ GetMode = 0x4b44,
+ SetMode = 0x4b45,
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct Stat
+ {
+ public IntPtr dev; /* ID of device containing file */
+ public IntPtr ino; /* inode number */
+ public IntPtr mode; /* protection */
+ public IntPtr nlink; /* number of hard links */
+ public IntPtr uid; /* user ID of owner */
+ public IntPtr gid; /* group ID of owner */
+ public IntPtr rdev; /* device ID (if special file) */
+ public IntPtr size; /* total size, in bytes */
+ public IntPtr blksize; /* blocksize for file system I/O */
+ public IntPtr blocks; /* number of 512B blocks allocated */
+ public IntPtr atime; /* time of last access */
+ public IntPtr mtime; /* time of last modification */
+ public IntPtr ctime; /* time of last status change */
+ }
+
+ struct EvdevInputId
+ {
+ public ushort BusType;
+ public ushort Vendor;
+ public ushort Product;
+ public ushort Version;
+ }
+
+ struct JoystickEvent
+ {
+ public uint Time; // (u32) event timestamp in milliseconds
+ public short Value; // (s16) value
+ public JoystickEventType Type; // (u8) event type
+ public byte Number; // (u8) axis/button number
+ }
+}
+
View
65 Source/OpenTK/Platform/Linux/Bindings/Poll.cs
@@ -0,0 +1,65 @@
+#region License
+//
+// Poll.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace OpenTK.Platform.Linux
+{
+ partial class Libc
+ {
+ [DllImport(lib, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
+ public static extern int poll(ref PollFD fd, IntPtr fd_count, int timeout);
+
+ public static int poll(ref PollFD fd, int fd_count, int timeout)
+ {
+ return poll(ref fd, (IntPtr)fd_count, timeout);
+ }
+ }
+
+ [Flags]
+ enum PollFlags : short
+ {
+ In = 0x01,
+ Pri = 0x02,
+ Out = 0x04,
+ Error = 0x08,
+ Hup = 0x10,
+ Invalid = 0x20,
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct PollFD
+ {
+ public int fd;
+ public PollFlags events;
+ public PollFlags revents;
+ }
+}
+
View
170 Source/OpenTK/Platform/Linux/Bindings/Terminal.cs
@@ -0,0 +1,170 @@
+#region License
+//
+// Terminal.cs
+//
+// Author:
+// Stefanos A. <stapostol@gmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+//
+// 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.
+//
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace OpenTK.Platform.Linux
+{
+ class Terminal
+ {
+ const string lib = "libc";
+
+ [DllImport(lib, EntryPoint = "isatty", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern bool IsTerminal(int fd);
+
+ [DllImport(lib, EntryPoint = "tcgetattr", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int GetAttributes(int fd, out TerminalState state);
+
+ [DllImport(lib, EntryPoint = "tcsetattr", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int SetAttributes(int fd, OptionalActions actions, ref TerminalState state);
+ }
+
+ [Flags]
+ enum InputFlags
+ {
+ IGNBRK = 1 << 0,
+ BRKINT = 1 << 1,
+ IGNPAR = 1 << 2,
+ PARMRK = 1 << 3,
+ INPCK = 1 << 4,
+ ISTRIP = 1 << 5,
+ INLCR = 1 << 6,
+ IGNCR = 1 << 7,
+ ICRNL = 1 << 8,
+ IUCLC = 1 << 9,
+ IXON = 1 << 10,
+ IXANY = 1 << 11,
+ IXOFF = 1 << 12,
+ IMAXBEL = 1 << 13,
+ IUTF8 = 1 << 14,
+ }
+
+ [Flags]
+ enum OutputFlags
+ {
+ OPOST = 1 << 1,
+ OLCUC = 1 << 2,
+ ONLCR = 1 << 3,
+ OCRNL = 1 << 4,
+ ONOCR = 1 << 5,
+ ONLRET = 1 << 6,
+ OFILL = 1 << 7,
+ OFDEL = 1 << 8,
+ }
+
+ [Flags]
+ enum ControlFlags
+ {
+ B0 = 0, // hang up
+ B50,
+ B75,
+ B110,
+ B134,
+ B150,
+ B200,
+ B300,
+ B600,
+ B1200,
+ B1800,
+ B2400,
+ B4800,
+ B9600,
+ B19200,
+ B38400,
+ }
+
+ [Flags]
+ enum LocalFlags
+ {
+ ISIG = 0x01,
+ ICANON = 0x02,
+ ECHO = 0x08,
+ }
+
+ enum OptionalActions
+ {
+ NOW = 0,
+ DRAIN = 1,
+ FLUSH = 2
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct TerminalState
+ {
+ public InputFlags InputMode;
+ public OutputFlags OutputMode;
+ public ControlFlags ControlMode;
+ public LocalFlags LocalMode;
+ public byte LineDiscipline;
+ public ControlCharacters ControlCharacters;
+ public int InputSpeed;
+ public int OutputSpeed;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ str