[KMS] Added new Linux KMS driver
This commit is contained in:
parent
c3451530a6
commit
6f6798de62
12 changed files with 643 additions and 168 deletions
|
@ -101,6 +101,15 @@ namespace Examples
|
|||
public static void Main(string[] args)
|
||||
{
|
||||
Trace.Listeners.Add(new ConsoleTraceListener());
|
||||
Tests.GameWindowStates.Main();
|
||||
return;
|
||||
|
||||
using (var gw = new GameWindow())
|
||||
{
|
||||
gw.KeyDown += (sender, e) => gw.Exit();
|
||||
gw.Run(60);
|
||||
}
|
||||
return;
|
||||
|
||||
if (args.Length > 0)
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
@ -809,8 +806,13 @@
|
|||
<Compile Include="Platform\Linux\Bindings\Drm.cs" />
|
||||
<Compile Include="Platform\Linux\LinuxFactory.cs" />
|
||||
<Compile Include="Platform\Linux\LinuxNativeWindow.cs" />
|
||||
<Compile Include="Platform\Linux\Bindings\Linux.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" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace OpenTK.Platform
|
|||
|
||||
// Create regular platform backend
|
||||
if (Configuration.RunningOnSdl2) Default = new SDL2.Sdl2Factory();
|
||||
else if (Configuration.RunningOnLinux) Default = new Linux.LinuxFactory();
|
||||
else if (Configuration.RunningOnX11) Default = new X11.X11Factory();
|
||||
else if (Configuration.RunningOnWindows) Default = new Windows.WinFactory();
|
||||
else if (Configuration.RunningOnMacOS) Default = new MacOS.MacOSFactory();
|
||||
|
@ -70,7 +71,8 @@ namespace OpenTK.Platform
|
|||
}
|
||||
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();
|
||||
|
|
|
@ -36,20 +36,115 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
const string lib = "libdrm";
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetCrtc", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ModeGetCrtc(int fd, uint 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, uint connector_id);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetEncoder", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ModeGetEncoder(int fd, uint encoder_id);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetResources", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern IntPtr ModeGetResources(int fd);
|
||||
public static extern IntPtr ModeGetResources(int fd);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeSetCrtc", CallingConvention = CallingConvention.Cdecl)]
|
||||
unsafe public static extern int ModeSetCrtc(int fd, uint crtcId, uint bufferId,
|
||||
uint x, uint y, uint* connectors, int count, ModeInfo* mode);
|
||||
}
|
||||
|
||||
struct ModeRes
|
||||
enum ModeConnection : byte
|
||||
{
|
||||
Connected = 1,
|
||||
Disconnected = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
enum ModeSubPixel : byte
|
||||
{
|
||||
Unknown = 1,
|
||||
HorizontalRgb = 2,
|
||||
HorizontalBgr = 3,
|
||||
VerticalRgb = 4,
|
||||
VerticalBgr = 5,
|
||||
None = 6
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
unsafe struct ModeConnector
|
||||
{
|
||||
public uint connector_id;
|
||||
public uint encoder_id;
|
||||
public uint connector_type;
|
||||
public uint connector_type_id;
|
||||
public ModeConnection connection;
|
||||
public uint mmWidth, mmHeight;
|
||||
public ModeSubPixel subpixel;
|
||||
|
||||
public int count_modes;
|
||||
public ModeInfo* modes;
|
||||
|
||||
public int count_props;
|
||||
public uint *props;
|
||||
public ulong *prop_values;
|
||||
|
||||
public int count_encoders;
|
||||
public uint *encoders;
|
||||
}
|
||||
|
||||
struct ModeCrtc
|
||||
{
|
||||
public uint crtc_id;
|
||||
public uint buffer_id;
|
||||
|
||||
public uint x, y;
|
||||
public uint width, height;
|
||||
public int mode_valid;
|
||||
public ModeInfo mode;
|
||||
|
||||
public int gamma_size;
|
||||
}
|
||||
|
||||
struct ModeEncoder
|
||||
{
|
||||
public uint encoder_id;
|
||||
public uint encoder_type;
|
||||
public uint crtc_id;
|
||||
public uint possible_crtcs;
|
||||
public uint 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 uint 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 IntPtr fbs; //uint*
|
||||
public uint* fbs;
|
||||
public int count_crtcs;
|
||||
public IntPtr crtcs; //uint*
|
||||
public uint* crtcs;
|
||||
public int count_connectors;
|
||||
public IntPtr connectors; //uint*
|
||||
public uint* connectors;
|
||||
public int count_encoders;
|
||||
public IntPtr encoders; //uint*
|
||||
public uint* encoders;
|
||||
public int min_width, max_width;
|
||||
public int min_height, max_height;
|
||||
}
|
||||
|
|
|
@ -29,22 +29,62 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
class Linux
|
||||
class Libc
|
||||
{
|
||||
[DllImport("glib", EntryPoint = "open", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int Open(string pathname, OpenFlags flags);
|
||||
const string lib = "libc";
|
||||
|
||||
[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 open([MarshalAs(UnmanagedType.LPStr)]string 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);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum OpenFlags
|
||||
{
|
||||
ReadOnly = 0,
|
||||
WriteOnly = 1,
|
||||
ReadWrite = 2,
|
||||
CloseOnExec = 4096
|
||||
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)
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
@ -64,5 +104,21 @@ namespace OpenTK.Platform.Linux
|
|||
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
|
||||
}
|
||||
}
|
||||
|
282
Source/OpenTK/Platform/Linux/LinuxDisplayDriver.cs
Normal file
282
Source/OpenTK/Platform/Linux/LinuxDisplayDriver.cs
Normal file
|
@ -0,0 +1,282 @@
|
|||
#region License
|
||||
//
|
||||
// LinuxDisplayDriver.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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
class LinuxDisplayDriver : DisplayDeviceBase
|
||||
{
|
||||
unsafe class LinuxDisplay
|
||||
{
|
||||
public ModeConnector* Connector;
|
||||
public ModeEncoder* Encoder;
|
||||
public ModeCrtc* Crtc;
|
||||
public ModeInfo Mode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Crtc == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
return Crtc->mode;
|
||||
}
|
||||
}
|
||||
public ModeInfo OriginalMode;
|
||||
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Crtc == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
return (int)Crtc->crtc_id;
|
||||
}
|
||||
}
|
||||
|
||||
public LinuxDisplay(ModeConnector* c, ModeEncoder* e, ModeCrtc* r)
|
||||
{
|
||||
Connector = c;
|
||||
Encoder = e;
|
||||
Crtc = r;
|
||||
OriginalMode = Crtc->mode; // in case we change resolution later on
|
||||
}
|
||||
}
|
||||
|
||||
readonly int FD;
|
||||
readonly GbmDevice Device;
|
||||
readonly Dictionary<int, int> DisplayIds =
|
||||
new Dictionary<int, int>();
|
||||
|
||||
public LinuxDisplayDriver(int fd)
|
||||
{
|
||||
FD = fd;
|
||||
QueryDisplays();
|
||||
}
|
||||
|
||||
void QueryDisplays()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
AvailableDevices.Clear();
|
||||
DisplayIds.Clear();
|
||||
|
||||
ModeRes* resources = (ModeRes*)Drm.ModeGetResources(FD);
|
||||
if (resources == null)
|
||||
{
|
||||
throw new NotSupportedException("[KMS] DRM ModeGetResources failed");
|
||||
}
|
||||
Debug.Print("[KMS] DRM found {0} connectors", resources->count_connectors);
|
||||
|
||||
// Search for a valid connector
|
||||
ModeConnector* connector = null;
|
||||
for (int i = 0; i < resources->count_connectors; i++)
|
||||
{
|
||||
connector = (ModeConnector*)Drm.ModeGetConnector(FD,
|
||||
*(resources->connectors + i));
|
||||
if (connector != null)
|
||||
{
|
||||
if (connector->connection == ModeConnection.Connected &&
|
||||
connector->count_modes > 0)
|
||||
{
|
||||
// Connector found!
|
||||
AddDisplay(connector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is not the display we are looking for
|
||||
Drm.ModeFreeConnector((IntPtr)connector);
|
||||
connector = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AvailableDevices.Count == 0)
|
||||
{
|
||||
Debug.Print("[KMS] Failed to find any active displays");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe void AddDisplay(ModeConnector* c)
|
||||
{
|
||||
// Find corresponding encoder
|
||||
ModeEncoder* encoder = null;
|
||||
for (int i = 0; i < c->count_encoders && encoder == null; i++)
|
||||
{
|
||||
ModeEncoder* e = (ModeEncoder*)Drm.ModeGetEncoder(
|
||||
FD, *(c->encoders + i));
|
||||
if (e != null)
|
||||
{
|
||||
if (e->encoder_id == c->encoder_id)
|
||||
{
|
||||
encoder = e;
|
||||
}
|
||||
else
|
||||
{
|
||||
Drm.ModeFreeEncoder((IntPtr)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder != null)
|
||||
{
|
||||
Debug.Print("[KMS] Encoder {0} found for connector {1}",
|
||||
encoder->encoder_id, c->connector_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[KMS] Failed to find encoder for connector {0}", c->connector_id);
|
||||
return;
|
||||
}
|
||||
|
||||
ModeCrtc* crtc = (ModeCrtc*)Drm.ModeGetCrtc(FD, encoder->crtc_id);
|
||||
if (crtc != null)
|
||||
{
|
||||
Debug.Print("[KMS] CRTC {0} found for encoder {1}",
|
||||
encoder->crtc_id, encoder->encoder_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[KMS] Failed to find crtc {0} for encoder {1}",
|
||||
encoder->crtc_id, encoder->encoder_id);
|
||||
return;
|
||||
}
|
||||
|
||||
LinuxDisplay display = new LinuxDisplay(c, encoder, crtc);
|
||||
if (!DisplayIds.ContainsKey(display.Id))
|
||||
{
|
||||
DisplayIds.Add(display.Id, AvailableDevices.Count);
|
||||
}
|
||||
|
||||
List<DisplayResolution> modes = new List<DisplayResolution>();
|
||||
for (int i = 0; i < display.Connector->count_modes; i++)
|
||||
{
|
||||
ModeInfo* mode = display.Connector->modes + i;
|
||||
DisplayResolution res = GetDisplayResolution(mode);
|
||||
modes.Add(res);
|
||||
}
|
||||
ModeInfo current_mode = display.Mode;
|
||||
DisplayResolution current = GetDisplayResolution(¤t_mode);
|
||||
|
||||
// Note: since we are not running a display manager, we are free
|
||||
// to choose the display layout for multiple displays ourselves.
|
||||
// We choose the simplest layout: displays are laid out side-by-side
|
||||
// from left to right. Primary display is the first display we encounter.
|
||||
System.Drawing.Rectangle bounds =
|
||||
new System.Drawing.Rectangle(
|
||||
AvailableDevices.Count == 0 ? 0 : AvailableDevices[0].Bounds.Right,
|
||||
0,
|
||||
current.Width,
|
||||
current.Height);
|
||||
|
||||
DisplayDevice device = new DisplayDevice(
|
||||
current,
|
||||
AvailableDevices.Count == 0,
|
||||
modes,
|
||||
bounds,
|
||||
display);
|
||||
|
||||
if (AvailableDevices.Count == 0)
|
||||
{
|
||||
Primary = device;
|
||||
}
|
||||
|
||||
AvailableDevices.Add(device);
|
||||
}
|
||||
|
||||
unsafe static DisplayResolution GetDisplayResolution(ModeInfo* mode)
|
||||
{
|
||||
if (mode == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
return new DisplayResolution(
|
||||
0, 0,
|
||||
mode->htotal, mode->vtotal,
|
||||
32, // This is actually part of the framebuffer, not the DisplayResolution
|
||||
mode->vrefresh / 1000.0f);
|
||||
}
|
||||
|
||||
unsafe static ModeInfo* GetModeInfo(LinuxDisplay display, DisplayResolution resolution)
|
||||
{
|
||||
for (int i = 0; i < display.Connector->count_modes; i++)
|
||||
{
|
||||
ModeInfo* mode = display.Connector->modes + i;
|
||||
if (mode != null &&
|
||||
mode->htotal == resolution.Width &&
|
||||
mode->vtotal == resolution.Height)
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region IDisplayDeviceDriver
|
||||
|
||||
public override bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
LinuxDisplay display = (LinuxDisplay)device.Id;
|
||||
ModeInfo* mode = GetModeInfo(display, resolution);
|
||||
uint connector_id = display.Connector->connector_id;
|
||||
if (mode != null)
|
||||
{
|
||||
return Drm.ModeSetCrtc(FD, (uint)display.Id, 0, 0, 0,
|
||||
&connector_id, 1, mode) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryRestoreResolution(DisplayDevice device)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
LinuxDisplay display = (LinuxDisplay)device.Id;
|
||||
uint connector_id = display.Connector->connector_id;
|
||||
ModeInfo mode = display.OriginalMode;
|
||||
return Drm.ModeSetCrtc(FD, (uint)display.Id, 0, 0, 0,
|
||||
&connector_id, 1, &mode) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -32,70 +32,93 @@ using System.Diagnostics;
|
|||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
using Egl = OpenTK.Platform.Egl.Egl;
|
||||
|
||||
// Linux KMS platform
|
||||
class LinuxFactory : PlatformFactoryBase
|
||||
{
|
||||
int fd;
|
||||
GbmDevice device;
|
||||
GbmDevice gbm_device;
|
||||
IntPtr display;
|
||||
|
||||
IJoystickDriver2 JoystickDriver;
|
||||
IDisplayDeviceDriver DisplayDriver;
|
||||
|
||||
public LinuxFactory()
|
||||
{
|
||||
SetupEgl();
|
||||
}
|
||||
|
||||
#region Private Members
|
||||
|
||||
void SetupEgl()
|
||||
{
|
||||
// Todo: support multi-GPU systems
|
||||
string gpu = "/dev/dri/card0";
|
||||
fd = Linux.Open(gpu, OpenFlags.ReadOnly | OpenFlags.CloseOnExec);
|
||||
fd = Libc.open(gpu, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
|
||||
if (fd < 0)
|
||||
{
|
||||
throw new NotSupportedException("No KMS-capable GPU available");
|
||||
throw new NotSupportedException("[KMS] No KMS-capable GPU available");
|
||||
}
|
||||
Debug.Print("GPU {0} opened as fd:{1}", gpu, fd);
|
||||
Debug.Print("[KMS] GPU '{0}' opened as fd:{1}", gpu, fd);
|
||||
|
||||
IntPtr dev = Gbm.CreateDevice(fd);
|
||||
if (dev == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("Failed to create GBM device");
|
||||
throw new NotSupportedException("[KMS] Failed to create GBM device");
|
||||
}
|
||||
device = (GbmDevice)Marshal.PtrToStructure(dev, typeof(GbmDevice));
|
||||
Debug.Print("GBM {0:x} '{1}' created successfully",
|
||||
dev, Marshal.PtrToStringAnsi(device.name));
|
||||
gbm_device = (GbmDevice)Marshal.PtrToStructure(dev, typeof(GbmDevice));
|
||||
Debug.Print("[KMS] GBM {0:x} created successfully", dev);
|
||||
|
||||
display = Egl.Egl.GetDisplay(dev);
|
||||
display = Egl.GetDisplay(dev);
|
||||
if (display == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("Failed to create EGL display");
|
||||
throw new NotSupportedException("[KMS] Failed to create EGL display");
|
||||
}
|
||||
Debug.Print("EGL display {0:x} created successfully", display);
|
||||
Debug.Print("[KMS] EGL display {0:x} created successfully", display);
|
||||
|
||||
int major, minor;
|
||||
if (!Egl.Egl.Initialize(display, out major, out minor))
|
||||
if (!Egl.Initialize(display, out major, out minor))
|
||||
{
|
||||
int error = Egl.Egl.GetError();
|
||||
throw new NotSupportedException("Failed to initialize EGL display. Error code: " + error);
|
||||
int error = Egl.GetError();
|
||||
throw new NotSupportedException("[KMS] Failed to initialize EGL display. Error code: " + error);
|
||||
}
|
||||
Debug.Print("EGL {0}.{1} initialized successfully on display {2:x}", major, minor, display);
|
||||
Debug.Print("[KMS] EGL {0}.{1} initialized successfully on display {2:x}", major, minor, display);
|
||||
}
|
||||
|
||||
public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
||||
#endregion
|
||||
|
||||
#region IPlatformFactory Members
|
||||
|
||||
public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice display_device)
|
||||
{
|
||||
return new LinuxNativeWindow(x, y, width, height, title, mode, options, device);
|
||||
return new LinuxNativeWindow(display, gbm_device, width, height, title, mode, options, display_device);
|
||||
}
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
lock (this)
|
||||
{
|
||||
DisplayDriver = DisplayDriver ?? new LinuxDisplayDriver(fd);
|
||||
return DisplayDriver;
|
||||
}
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return new EglUnixContext(mode, (EglWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Egl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
|
||||
public override IKeyboardDriver2 CreateKeyboardDriver()
|
||||
|
@ -110,8 +133,14 @@ namespace OpenTK.Platform.Linux
|
|||
|
||||
public override IJoystickDriver2 CreateJoystickDriver()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
lock (this)
|
||||
{
|
||||
JoystickDriver = JoystickDriver ?? new LinuxJoystick();
|
||||
return JoystickDriver;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ using System.Runtime.InteropServices;
|
|||
using System.Text;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
struct X11JoyDetails
|
||||
struct LinuxJoyDetails
|
||||
{
|
||||
public Guid Guid;
|
||||
public int FileDescriptor;
|
||||
|
@ -43,7 +43,7 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
|
||||
// Note: despite what the name says, this class is Linux-specific.
|
||||
sealed class X11Joystick : IJoystickDriver2
|
||||
sealed class LinuxJoystick : IJoystickDriver2
|
||||
{
|
||||
#region Fields
|
||||
|
||||
|
@ -52,7 +52,7 @@ namespace OpenTK.Platform.X11
|
|||
readonly FileSystemWatcher watcher = new FileSystemWatcher();
|
||||
|
||||
readonly Dictionary<int, int> index_to_stick = new Dictionary<int, int>();
|
||||
List<JoystickDevice<X11JoyDetails>> sticks = new List<JoystickDevice<X11JoyDetails>>();
|
||||
List<JoystickDevice<LinuxJoyDetails>> sticks = new List<JoystickDevice<LinuxJoyDetails>>();
|
||||
|
||||
bool disposed;
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
#region Constructors
|
||||
|
||||
public X11Joystick()
|
||||
public LinuxJoystick()
|
||||
{
|
||||
string path =
|
||||
Directory.Exists(JoystickPath) ? JoystickPath :
|
||||
|
@ -89,7 +89,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
foreach (string file in Directory.GetFiles(path))
|
||||
{
|
||||
JoystickDevice<X11JoyDetails> stick = OpenJoystick(file);
|
||||
JoystickDevice<LinuxJoyDetails> stick = OpenJoystick(file);
|
||||
if (stick != null)
|
||||
{
|
||||
//stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons, {3}{0})",
|
||||
|
@ -155,7 +155,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
#region Private Members
|
||||
|
||||
Guid CreateGuid(JoystickDevice<X11JoyDetails> js, string path, int number)
|
||||
Guid CreateGuid(JoystickDevice<LinuxJoyDetails> js, string path, int number)
|
||||
{
|
||||
byte[] bytes = new byte[16];
|
||||
for (int i = 0; i < Math.Min(bytes.Length, js.Description.Length); i++)
|
||||
|
@ -221,9 +221,9 @@ namespace OpenTK.Platform.X11
|
|||
#endif
|
||||
}
|
||||
|
||||
JoystickDevice<X11JoyDetails> OpenJoystick(string path)
|
||||
JoystickDevice<LinuxJoyDetails> OpenJoystick(string path)
|
||||
{
|
||||
JoystickDevice<X11JoyDetails> stick = null;
|
||||
JoystickDevice<LinuxJoyDetails> stick = null;
|
||||
|
||||
int number = GetJoystickNumber(Path.GetFileName(path));
|
||||
if (number >= 0)
|
||||
|
@ -231,28 +231,28 @@ namespace OpenTK.Platform.X11
|
|||
int fd = -1;
|
||||
try
|
||||
{
|
||||
fd = UnsafeNativeMethods.open(path, OpenFlags.NonBlock);
|
||||
fd = Libc.open(path, OpenFlags.NonBlock);
|
||||
if (fd == -1)
|
||||
return null;
|
||||
|
||||
// Check joystick driver version (must be 1.0+)
|
||||
int driver_version = 0x00000800;
|
||||
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Version, ref driver_version);
|
||||
Libc.ioctl(fd, JoystickIoctlCode.Version, ref driver_version);
|
||||
if (driver_version < 0x00010000)
|
||||
return null;
|
||||
|
||||
// Get number of joystick axes
|
||||
int axes = 0;
|
||||
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Axes, ref axes);
|
||||
Libc.ioctl(fd, JoystickIoctlCode.Axes, ref axes);
|
||||
|
||||
// Get number of joystick buttons
|
||||
int buttons = 0;
|
||||
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Buttons, ref buttons);
|
||||
Libc.ioctl(fd, JoystickIoctlCode.Buttons, ref buttons);
|
||||
|
||||
stick = new JoystickDevice<X11JoyDetails>(number, axes, buttons);
|
||||
stick = new JoystickDevice<LinuxJoyDetails>(number, axes, buttons);
|
||||
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
UnsafeNativeMethods.ioctl(fd, JoystickIoctlCode.Name128, sb);
|
||||
Libc.ioctl(fd, JoystickIoctlCode.Name128, sb);
|
||||
stick.Description = sb.ToString();
|
||||
|
||||
stick.Details.FileDescriptor = fd;
|
||||
|
@ -287,16 +287,16 @@ namespace OpenTK.Platform.X11
|
|||
finally
|
||||
{
|
||||
if (stick == null && fd != -1)
|
||||
UnsafeNativeMethods.close(fd);
|
||||
Libc.close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
return stick;
|
||||
}
|
||||
|
||||
void CloseJoystick(JoystickDevice<X11JoyDetails> js)
|
||||
void CloseJoystick(JoystickDevice<LinuxJoyDetails> js)
|
||||
{
|
||||
UnsafeNativeMethods.close(js.Details.FileDescriptor);
|
||||
Libc.close(js.Details.FileDescriptor);
|
||||
js.Details.State = new JoystickState(); // clear joystick state
|
||||
js.Details.FileDescriptor = -1;
|
||||
|
||||
|
@ -317,13 +317,13 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
}
|
||||
|
||||
void PollJoystick(JoystickDevice<X11JoyDetails> js)
|
||||
void PollJoystick(JoystickDevice<LinuxJoyDetails> js)
|
||||
{
|
||||
JoystickEvent e;
|
||||
|
||||
unsafe
|
||||
{
|
||||
while ((long)UnsafeNativeMethods.read(js.Details.FileDescriptor, (void*)&e, (UIntPtr)sizeof(JoystickEvent)) > 0)
|
||||
while ((long)Libc.read(js.Details.FileDescriptor, (void*)&e, (UIntPtr)sizeof(JoystickEvent)) > 0)
|
||||
{
|
||||
e.Type &= ~JoystickEventType.Init;
|
||||
|
||||
|
@ -352,78 +352,9 @@ namespace OpenTK.Platform.X11
|
|||
return index_to_stick.ContainsKey(index);
|
||||
}
|
||||
|
||||
#region UnsafeNativeMethods
|
||||
|
||||
struct EvdevInputId
|
||||
{
|
||||
public ushort BusType;
|
||||
public ushort Vendor;
|
||||
public ushort Product;
|
||||
public ushort Version;
|
||||
}
|
||||
|
||||
enum EvdevIoctlCode : uint
|
||||
{
|
||||
Id = ((byte)'E' << 8) | (0x02 << 0) //EVIOCGID, which is _IOR('E', 0x02, struct input_id)
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
[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)
|
||||
}
|
||||
|
||||
static readonly string JoystickPath = "/dev/input";
|
||||
static readonly string JoystickPathLegacy = "/dev";
|
||||
|
||||
[Flags]
|
||||
enum OpenFlags
|
||||
{
|
||||
NonBlock = 0x00000800
|
||||
}
|
||||
|
||||
static class UnsafeNativeMethods
|
||||
{
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
public static extern int ioctl(int d, JoystickIoctlCode request, ref int data);
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
public static extern int ioctl(int d, JoystickIoctlCode request, StringBuilder data);
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
public static extern int ioctl(int d, EvdevIoctlCode request, out EvdevInputId data);
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
public static extern int open([MarshalAs(UnmanagedType.LPStr)]string pathname, OpenFlags flags);
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
public static extern int close(int fd);
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
unsafe public static extern IntPtr read(int fd, void* buffer, UIntPtr count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
@ -443,7 +374,7 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
|
||||
watcher.Dispose();
|
||||
foreach (JoystickDevice<X11JoyDetails> js in sticks)
|
||||
foreach (JoystickDevice<LinuxJoyDetails> js in sticks)
|
||||
{
|
||||
CloseJoystick(js);
|
||||
}
|
||||
|
@ -452,7 +383,7 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
}
|
||||
|
||||
~X11Joystick()
|
||||
~LinuxJoystick()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
@ -465,7 +396,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
if (IsValid(index))
|
||||
{
|
||||
JoystickDevice<X11JoyDetails> js =
|
||||
JoystickDevice<LinuxJoyDetails> js =
|
||||
sticks[index_to_stick[index]];
|
||||
PollJoystick(js);
|
||||
return js.Details.State;
|
||||
|
@ -478,7 +409,7 @@ namespace OpenTK.Platform.X11
|
|||
JoystickCapabilities caps = new JoystickCapabilities();
|
||||
if (IsValid(index))
|
||||
{
|
||||
JoystickDevice<X11JoyDetails> js = sticks[index_to_stick[index]];
|
||||
JoystickDevice<LinuxJoyDetails> js = sticks[index_to_stick[index]];
|
||||
caps = new JoystickCapabilities(
|
||||
js.Axis.Count,
|
||||
js.Button.Count,
|
||||
|
@ -492,7 +423,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
if (IsValid(index))
|
||||
{
|
||||
JoystickDevice<X11JoyDetails> js = sticks[index_to_stick[index]];
|
||||
JoystickDevice<LinuxJoyDetails> js = sticks[index_to_stick[index]];
|
||||
return js.Details.Guid;
|
||||
}
|
||||
return new Guid();
|
|
@ -28,42 +28,74 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
using Egl = OpenTK.Platform.Egl.Egl;
|
||||
|
||||
class LinuxNativeWindow : NativeWindowBase
|
||||
{
|
||||
LinuxWindowInfo window_info;
|
||||
string title;
|
||||
Icon icon;
|
||||
bool exists;
|
||||
Rectangle bounds;
|
||||
Size client_size;
|
||||
|
||||
public LinuxNativeWindow(IntPtr display, GbmDevice device,
|
||||
int width, int height, string title, GraphicsMode mode, GameWindowFlags options,
|
||||
DisplayDevice display_device)
|
||||
{
|
||||
Title = title;
|
||||
bounds = new Rectangle(0, 0, width, height);
|
||||
client_size = bounds.Size;
|
||||
|
||||
//window_info = new LinuxWindowInfo(
|
||||
// Egl.CreateWindowSurface(
|
||||
|
||||
exists = true;
|
||||
}
|
||||
|
||||
#region INativeWindow Members
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
exists = false;
|
||||
}
|
||||
|
||||
public override System.Drawing.Point PointToClient(System.Drawing.Point point)
|
||||
public override Point PointToClient(Point point)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Todo
|
||||
return point;
|
||||
}
|
||||
|
||||
public override System.Drawing.Point PointToScreen(System.Drawing.Point point)
|
||||
public override Point PointToScreen(Point point)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Todo
|
||||
return point;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Todo
|
||||
}
|
||||
|
||||
public override System.Drawing.Icon Icon
|
||||
public override Icon Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return icon;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (icon != value)
|
||||
{
|
||||
icon = value;
|
||||
OnIconChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,11 +103,15 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return title;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (title != value)
|
||||
{
|
||||
title = value;
|
||||
OnTitleChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +119,7 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,11 +127,10 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return true;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +138,7 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +146,7 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return window_info;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,11 +154,10 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return WindowState.Fullscreen;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,35 +165,32 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return WindowBorder.Hidden;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override System.Drawing.Rectangle Bounds
|
||||
public override Rectangle Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return bounds;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override System.Drawing.Size ClientSize
|
||||
public override Size ClientSize
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return client_size;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,11 +198,10 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,18 +209,14 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return MouseCursor.Empty;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
43
Source/OpenTK/Platform/Linux/LinuxWindowInfo.cs
Normal file
43
Source/OpenTK/Platform/Linux/LinuxWindowInfo.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
#region License
|
||||
//
|
||||
// LinuxWindowInfo.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 OpenTK.Platform.Egl;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
class LinuxWindowInfo : EglWindowInfo
|
||||
{
|
||||
public LinuxWindowInfo(IntPtr handle, IntPtr display, IntPtr surface)
|
||||
: base(handle, display, surface)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
readonly X11Mouse mouse = new X11Mouse();
|
||||
readonly X11Keyboard keyboard = new X11Keyboard();
|
||||
readonly X11Joystick joystick = new X11Joystick();
|
||||
readonly Linux.LinuxJoystick joystick = new Linux.LinuxJoystick();
|
||||
readonly IGamePadDriver gamepad = new MappedGamePadDriver();
|
||||
|
||||
internal X11Input()
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace OpenTK.Platform.X11
|
|||
class XI2Input : IInputDriver2
|
||||
{
|
||||
readonly XI2MouseKeyboard mouse_keyboard = new XI2MouseKeyboard();
|
||||
readonly X11Joystick joystick = new X11Joystick();
|
||||
readonly Linux.LinuxJoystick joystick = new Linux.LinuxJoystick();
|
||||
readonly IGamePadDriver gamepad = new MappedGamePadDriver();
|
||||
|
||||
internal XI2Input()
|
||||
|
|
Loading…
Reference in a new issue