EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrowIDE", "CrowIDE\CrowIDE.csproj", "{B6D911CD-1D09-42FC-B300-9187190F2AE1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK", "..\..\src\opentk-git\src\OpenTK\OpenTK.csproj", "{A37A7E14-0000-0000-0000-000000000000}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testDrm", "testDrm\testDrm.csproj", "{4B57740A-75FB-4978-A8E8-8B1793B7474F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4B57740A-75FB-4978-A8E8-8B1793B7474F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B57740A-75FB-4978-A8E8-8B1793B7474F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4B57740A-75FB-4978-A8E8-8B1793B7474F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4B57740A-75FB-4978-A8E8-8B1793B7474F}.Release|Any CPU.Build.0 = Release|Any CPU
{74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6D911CD-1D09-42FC-B300-9187190F2AE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6D911CD-1D09-42FC-B300-9187190F2AE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6D911CD-1D09-42FC-B300-9187190F2AE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
class BasicTests : CrowWindow
{
public BasicTests ()
- : base(800, 600,"test: press <F3> to toogle test files")
+ : base(1600, 900,"test: press <F3> to toogle test files")
{
}
#endregion
#region ctor
- public CrowWindow(int _width = 800, int _height = 600, string _title="Crow",
+ public CrowWindow(int _width = 1600, int _height = 900, string _title="Crow",
int colors = 32, int depth = 24, int stencil = 0, int samples = 1,
int major=3, int minor=3)
: this(_width, _height, new OpenTK.Graphics.GraphicsMode(colors, depth, stencil, samples),
GeomSourcePath;
#region Sources
protected string _vertSource = @"
- #version 330
+ #version 300 es
precision lowp float;
uniform mat4 mvp;
}";
protected string _fragSource = @"
- #version 330
+ #version 300 es
precision lowp float;
uniform sampler2D tex;
GL.GetProgramInfoLog(pgmId, out info);
if (!string.IsNullOrEmpty (info)) {
- Debug.WriteLine ("Linkage:");
- Debug.WriteLine (info);
+ Console.WriteLine ("Linkage:");
+ Console.WriteLine (info);
}
info = null;
GL.ValidateProgram(pgmId);
GL.GetProgramInfoLog(pgmId, out info);
if (!string.IsNullOrEmpty (info)) {
- Debug.WriteLine ("Validation:");
- Debug.WriteLine (info);
+ Console.WriteLine ("Validation:");
+ Console.WriteLine (info);
}
GL.UseProgram (pgmId);
string info;
GL.GetShaderInfoLog(shader, out info);
- Debug.WriteLine(info);
+ Console.WriteLine(info);
int compileResult;
GL.GetShader(shader, ShaderParameter.CompileStatus, out compileResult);
if (compileResult != 1)
{
- Debug.WriteLine("Compile Error!");
- Debug.WriteLine(source);
+ Console.WriteLine("Compile Error!");
+ Console.WriteLine(source);
}
}
public override string ToString ()
<OutputType>Exe</OutputType>
<RootNamespace>Tests</RootNamespace>
<AssemblyName>Tests</AssemblyName>
- <StartupObject>Tests.Showcase</StartupObject>
+ <StartupObject>Tests.BasicTests</StartupObject>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ReleaseVersion>0.5</ReleaseVersion>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<DefineConstants>DEBUG;TRACE;MEASURE_TIME</DefineConstants>
+ <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
+ <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<WarningLevel>0</WarningLevel>
<ConsolePause>false</ConsolePause>
+ <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
+ <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="cairo-sharp">
<Package>gtk-sharp-3.0</Package>
</Reference>
- <Reference Include="OpenTK">
- <HintPath>$(SolutionDir)packages\OpenTK.2.0.0\lib\net20\OpenTK.dll</HintPath>
- <Package>opentk</Package>
+ <Reference Include="OpenTK, Version=2.0.6332.25999, Culture=neutral, PublicKeyToken=bad199fe84eb3df4">
+ <HintPath>..\..\..\src\opentk-git\src\OpenTK\bin\Release\OpenTK.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
--- /dev/null
+//
+// HelloWorld.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.
+
+using System;
+using Crow;
+using Cairo;
+using System.Diagnostics;
+
+namespace Tests2
+{
+ static class Test
+ {
+ const int H = 600;
+ const int W = 800;
+ [STAThread]
+ static void Main ()
+ {
+ Console.WriteLine ("Single Surface Instance");
+ Stopwatch sw = Stopwatch.StartNew ();
+ Surface surf = new ImageSurface (Format.Argb32, W, H);
+ for (int i = 0; i < 1000; i++) {
+ using (Context ctx = new Context (surf)) {
+ clearSurf (ctx);
+ ctx.Rectangle (50, 50, 50, 50);
+ ctx.SetSourceRGB (1, 0, 0);
+ ctx.Fill ();
+ }
+ }
+ sw.Stop ();
+ Console.WriteLine ("elapse: {0} ticks, {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds);
+
+ Console.WriteLine ("Multiple Surface Instances");
+ sw = Stopwatch.StartNew ();
+ for (int i = 0; i < 1000; i++) {
+ byte[] bmp = new byte[W * H * 4];
+ using (Surface s = new ImageSurface (bmp, Format.Argb32, W, H, W * 4)){
+ using (Context ctx = new Context (s)) {
+ //clearSurf (ctx);
+ ctx.Rectangle (50, 50, 50, 50);
+ ctx.SetSourceRGB (1, 0, 0);
+ ctx.Fill ();
+ }
+ }
+ }
+ sw.Stop ();
+ Console.WriteLine ("elapse: {0} ticks, {1} ms", sw.ElapsedTicks, sw.ElapsedMilliseconds);
+
+ }
+
+ static void clearSurf(Context ctx){
+ ctx.Operator = Operator.Clear;
+ ctx.SetSourceRGB (1, 1, 1);
+ ctx.Rectangle (0, 0, W, H);
+ ctx.Fill ();
+ ctx.Operator = Operator.Over;
+ }
+ }
+}
\ No newline at end of file
public Rectangle LastPaintedSlot;
/// <summary>Prevent requeuing multiple times the same widget</summary>
public bool IsQueueForRedraw = false;
- /// <summary>drawing Cache, if null, a redraw is done, cached or not</summary>
+ /// <summary>drawing Cache bitmap</summary>
public byte[] bmp;
+ /// <summary>if true, content has to be recreated</summary>
public bool IsDirty = true;
/// <summary>
/// This size is computed on each child' layout changes.
using System.ComponentModel;
using System.Xml.Serialization;
using Cairo;
-using OpenTK.Input;
using System.Diagnostics;
using System.Reflection;
using System;
using System.Xml.Serialization;
using System.ComponentModel;
-using OpenTK.Input;
namespace Crow
{
using System;
using System.Xml.Serialization;
using System.ComponentModel;
-using OpenTK.Input;
namespace Crow
{
// THE SOFTWARE.
using System;
-namespace OpenTK.Input
+namespace Crow
{
/// <summary>
/// Enumerates available buttons for a <c>GamePad</c> device.
using System;
using System.IO;
using System.Diagnostics;
-using OpenTK;
using System.Collections.Generic;
namespace Crow
--- /dev/null
+//
+// Main.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.
+using System;
+using System.Diagnostics;
+using System.IO;
+using OpenTK.Platform.Linux;
+using System.Collections.Generic;
+using OpenTK;
+using OpenTK.Platform.Egl;
+using Cairo;
+
+namespace testDrm
+{
+ // Stores platform-specific information about a display
+ class LinuxDisplay
+ {
+ public int FD;
+ public IntPtr Connector;
+ public IntPtr Crtc;
+ public IntPtr Encoder;
+
+ unsafe public ModeConnector* pConnector { get { return (ModeConnector*)Connector; } }
+ unsafe public ModeCrtc* pCrtc { get { return (ModeCrtc*)Crtc; } }
+ unsafe public ModeEncoder* pEncoder { get { return (ModeEncoder*)Encoder; } }
+ /*
+ public ModeInfo Mode
+ {
+ get
+ {
+ if (Crtc == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ unsafe
+ {
+ return pCrtc->mode;
+ }
+ }
+ }
+ */
+
+ public ModeInfo OriginalMode;
+
+ public int Id
+ {
+ get
+ {
+ if (Crtc == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ unsafe
+ {
+ return (int)pCrtc->crtc_id;
+ }
+ }
+ }
+
+ public LinuxDisplay(int fd, IntPtr c, IntPtr e, IntPtr r)
+ {
+ FD = fd;
+ Connector = c;
+ Encoder = e;
+ Crtc = r;
+ unsafe
+ {
+ OriginalMode = pCrtc->mode; // in case we change resolution later on
+ }
+ }
+ }
+ static class TestDrm
+ {
+ const string gpu_path = "/dev/dri"; // card0, card1, ...
+
+ [STAThread]
+ static void Main ()
+ {
+
+
+// using (Surface s = new ImageSurface (Format.Argb32,800,600)) {
+//
+// }
+// IntPtr gbm_device;
+// IntPtr egl_display;
+//
+// int gpu_fd = CreateDisplay(out gbm_device, out egl_display);
+ using (DrmDevice drm = new DrmDevice ()) {
+ drm.RenderingLoop ();
+ }
+ }
+
+ static int CreateDisplay(out IntPtr gbm_device, out IntPtr egl_display)
+ {
+ // Query all GPUs until we find one that has a connected display.
+ // This is necessary in multi-gpu systems, where only one GPU
+ // can output a signal.
+ // Todo: allow OpenTK to drive multiple GPUs
+ // Todo: allow OpenTK to run on an offscreen GPU
+ // Todo: allow the user to pick a GPU
+ int fd = 0;
+ gbm_device = IntPtr.Zero;
+ egl_display = IntPtr.Zero;
+
+ var files = Directory.GetFiles(gpu_path);
+ foreach (var gpu in files)
+ {
+ if (System.IO.Path.GetFileName(gpu).StartsWith("card"))
+ {
+ int test_fd = SetupDisplay(gpu, out gbm_device, out egl_display);
+ if (test_fd >= 0)
+ {
+ try
+ {
+ if (QueryDisplays(test_fd, null))
+ {
+ fd = test_fd;
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine(e.ToString());
+ }
+
+ Console.WriteLine("[KMS] GPU '{0}' is not connected, skipping.", gpu);
+ Libc.close(test_fd);
+ }
+ }
+ }
+
+ if (fd == 0)
+ {
+ Console.WriteLine("[Error] No valid GPU found, bailing out.");
+ throw new PlatformNotSupportedException();
+ }
+
+ return fd;
+ }
+ static bool QueryDisplays(int fd, List<LinuxDisplay> displays)
+ {
+ unsafe
+ {
+ bool has_displays = false;
+ if (displays != null)
+ {
+ displays.Clear();
+ }
+
+ ModeRes* resources = (ModeRes*)Drm.ModeGetResources(fd);
+ if (resources == null)
+ {
+ Console.WriteLine("[KMS] Drm.ModeGetResources failed.");
+ return false;
+ }
+ Console.WriteLine("[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)
+ {
+ bool success = false;
+ LinuxDisplay display = null;
+ try
+ {
+ if (connector->connection == ModeConnection.Connected && connector->count_modes > 0)
+ {
+ success = QueryDisplay(fd, connector, out display);
+ has_displays |= success;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("[KMS] Failed to add display. Error: {0}", e);
+ }
+
+ if (success && displays != null)
+ {
+ displays.Add(display);
+ }
+ else
+ {
+ Drm.ModeFreeConnector((IntPtr)connector);
+ connector = null;
+ }
+ }
+ }
+
+ return has_displays;
+ }
+ }
+ unsafe static bool QueryDisplay(int fd, ModeConnector* c, out LinuxDisplay display)
+ {
+ display = null;
+
+ // Find corresponding encoder
+ ModeEncoder* encoder = GetEncoder(fd, c);
+ if (encoder == null)
+ return false;
+
+ ModeCrtc* crtc = GetCrtc(fd, encoder);
+ if (crtc == null)
+ return false;
+
+ display = new LinuxDisplay(fd, (IntPtr)c, (IntPtr)encoder, (IntPtr)crtc);
+ return true;
+ }
+ unsafe static ModeEncoder* GetEncoder(int fd, ModeConnector* c)
+ {
+ 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)
+ continue;
+
+ if (e->encoder_id == c->encoder_id)
+ encoder = e;
+ else
+ Drm.ModeFreeEncoder((IntPtr)e);
+ }
+
+ if (encoder != null)
+ Console.WriteLine("[KMS] Encoder {0} found for connector {1}", encoder->encoder_id, c->connector_id);
+ else
+ Console.WriteLine("[KMS] Failed to find encoder for connector {0}", c->connector_id);
+
+ return encoder;
+ }
+
+ unsafe static ModeCrtc* GetCrtc(int fd, ModeEncoder* encoder)
+ {
+ ModeCrtc* crtc = (ModeCrtc*)Drm.ModeGetCrtc(fd, encoder->crtc_id);
+ if (crtc != null)
+ {
+ Console.WriteLine("[KMS] CRTC {0} found for encoder {1}",
+ encoder->crtc_id, encoder->encoder_id);
+ }
+ else
+ {
+ Console.WriteLine("[KMS] Failed to find crtc {0} for encoder {1}",
+ encoder->crtc_id, encoder->encoder_id);
+ }
+ return crtc;
+ }
+
+ unsafe static void GetModes(LinuxDisplay display, DisplayResolution[] modes, out DisplayResolution current)
+ {
+ int mode_count = display.pConnector->count_modes;
+ Console.WriteLine("[KMS] Display supports {0} mode(s)", mode_count);
+ for (int i = 0; i < mode_count; i++)
+ {
+ ModeInfo* mode = display.pConnector->modes + i;
+ if (mode != null)
+ {
+ Console.WriteLine("Mode {0}: {1}x{2} @{3}", i,
+ mode->hdisplay, mode->vdisplay, mode->vrefresh);
+ DisplayResolution res = GetDisplayResolution(mode);
+ modes[i] = res;
+ }
+ }
+
+ if (display.pCrtc->mode_valid != 0)
+ {
+ ModeInfo cmode = display.pCrtc->mode;
+ current = GetDisplayResolution(&cmode);
+ }
+ else
+ {
+ current = GetDisplayResolution(display.pConnector->modes);
+ }
+ Console.WriteLine("Current mode: {0}", current.ToString());
+ }
+ unsafe static DisplayResolution GetDisplayResolution(ModeInfo* mode)
+ {
+ return new DisplayResolution(
+ 0, 0,
+ mode->hdisplay, mode->vdisplay,
+ 32, // This is actually part of the framebuffer, not the DisplayResolution
+ mode->vrefresh);
+ }
+
+ unsafe static ModeInfo* GetModeInfo(LinuxDisplay display, DisplayResolution resolution)
+ {
+ for (int i = 0; i < display.pConnector->count_modes; i++)
+ {
+ ModeInfo* mode = display.pConnector->modes + i;
+ if (mode != null &&
+ mode->hdisplay == resolution.Width &&
+ mode->vdisplay == resolution.Height)
+ {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ static int SetupDisplay(string gpu, out IntPtr gbm_device, out IntPtr egl_display)
+ {
+ Console.WriteLine("[KMS] Attempting to use gpu '{0}'.", gpu);
+
+ gbm_device = IntPtr.Zero;
+ egl_display = IntPtr.Zero;
+
+ int fd = Libc.open(gpu, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
+ if (fd < 0)
+ {
+ Console.WriteLine("[KMS] Failed to open gpu");
+ return fd;
+ }
+ Console.WriteLine("[KMS] GPU '{0}' opened as fd:{1}", gpu, fd);
+
+ gbm_device = Gbm.CreateDevice(fd);
+ if (gbm_device == IntPtr.Zero)
+ {
+ throw new NotSupportedException("[KMS] Failed to create GBM device");
+ }
+ Console.WriteLine("[KMS] GBM {0:x} created successfully; ", gbm_device);
+
+ egl_display = Egl.GetDisplay(gbm_device);
+ if (egl_display == IntPtr.Zero)
+ {
+ throw new NotSupportedException("[KMS] Failed to create EGL display");
+ }
+ Console.WriteLine("[KMS] EGL display {0:x} created successfully", egl_display);
+
+ int major, minor;
+ if (!Egl.Initialize(egl_display, out major, out minor))
+ {
+ ErrorCode error = Egl.GetError();
+ throw new NotSupportedException("[KMS] Failed to initialize EGL display. Error code: " + error);
+ }
+ Console.WriteLine("[KMS] EGL {0}.{1} initialized successfully on display {2:x}", major, minor, egl_display);
+
+ return fd;
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Antialias.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum Antialias
+ {
+ Default,
+ None,
+ Gray,
+ Subpixel,
+ }
+}
--- /dev/null
+//
+// Cairo.cs - a simplistic binding of the Cairo API to C#.
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// John Luke (john.luke@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005 John Luke
+// Copyright (C) 2006 Alp Toker
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo
+{
+ public static class CairoAPI {
+ static public int Version {
+ get {
+ return Cairo.NativeMethods.cairo_version ();
+ }
+ }
+
+ static public string VersionString {
+ get {
+ IntPtr x = Cairo.NativeMethods.cairo_version_string ();
+ return Marshal.PtrToStringAnsi (x);
+ }
+ }
+ }
+}
--- /dev/null
+//
+// CairoDebug.cs
+//
+// Author:
+// Michael Hutchinson (mhutch@xamarin.com)
+//
+// Copyright (C) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ static class CairoDebug
+ {
+ static System.Collections.Generic.Dictionary<IntPtr,string> traces;
+
+ public static readonly bool Enabled;
+
+ static CairoDebug ()
+ {
+ var dbg = Environment.GetEnvironmentVariable ("MONO_CAIRO_DEBUG_DISPOSE");
+ if (dbg == null)
+ return;
+ Enabled = true;
+ traces = new System.Collections.Generic.Dictionary<IntPtr,string> ();
+ }
+
+ public static void OnAllocated (IntPtr obj)
+ {
+ if (!Enabled)
+ throw new InvalidOperationException ();
+
+ traces[obj] = Environment.StackTrace;
+ }
+
+ public static void OnDisposed<T> (IntPtr obj, bool disposing)
+ {
+ if (disposing && !Enabled)
+ throw new InvalidOperationException ();
+
+ if (Environment.HasShutdownStarted)
+ return;
+
+ if (!disposing) {
+ Console.Error.WriteLine ("{0} is leaking, programmer is missing a call to Dispose", typeof(T).FullName);
+ if (Enabled) {
+ string val;
+ if (traces.TryGetValue (obj, out val)) {
+ Console.Error.WriteLine ("Allocated from:");
+ Console.Error.WriteLine (val);
+ }
+ } else {
+ Console.Error.WriteLine ("Set MONO_CAIRO_DEBUG_DISPOSE to track allocation traces");
+ }
+ }
+
+ if (Enabled)
+ traces.Remove (obj);
+ }
+ }
+
+}
--- /dev/null
+//
+// Mono.Cairo.Context.cs
+//
+// Author:
+// Duncan Mak (duncan@ximian.com)
+// Miguel de Icaza (miguel@novell.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell Inc, 2003.
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+namespace Cairo {
+
+ public struct Color
+ {
+ public Color(double r, double g, double b) : this (r, g, b, 1.0)
+ {
+ }
+
+ public Color(double r, double g, double b, double a)
+ {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = a;
+ }
+
+ double r, g, b, a;
+
+ public double R {
+ get { return r; }
+ set { r = value; }
+ }
+
+ public double G {
+ get { return g; }
+ set { g = value; }
+ }
+
+ public double B {
+ get { return b; }
+ set { b = value; }
+ }
+
+ public double A {
+ get { return a; }
+ set { a = value; }
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Content.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ //[Flags]
+ [Serializable]
+ public enum Content
+ {
+ Color = 0x1000,
+ Alpha = 0x2000,
+ ColorAlpha = 0x3000,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Context.cs
+//
+// Author:
+// Duncan Mak (duncan@ximian.com)
+// Miguel de Icaza (miguel@novell.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell Inc, 2003.
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using Cairo;
+
+namespace Cairo {
+
+ [Obsolete ("Renamed Cairo.Context per suggestion from cairo binding guidelines.")]
+ public class Graphics : Context {
+ public Graphics (IntPtr state) : base (state) {}
+ public Graphics (Surface surface) : base (surface) {}
+ }
+
+ public class Context : IDisposable
+ {
+ IntPtr handle = IntPtr.Zero;
+
+ static int native_glyph_size, c_compiler_long_size;
+
+ static Context ()
+ {
+ //
+ // This is used to determine what kind of structure
+ // we should use to marshal Glyphs, as the public
+ // definition in Cairo uses `long', which can be
+ // 32 bits or 64 bits depending on the platform.
+ //
+ // We assume that sizeof(long) == sizeof(void*)
+ // except in the case of Win64 where sizeof(long)
+ // is 32 bits
+ //
+ int ptr_size = Marshal.SizeOf (typeof (IntPtr));
+
+ PlatformID platform = Environment.OSVersion.Platform;
+ if (platform == PlatformID.Win32NT ||
+ platform == PlatformID.Win32S ||
+ platform == PlatformID.Win32Windows ||
+ platform == PlatformID.WinCE ||
+ ptr_size == 4){
+ c_compiler_long_size = 4;
+ native_glyph_size = Marshal.SizeOf (typeof (NativeGlyph_4byte_longs));
+ } else {
+ c_compiler_long_size = 8;
+ native_glyph_size = Marshal.SizeOf (typeof (Glyph));
+ }
+ }
+
+ public Context (Surface surface) : this (NativeMethods.cairo_create (surface.Handle), true)
+ {
+ }
+
+
+ public Context (IntPtr handle, bool owner)
+ {
+ this.handle = handle;
+ if (!owner)
+ NativeMethods.cairo_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ [Obsolete]
+ public Context (IntPtr state) : this (state, true)
+ {
+ }
+
+ ~Context ()
+ {
+ Dispose (false);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Context> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_destroy (handle);
+ handle = IntPtr.Zero;
+
+ }
+
+ public void Save ()
+ {
+ NativeMethods.cairo_save (handle);
+ }
+
+ public void Restore ()
+ {
+ NativeMethods.cairo_restore (handle);
+ }
+
+ public Antialias Antialias {
+ get { return NativeMethods.cairo_get_antialias (handle); }
+ set { NativeMethods.cairo_set_antialias (handle, value); }
+ }
+
+ public Cairo.Status Status {
+ get {
+ return NativeMethods.cairo_status (handle);
+ }
+ }
+
+ public IntPtr Handle {
+ get {
+ return handle;
+ }
+ }
+
+ public Operator Operator {
+ set {
+ NativeMethods.cairo_set_operator (handle, value);
+ }
+
+ get {
+ return NativeMethods.cairo_get_operator (handle);
+ }
+ }
+
+ [Obsolete ("Use SetSourceColor method")]
+ public Color Color {
+ set {
+ SetSourceColor (value);
+ }
+ }
+
+ [Obsolete ("Use SetSourceRGBA method")]
+ public Cairo.Color ColorRgb {
+ set {
+ Color = new Color (value.R, value.G, value.B);
+ }
+ }
+
+ public double Tolerance {
+ get {
+ return NativeMethods.cairo_get_tolerance (handle);
+ }
+
+ set {
+ NativeMethods.cairo_set_tolerance (handle, value);
+ }
+ }
+
+ public Cairo.FillRule FillRule {
+ set {
+ NativeMethods.cairo_set_fill_rule (handle, value);
+ }
+
+ get {
+ return NativeMethods.cairo_get_fill_rule (handle);
+ }
+ }
+
+ public double LineWidth {
+ set {
+ NativeMethods.cairo_set_line_width (handle, value);
+ }
+
+ get {
+ return NativeMethods.cairo_get_line_width (handle);
+ }
+ }
+
+ public Cairo.LineCap LineCap {
+ set {
+ NativeMethods.cairo_set_line_cap (handle, value);
+ }
+
+ get {
+ return NativeMethods.cairo_get_line_cap (handle);
+ }
+ }
+
+ public Cairo.LineJoin LineJoin {
+ set {
+ NativeMethods.cairo_set_line_join (handle, value);
+ }
+
+ get {
+ return NativeMethods.cairo_get_line_join (handle);
+ }
+ }
+
+ public void SetDash (double [] dashes, double offset)
+ {
+ NativeMethods.cairo_set_dash (handle, dashes, dashes.Length, offset);
+ }
+
+ [Obsolete("Use GetSource/SetSource")]
+ public Pattern Pattern {
+ set {
+ SetSource (value);
+ }
+ get {
+ return GetSource ();
+ }
+ }
+
+ //This is obsolete because it wasn't obvious it needed to be disposed
+ [Obsolete("Use GetSource/SetSource")]
+ public Pattern Source {
+ set {
+ SetSource (value);
+ }
+ get {
+ return GetSource ();
+ }
+ }
+
+ public void SetSource (Pattern source)
+ {
+ NativeMethods.cairo_set_source (handle, source.Handle);
+ }
+
+ public Pattern GetSource ()
+ {
+ var ptr = NativeMethods.cairo_get_source (handle);
+ return Cairo.Pattern.Lookup (ptr, false);
+ }
+
+ public double MiterLimit {
+ set {
+ NativeMethods.cairo_set_miter_limit (handle, value);
+ }
+
+ get {
+ return NativeMethods.cairo_get_miter_limit (handle);
+ }
+ }
+
+ public PointD CurrentPoint {
+ get {
+ double x, y;
+ NativeMethods.cairo_get_current_point (handle, out x, out y);
+ return new PointD (x, y);
+ }
+ }
+
+ public bool HasCurrentPoint {
+ get {
+ return NativeMethods.cairo_has_current_point (handle);
+ }
+ }
+
+ [Obsolete ("Use GetTarget/SetTarget")]
+ public Cairo.Surface Target {
+ set {
+ if (handle != IntPtr.Zero)
+ NativeMethods.cairo_destroy (handle);
+
+ handle = NativeMethods.cairo_create (value.Handle);
+ }
+
+ get {
+ return GetTarget ();
+ }
+ }
+
+ public Surface GetTarget ()
+ {
+ return Surface.Lookup (NativeMethods.cairo_get_target (handle), false);
+ }
+
+ public void SetTarget (Surface target)
+ {
+ if (handle != IntPtr.Zero)
+ NativeMethods.cairo_destroy (handle);
+ handle = NativeMethods.cairo_create (target.Handle);
+ }
+
+ [Obsolete("Use GetScaledFont/SetScaledFont")]
+ public ScaledFont ScaledFont {
+ set {
+ SetScaledFont (value);
+ }
+
+ get {
+ return GetScaledFont ();
+ }
+ }
+
+ public ScaledFont GetScaledFont ()
+ {
+ return new ScaledFont (NativeMethods.cairo_get_scaled_font (handle), false);
+ }
+
+ public void SetScaledFont (ScaledFont font)
+ {
+ NativeMethods.cairo_set_scaled_font (handle, font.Handle);
+ }
+
+ public uint ReferenceCount {
+ get { return NativeMethods.cairo_get_reference_count (handle); }
+ }
+
+ public void SetSourceColor (Color color)
+ {
+ NativeMethods.cairo_set_source_rgba (handle, color.R, color.G, color.B, color.A);
+ }
+
+ public void SetSourceRGB (double r, double g, double b)
+ {
+ NativeMethods.cairo_set_source_rgb (handle, r, g, b);
+ }
+
+ public void SetSourceRGBA (double r, double g, double b, double a)
+ {
+ NativeMethods.cairo_set_source_rgba (handle, r, g, b, a);
+ }
+
+ //[Obsolete ("Use SetSource method (with double parameters)")]
+ public void SetSourceSurface (Surface source, int x, int y)
+ {
+ NativeMethods.cairo_set_source_surface (handle, source.Handle, x, y);
+ }
+
+ public void SetSource (Surface source, double x, double y)
+ {
+ NativeMethods.cairo_set_source_surface (handle, source.Handle, x, y);
+ }
+
+ public void SetSource (Surface source)
+ {
+ NativeMethods.cairo_set_source_surface (handle, source.Handle, 0, 0);
+ }
+
+#region Path methods
+
+ public void NewPath ()
+ {
+ NativeMethods.cairo_new_path (handle);
+ }
+
+ public void NewSubPath ()
+ {
+ NativeMethods.cairo_new_sub_path (handle);
+ }
+
+ public void MoveTo (PointD p)
+ {
+ MoveTo (p.X, p.Y);
+ }
+
+ public void MoveTo (double x, double y)
+ {
+ NativeMethods.cairo_move_to (handle, x, y);
+ }
+
+ public void LineTo (PointD p)
+ {
+ LineTo (p.X, p.Y);
+ }
+
+ public void LineTo (double x, double y)
+ {
+ NativeMethods.cairo_line_to (handle, x, y);
+ }
+
+ public void CurveTo (PointD p1, PointD p2, PointD p3)
+ {
+ CurveTo (p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y);
+ }
+
+ public void CurveTo (double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ NativeMethods.cairo_curve_to (handle, x1, y1, x2, y2, x3, y3);
+ }
+
+ public void RelMoveTo (Distance d)
+ {
+ RelMoveTo (d.Dx, d.Dy);
+ }
+
+ public void RelMoveTo (double dx, double dy)
+ {
+ NativeMethods.cairo_rel_move_to (handle, dx, dy);
+ }
+
+ public void RelLineTo (Distance d)
+ {
+ RelLineTo (d.Dx, d.Dy);
+ }
+
+ public void RelLineTo (double dx, double dy)
+ {
+ NativeMethods.cairo_rel_line_to (handle, dx, dy);
+ }
+
+ public void RelCurveTo (Distance d1, Distance d2, Distance d3)
+ {
+ RelCurveTo (d1.Dx, d1.Dy, d2.Dx, d2.Dy, d3.Dx, d3.Dy);
+ }
+
+ public void RelCurveTo (double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
+ {
+ NativeMethods.cairo_rel_curve_to (handle, dx1, dy1, dx2, dy2, dx3, dy3);
+ }
+
+ public void Arc (double xc, double yc, double radius, double angle1, double angle2)
+ {
+ NativeMethods.cairo_arc (handle, xc, yc, radius, angle1, angle2);
+ }
+
+ public void ArcNegative (double xc, double yc, double radius, double angle1, double angle2)
+ {
+ NativeMethods.cairo_arc_negative (handle, xc, yc, radius, angle1, angle2);
+ }
+
+ public void Rectangle (Rectangle rectangle)
+ {
+ Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
+ }
+
+ public void Rectangle (PointD p, double width, double height)
+ {
+ Rectangle (p.X, p.Y, width, height);
+ }
+
+ public void Rectangle (double x, double y, double width, double height)
+ {
+ NativeMethods.cairo_rectangle (handle, x, y, width, height);
+ }
+
+ public void ClosePath ()
+ {
+ NativeMethods.cairo_close_path (handle);
+ }
+
+ public Path CopyPath ()
+ {
+ return new Path (NativeMethods.cairo_copy_path (handle));
+ }
+
+ public Path CopyPathFlat ()
+ {
+ return new Path (NativeMethods.cairo_copy_path_flat (handle));
+ }
+
+ public void AppendPath (Path path)
+ {
+ NativeMethods.cairo_append_path (handle, path.Handle);
+ }
+
+#endregion
+
+#region Painting Methods
+ public void Paint ()
+ {
+ NativeMethods.cairo_paint (handle);
+ }
+
+ public void PaintWithAlpha (double alpha)
+ {
+ NativeMethods.cairo_paint_with_alpha (handle, alpha);
+ }
+
+ public void Mask (Pattern pattern)
+ {
+ NativeMethods.cairo_mask (handle, pattern.Handle);
+ }
+
+ public void MaskSurface (Surface surface, double surface_x, double surface_y)
+ {
+ NativeMethods.cairo_mask_surface (handle, surface.Handle, surface_x, surface_y);
+ }
+
+ public void Stroke ()
+ {
+ NativeMethods.cairo_stroke (handle);
+ }
+
+ public void StrokePreserve ()
+ {
+ NativeMethods.cairo_stroke_preserve (handle);
+ }
+
+ public Rectangle StrokeExtents ()
+ {
+ double x1, y1, x2, y2;
+ NativeMethods.cairo_stroke_extents (handle, out x1, out y1, out x2, out y2);
+ return new Rectangle (x1, y1, x2 - x1, y2 - y1);
+ }
+
+ public void Fill ()
+ {
+ NativeMethods.cairo_fill (handle);
+ }
+
+ public Rectangle FillExtents ()
+ {
+ double x1, y1, x2, y2;
+ NativeMethods.cairo_fill_extents (handle, out x1, out y1, out x2, out y2);
+ return new Rectangle (x1, y1, x2 - x1, y2 - y1);
+ }
+
+ public void FillPreserve ()
+ {
+ NativeMethods.cairo_fill_preserve (handle);
+ }
+
+#endregion
+
+ public void Clip ()
+ {
+ NativeMethods.cairo_clip (handle);
+ }
+
+ public void ClipPreserve ()
+ {
+ NativeMethods.cairo_clip_preserve (handle);
+ }
+
+ public void ResetClip ()
+ {
+ NativeMethods.cairo_reset_clip (handle);
+ }
+
+ public bool InClip (double x, double y)
+ {
+ return NativeMethods.cairo_in_clip (handle, x, y);
+ }
+
+ public bool InStroke (double x, double y)
+ {
+ return NativeMethods.cairo_in_stroke (handle, x, y);
+ }
+
+ public bool InFill (double x, double y)
+ {
+ return NativeMethods.cairo_in_fill (handle, x, y);
+ }
+
+ public Pattern PopGroup ()
+ {
+ return Pattern.Lookup (NativeMethods.cairo_pop_group (handle), true);
+ }
+
+ public void PopGroupToSource ()
+ {
+ NativeMethods.cairo_pop_group_to_source (handle);
+ }
+
+ public void PushGroup ()
+ {
+ NativeMethods.cairo_push_group (handle);
+ }
+
+ public void PushGroup (Content content)
+ {
+ NativeMethods.cairo_push_group_with_content (handle, content);
+ }
+
+ [Obsolete ("Use GetGroupTarget()")]
+ public Surface GroupTarget {
+ get {
+ return GetGroupTarget ();
+ }
+ }
+
+ public Surface GetGroupTarget ()
+ {
+ IntPtr surface = NativeMethods.cairo_get_group_target (handle);
+ return Surface.Lookup (surface, false);
+ }
+
+ public void Rotate (double angle)
+ {
+ NativeMethods.cairo_rotate (handle, angle);
+ }
+
+ public void Scale (double sx, double sy)
+ {
+ NativeMethods.cairo_scale (handle, sx, sy);
+ }
+
+ public void Translate (double tx, double ty)
+ {
+ NativeMethods.cairo_translate (handle, tx, ty);
+ }
+
+ public void Transform (Matrix m)
+ {
+ NativeMethods.cairo_transform (handle, m);
+ }
+
+ [Obsolete("Use UserToDevice instead")]
+ public void TransformPoint (ref double x, ref double y)
+ {
+ NativeMethods.cairo_user_to_device (handle, ref x, ref y);
+ }
+
+ [Obsolete("Use UserToDeviceDistance instead")]
+ public void TransformDistance (ref double dx, ref double dy)
+ {
+ NativeMethods.cairo_user_to_device_distance (handle, ref dx, ref dy);
+ }
+
+ [Obsolete("Use InverseTransformPoint instead")]
+ public void InverseTransformPoint (ref double x, ref double y)
+ {
+ NativeMethods.cairo_device_to_user (handle, ref x, ref y);
+ }
+
+ [Obsolete("Use DeviceToUserDistance instead")]
+ public void InverseTransformDistance (ref double dx, ref double dy)
+ {
+ NativeMethods.cairo_device_to_user_distance (handle, ref dx, ref dy);
+ }
+
+ public void UserToDevice (ref double x, ref double y)
+ {
+ NativeMethods.cairo_user_to_device (handle, ref x, ref y);
+ }
+
+ public void UserToDeviceDistance (ref double dx, ref double dy)
+ {
+ NativeMethods.cairo_user_to_device_distance (handle, ref dx, ref dy);
+ }
+
+ public void DeviceToUser (ref double x, ref double y)
+ {
+ NativeMethods.cairo_device_to_user (handle, ref x, ref y);
+ }
+
+ public void DeviceToUserDistance (ref double dx, ref double dy)
+ {
+ NativeMethods.cairo_device_to_user_distance (handle, ref dx, ref dy);
+ }
+
+ public Matrix Matrix {
+ set {
+ NativeMethods.cairo_set_matrix (handle, value);
+ }
+
+ get {
+ Matrix m = new Matrix();
+ NativeMethods.cairo_get_matrix (handle, m);
+ return m;
+ }
+ }
+
+ public void SetFontSize (double scale)
+ {
+ NativeMethods.cairo_set_font_size (handle, scale);
+ }
+
+ public void IdentityMatrix ()
+ {
+ NativeMethods.cairo_identity_matrix (handle);
+ }
+
+ [Obsolete ("Use SetFontSize() instead.")]
+ public void FontSetSize (double scale)
+ {
+ SetFontSize (scale);
+ }
+
+ [Obsolete ("Use SetFontSize() instead.")]
+ public double FontSize {
+ set { SetFontSize (value); }
+ }
+
+ public Matrix FontMatrix {
+ get {
+ Matrix m;
+ NativeMethods.cairo_get_font_matrix (handle, out m);
+ return m;
+ }
+ set { NativeMethods.cairo_set_font_matrix (handle, value); }
+ }
+
+ public FontOptions FontOptions {
+ get {
+ FontOptions options = new FontOptions ();
+ NativeMethods.cairo_get_font_options (handle, options.Handle);
+ return options;
+ }
+ set { NativeMethods.cairo_set_font_options (handle, value.Handle); }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct NativeGlyph_4byte_longs {
+ public int index;
+ public double x;
+ public double y;
+
+ public NativeGlyph_4byte_longs (Glyph source)
+ {
+ index = (int) source.index;
+ x = source.x;
+ y = source.y;
+ }
+ }
+
+ static internal IntPtr FromGlyphToUnManagedMemory(Glyph [] glyphs)
+ {
+ IntPtr dest = Marshal.AllocHGlobal (native_glyph_size * glyphs.Length);
+ long pos = dest.ToInt64();
+
+ if (c_compiler_long_size == 8){
+ foreach (Glyph g in glyphs){
+ Marshal.StructureToPtr (g, (IntPtr)pos, false);
+ pos += native_glyph_size;
+ }
+ } else {
+ foreach (Glyph g in glyphs){
+ NativeGlyph_4byte_longs n = new NativeGlyph_4byte_longs (g);
+
+ Marshal.StructureToPtr (n, (IntPtr)pos, false);
+ pos += native_glyph_size;
+ }
+ }
+
+ return dest;
+ }
+
+ public void ShowGlyphs (Glyph[] glyphs)
+ {
+ IntPtr ptr;
+
+ ptr = FromGlyphToUnManagedMemory (glyphs);
+
+ NativeMethods.cairo_show_glyphs (handle, ptr, glyphs.Length);
+
+ Marshal.FreeHGlobal (ptr);
+ }
+
+ [Obsolete("The matrix argument was never used, use ShowGlyphs(Glyphs []) instead")]
+ public void ShowGlyphs (Matrix matrix, Glyph[] glyphs)
+ {
+ ShowGlyphs (glyphs);
+ }
+
+ [Obsolete("The matrix argument was never used, use GlyphPath(Glyphs []) instead")]
+ public void GlyphPath (Matrix matrix, Glyph[] glyphs)
+ {
+ GlyphPath (glyphs);
+ }
+
+ public void GlyphPath (Glyph[] glyphs)
+ {
+ IntPtr ptr;
+
+ ptr = FromGlyphToUnManagedMemory (glyphs);
+
+ NativeMethods.cairo_glyph_path (handle, ptr, glyphs.Length);
+
+ Marshal.FreeHGlobal (ptr);
+
+ }
+
+ public FontExtents FontExtents {
+ get {
+ FontExtents f_extents;
+ NativeMethods.cairo_font_extents (handle, out f_extents);
+ return f_extents;
+ }
+ }
+
+ public void CopyPage ()
+ {
+ NativeMethods.cairo_copy_page (handle);
+ }
+
+ [Obsolete ("Use SelectFontFace() instead.")]
+ public void FontFace (string family, FontSlant slant, FontWeight weight)
+ {
+ SelectFontFace (family, slant, weight);
+ }
+
+ [Obsolete("Use GetFontFace/SetFontFace")]
+ public FontFace ContextFontFace {
+ get {
+ return GetContextFontFace ();
+ }
+ set {
+ SetContextFontFace (value);
+ }
+ }
+
+ public FontFace GetContextFontFace ()
+ {
+ return Cairo.FontFace.Lookup (NativeMethods.cairo_get_font_face (handle), false);
+ }
+
+ public void SetContextFontFace (FontFace value)
+ {
+ NativeMethods.cairo_set_font_face (handle, value == null ? IntPtr.Zero : value.Handle);
+ }
+
+ public void SelectFontFace (string family, FontSlant slant, FontWeight weight)
+ {
+ NativeMethods.cairo_select_font_face (handle, family, slant, weight);
+ }
+
+ public void ShowPage ()
+ {
+ NativeMethods.cairo_show_page (handle);
+ }
+
+ private static byte[] TerminateUtf8(byte[] utf8)
+ {
+ if (utf8.Length > 0 && utf8[utf8.Length - 1] == 0)
+ return utf8;
+ var termedArray = new byte[utf8.Length + 1];
+ Array.Copy(utf8, termedArray, utf8.Length);
+ termedArray[utf8.Length] = 0;
+ return termedArray;
+ }
+
+ private static byte[] TerminateUtf8(string s)
+ {
+ // compute the byte count including the trailing \0
+ var byteCount = Encoding.UTF8.GetMaxByteCount(s.Length + 1);
+ var bytes = new byte[byteCount];
+ Encoding.UTF8.GetBytes(s, 0, s.Length, bytes, 0);
+ return bytes;
+ }
+
+ public void ShowText(string str)
+ {
+ NativeMethods.cairo_show_text (handle, TerminateUtf8(str));
+ }
+
+ public void ShowText(byte[] utf8)
+ {
+ NativeMethods.cairo_show_text (handle, TerminateUtf8(utf8));
+ }
+
+ public void TextPath(string str)
+ {
+ NativeMethods.cairo_text_path (handle, TerminateUtf8(str));
+ }
+
+ public void TextPath(byte[] utf8)
+ {
+ NativeMethods.cairo_text_path (handle, TerminateUtf8(utf8));
+ }
+
+ public TextExtents TextExtents(string s)
+ {
+ TextExtents extents;
+ NativeMethods.cairo_text_extents (handle, TerminateUtf8(s), out extents);
+ return extents;
+ }
+
+ public TextExtents TextExtents(byte[] utf8)
+ {
+ TextExtents extents;
+ NativeMethods.cairo_text_extents (handle, TerminateUtf8(utf8), out extents);
+ return extents;
+ }
+
+ public TextExtents GlyphExtents (Glyph[] glyphs)
+ {
+ IntPtr ptr = FromGlyphToUnManagedMemory (glyphs);
+
+ TextExtents extents;
+
+ NativeMethods.cairo_glyph_extents (handle, ptr, glyphs.Length, out extents);
+
+ Marshal.FreeHGlobal (ptr);
+
+ return extents;
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Device.cs
+//
+// Authors:
+// JP Bruyère (jp_bruyere@hotmail.com)
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2016 JP Bruyère
+//
+// 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.
+//
+using System;
+
+namespace Cairo
+{
+ public class Device : IDisposable
+ {
+ IntPtr handle = IntPtr.Zero;
+
+ protected Device()
+ {
+ }
+
+ protected Device (IntPtr ptr) : this (ptr, true)
+ {
+ }
+
+ protected Device (IntPtr handle, bool owner)
+ {
+ this.handle = handle;
+ if (!owner)
+ NativeMethods.cairo_device_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ ~Device ()
+ {
+ Dispose (false);
+ }
+
+ public IntPtr Handle {
+ get {
+ return handle;
+ }
+ }
+ public string Status {
+ get {
+ return System.Runtime.InteropServices.Marshal.PtrToStringAuto(NativeMethods.cairo_status_to_string (NativeMethods.cairo_device_status (handle)));
+ }
+ }
+ public void SetThreadAware (bool value){
+ NativeMethods.cairo_gl_device_set_thread_aware (handle, value ? 1 : 0);
+ }
+ public Status Acquire()
+ {
+ return NativeMethods.cairo_device_acquire (handle);
+ }
+ public void Release()
+ {
+ NativeMethods.cairo_device_release (handle);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Device> (handle, disposing);
+
+ if (!disposing || handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_device_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.DirectFBSurface.cs
+//
+// Authors:
+// Alp Toker
+//
+// (C) Alp Toker, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+ public class DirectFBSurface : Surface
+ {
+ internal DirectFBSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public DirectFBSurface (IntPtr dfb, IntPtr dfb_surface)
+ : base (NativeMethods.cairo_directfb_surface_create (dfb, dfb_surface), true)
+ {
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Context.cs
+//
+// Author:
+// Duncan Mak (duncan@ximian.com)
+// Miguel de Icaza (miguel@novell.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell Inc, 2003.
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+namespace Cairo {
+
+ public struct Distance
+ {
+ public Distance (double dx, double dy)
+ {
+ this.dx = dx;
+ this.dy = dy;
+ }
+
+ double dx, dy;
+ public double Dx {
+ get { return dx; }
+ set { dx = value; }
+ }
+
+ public double Dy {
+ get { return dy; }
+ set { dy = value; }
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Device.cs
+//
+// Authors:
+// JP Bruyère (jp_bruyere@hotmail.com)
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2016 JP Bruyère
+//
+// 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.
+//
+using System;
+
+namespace Cairo
+{
+ public class EGLDevice : Device
+ {
+ public EGLDevice (IntPtr dpy, IntPtr gl_ctx) : base (NativeMethods.cairo_egl_device_create (dpy, gl_ctx), true)
+ {
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Extend.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// John Luke (john.luke@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005 John Luke
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum Extend
+ {
+ None,
+ Repeat,
+ Reflect,
+ Pad,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.FillRule.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum FillRule
+ {
+ Winding,
+ EvenOdd
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Filter.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum Filter
+ {
+ Fast,
+ Good,
+ Best,
+ Nearest,
+ Bilinear,
+ Gaussian,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.FontExtents.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+//
+// This is a simplistic binding of the Cairo API to C#. All functions
+// in cairo.h are transcribed into their C# equivelants
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo
+{
+ [StructLayout (LayoutKind.Sequential)]
+ public struct FontExtents
+ {
+ double ascent;
+ double descent;
+ double height;
+ double maxXAdvance;
+ double maxYAdvance;
+
+ public double Ascent {
+ get { return ascent; }
+ set { ascent = value; }
+ }
+
+ public double Descent {
+ get { return descent; }
+ set { descent = value; }
+ }
+
+ public double Height {
+ get { return height; }
+ set { height = value; }
+ }
+
+ public double MaxXAdvance {
+ get { return maxXAdvance; }
+ set { maxXAdvance = value; }
+ }
+
+ public double MaxYAdvance {
+ get { return maxYAdvance; }
+ set { maxYAdvance = value; }
+ }
+
+ public FontExtents (double ascent, double descent, double height, double maxXAdvance, double maxYAdvance)
+ {
+ this.ascent = ascent;
+ this.descent = descent;
+ this.height = height;
+ this.maxXAdvance = maxXAdvance;
+ this.maxYAdvance = maxYAdvance;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj is FontExtents)
+ return this == (FontExtents) obj;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) Ascent ^ (int) Descent ^ (int) Height ^ (int) MaxXAdvance ^ (int) MaxYAdvance;
+ }
+
+ public static bool operator == (FontExtents extents, FontExtents other)
+ {
+ return extents.Ascent == other.Ascent && extents.Descent == other.Descent && extents.Height == other.Height && extents.MaxXAdvance == other.MaxXAdvance && extents.MaxYAdvance == other.MaxYAdvance;
+ }
+
+ public static bool operator != (FontExtents extents, FontExtents other)
+ {
+ return !(extents == other);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.FontFace.cs
+//
+// Author:
+// Alp Toker (alp@atoker.com)
+// Miguel de Icaza (miguel@novell.com)
+//
+// (C) Ximian Inc, 2003.
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright (C) 2004, 2007 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+using System;
+
+namespace Cairo
+{
+ public class FontFace : IDisposable
+ {
+ IntPtr handle;
+
+ internal static FontFace Lookup (IntPtr handle, bool owner)
+ {
+ if (handle == IntPtr.Zero)
+ return null;
+ return new FontFace (handle, owner);
+ }
+
+ ~FontFace ()
+ {
+ Dispose (false);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<FontFace> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_font_face_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+
+ [Obsolete]
+ public FontFace (IntPtr handle) : this (handle, true)
+ {
+ }
+
+ public FontFace (IntPtr handle, bool owned)
+ {
+ this.handle = handle;
+ if (!owned)
+ NativeMethods.cairo_font_face_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ public IntPtr Handle {
+ get {
+ return handle;
+ }
+ }
+
+ public Status Status {
+ get {
+ return NativeMethods.cairo_font_face_status (handle);
+ }
+ }
+
+ public FontType FontType {
+ get {
+ return NativeMethods.cairo_font_face_get_type (handle);
+ }
+ }
+
+ public uint ReferenceCount {
+ get { return NativeMethods.cairo_font_face_get_reference_count (handle); }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.FontOptions.cs
+//
+// Author:
+// John Luke (john.luke@gmail.com)
+//
+// (C) John Luke 2005.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ public class FontOptions : IDisposable
+ {
+ IntPtr handle;
+
+ public FontOptions () : this (NativeMethods.cairo_font_options_create ())
+ {
+ }
+
+ ~FontOptions ()
+ {
+ Dispose (false);
+ }
+
+ internal FontOptions (IntPtr handle)
+ {
+ this.handle = handle;
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ public FontOptions Copy ()
+ {
+ return new FontOptions (NativeMethods.cairo_font_options_copy (handle));
+ }
+
+ [Obsolete ("Use Dispose()")]
+ public void Destroy ()
+ {
+ Dispose ();
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<FontOptions> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_font_options_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+
+ public static bool operator == (FontOptions options, FontOptions other)
+ {
+ return Equals (options, other);
+ }
+
+ public static bool operator != (FontOptions options, FontOptions other)
+ {
+ return !(options == other);
+ }
+
+ public override bool Equals (object other)
+ {
+ return Equals (other as FontOptions);
+ }
+
+ bool Equals (FontOptions options)
+ {
+ return options != null && NativeMethods.cairo_font_options_equal (Handle, options.Handle);
+ }
+
+ public IntPtr Handle {
+ get { return handle; }
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) NativeMethods.cairo_font_options_hash (handle);
+ }
+
+ public void Merge (FontOptions other)
+ {
+ if (other == null)
+ throw new ArgumentNullException ("other");
+ NativeMethods.cairo_font_options_merge (handle, other.Handle);
+ }
+
+ public Antialias Antialias {
+ get { return NativeMethods.cairo_font_options_get_antialias (handle); }
+ set { NativeMethods.cairo_font_options_set_antialias (handle, value); }
+ }
+
+ public HintMetrics HintMetrics {
+ get { return NativeMethods.cairo_font_options_get_hint_metrics (handle);}
+ set { NativeMethods.cairo_font_options_set_hint_metrics (handle, value); }
+ }
+
+ public HintStyle HintStyle {
+ get { return NativeMethods.cairo_font_options_get_hint_style (handle);}
+ set { NativeMethods.cairo_font_options_set_hint_style (handle, value); }
+ }
+
+ public Status Status {
+ get { return NativeMethods.cairo_font_options_status (handle); }
+ }
+
+ public SubpixelOrder SubpixelOrder {
+ get { return NativeMethods.cairo_font_options_get_subpixel_order (handle);}
+ set { NativeMethods.cairo_font_options_set_subpixel_order (handle, value); }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.FontSlant.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum FontSlant
+ {
+ Normal,
+ Italic,
+ Oblique
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.FontType.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ [Serializable]
+ public enum FontType
+ {
+ Toy,
+ FreeType,
+ Win32,
+ Atsui,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.FontWeight.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum FontWeight
+ {
+ Normal,
+ Bold,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Format.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum Format
+ {
+ Argb32 = 0,
+ Rgb24 = 1,
+ A8 = 2,
+ A1 = 3,
+ Rgb16565 = 4,
+
+ //[Obsolete ("Use Argb32")]
+ ARGB32 = Argb32,
+ //[Obsolete ("Use Rgb24")]
+ RGB24 = Rgb24,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.GLSurface.cs
+//
+// Authors:
+// JP Bruyère (jp_bruyere@hotmail.com)
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2016 JP Bruyère
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class GLSurface : Surface
+ {
+
+ public GLSurface (IntPtr ptr, bool own) : base (ptr, own)
+ {}
+
+ public GLSurface (Device device, Cairo.Content content, uint tex, int width, int height)
+ : base (NativeMethods.cairo_gl_surface_create_for_texture (device.Handle, (uint)content, tex, width, height), true)
+ {}
+
+ public GLSurface (EGLDevice device, IntPtr eglSurf, int width, int height)
+ : base (NativeMethods.cairo_gl_surface_create_for_egl (device.Handle, eglSurf, width, height), true)
+ {}
+
+ public GLSurface (GLXDevice device, IntPtr window, int width, int height)
+ : base (NativeMethods.cairo_gl_surface_create_for_window (device.Handle, window, width, height),true)
+ {}
+
+ public GLSurface (WGLDevice device, IntPtr hdc, int width, int height)
+ : base (NativeMethods.cairo_gl_surface_create_for_dc (device.Handle, hdc, width, height), true)
+ {}
+
+ public void SwapBuffers(){
+ NativeMethods.cairo_gl_surface_swapbuffers (this.Handle);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Device.cs
+//
+// Authors:
+// JP Bruyère (jp_bruyere@hotmail.com)
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2016 JP Bruyère
+//
+// 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.
+//
+using System;
+
+namespace Cairo
+{
+ public class GLXDevice : Device
+ {
+ public GLXDevice (IntPtr dpy, IntPtr gl_ctx) : base (NativeMethods.cairo_glx_device_create (dpy, gl_ctx), true)
+ {
+ }
+
+ public IntPtr Display {
+ get { return NativeMethods.cairo_glx_device_get_display (Handle); }
+ }
+
+ public IntPtr Context {
+ get { return NativeMethods.cairo_glx_device_get_context (Handle); }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.GlitzSurface.cs
+//
+// Authors:
+// Alp Toker
+//
+// (C) Alp Toker, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+ public class GlitzSurface : Surface
+ {
+ internal GlitzSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public GlitzSurface (IntPtr glitz_surface)
+ : base (NativeMethods.cairo_glitz_surface_create (glitz_surface), true)
+ {
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Glyph.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo
+{
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Glyph
+ {
+ internal long index;
+ internal double x;
+ internal double y;
+
+ public Glyph (long index, double x, double y)
+ {
+ this.index = index;
+ this.x = x;
+ this.y = y;
+ }
+
+ public long Index {
+ get { return index; }
+ set { index = value; }
+ }
+
+ public double X {
+ get { return x; }
+ set { x = value; }
+ }
+
+ public double Y {
+ get { return y; }
+ set { y = value; }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj is Glyph)
+ return this == (Glyph)obj;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) Index ^ (int) X ^ (int) Y;
+ }
+
+ internal static IntPtr GlyphsToIntPtr (Glyph[] glyphs)
+ {
+ int size = Marshal.SizeOf (glyphs[0]);
+ IntPtr dest = Marshal.AllocHGlobal (size * glyphs.Length);
+ long pos = dest.ToInt64 ();
+ for (int i = 0; i < glyphs.Length; i++, pos += size)
+ Marshal.StructureToPtr (glyphs[i], (IntPtr) pos, false);
+ return dest;
+ }
+
+ public static bool operator == (Glyph glyph, Glyph other)
+ {
+ return glyph.Index == other.Index && glyph.X == other.X && glyph.Y == other.Y;
+ }
+
+ public static bool operator != (Glyph glyph, Glyph other)
+ {
+ return !(glyph == other);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Gradient.cs
+//
+// Author: Jordi Mas (jordi@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// (C) Ximian Inc, 2004.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class Gradient : Pattern
+ {
+ protected Gradient (IntPtr handle, bool owned) : base (handle, owned)
+ {
+ }
+
+ [Obsolete]
+ protected Gradient ()
+ {
+ }
+
+ public int ColorStopCount {
+ get {
+ int cnt;
+ NativeMethods.cairo_pattern_get_color_stop_count (Handle, out cnt);
+ return cnt;
+ }
+ }
+
+ public Status AddColorStop (double offset, Color c)
+ {
+ NativeMethods.cairo_pattern_add_color_stop_rgba (Handle, offset, c.R, c.G, c.B, c.A);
+ return Status;
+ }
+
+ public Status AddColorStopRgb (double offset, Color c)
+ {
+ NativeMethods.cairo_pattern_add_color_stop_rgb (Handle, offset, c.R, c.G, c.B);
+ return Status;
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.HintMetrics.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum HintMetrics
+ {
+ Default,
+ Off,
+ On,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.HintStyle.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum HintStyle
+ {
+ Default,
+ None,
+ Slight,
+ Medium,
+ Full,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.ImageSurface.cs
+//
+// Authors:
+// Duncan Mak
+// Miguel de Icaza.
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell, Inc. 2003.
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo {
+
+ public class ImageSurface : Surface
+ {
+ internal ImageSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public ImageSurface (Format format, int width, int height)
+ : base (NativeMethods.cairo_image_surface_create (format, width, height), true)
+ {
+ }
+
+ [Obsolete ("Use ImageSurface (byte[] data, Cairo.Format format, int width, int height, int stride)")]
+ public ImageSurface (ref byte[] data, Cairo.Format format, int width, int height, int stride)
+ : this (data, format, width, height, stride)
+ {
+ }
+
+ public ImageSurface (byte[] data, Format format, int width, int height, int stride)
+ : base (NativeMethods.cairo_image_surface_create_for_data (data, format, width, height, stride), true)
+ {
+ }
+
+ public ImageSurface (IntPtr data, Format format, int width, int height, int stride)
+ : base (NativeMethods.cairo_image_surface_create_for_data (data, format, width, height, stride), true)
+ {
+ }
+
+ public ImageSurface (string filename)
+ : base (NativeMethods.cairo_image_surface_create_from_png (filename), true)
+ {
+ }
+
+ public int Width {
+ get { return NativeMethods.cairo_image_surface_get_width (Handle); }
+ }
+
+ public int Height {
+ get { return NativeMethods.cairo_image_surface_get_height (Handle); }
+ }
+
+ public byte[] Data {
+ get {
+ IntPtr ptr = NativeMethods.cairo_image_surface_get_data (Handle);
+ int length = Height * Stride;
+ byte[] data = new byte[length];
+ Marshal.Copy (ptr, data, 0, length);
+ return data;
+ }
+ }
+
+ public IntPtr DataPtr {
+ get {
+ return NativeMethods.cairo_image_surface_get_data (Handle);
+ }
+ }
+
+ public Format Format {
+ get { return NativeMethods.cairo_image_surface_get_format (Handle); }
+ }
+
+ public int Stride {
+ get { return NativeMethods.cairo_image_surface_get_stride (Handle); }
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.LineCap.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum LineCap
+ {
+ Butt,
+ Round,
+ Square,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.LineJoin.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum LineJoin
+ {
+ Miter,
+ Round,
+ Bevel
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.LinearGradient.cs
+//
+// Author: Jordi Mas (jordi@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// (C) Ximian Inc, 2004.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class LinearGradient : Gradient
+ {
+ internal LinearGradient (IntPtr handle, bool owned) : base (handle, owned)
+ {
+ }
+
+ public LinearGradient (double x0, double y0, double x1, double y1)
+ : base (NativeMethods.cairo_pattern_create_linear (x0, y0, x1, y1), true)
+ {
+ }
+
+ public PointD[] LinearPoints {
+ get {
+ double x0, y0, x1, y1;
+ PointD[] points = new PointD [2];
+
+ NativeMethods.cairo_pattern_get_linear_points (Handle, out x0, out y0, out x1, out y1);
+
+ points[0] = new PointD (x0, y0);
+ points[1] = new PointD (x1, y1);
+ return points;
+ }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Matrix.cs
+//
+// Author: Duncan Mak
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// Idan Gazit (idan@fastmail.fm)
+//
+// (C) Ximian Inc, 2003 - 2005.
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo {
+
+ [StructLayout(LayoutKind.Sequential)]
+ public class Matrix : ICloneable
+ {
+ public double Xx;
+ public double Yx;
+ public double Xy;
+ public double Yy;
+ public double X0;
+ public double Y0;
+
+ public Matrix (double xx, double yx, double xy, double yy,
+ double x0, double y0)
+ {
+ this.Xx = xx; this.Yx = yx; this.Xy = xy;
+ this.Yy = yy; this.X0 = x0; this.Y0 = y0;
+ }
+
+ public Matrix ()
+ {
+ this.InitIdentity ();
+ }
+
+ public bool IsIdentity ()
+ {
+ return (this == new Matrix ());
+ }
+
+ public void InitIdentity ()
+ {
+ // this.Init(1,0,0,1,0,0);
+ NativeMethods.cairo_matrix_init_identity (this);
+ }
+
+ public void Init (double xx, double yx, double xy, double yy,
+ double x0, double y0)
+ {
+ this.Xx = xx; this.Yx = yx; this.Xy = xy;
+ this.Yy = yy; this.X0 = x0; this.Y0 = y0;
+ }
+
+ public void InitTranslate (double tx, double ty)
+ {
+ //this.Init (1, 0, 0, 1, tx, ty);
+ NativeMethods.cairo_matrix_init_translate (this, tx, ty);
+ }
+
+ public void Translate (double tx, double ty)
+ {
+ NativeMethods.cairo_matrix_translate (this, tx, ty);
+ }
+
+ public void InitScale (double sx, double sy)
+ {
+ //this.Init (sx, 0, 0, sy, 0, 0);
+ NativeMethods.cairo_matrix_init_scale (this, sx, sy);
+ }
+
+ public void Scale (double sx, double sy)
+ {
+ NativeMethods.cairo_matrix_scale (this, sx, sy);
+ }
+
+ public void InitRotate (double radians)
+ {
+ /*
+ double s, c;
+ s = Math.Sin (radians);
+ c = Math.Cos (radians);
+ this.Init (c, s, -s, c, 0, 0);
+ */
+ NativeMethods.cairo_matrix_init_rotate (this, radians);
+ }
+
+ public void Rotate (double radians)
+ {
+ NativeMethods.cairo_matrix_rotate (this, radians);
+ }
+
+ public Cairo.Status Invert ()
+ {
+ return NativeMethods.cairo_matrix_invert (this);
+ }
+
+ public void Multiply (Matrix b)
+ {
+ Matrix a = (Matrix) this.Clone ();
+ NativeMethods.cairo_matrix_multiply (this, a, b);
+ }
+
+ public static Matrix Multiply (Matrix a, Matrix b) {
+ Matrix result = new Matrix ();
+ NativeMethods.cairo_matrix_multiply (result, a, b);
+ return result;
+ }
+
+
+ public void TransformDistance (ref double dx, ref double dy)
+ {
+ NativeMethods.cairo_matrix_transform_distance (this, ref dx, ref dy);
+ }
+
+ public void TransformPoint (ref double x, ref double y)
+ {
+ NativeMethods.cairo_matrix_transform_point (this, ref x, ref y);
+ }
+
+ public override String ToString ()
+ {
+ String s = String.Format ("xx:{0:##0.0#} yx:{1:##0.0#} xy:{2:##0.0#} yy:{3:##0.0#} x0:{4:##0.0#} y0:{5:##0.0#}",
+ this.Xx, this.Yx, this.Xy, this.Yy, this.X0, this.Y0);
+ return s;
+ }
+
+ public static bool operator == (Matrix lhs, Matrix rhs)
+ {
+ return (lhs.Xx == rhs.Xx &&
+ lhs.Xy == rhs.Xy &&
+ lhs.Yx == rhs.Yx &&
+ lhs.Yy == rhs.Yy &&
+ lhs.X0 == rhs.X0 &&
+ lhs.Y0 == rhs.Y0 );
+ }
+
+ public static bool operator != (Matrix lhs, Matrix rhs)
+ {
+ return !(lhs==rhs);
+ }
+
+
+
+ public override bool Equals(object o)
+ {
+ if (! (o is Matrix))
+ return false;
+ else
+ return (this == (Matrix) o);
+ }
+
+ public override int GetHashCode()
+ {
+ return (int)this.Xx ^ (int)this.Xx>>32 ^
+ (int)this.Xy ^ (int)this.Xy>>32 ^
+ (int)this.Yx ^ (int)this.Yx>>32 ^
+ (int)this.Yy ^ (int)this.Yy>>32 ^
+ (int)this.X0 ^ (int)this.X0>>32 ^
+ (int)this.Y0 ^ (int)this.Y0>>32;
+ }
+
+ public object Clone()
+ {
+ return this.MemberwiseClone ();
+ }
+
+ }
+}
--- /dev/null
+//
+// Cairo.cs - a simplistic binding of the Cairo API to C#.
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// John Luke (john.luke@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005 John Luke
+// Copyright (C) 2006 Alp Toker
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo
+{
+ // sort the functions like in the following page so it is easier to find what is missing
+ // http://cairographics.org/manual/index-all.html
+
+ internal static class NativeMethods
+ {
+#if MONOTOUCH
+ const string cairo = "__Internal";
+#else
+ const string cairo = "libcairo-2.dll";
+#endif
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern void cairo_append_path (IntPtr cr, Path path);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_arc (IntPtr cr, double xc, double yc, double radius, double angle1, double angle2);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_arc_negative (IntPtr cr, double xc, double yc, double radius, double angle1, double angle2);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_atsui_font_face_create_for_atsu_font_id (IntPtr font_id);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_clip (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_clip_preserve (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_clip_extents (IntPtr cr, out double x1, out double y1, out double x2, out double y2);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_close_path (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_copy_page (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_copy_path (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_copy_path_flat (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_append_path (IntPtr cr, IntPtr path);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_create (IntPtr target);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_curve_to (IntPtr cr, double x1, double y1, double x2, double y2, double x3, double y3);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_debug_reset_static_data ();
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_destroy (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_device_to_user (IntPtr cr, ref double x, ref double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_device_to_user_distance (IntPtr cr, ref double dx, ref double dy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_fill (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_fill_extents (IntPtr cr, out double x1, out double y1, out double x2, out double y2);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_fill_preserve (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_extents (IntPtr cr, out FontExtents extents);
+
+ // FontFace
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_face_destroy (IntPtr font_face);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern FontType cairo_font_face_get_type (IntPtr font_face);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern void cairo_font_face_get_user_data (IntPtr font_face);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern void cairo_font_face_set_user_data (IntPtr font_face);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_font_face_reference (IntPtr font_face);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_font_face_status (IntPtr font_face);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern uint cairo_font_face_get_reference_count (IntPtr surface);
+
+ // FontOptions
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_font_options_copy (IntPtr original);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_font_options_create ();
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_options_destroy (IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ [return: MarshalAs (UnmanagedType.U1)]
+ internal static extern bool cairo_font_options_equal (IntPtr options, IntPtr other);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Antialias cairo_font_options_get_antialias (IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern HintMetrics cairo_font_options_get_hint_metrics (IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern HintStyle cairo_font_options_get_hint_style (IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern SubpixelOrder cairo_font_options_get_subpixel_order (IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern long cairo_font_options_hash (IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_options_merge (IntPtr options, IntPtr other);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_options_set_antialias (IntPtr options, Antialias aa);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_options_set_hint_metrics (IntPtr options, HintMetrics metrics);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_options_set_hint_style (IntPtr options, HintStyle style);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_font_options_set_subpixel_order (IntPtr options, SubpixelOrder order);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_font_options_status (IntPtr options);
+
+ // Freetype / FontConfig
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_ft_font_face_create_for_ft_face (IntPtr face, int load_flags);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_ft_font_face_create_for_pattern (IntPtr fc_pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_ft_font_options_substitute (FontOptions options, IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_ft_scaled_font_lock_face (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_ft_scaled_font_unlock_face (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Antialias cairo_get_antialias (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_get_current_point (IntPtr cr, out double x, out double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern FillRule cairo_get_fill_rule (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_get_font_face (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_get_font_matrix (IntPtr cr, out Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_get_font_options (IntPtr cr, IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_get_group_target (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern LineCap cairo_get_line_cap (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern LineJoin cairo_get_line_join (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern double cairo_get_line_width (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_get_matrix (IntPtr cr, Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern double cairo_get_miter_limit (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Operator cairo_get_operator (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern uint cairo_get_reference_count (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_get_source (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_get_target (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern double cairo_get_tolerance (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_glitz_surface_create (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_glyph_extents (IntPtr cr, IntPtr glyphs, int num_glyphs, out TextExtents extents);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_glyph_path (IntPtr cr, IntPtr glyphs, int num_glyphs);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ [return: MarshalAs (UnmanagedType.U1)]
+ internal static extern bool cairo_has_current_point (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_identity_matrix (IntPtr cr);
+
+ // ImageSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_image_surface_create (Cairo.Format format, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_image_surface_create_for_data (byte[] data, Cairo.Format format, int width, int height, int stride);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_image_surface_create_for_data (IntPtr data, Cairo.Format format, int width, int height, int stride);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_image_surface_create_from_png (string filename);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern IntPtr cairo_image_surface_create_from_png_stream (string filename);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_image_surface_get_data (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Format cairo_image_surface_get_format (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_image_surface_get_height (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_image_surface_get_stride (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_image_surface_get_width (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ [return: MarshalAs (UnmanagedType.U1)]
+ internal static extern bool cairo_in_clip (IntPtr cr, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ [return: MarshalAs (UnmanagedType.U1)]
+ internal static extern bool cairo_in_fill (IntPtr cr, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ [return: MarshalAs (UnmanagedType.U1)]
+ internal static extern bool cairo_in_stroke (IntPtr cr, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_line_to (IntPtr cr, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_mask (IntPtr cr, IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_mask_surface (IntPtr cr, IntPtr surface, double x, double y);
+
+ // Matrix
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_init (Matrix matrix, double xx, double yx, double xy, double yy, double x0, double y0);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_init_identity (Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_init_rotate (Matrix matrix, double radians);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_init_scale (Matrix matrix, double sx, double sy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_init_translate (Matrix matrix, double tx, double ty);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_matrix_invert (Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_multiply (Matrix result, Matrix a, Matrix b);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_scale (Matrix matrix, double sx, double sy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_rotate (Matrix matrix, double radians);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_transform_distance (Matrix matrix, ref double dx, ref double dy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_transform_point (Matrix matrix, ref double x, ref double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_matrix_translate (Matrix matrix, double tx, double ty);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_move_to (IntPtr cr, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_new_path (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_new_sub_path (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_paint (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_paint_with_alpha (IntPtr cr, double alpha);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_path_destroy (IntPtr path);
+
+ // Pattern
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_add_color_stop_rgb (IntPtr pattern, double offset, double red, double green, double blue);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_add_color_stop_rgba (IntPtr pattern, double offset, double red, double green, double blue, double alpha);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_get_color_stop_count (IntPtr pattern, out int count);
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_get_color_stop_rgba (IntPtr pattern, int index, out double offset, out double red, out double green, out double blue, out double alpha);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pattern_create_for_surface (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_get_surface (IntPtr pattern, out IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pattern_create_linear (double x0, double y0, double x1, double y1);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_get_linear_points (IntPtr pattern, out double x0, out double y0, out double x1, out double y1);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pattern_create_radial (double cx0, double cy0, double radius0, double cx1, double cy1, double radius1);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_get_radial_circles (IntPtr pattern, out double x0, out double y0, out double r0, out double x1, out double y1, out double r1);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pattern_create_rgb (double r, double g, double b);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pattern_create_rgba (double r, double g, double b, double a);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_get_rgba (IntPtr pattern, out double red, out double green, out double blue, out double alpha);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_destroy (IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Extend cairo_pattern_get_extend (IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Filter cairo_pattern_get_filter (IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_get_matrix (IntPtr pattern, Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern PatternType cairo_pattern_get_type (IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pattern_reference (IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_set_extend (IntPtr pattern, Extend extend);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_set_filter (IntPtr pattern, Filter filter);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pattern_set_matrix (IntPtr pattern, Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_pattern_status (IntPtr pattern);
+
+ // PdfSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pdf_surface_create (string filename, double width, double height);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern IntPtr cairo_pdf_surface_create_for_stream (string filename, double width, double height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pdf_surface_set_size (IntPtr surface, double x, double y);
+
+ // PostscriptSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_ps_surface_create (string filename, double width, double height);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern IntPtr cairo_ps_surface_create_for_stream (string filename, double width, double height);
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_ps_surface_dsc_begin_page_setup (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_ps_surface_dsc_begin_setup (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_ps_surface_dsc_comment (IntPtr surface, string comment);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_ps_surface_set_size (IntPtr surface, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_pop_group (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_pop_group_to_source (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_push_group (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_push_group_with_content (IntPtr cr, Content content);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_quartz_surface_create (IntPtr context, bool flipped, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_rectangle (IntPtr cr, double x, double y, double width, double height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_reference (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern bool cairo_region_contains_point (IntPtr region, int x, int y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern RegionOverlap cairo_region_contains_rectangle (IntPtr region, ref RectangleInt rectangle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_region_copy (IntPtr original);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_region_create ();
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_region_create_rectangle (ref RectangleInt rect);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_region_create_rectangles (RectangleInt[] rects, int count);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_region_destroy (IntPtr region);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern bool cairo_region_equal (IntPtr a, IntPtr b);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_region_get_extents (IntPtr region, out RectangleInt extents);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_region_get_rectangle (IntPtr region, int nth, out RectangleInt rectangle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_intersect (IntPtr dst, IntPtr other);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_intersect_rectangle (IntPtr dst, ref RectangleInt rectangle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern bool cairo_region_is_empty (IntPtr region);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_region_num_rectangles (IntPtr region);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_region_reference (IntPtr region);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_status (IntPtr region);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_subtract (IntPtr dst, IntPtr other);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_subtract_rectangle (IntPtr dst, ref RectangleInt rectangle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_region_translate (IntPtr region, int dx, int dy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_union (IntPtr dst, IntPtr other);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_union_rectangle (IntPtr dst, ref RectangleInt rectangle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_xor (IntPtr dst, IntPtr other);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_region_xor_rectangle (IntPtr dst, ref RectangleInt rectangle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_rel_curve_to (IntPtr cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_rel_line_to (IntPtr cr, double dx, double dy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_rel_move_to (IntPtr cr, double dx, double dy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_reset_clip (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_restore (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_rotate (IntPtr cr, double angle);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_save (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_scale (IntPtr cr, double sx, double sy);
+
+ // ScaledFont
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_scaled_font_create (IntPtr fontFace, Matrix matrix, Matrix ctm, IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_scaled_font_destroy (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_scaled_font_extents (IntPtr scaled_font, out FontExtents extents);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_scaled_font_get_ctm (IntPtr scaled_font, out Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_scaled_font_get_font_face (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_scaled_font_get_font_matrix (IntPtr scaled_font, out Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_scaled_font_get_font_options (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern FontType cairo_scaled_font_get_type (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_scaled_font_glyph_extents (IntPtr scaled_font, IntPtr glyphs, int num_glyphs, out TextExtents extents);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_scaled_font_reference (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_scaled_font_status (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_scaled_font (IntPtr cr, IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_get_scaled_font (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_scaled_font_text_extents (IntPtr scaled_font, byte[] utf8, out TextExtents extents);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_select_font_face (IntPtr cr, string family, FontSlant slant, FontWeight weight);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_antialias (IntPtr cr, Antialias antialias);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_dash (IntPtr cr, double [] dashes, int ndash, double offset);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_get_dash (IntPtr cr, IntPtr dashes, out double offset);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_get_dash_count (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_fill_rule (IntPtr cr, Cairo.FillRule fill_rule);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_font_face (IntPtr cr, IntPtr fontFace);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_font_matrix (IntPtr cr, Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_font_options (IntPtr cr, IntPtr options);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_font_size (IntPtr cr, double size);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_line_cap (IntPtr cr, LineCap line_cap);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_line_join (IntPtr cr, LineJoin line_join);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_line_width (IntPtr cr, double width);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_matrix (IntPtr cr, Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_miter_limit (IntPtr cr, double limit);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_operator (IntPtr cr, Cairo.Operator op);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_source (IntPtr cr, IntPtr pattern);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_source_rgb (IntPtr cr, double red, double green, double blue);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_source_rgba (IntPtr cr, double red, double green, double blue, double alpha);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_source_surface (IntPtr cr, IntPtr surface, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_set_tolerance (IntPtr cr, double tolerance);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_show_glyphs (IntPtr ct, IntPtr glyphs, int num_glyphs);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_show_page (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_show_text (IntPtr cr, byte[] utf8);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_status (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_status_to_string (Status status);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_stroke (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_stroke_extents (IntPtr cr, out double x1, out double y1, out double x2, out double y2);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_stroke_preserve (IntPtr cr);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_rectangle_list_destroy (IntPtr rectangle_list);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_copy_clip_rectangle_list (IntPtr cr);
+
+ // Surface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_surface_create_similar (IntPtr surface, Cairo.Content content, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_destroy (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_finish (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_flush (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Content cairo_surface_get_content (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_get_device_offset (IntPtr surface, out double x, out double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_get_font_options (IntPtr surface, IntPtr FontOptions);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern uint cairo_surface_get_reference_count (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern SurfaceType cairo_surface_get_type (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_mark_dirty (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_mark_dirty_rectangle (IntPtr surface, int x, int y, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_surface_reference (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_set_device_offset (IntPtr surface, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_set_fallback_resolution (IntPtr surface, double x, double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_surface_status (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_surface_write_to_png (IntPtr surface, string filename);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern void cairo_surface_write_to_png_stream (IntPtr surface, WriteFunc writeFunc);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_svg_surface_create (string fileName, double width, double height);
+
+ //[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ //internal static extern IntPtr cairo_svg_surface_create_for_stream (double width, double height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_svg_surface_restrict_to_version (IntPtr surface, SvgVersion version);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_text_extents (IntPtr cr, byte[] utf8, out TextExtents extents);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_text_path (IntPtr ct, byte[] utf8);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_transform (IntPtr cr, Matrix matrix);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_translate (IntPtr cr, double tx, double ty);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_user_to_device (IntPtr cr, ref double x, ref double y);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_user_to_device_distance (IntPtr cr, ref double dx, ref double dy);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_version ();
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_version_string ();
+
+ // DirectFBSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_directfb_surface_create (IntPtr dfb, IntPtr surface);
+
+ // win32 fonts
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_win32_font_face_create_for_logfontw (IntPtr logfontw);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_win32_scaled_font_done_font (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern double cairo_win32_scaled_font_get_metrics_factor (IntPtr scaled_font);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_win32_scaled_font_select_font (IntPtr scaled_font, IntPtr hdc);
+
+ // win32 surface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_win32_surface_create (IntPtr hdc);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_win32_surface_create_with_ddb (IntPtr hdc, Format format, int width, int height);
+
+ // XcbSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xcb_surface_create (IntPtr connection, uint drawable, IntPtr visual, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xcb_surface_create_for_bitmap (IntPtr connection, uint bitmap, IntPtr screen, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_xcb_surface_set_size (IntPtr surface, int width, int height);
+
+ // XlibSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xlib_surface_create (IntPtr display, IntPtr drawable, IntPtr visual, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xlib_surface_create_for_bitmap (IntPtr display, IntPtr bitmap, IntPtr screen, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_xlib_surface_get_depth (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xlib_surface_get_display (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xlib_surface_get_drawable (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_xlib_surface_get_height (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xlib_surface_get_screen (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_xlib_surface_get_visual (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_xlib_surface_get_width (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_xlib_surface_set_drawable (IntPtr surface, IntPtr drawable, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_xlib_surface_set_size (IntPtr surface, int width, int height);
+
+ #region GLSurface
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_gl_surface_create (IntPtr device, uint content, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_gl_surface_create_for_texture (IntPtr device, uint content, uint tex, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_gl_surface_set_size (IntPtr surface, int width, int height);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_gl_surface_get_width (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern int cairo_gl_surface_get_height (IntPtr surface);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_gl_surface_swapbuffers (IntPtr surf);
+ #endregion
+
+ #region GLX Functions
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_glx_device_create (IntPtr dpy, IntPtr gl_ctx);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_glx_device_get_display (IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_glx_device_get_context (IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_gl_surface_create_for_window (IntPtr device, IntPtr window, int width, int height);
+ #endregion
+
+ #region WGL Fucntions
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_wgl_device_create (IntPtr hglrc);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_wgl_device_get_context (IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_gl_surface_create_for_dc (IntPtr device, IntPtr hdc, int width, int height);
+ #endregion
+
+ #region EGL Functions
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_egl_device_create (IntPtr dpy, IntPtr gl_ctx);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_gl_surface_create_for_egl (IntPtr device, IntPtr eglSurface, int width, int height);
+ #endregion
+
+ #region Device
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern IntPtr cairo_device_reference (IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_device_status(IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_device_destroy (IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern Status cairo_device_acquire(IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_device_release(IntPtr device);
+
+ [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+ internal static extern void cairo_gl_device_set_thread_aware(IntPtr device, int value);
+ #endregion
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// Mono.Cairo.Operator.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// John Luke (john.luke@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005 John Luke
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum Operator
+ {
+ Clear,
+ Source,
+ Over,
+ In,
+ Out,
+ Atop,
+
+ Dest,
+ DestOver,
+ DestIn,
+ DestOut,
+ DestAtop,
+
+ Xor,
+ Add,
+ Saturate,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.PostscriptSurface.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class PSSurface : Surface
+ {
+ internal PSSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public PSSurface (string filename, double width, double height)
+ : base (NativeMethods.cairo_ps_surface_create (filename, width, height), true)
+ {
+ }
+
+ public void BeginPageSetup ()
+ {
+ NativeMethods.cairo_ps_surface_dsc_begin_page_setup (Handle);
+ }
+
+ public void BeginSetup ()
+ {
+ NativeMethods.cairo_ps_surface_dsc_begin_setup (Handle);
+ }
+
+ public void DscComment (string comment)
+ {
+ NativeMethods.cairo_ps_surface_dsc_comment (Handle, comment);
+ }
+
+ public void SetSize (double width, double height)
+ {
+ NativeMethods.cairo_ps_surface_set_size (Handle, width, height);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Context.cs
+//
+// Author:
+// Miguel de Icaza (miguel@novell.com)
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright 2007 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+using Cairo;
+
+namespace Cairo {
+
+ public class Path : IDisposable
+ {
+ IntPtr handle = IntPtr.Zero;
+
+ internal Path (IntPtr handle)
+ {
+ this.handle = handle;
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ ~Path ()
+ {
+ Dispose (false);
+ }
+
+ public IntPtr Handle { get { return handle; } }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Path> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_path_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Pattern.cs
+//
+// Author: Jordi Mas (jordi@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// (C) Ximian Inc, 2004.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Collections;
+
+namespace Cairo {
+
+ public class Pattern : IDisposable
+ {
+ [Obsolete]
+ protected IntPtr pattern = IntPtr.Zero;
+
+ public static Pattern Lookup (IntPtr pattern, bool owner)
+ {
+ if (pattern == IntPtr.Zero)
+ return null;
+
+ PatternType pt = NativeMethods.cairo_pattern_get_type (pattern);
+ switch (pt) {
+ case PatternType.Solid:
+ return new SolidPattern (pattern, owner);
+ case PatternType.Surface:
+ return new SurfacePattern (pattern, owner);
+ case PatternType.Linear:
+ return new LinearGradient (pattern, owner);
+ case PatternType.Radial:
+ return new RadialGradient (pattern, owner);
+ default:
+ return new Pattern (pattern, owner);
+ }
+ }
+
+ [Obsolete]
+ protected Pattern ()
+ {
+ }
+
+ internal Pattern (IntPtr handle, bool owned)
+ {
+ Handle = handle;
+ if (!owned)
+ NativeMethods.cairo_pattern_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ ~Pattern ()
+ {
+ Dispose (false);
+ }
+
+ [Obsolete ("Use the SurfacePattern constructor")]
+ public Pattern (Surface surface)
+ : this ( NativeMethods.cairo_pattern_create_for_surface (surface.Handle), true)
+ {
+ }
+
+ [Obsolete]
+ protected void Reference ()
+ {
+ NativeMethods.cairo_pattern_reference (pattern);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Pattern> (Handle, disposing);
+
+ if (!disposing|| Handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_pattern_destroy (Handle);
+ Handle = IntPtr.Zero;
+ }
+
+ [Obsolete ("Use Dispose()")]
+ public void Destroy ()
+ {
+ Dispose ();
+ }
+
+ public Status Status
+ {
+ get { return NativeMethods.cairo_pattern_status (Handle); }
+ }
+
+ public Extend Extend
+ {
+ get { return NativeMethods.cairo_pattern_get_extend (Handle); }
+ set { NativeMethods.cairo_pattern_set_extend (Handle, value); }
+ }
+
+ public Matrix Matrix {
+ set {
+ NativeMethods.cairo_pattern_set_matrix (Handle, value);
+ }
+
+ get {
+ Matrix m = new Matrix ();
+ NativeMethods.cairo_pattern_get_matrix (Handle, m);
+ return m;
+ }
+ }
+
+#pragma warning disable 612
+ public IntPtr Handle {
+ get { return pattern; }
+ private set { pattern = value; }
+ }
+#pragma warning restore 612
+
+ [Obsolete]
+ public IntPtr Pointer {
+ get { return pattern; }
+ }
+
+ public PatternType PatternType {
+ get { return NativeMethods.cairo_pattern_get_type (Handle); }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.PatternType.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ [Serializable]
+ public enum PatternType
+ {
+ Solid,
+ Surface,
+ Linear,
+ Radial,
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.PdfSurface.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class PdfSurface : Surface
+ {
+ internal PdfSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public PdfSurface (string filename, double width, double height)
+ : base (NativeMethods.cairo_pdf_surface_create (filename, width, height), true)
+ {
+ }
+
+ public void SetSize (double width, double height)
+ {
+ NativeMethods.cairo_pdf_surface_set_size (Handle, width, height);
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Context.cs
+//
+// Author:
+// Duncan Mak (duncan@ximian.com)
+// Miguel de Icaza (miguel@novell.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell Inc, 2003.
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+namespace Cairo {
+ public struct Point
+ {
+ public Point (int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ int x, y;
+ public int X {
+ get { return x; }
+ set { x = value; }
+ }
+
+ public int Y {
+ get { return y; }
+ set { y = value; }
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Context.cs
+//
+// Author:
+// Duncan Mak (duncan@ximian.com)
+// Miguel de Icaza (miguel@novell.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell Inc, 2003.
+//
+// This is an OO wrapper API for the Cairo API.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+namespace Cairo {
+
+ public struct PointD
+ {
+ public PointD (double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ double x, y;
+ public double X {
+ get { return x; }
+ set { x = value; }
+ }
+
+ public double Y {
+ get { return y; }
+ set { y = value; }
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Pattern.cs
+//
+// Author: Jordi Mas (jordi@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// (C) Ximian Inc, 2004.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class RadialGradient : Gradient
+ {
+ internal RadialGradient (IntPtr handle, bool owned) : base (handle, owned)
+ {
+ }
+
+ public RadialGradient (double cx0, double cy0, double radius0, double cx1, double cy1, double radius1)
+ : base (NativeMethods.cairo_pattern_create_radial (cx0, cy0, radius0, cx1, cy1, radius1), true)
+ {
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Rectangle.cs
+//
+// Author:
+// John Luke (john.luke@gmail.com)
+//
+// (C) John Luke 2005.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ public struct Rectangle
+ {
+ double x;
+ double y;
+ double width;
+ double height;
+
+ public Rectangle (double x, double y, double width, double height)
+ {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ public Rectangle (Point point, double width, double height)
+ {
+ x = point.X;
+ y = point.Y;
+ this.width = width;
+ this.height = height;
+ }
+
+ public double X {
+ get { return x; }
+ }
+
+ public double Y {
+ get { return y; }
+ }
+
+ public double Width {
+ get { return width; }
+ }
+
+ public double Height {
+ get { return height; }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj is Rectangle)
+ return this == (Rectangle)obj;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) (x + y + width + height);
+ }
+
+ public override string ToString ()
+ {
+ return String.Format ("x:{0} y:{1} w:{2} h:{3}", x, y, width, height);
+ }
+
+ public static bool operator == (Rectangle rectangle, Rectangle other)
+ {
+ return rectangle.X == other.X && rectangle.Y == other.Y && rectangle.Width == other.Width && rectangle.Height == other.Height;
+ }
+
+ public static bool operator != (Rectangle rectangle, Rectangle other)
+ {
+ return !(rectangle == other);
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2011 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo
+{
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RectangleInt {
+ public int X;
+ public int Y;
+ public int Width;
+ public int Height;
+ }
+
+ public enum RegionOverlap {
+ In,
+ Out,
+ Part,
+ }
+
+ public class Region : IDisposable {
+
+ IntPtr handle;
+ public IntPtr Handle {
+ get { return handle; }
+ }
+
+ [Obsolete]
+ public Region (IntPtr handle) : this (handle, false) {}
+
+ public Region (IntPtr handle, bool owned)
+ {
+ this.handle = handle;
+ if (!owned)
+ NativeMethods.cairo_region_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ public Region () : this (NativeMethods.cairo_region_create () , true)
+ {
+ }
+
+ public Region (RectangleInt rect)
+ {
+ handle = NativeMethods.cairo_region_create_rectangle (ref rect);
+ }
+
+ public Region (RectangleInt[] rects)
+ {
+ handle = NativeMethods.cairo_region_create_rectangles (rects, rects.Length);
+ }
+
+ public Region Copy ()
+ {
+ return new Region (NativeMethods.cairo_region_copy (Handle), true);
+ }
+
+ ~Region ()
+ {
+ Dispose (false);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Region> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_region_destroy (Handle);
+ handle = IntPtr.Zero;
+ }
+
+ public override bool Equals (object obj)
+ {
+ return (obj is Region) && NativeMethods.cairo_region_equal (Handle, (obj as Region).Handle);
+ }
+
+ public override int GetHashCode ()
+ {
+ return Handle.GetHashCode ();
+ }
+
+ public Status Status {
+ get { return NativeMethods.cairo_region_status (Handle); }
+ }
+
+ public RectangleInt Extents {
+ get {
+ RectangleInt result;
+ NativeMethods.cairo_region_get_extents (Handle, out result);
+ return result;
+ }
+ }
+
+ public int NumRectangles {
+ get { return NativeMethods.cairo_region_num_rectangles (Handle); }
+ }
+
+ public RectangleInt GetRectangle (int nth)
+ {
+ RectangleInt val;
+ NativeMethods.cairo_region_get_rectangle (Handle, nth, out val);
+ return val;
+ }
+
+ public bool IsEmpty {
+ get { return NativeMethods.cairo_region_is_empty (Handle); }
+ }
+
+ public RegionOverlap ContainsPoint (RectangleInt rectangle)
+ {
+ return NativeMethods.cairo_region_contains_rectangle (Handle, ref rectangle);
+ }
+
+ public bool ContainsPoint (int x, int y)
+ {
+ return NativeMethods.cairo_region_contains_point (Handle, x, y);
+ }
+
+ public void Translate (int dx, int dy)
+ {
+ NativeMethods.cairo_region_translate (Handle, dx, dy);
+ }
+
+ public Status Subtract (Region other)
+ {
+ return NativeMethods.cairo_region_subtract (Handle, other.Handle);
+ }
+
+ public Status SubtractRectangle (RectangleInt rectangle)
+ {
+ return NativeMethods.cairo_region_subtract_rectangle (Handle, ref rectangle);
+ }
+
+ public Status Intersect (Region other)
+ {
+ return NativeMethods.cairo_region_intersect (Handle, other.Handle);
+ }
+
+ public Status IntersectRectangle (RectangleInt rectangle)
+ {
+ return NativeMethods.cairo_region_intersect_rectangle (Handle, ref rectangle);
+ }
+
+ public Status Union (Region other)
+ {
+ return NativeMethods.cairo_region_union (Handle, other.Handle);
+ }
+
+ public Status UnionRectangle (RectangleInt rectangle)
+ {
+ return NativeMethods.cairo_region_union_rectangle (Handle, ref rectangle);
+ }
+
+ public Status Xor (Region other)
+ {
+ return NativeMethods.cairo_region_xor (Handle, other.Handle);
+ }
+
+ public Status XorRectangle (RectangleInt rectangle)
+ {
+ return NativeMethods.cairo_region_xor_rectangle (Handle, ref rectangle);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.ScaledFont.cs
+//
+// (c) 2008 Jordi Mas i Hernandez (jordimash@gmail.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo {
+
+ public class ScaledFont : IDisposable
+ {
+ protected IntPtr handle = IntPtr.Zero;
+
+ internal ScaledFont (IntPtr handle, bool owner)
+ {
+ this.handle = handle;
+ if (!owner)
+ NativeMethods.cairo_scaled_font_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ public ScaledFont (FontFace fontFace, Matrix matrix, Matrix ctm, FontOptions options)
+ : this (NativeMethods.cairo_scaled_font_create (fontFace.Handle, matrix, ctm, options.Handle), true)
+ {
+ }
+
+ ~ScaledFont ()
+ {
+ Dispose (false);
+ }
+
+ public IntPtr Handle {
+ get {
+ return handle;
+ }
+ }
+
+ public FontExtents FontExtents {
+ get {
+ FontExtents extents;
+ NativeMethods.cairo_scaled_font_extents (handle, out extents);
+ return extents;
+ }
+ }
+
+ public Matrix FontMatrix {
+ get {
+ Matrix m;
+ NativeMethods.cairo_scaled_font_get_font_matrix (handle, out m);
+ return m;
+ }
+ }
+
+ public FontType FontType {
+ get {
+ return NativeMethods.cairo_scaled_font_get_type (handle);
+ }
+ }
+
+ public TextExtents GlyphExtents (Glyph[] glyphs)
+ {
+ IntPtr ptr = Context.FromGlyphToUnManagedMemory (glyphs);
+ TextExtents extents;
+
+ NativeMethods.cairo_scaled_font_glyph_extents (handle, ptr, glyphs.Length, out extents);
+
+ Marshal.FreeHGlobal (ptr);
+ return extents;
+ }
+
+ public Status Status
+ {
+ get { return NativeMethods.cairo_scaled_font_status (handle); }
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<ScaledFont> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_scaled_font_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+
+ [Obsolete]
+ protected void Reference ()
+ {
+ NativeMethods.cairo_scaled_font_reference (handle);
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Pattern.cs
+//
+// Author: Jordi Mas (jordi@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// (C) Ximian Inc, 2004.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class SolidPattern : Pattern
+ {
+ internal SolidPattern (IntPtr handle, bool owned) : base (handle, owned)
+ {
+ }
+
+ public SolidPattern (Color color)
+ : base (NativeMethods.cairo_pattern_create_rgba (color.R, color.G, color.B, color.A), true)
+ {
+ }
+
+ public SolidPattern (double r, double g, double b)
+ : base (NativeMethods.cairo_pattern_create_rgb (r, g, b), true)
+ {
+ }
+
+ public SolidPattern (double r, double g, double b, double a)
+ : base (NativeMethods.cairo_pattern_create_rgba (r, g, b, a), true)
+ {
+ }
+
+ public SolidPattern (Color color, bool solid)
+ : base (solid
+ ? NativeMethods.cairo_pattern_create_rgb (color.R, color.G, color.B)
+ : NativeMethods.cairo_pattern_create_rgba (color.R, color.G, color.B, color.A),
+ true)
+ {
+ }
+
+ public Color Color {
+ get {
+ double red, green, blue, alpha;
+ NativeMethods.cairo_pattern_get_rgba (Handle, out red, out green, out blue, out alpha);
+ return new Color (red, green, blue, alpha);
+ }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Status.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// John Luke (john.luke@gmail.com)
+// Alp Toker (alp@atoker.com)
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005 John Luke
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum Status
+ {
+ Success = 0,
+ NoMemory,
+ InvalidRestore,
+ InvalidPopGroup,
+ NoCurrentPoint,
+ InvalidMatrix,
+ InvalidStatus,
+ NullPointer,
+ InvalidString,
+ InvalidPathData,
+ ReadError,
+ WriteError,
+ SurfaceFinished,
+ SurfaceTypeMismatch,
+ PatternTypeMismatch,
+ InvalidContent,
+ InvalidFormat,
+ InvalidVisual,
+ FileNotFound,
+ InvalidDash,
+ InvalidDscComment,
+ InvalidIndex,
+ ClipNotRepresentable,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Cairo.cs
+//
+// Authors:
+// John Luke (john.luke@gmail.com)
+//
+// Copyright (C) John Luke 2005
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo
+{
+ [Serializable]
+ public enum SubpixelOrder
+ {
+ Default,
+ Rgb,
+ Bgr,
+ Vrgb,
+ Vbgr,
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Surface.cs
+//
+// Authors:
+// Duncan Mak
+// Miguel de Icaza.
+// Alp Toker
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell, Inc. 2003.
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Collections;
+
+namespace Cairo {
+
+ public class Surface : IDisposable
+ {
+ [Obsolete]
+ protected static Hashtable surfaces = new Hashtable ();
+
+ IntPtr handle = IntPtr.Zero;
+
+ [Obsolete]
+ protected Surface()
+ {
+ }
+
+ [Obsolete]
+ protected Surface (IntPtr ptr) : this (ptr, true)
+ {
+ }
+
+ protected Surface (IntPtr handle, bool owner)
+ {
+ this.handle = handle;
+ if (!owner)
+ NativeMethods.cairo_surface_reference (handle);
+ if (CairoDebug.Enabled)
+ CairoDebug.OnAllocated (handle);
+ }
+
+ public static Surface Lookup (IntPtr surface, bool owned)
+ {
+ SurfaceType st = NativeMethods.cairo_surface_get_type (surface);
+ switch (st) {
+ case SurfaceType.Image:
+ return new ImageSurface (surface, owned);
+ case SurfaceType.Xlib:
+ return new XlibSurface (surface, owned);
+ case SurfaceType.Xcb:
+ return new XcbSurface (surface, owned);
+ case SurfaceType.Glitz:
+ return new GlitzSurface (surface, owned);
+ case SurfaceType.Win32:
+ return new Win32Surface (surface, owned);
+ case SurfaceType.Pdf:
+ return new PdfSurface (surface, owned);
+ case SurfaceType.PS:
+ return new PSSurface (surface, owned);
+ case SurfaceType.DirectFB:
+ return new DirectFBSurface (surface, owned);
+ case SurfaceType.Svg:
+ return new SvgSurface (surface, owned);
+ case SurfaceType.GL:
+ return new GLSurface (surface, owned);
+ default:
+ return new Surface (surface, owned);
+ }
+ }
+
+ [Obsolete ("Use an ImageSurface constructor instead.")]
+ public static Cairo.Surface CreateForImage (
+ ref byte[] data, Cairo.Format format, int width, int height, int stride)
+ {
+ IntPtr p = NativeMethods.cairo_image_surface_create_for_data (
+ data, format, width, height, stride);
+
+ return new Cairo.Surface (p, true);
+ }
+
+ [Obsolete ("Use an ImageSurface constructor instead.")]
+ public static Cairo.Surface CreateForImage (
+ Cairo.Format format, int width, int height)
+ {
+ IntPtr p = NativeMethods.cairo_image_surface_create (
+ format, width, height);
+
+ return new Cairo.Surface (p, true);
+ }
+
+
+ public Cairo.Surface CreateSimilar (
+ Cairo.Content content, int width, int height)
+ {
+ IntPtr p = NativeMethods.cairo_surface_create_similar (
+ this.Handle, content, width, height);
+
+ return new Cairo.Surface (p, true);
+ }
+
+ ~Surface ()
+ {
+ Dispose (false);
+ }
+
+ //[Obsolete ("Use Context.SetSource() followed by Context.Paint()")]
+ public void Show (Context gr, double x, double y)
+ {
+ NativeMethods.cairo_set_source_surface (gr.Handle, handle, x, y);
+ NativeMethods.cairo_paint (gr.Handle);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Surface> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_surface_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+
+ public Status Finish ()
+ {
+ NativeMethods.cairo_surface_finish (handle);
+ return Status;
+ }
+
+ public void Flush ()
+ {
+ NativeMethods.cairo_surface_flush (handle);
+ }
+
+ public void MarkDirty ()
+ {
+ NativeMethods.cairo_surface_mark_dirty (Handle);
+ }
+
+ public void MarkDirty (Rectangle rectangle)
+ {
+ NativeMethods.cairo_surface_mark_dirty_rectangle (Handle, (int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height);
+ }
+
+ public IntPtr Handle {
+ get {
+ return handle;
+ }
+ }
+
+ public PointD DeviceOffset {
+ get {
+ double x, y;
+ NativeMethods.cairo_surface_get_device_offset (handle, out x, out y);
+ return new PointD (x, y);
+ }
+
+ set {
+ NativeMethods.cairo_surface_set_device_offset (handle, value.X, value.Y);
+ }
+ }
+
+ [Obsolete ("Use Dispose()")]
+ public void Destroy()
+ {
+ Dispose ();
+ }
+
+ public void SetFallbackResolution (double x, double y)
+ {
+ NativeMethods.cairo_surface_set_fallback_resolution (handle, x, y);
+ }
+
+ public void WriteToPng (string filename)
+ {
+ NativeMethods.cairo_surface_write_to_png (handle, filename);
+ }
+
+ [Obsolete ("Use Handle instead.")]
+ public IntPtr Pointer {
+ get {
+ return handle;
+ }
+ }
+
+ public Status Status {
+ get { return NativeMethods.cairo_surface_status (handle); }
+ }
+
+ public Content Content {
+ get { return NativeMethods.cairo_surface_get_content (handle); }
+ }
+
+ public SurfaceType SurfaceType {
+ get { return NativeMethods.cairo_surface_get_type (handle); }
+ }
+
+ public uint ReferenceCount {
+ get { return NativeMethods.cairo_surface_get_reference_count (handle); }
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Pattern.cs
+//
+// Author: Jordi Mas (jordi@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+// (C) Ximian Inc, 2004.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class SurfacePattern : Pattern
+ {
+ internal SurfacePattern (IntPtr handle, bool owned) : base (handle, owned)
+ {
+ }
+
+ public SurfacePattern (Surface surface)
+ : base (NativeMethods.cairo_pattern_create_for_surface (surface.Handle), true)
+ {
+ }
+
+ //no idea why this is here, the base one is identical, but we can't remove it now
+ public new Extend Extend {
+ set { NativeMethods.cairo_pattern_set_extend (Handle, value); }
+ get { return NativeMethods.cairo_pattern_get_extend (Handle); }
+ }
+
+ public Filter Filter {
+ set { NativeMethods.cairo_pattern_set_filter (Handle, value); }
+ get { return NativeMethods.cairo_pattern_get_filter (Handle); }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.SurfaceType.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ [Serializable]
+ public enum SurfaceType
+ {
+ Image,
+ Pdf,
+ PS,
+ Xlib,
+ Xcb,
+ Glitz,
+ Quartz,
+ Win32,
+ BeOS,
+ DirectFB,
+ Svg,
+ OS2,
+ Win32Printing,
+ QuartzImage,
+ Script,
+ Qt,
+ Recording,
+ VG,
+ GL,
+ Drm,
+ Tee,
+ Xml,
+ Skia,
+ SubSurface
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.SvgSurface.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class SvgSurface : Surface
+ {
+ internal SvgSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public SvgSurface (string filename, double width, double height)
+ : base (NativeMethods.cairo_svg_surface_create (filename, width, height), true)
+ {
+ }
+
+ public void RestrictToVersion (SvgVersion version)
+ {
+ NativeMethods.cairo_svg_surface_restrict_to_version (Handle, version);
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.SvgVersion.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ [Serializable]
+ public enum SvgVersion
+ {
+ // FIXME: yuck
+ OnePointOne = 0,
+ OnePointTwo,
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.TextExtents.cs
+//
+// Authors:
+// Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cairo
+{
+ [StructLayout (LayoutKind.Sequential)]
+ public struct TextExtents
+ {
+ double xbearing;
+ double ybearing;
+ double width;
+ double height;
+ double xadvance;
+ double yadvance;
+
+ public double XBearing {
+ get { return xbearing; }
+ set { xbearing = value; }
+ }
+
+ public double YBearing {
+ get { return ybearing; }
+ set { ybearing = value; }
+ }
+
+ public double Width {
+ get { return width; }
+ set { width = value; }
+ }
+
+ public double Height {
+ get { return height; }
+ set { height = value; }
+ }
+
+ public double XAdvance {
+ get { return xadvance; }
+ set { xadvance = value; }
+ }
+
+ public double YAdvance {
+ get { return yadvance; }
+ set { yadvance = value; }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj is TextExtents)
+ return this == (TextExtents)obj;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int)XBearing ^ (int)YBearing ^ (int)Width ^ (int)Height ^ (int)XAdvance ^ (int)YAdvance;
+ }
+
+ public static bool operator == (TextExtents extents, TextExtents other)
+ {
+ return extents.XBearing == other.XBearing && extents.YBearing == other.YBearing && extents.Width == other.Width && extents.Height == other.Height && extents.XAdvance == other.XAdvance && extents.YAdvance == other.YAdvance;
+ }
+
+ public static bool operator != (TextExtents extents, TextExtents other)
+ {
+ return !(extents == other);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.Device.cs
+//
+// Authors:
+// JP Bruyère (jp_bruyere@hotmail.com)
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2016 JP Bruyère
+//
+// 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.
+//
+using System;
+
+namespace Cairo
+{
+ public class WGLDevice : Device
+ {
+ public WGLDevice (IntPtr hglrc) : base (NativeMethods.cairo_wgl_device_create (hglrc), true)
+ {
+ }
+
+ public IntPtr Context {
+ get { return NativeMethods.cairo_wgl_device_get_context (Handle); }
+ }
+ }
+}
+
--- /dev/null
+//
+// Mono.Cairo.Win32Surface.cs
+//
+// Authors:
+// John Luke
+//
+// (C) John Luke, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class Win32Surface : Surface
+ {
+ internal Win32Surface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public Win32Surface (IntPtr hdc)
+ : base (NativeMethods.cairo_win32_surface_create (hdc), true)
+ {
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.XcbSurface.cs
+//
+// Authors:
+// Alp Toker
+//
+// (C) Alp Toker, 2006.
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+ public class XcbSurface : Surface
+ {
+ internal XcbSurface (IntPtr handle, bool owns) : base (handle, owns)
+ {
+ }
+
+ public XcbSurface (IntPtr connection, uint drawable, IntPtr visual, int width, int height)
+ : base (NativeMethods.cairo_xcb_surface_create (connection, drawable, visual, width, height), true)
+ {
+ }
+
+ public static XcbSurface FromBitmap (IntPtr connection, uint bitmap, IntPtr screen, int width, int height)
+ {
+ IntPtr ptr = NativeMethods.cairo_xcb_surface_create_for_bitmap (connection, bitmap, screen, width, height);
+ return new XcbSurface (ptr, true);
+ }
+
+ public void SetSize (int width, int height)
+ {
+ NativeMethods.cairo_xcb_surface_set_size (Handle, width, height);
+ }
+ }
+}
--- /dev/null
+//
+// Mono.Cairo.XlibSurface.cs
+//
+// Authors:
+// Duncan Mak
+// Miguel de Icaza.
+//
+// (C) Ximian Inc, 2003.
+// (C) Novell, Inc. 2003.
+//
+// This is an OO wrapper API for the Cairo API
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+
+namespace Cairo {
+
+ public class XlibSurface : Surface
+ {
+ public XlibSurface (IntPtr display, IntPtr drawable, IntPtr visual, int width, int height)
+ : base (NativeMethods.cairo_xlib_surface_create (display, drawable, visual, width, height), true)
+ {
+ }
+
+ public XlibSurface (IntPtr ptr, bool own) : base (ptr, own)
+ {
+ }
+
+ public static XlibSurface FromBitmap (IntPtr display, IntPtr bitmap, IntPtr screen, int width, int height)
+ {
+ IntPtr ptr = NativeMethods.cairo_xlib_surface_create_for_bitmap (display, bitmap, screen, width, height);
+ return new XlibSurface(ptr, true);
+ }
+
+ public void SetDrawable (IntPtr drawable, int width, int height)
+ {
+ NativeMethods.cairo_xlib_surface_set_drawable (Handle, drawable, width, height);
+ }
+
+ public void SetSize (int width, int height)
+ {
+ NativeMethods.cairo_xlib_surface_set_size (Handle, width, height);
+ }
+
+ public int Depth {
+ get { return NativeMethods.cairo_xlib_surface_get_depth (Handle); }
+ }
+
+ public IntPtr Display {
+ get { return NativeMethods.cairo_xlib_surface_get_display (Handle); }
+ }
+
+ public IntPtr Drawable {
+ get { return NativeMethods.cairo_xlib_surface_get_drawable (Handle); }
+ }
+
+ public int Height {
+ get { return NativeMethods.cairo_xlib_surface_get_height (Handle); }
+ }
+
+ public IntPtr Screen {
+ get { return NativeMethods.cairo_xlib_surface_get_screen (Handle); }
+ }
+
+ public IntPtr Visual {
+ get { return NativeMethods.cairo_xlib_surface_get_visual (Handle); }
+ }
+
+ public int Width {
+ get { return NativeMethods.cairo_xlib_surface_get_width (Handle); }
+ }
+
+ }
+}
--- /dev/null
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2010 the Open Toolkit library.
+//
+// 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.Text;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.Reflection;
+
+namespace OpenTK
+{
+ #region BlittableValueType<T>
+
+ /// <summary>
+ /// Checks whether the specified type parameter is a blittable value type.
+ /// </summary>
+ /// <remarks>
+ /// A blittable value type is a struct that only references other value types recursively,
+ /// which allows it to be passed to unmanaged code directly.
+ /// </remarks>
+ public static class BlittableValueType<T>
+ {
+ #region Fields
+
+ static readonly Type Type;
+ static readonly int stride;
+
+ #endregion
+
+ #region Constructors
+
+ static BlittableValueType()
+ {
+ Type = typeof(T);
+ if (Type.IsValueType && !Type.IsGenericType)
+ {
+ // Does this support generic types? On Mono 2.4.3 it does
+ // On .Net it doesn't.
+ // http://msdn.microsoft.com/en-us/library/5s4920fa.aspx
+ stride = Marshal.SizeOf(typeof(T));
+ }
+ }
+
+ #endregion
+
+ #region Public Members
+
+ /// <summary>
+ /// Gets the size of the type in bytes or 0 for non-blittable types.
+ /// </summary>
+ /// <remarks>
+ /// This property returns 0 for non-blittable types.
+ /// </remarks>
+ public static int Stride { get { return stride; } }
+
+ #region Check
+
+ /// <summary>
+ /// Checks whether the current typename T is blittable.
+ /// </summary>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ public static bool Check()
+ {
+ return Check(Type);
+ }
+
+ /// <summary>
+ /// Checks whether type is a blittable value type.
+ /// </summary>
+ /// <param name="type">A System.Type to check.</param>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ public static bool Check(Type type)
+ {
+ if (!CheckStructLayoutAttribute(type))
+ Debug.Print("Warning: type {0} does not specify a StructLayoutAttribute with Pack=1. The memory layout of the struct may change between platforms.", type.Name);
+
+ return CheckType(type);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Private Members
+
+ // Checks whether the parameter is a primitive type or consists of primitive types recursively.
+ // Throws a NotSupportedException if it is not.
+ static bool CheckType(Type type)
+ {
+ //Debug.Print("Checking type {0} (size: {1} bytes).", type.Name, Marshal.SizeOf(type));
+ if (type.IsPrimitive)
+ return true;
+
+ if (!type.IsValueType)
+ return false;
+
+ FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ Debug.Indent();
+ foreach (FieldInfo field in fields)
+ {
+ if (!CheckType(field.FieldType))
+ return false;
+ }
+ Debug.Unindent();
+
+ return Stride != 0;
+ }
+
+ // Checks whether the specified struct defines [StructLayout(LayoutKind.Sequential, Pack=1)]
+ // or [StructLayout(LayoutKind.Explicit)]
+ static bool CheckStructLayoutAttribute(Type type)
+ {
+ StructLayoutAttribute[] attr = (StructLayoutAttribute[])
+ type.GetCustomAttributes(typeof(StructLayoutAttribute), true);
+
+ if ((attr == null) ||
+ (attr != null && attr.Length > 0 && attr[0].Value != LayoutKind.Explicit && attr[0].Pack != 1))
+ return false;
+
+ return true;
+ }
+
+ #endregion
+ }
+
+ #endregion
+
+ #region BlittableValueType
+
+ /// <summary>
+ /// Checks whether the specified type parameter is a blittable value type.
+ /// </summary>
+ /// <remarks>
+ /// A blittable value type is a struct that only references other value types recursively,
+ /// which allows it to be passed to unmanaged code directly.
+ /// </remarks>
+ public static class BlittableValueType
+ {
+ #region Check
+
+ /// <summary>
+ /// Checks whether type is a blittable value type.
+ /// </summary>
+ /// <param name="type">An instance of the type to check.</param>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ public static bool Check<T>(T type)
+ {
+ return BlittableValueType<T>.Check();
+ }
+
+ /// <summary>
+ /// Checks whether type is a blittable value type.
+ /// </summary>
+ /// <param name="type">An instance of the type to check.</param>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ [CLSCompliant(false)]
+ public static bool Check<T>(T[] type)
+ {
+ return BlittableValueType<T>.Check();
+ }
+
+ /// <summary>
+ /// Checks whether type is a blittable value type.
+ /// </summary>
+ /// <param name="type">An instance of the type to check.</param>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ [CLSCompliant(false)]
+ public static bool Check<T>(T[,] type)
+ {
+ return BlittableValueType<T>.Check();
+ }
+
+ /// <summary>
+ /// Checks whether type is a blittable value type.
+ /// </summary>
+ /// <param name="type">An instance of the type to check.</param>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ [CLSCompliant(false)]
+ public static bool Check<T>(T[, ,] type)
+ {
+ return BlittableValueType<T>.Check();
+ }
+
+ /// <summary>
+ /// Checks whether type is a blittable value type.
+ /// </summary>
+ /// <param name="type">An instance of the type to check.</param>
+ /// <returns>True if T is blittable; false otherwise.</returns>
+ [CLSCompliant(false)]
+ public static bool Check<T>(T[][] type)
+ {
+ return BlittableValueType<T>.Check();
+ }
+
+ #endregion
+
+ #region StrideOf
+
+ /// <summary>
+ /// Returns the size of the specified value type in bytes or 0 if the type is not blittable.
+ /// </summary>
+ /// <typeparam name="T">The value type. Must be blittable.</typeparam>
+ /// <param name="type">An instance of the value type.</param>
+ /// <returns>An integer, specifying the size of the type in bytes.</returns>
+ /// <exception cref="System.ArgumentException">Occurs when type is not blittable.</exception>
+ public static int StrideOf<T>(T type)
+ {
+ if (!Check(type))
+ throw new ArgumentException("type");
+
+ return BlittableValueType<T>.Stride;
+ }
+
+ /// <summary>
+ /// Returns the size of a single array element in bytes or 0 if the element is not blittable.
+ /// </summary>
+ /// <typeparam name="T">The value type.</typeparam>
+ /// <param name="type">An instance of the value type.</param>
+ /// <returns>An integer, specifying the size of the type in bytes.</returns>
+ /// <exception cref="System.ArgumentException">Occurs when type is not blittable.</exception>
+ [CLSCompliant(false)]
+ public static int StrideOf<T>(T[] type)
+ {
+ if (!Check(type))
+ throw new ArgumentException("type");
+
+ return BlittableValueType<T>.Stride;
+ }
+
+ /// <summary>
+ /// Returns the size of a single array element in bytes or 0 if the element is not blittable.
+ /// </summary>
+ /// <typeparam name="T">The value type.</typeparam>
+ /// <param name="type">An instance of the value type.</param>
+ /// <returns>An integer, specifying the size of the type in bytes.</returns>
+ /// <exception cref="System.ArgumentException">Occurs when type is not blittable.</exception>
+ [CLSCompliant(false)]
+ public static int StrideOf<T>(T[,] type)
+ {
+ if (!Check(type))
+ throw new ArgumentException("type");
+
+ return BlittableValueType<T>.Stride;
+ }
+
+ /// <summary>
+ /// Returns the size of a single array element in bytes or 0 if the element is not blittable.
+ /// </summary>
+ /// <typeparam name="T">The value type.</typeparam>
+ /// <param name="type">An instance of the value type.</param>
+ /// <returns>An integer, specifying the size of the type in bytes.</returns>
+ /// <exception cref="System.ArgumentException">Occurs when type is not blittable.</exception>
+ [CLSCompliant(false)]
+ public static int StrideOf<T>(T[, ,] type)
+ {
+ if (!Check(type))
+ throw new ArgumentException("type");
+
+ return BlittableValueType<T>.Stride;
+ }
+
+ #endregion
+ }
+
+ #endregion
+}
--- /dev/null
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2010 the Open Toolkit library.
+//
+// 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;
+#if !MINIMAL
+using System.Drawing;
+#endif
+
+namespace OpenTK
+{
+ /// <summary>
+ /// Defines a display device on the underlying system, and provides
+ /// methods to query and change its display parameters.
+ /// </summary>
+ public class DisplayDevice
+ {
+ // TODO: Add properties that describe the 'usable' size of the Display, i.e. the maximized size without the taskbar etc.
+ // TODO: Does not detect changes to primary device.
+
+ #region Fields
+
+ bool primary;
+ Rectangle bounds;
+ DisplayResolution current_resolution = new DisplayResolution();
+ DisplayResolution original_resolution;
+ List<DisplayResolution> available_resolutions = new List<DisplayResolution>();
+ IList<DisplayResolution> available_resolutions_readonly;
+
+ internal object Id; // A platform-specific id for this monitor
+
+ static readonly object display_lock = new object();
+ static DisplayDevice primary_display;
+
+ static Platform.IDisplayDeviceDriver implementation;
+
+ #endregion
+
+ #region Constructors
+
+ static DisplayDevice()
+ {
+ implementation = Platform.Factory.Default.CreateDisplayDeviceDriver();
+ }
+
+ internal DisplayDevice()
+ {
+ available_resolutions_readonly = available_resolutions.AsReadOnly();
+ }
+
+ internal DisplayDevice(DisplayResolution currentResolution, bool primary,
+ IEnumerable<DisplayResolution> availableResolutions, Rectangle bounds,
+ object id)
+ : this()
+ {
+ // Todo: Consolidate current resolution with bounds? Can they fall out of sync right now?
+ this.current_resolution = currentResolution;
+ IsPrimary = primary;
+ this.available_resolutions.AddRange(availableResolutions);
+ #pragma warning disable 612,618
+ this.bounds = bounds == Rectangle.Empty ? currentResolution.Bounds : bounds;
+ #pragma warning restore 612,618
+ this.Id = id;
+ }
+
+ #endregion
+
+ #region --- Public Methods ---
+
+ #region public Rectangle Bounds
+
+ /// <summary>
+ /// Gets the bounds of this instance in pixel coordinates..
+ /// </summary>
+ public Rectangle Bounds
+ {
+ get { return bounds; }
+ internal set
+ {
+ bounds = value;
+ current_resolution.Height = bounds.Height;
+ current_resolution.Width = bounds.Width;
+ }
+ }
+
+ #endregion
+
+ #region public int Width
+
+ /// <summary>Gets a System.Int32 that contains the width of this display in pixels.</summary>
+ public int Width { get { return current_resolution.Width; } }
+
+ #endregion
+
+ #region public int Height
+
+ /// <summary>Gets a System.Int32 that contains the height of this display in pixels.</summary>
+ public int Height { get { return current_resolution.Height; } }
+
+ #endregion
+
+ #region public int BitsPerPixel
+
+ /// <summary>Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32.</summary>
+ public int BitsPerPixel
+ {
+ get { return current_resolution.BitsPerPixel; }
+ internal set { current_resolution.BitsPerPixel = value; }
+ }
+
+ #endregion
+
+ #region public float RefreshRate
+
+ /// <summary>
+ /// Gets a System.Single representing the vertical refresh rate of this display.
+ /// </summary>
+ public float RefreshRate
+ {
+ get { return current_resolution.RefreshRate; }
+ internal set { current_resolution.RefreshRate = value; }
+ }
+
+ #endregion
+
+ #region public bool IsPrimary
+
+ /// <summary>Gets a System.Boolean that indicates whether this Display is the primary Display in systems with multiple Displays.</summary>
+ public bool IsPrimary
+ {
+ get { return primary; }
+ internal set
+ {
+ if (value && primary_display != null && primary_display != this)
+ primary_display.IsPrimary = false;
+
+ lock (display_lock)
+ {
+ primary = value;
+ if (value)
+ primary_display = this;
+ }
+ }
+ }
+
+ #endregion
+
+ #region public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
+
+ /// <summary>
+ /// Selects an available resolution that matches the specified parameters.
+ /// </summary>
+ /// <param name="width">The width of the requested resolution in pixels.</param>
+ /// <param name="height">The height of the requested resolution in pixels.</param>
+ /// <param name="bitsPerPixel">The bits per pixel of the requested resolution.</param>
+ /// <param name="refreshRate">The refresh rate of the requested resolution in hertz.</param>
+ /// <returns>The requested DisplayResolution or null if the parameters cannot be met.</returns>
+ /// <remarks>
+ /// <para>If a matching resolution is not found, this function will retry ignoring the specified refresh rate,
+ /// bits per pixel and resolution, in this order. If a matching resolution still doesn't exist, this function will
+ /// return the current resolution.</para>
+ /// <para>A parameter set to 0 or negative numbers will not be used in the search (e.g. if refreshRate is 0,
+ /// any refresh rate will be considered valid).</para>
+ /// <para>This function allocates memory.</para>
+ /// </remarks>
+ public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ {
+ DisplayResolution resolution = FindResolution(width, height, bitsPerPixel, refreshRate);
+ if (resolution == null)
+ resolution = FindResolution(width, height, bitsPerPixel, 0);
+ if (resolution == null)
+ resolution = FindResolution(width, height, 0, 0);
+ if (resolution == null)
+ return current_resolution;
+ return resolution;
+ }
+
+ #endregion
+
+ #region public IList<DisplayResolution> AvailableResolutions
+
+ /// <summary>
+ /// Gets the list of <see cref="DisplayResolution"/> objects available on this device.
+ /// </summary>
+ public IList<DisplayResolution> AvailableResolutions
+ {
+ get { return available_resolutions_readonly; }
+ internal set
+ {
+ available_resolutions = (List<DisplayResolution>)value;
+ available_resolutions_readonly = available_resolutions.AsReadOnly();
+ }
+ }
+
+ #endregion
+
+ #region public void ChangeResolution(DisplayResolution resolution)
+
+ /// <summary>Changes the resolution of the DisplayDevice.</summary>
+ /// <param name="resolution">The resolution to set. <see cref="DisplayDevice.SelectResolution"/></param>
+ /// <exception cref="Graphics.GraphicsModeException">Thrown if the requested resolution could not be set.</exception>
+ /// <remarks>If the specified resolution is null, this function will restore the original DisplayResolution.</remarks>
+ public void ChangeResolution(DisplayResolution resolution)
+ {
+ if (resolution == null)
+ this.RestoreResolution();
+
+ if (resolution == current_resolution)
+ return;
+
+ //effect.FadeOut();
+
+ if (implementation.TryChangeResolution(this, resolution))
+ {
+ if (original_resolution == null)
+ original_resolution = current_resolution;
+ current_resolution = resolution;
+ }
+ else throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to change resolution to {1}.",
+ this, resolution));
+
+ //effect.FadeIn();
+ }
+
+ #endregion
+
+ #region public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
+
+ /// <summary>Changes the resolution of the DisplayDevice.</summary>
+ /// <param name="width">The new width of the DisplayDevice.</param>
+ /// <param name="height">The new height of the DisplayDevice.</param>
+ /// <param name="bitsPerPixel">The new bits per pixel of the DisplayDevice.</param>
+ /// <param name="refreshRate">The new refresh rate of the DisplayDevice.</param>
+ /// <exception cref="Graphics.GraphicsModeException">Thrown if the requested resolution could not be set.</exception>
+ public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ {
+ this.ChangeResolution(this.SelectResolution(width, height, bitsPerPixel, refreshRate));
+ }
+
+ #endregion
+
+ #region public void RestoreResolution()
+
+ /// <summary>Restores the original resolution of the DisplayDevice.</summary>
+ /// <exception cref="Graphics.GraphicsModeException">Thrown if the original resolution could not be restored.</exception>
+ public void RestoreResolution()
+ {
+ if (original_resolution != null)
+ {
+ //effect.FadeOut();
+
+ if (implementation.TryRestoreResolution(this))
+ {
+ current_resolution = original_resolution;
+ original_resolution = null;
+ }
+ else throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to restore resolution.", this));
+
+ //effect.FadeIn();
+ }
+ }
+
+ #endregion
+
+ #region public static IList<DisplayDevice> AvailableDisplays
+
+ /// <summary>
+ /// Gets the list of available <see cref="DisplayDevice"/> objects.
+ /// This function allocates memory.
+ /// </summary>
+ [Obsolete("Use GetDisplay(DisplayIndex) instead.")]
+ public static IList<DisplayDevice> AvailableDisplays
+ {
+ get
+ {
+ List<DisplayDevice> displays = new List<DisplayDevice>();
+ for (int i = 0; i < 6; i++)
+ {
+ DisplayDevice dev = GetDisplay(DisplayIndex.First + i);
+ if (dev != null)
+ displays.Add(dev);
+ }
+
+ return displays.AsReadOnly();
+ }
+ }
+
+ #endregion
+
+ #region public static DisplayDevice Default
+
+ /// <summary>Gets the default (primary) display of this system.</summary>
+ public static DisplayDevice Default
+ {
+ get { return implementation.GetDisplay(DisplayIndex.Primary); }
+ }
+
+ #endregion
+
+ #region GetDisplay
+
+ /// <summary>
+ /// Gets the <see cref="DisplayDevice"/> for the specified <see cref="DisplayIndex"/>.
+ /// </summary>
+ /// <param name="index">The <see cref="DisplayIndex"/> that defines the desired display.</param>
+ /// <returns>A <see cref="DisplayDevice"/> or null, if no device corresponds to the specified index.</returns>
+ public static DisplayDevice GetDisplay(DisplayIndex index)
+ {
+ return implementation.GetDisplay(index);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region --- Internal Methods ---
+
+ #region internal DisplayResolution OriginalResolution
+
+ /// <summary>
+ /// Gets the original resolution of this instance.
+ /// </summary>
+ internal DisplayResolution OriginalResolution
+ {
+ get { return original_resolution; }
+ set { original_resolution = value; }
+ }
+
+ #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 ---
+
+ #region DisplayResolution FindResolution(int width, int height, int bitsPerPixel, float refreshRate)
+
+ DisplayResolution FindResolution(int width, int height, int bitsPerPixel, float refreshRate)
+ {
+ return available_resolutions.Find(delegate(DisplayResolution test)
+ {
+ return
+ ((width > 0 && width == test.Width) || width == 0) &&
+ ((height > 0 && height == test.Height) || height == 0) &&
+ ((bitsPerPixel > 0 && bitsPerPixel == test.BitsPerPixel) || bitsPerPixel == 0) &&
+ ((refreshRate > 0 && System.Math.Abs(refreshRate - test.RefreshRate) < 1.0) || refreshRate == 0);
+ });
+ }
+
+ #endregion
+
+ #endregion
+
+ #region --- Overrides ---
+
+ #region public override string ToString()
+
+ /// <summary>
+ /// Returns a System.String representing this DisplayDevice.
+ /// </summary>
+ /// <returns>A System.String representing this DisplayDevice.</returns>
+ public override string ToString()
+ {
+ return String.Format("{0}: {1} ({2} modes available)", IsPrimary ? "Primary" : "Secondary",
+ Bounds.ToString(), available_resolutions.Count);
+ }
+
+ #endregion
+
+ #region public override bool Equals(object obj)
+
+ ///// <summary>Determines whether the specified DisplayDevices are equal.</summary>
+ ///// <param name="obj">The System.Object to check against.</param>
+ ///// <returns>True if the System.Object is an equal DisplayDevice; false otherwise.</returns>
+ //public override bool Equals(object obj)
+ //{
+ // if (obj is DisplayDevice)
+ // {
+ // DisplayDevice dev = (DisplayDevice)obj;
+ // return
+ // IsPrimary == dev.IsPrimary &&
+ // current_resolution == dev.current_resolution &&
+ // available_resolutions.Count == dev.available_resolutions.Count;
+ // }
+
+ // return false;
+ //}
+
+ #endregion
+
+ #region public override int GetHashCode()
+
+ ///// <summary>Returns a unique hash representing this DisplayDevice.</summary>
+ ///// <returns>A System.Int32 that may serve as a hash code for this DisplayDevice.</returns>
+ ////public override int GetHashCode()
+ //{
+ // return current_resolution.GetHashCode() ^ IsPrimary.GetHashCode() ^ available_resolutions.Count;
+ //}
+
+ #endregion
+
+ #endregion
+ }
+
+ #region --- FadeEffect ---
+#if false
+ class FadeEffect : IDisposable
+ {
+ List<Form> forms = new List<Form>();
+ double opacity_step = 0.04;
+ int sleep_step;
+
+ internal FadeEffect()
+ {
+ foreach (Screen s in Screen.AllScreens)
+ {
+ Form form = new Form();
+ form.ShowInTaskbar = false;
+ form.StartPosition = FormStartPosition.Manual;
+ form.WindowState = FormWindowState.Maximized;
+ form.FormBorderStyle = FormBorderStyle.None;
+ form.TopMost = true;
+
+ form.BackColor = System.Drawing.Color.Black;
+ forms.Add(form);
+ }
+
+ sleep_step = 10 / forms.Count;
+ MoveToStartPositions();
+ }
+
+ void MoveToStartPositions()
+ {
+ int count = 0;
+ foreach (Screen s in Screen.AllScreens)
+ {
+ // forms[count++].Location = new System.Drawing.Point(s.Bounds.X, s.Bounds.Y);
+ //forms[count].Size = new System.Drawing.Size(4096, 4096);
+ count++;
+ }
+ }
+
+ bool FadedOut
+ {
+ get
+ {
+ bool ready = true;
+ foreach (Form form in forms)
+ ready = ready && form.Opacity >= 1.0;
+
+ return ready;
+ }
+ }
+
+ bool FadedIn
+ {
+ get
+ {
+ bool ready = true;
+ foreach (Form form in forms)
+ ready = ready && form.Opacity <= 0.0;
+
+ return ready;
+ }
+ }
+
+ internal void FadeOut()
+ {
+ MoveToStartPositions();
+
+ foreach (Form form in forms)
+ {
+ form.Opacity = 0.0;
+ form.Visible = true;
+ }
+
+ while (!FadedOut)
+ {
+ foreach (Form form in forms)
+ {
+ form.Opacity += opacity_step;
+ form.Refresh();
+ }
+ Thread.Sleep(sleep_step);
+ }
+ }
+
+ internal void FadeIn()
+ {
+ MoveToStartPositions();
+
+ foreach (Form form in forms)
+ form.Opacity = 1.0;
+
+ while (!FadedIn)
+ {
+ foreach (Form form in forms)
+ {
+ form.Opacity -= opacity_step;
+ form.Refresh();
+ }
+ Thread.Sleep(sleep_step);
+ }
+
+ foreach (Form form in forms)
+ form.Visible = false;
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ foreach (Form form in forms)
+ form.Dispose();
+ }
+
+ #endregion
+ }
+#endif
+ #endregion
+}
--- /dev/null
+#region --- License ---
+/* Licensed under the MIT/X11 license.
+ * Copyright (c) 2006-2008 the OpenTK team.
+ * This notice may not be removed.
+ * See license.txt for licensing detailed licensing details.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+#if !MINIMAL
+using System.Drawing;
+#endif
+
+namespace OpenTK
+{
+ /// <summary>Contains information regarding a monitor's display resolution.</summary>
+ public class DisplayResolution
+ {
+ Rectangle bounds;
+ int bits_per_pixel;
+ float refresh_rate;
+
+ #region --- Constructors ---
+
+ internal DisplayResolution() { }
+
+ #region public DisplayResolution(int width, int height, int bitsPerPixel, float refreshRate)
+
+ // Creates a new DisplayResolution object for the primary DisplayDevice.
+ internal DisplayResolution(int x, int y, int width, int height, int bitsPerPixel, float refreshRate)
+ {
+ // Refresh rate may be zero, since this information may not be available on some platforms.
+ if (width <= 0) throw new ArgumentOutOfRangeException("width", "Must be greater than zero.");
+ if (height <= 0) throw new ArgumentOutOfRangeException("height", "Must be greater than zero.");
+ if (bitsPerPixel <= 0) throw new ArgumentOutOfRangeException("bitsPerPixel", "Must be greater than zero.");
+ if (refreshRate < 0) throw new ArgumentOutOfRangeException("refreshRate", "Must be greater than, or equal to zero.");
+
+ this.bounds = new Rectangle(x, y, width, height);
+ this.bits_per_pixel = bitsPerPixel;
+ this.refresh_rate = refreshRate;
+ }
+
+ #endregion
+
+ #region public DisplayResolution(int width, int height, int bitsPerPixel, float refreshRate, DisplayDevice device)
+
+#if false
+
+ /// <summary>
+ /// Creates a new DisplayResolution object for the specified DisplayDevice.
+ /// </summary>
+ /// <param name="width">The requested width in pixels.</param>
+ /// <param name="height">The requested height in pixels.</param>
+ /// <param name="bitsPerPixel">The requested bits per pixel in bits.</param>
+ /// <param name="refreshRate">The requested refresh rate in hertz.</param>
+ /// <remarks>OpenTK will select the closest match between all available resolutions on the specified DisplayDevice.</remarks>
+ ///
+ public DisplayResolution(int width, int height, int bitsPerPixel, float refreshRate, DisplayDevice device)
+ {
+ // Refresh rate may be zero, since this information may not be available on some platforms.
+ if (width <= 0) throw new ArgumentOutOfRangeException("width", "Must be greater than zero.");
+ if (height <= 0) throw new ArgumentOutOfRangeException("height", "Must be greater than zero.");
+ if (bitsPerPixel <= 0) throw new ArgumentOutOfRangeException("bitsPerPixel", "Must be greater than zero.");
+ if (refreshRate < 0) throw new ArgumentOutOfRangeException("refreshRate", "Must be greater than, or equal to zero.");
+ if (device == null) throw new ArgumentNullException("DisplayDevice", "Must be a valid DisplayDevice");
+
+ DisplayResolution res = device.SelectResolution(width, height, bitsPerPixel, refreshRate);
+
+ this.width = res.width;
+ this.height = res.height;
+ this.bits_per_pixel = res.bits_per_pixel;
+ this.refresh_rate = res.refresh_rate;
+ }
+#endif
+ #endregion
+
+ #endregion
+
+ #region --- Public Methods ---
+
+ #region Bounds
+
+ /// <summary>
+ /// Gets a System.Drawing.Rectangle that contains the bounds of this display device.
+ /// </summary>
+ [Obsolete("This property will return invalid results if a monitor changes resolution. Use DisplayDevice.Bounds instead.")]
+ [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+ public Rectangle Bounds
+ {
+ get { return bounds; }
+ }
+
+ #endregion
+
+ #region public int Width
+
+ /// <summary>Gets a System.Int32 that contains the width of this display in pixels.</summary>
+ public int Width
+ {
+ get { return bounds.Width; }
+ internal set { bounds.Width = value; }
+ }
+
+ #endregion
+
+ #region public int Height
+
+ /// <summary>Gets a System.Int32 that contains the height of this display in pixels.</summary>
+ public int Height
+ {
+ get { return bounds.Height; }
+ internal set { bounds.Height = value; }
+ }
+
+ #endregion
+
+ #region public int BitsPerPixel
+
+ /// <summary>Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32.</summary>
+ public int BitsPerPixel
+ {
+ get { return bits_per_pixel; }
+ internal set { bits_per_pixel = value; }
+ }
+
+ #endregion
+
+ #region public float RefreshRate
+
+ /// <summary>
+ /// Gets a System.Single representing the vertical refresh rate of this display.
+ /// </summary>
+ public float RefreshRate
+ {
+ get { return refresh_rate; }
+ internal set { refresh_rate = value; }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region --- Overrides ---
+
+ #region public override string ToString()
+
+ /// <summary>
+ /// Returns a System.String representing this DisplayResolution.
+ /// </summary>
+ /// <returns>A System.String representing this DisplayResolution.</returns>
+ public override string ToString()
+ {
+ #pragma warning disable 612,618
+ return String.Format("{0}x{1}@{2}Hz", Bounds, bits_per_pixel, refresh_rate);
+ #pragma warning restore 612,618
+ }
+
+ #endregion
+
+ #region public override bool Equals(object obj)
+
+ /// <summary>Determines whether the specified resolutions are equal.</summary>
+ /// <param name="obj">The System.Object to check against.</param>
+ /// <returns>True if the System.Object is an equal DisplayResolution; false otherwise.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj == null) return false;
+ if (this.GetType() == obj.GetType())
+ {
+ DisplayResolution res = (DisplayResolution)obj;
+ return
+ Width == res.Width &&
+ Height == res.Height &&
+ BitsPerPixel == res.BitsPerPixel &&
+ RefreshRate == res.RefreshRate;
+ }
+
+ return false;
+ }
+
+ #endregion
+
+ #region public override int GetHashCode()
+
+ /// <summary>Returns a unique hash representing this resolution.</summary>
+ /// <returns>A System.Int32 that may serve as a hash code for this resolution.</returns>
+ public override int GetHashCode()
+ {
+ #pragma warning disable 612,618
+ return Bounds.GetHashCode() ^ bits_per_pixel ^ refresh_rate.GetHashCode();
+ #pragma warning restore 612,618
+ }
+
+ #endregion
+
+ #endregion
+
+ #region --- Operator Overloads ---
+
+ /// <summary>
+ /// Compares two instances for equality.
+ /// </summary>
+ /// <param name="left">The first instance.</param>
+ /// <param name="right">The second instance.</param>
+ /// <returns>True, if left equals right; false otherwise.</returns>
+ public static bool operator== (DisplayResolution left, DisplayResolution right)
+ {
+ if (((object)left) == null && ((object)right) == null)
+ return true;
+ else if ((((object)left) == null && ((object)right) != null) ||
+ (((object)left) != null && ((object)right) == null))
+ return false;
+ return left.Equals(right);
+ }
+
+ /// <summary>
+ /// Compares two instances for inequality.
+ /// </summary>
+ /// <param name="left">The first instance.</param>
+ /// <param name="right">The second instance.</param>
+ /// <returns>True, if left does not equal right; false otherwise.</returns>
+ public static bool operator !=(DisplayResolution left, DisplayResolution right)
+ {
+ return !(left == right);
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+//
+// DrmKms.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// 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.
+using System;
+using OpenTK.Platform.Linux;
+using OpenTK;
+using System.IO;
+using System.Collections.Generic;
+using System.Diagnostics;
+using OpenTK.Platform.Egl;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace testDrm
+{
+ public class DrmDevice : IDisposable
+ {
+ volatile bool run = true;
+
+ int fd = 0;
+ int major, minor;
+ IntPtr gbm_device, gbm_surface, egl_display, egl_config, egl_surface, egl_ctx;
+
+ int r, g, b, a;
+
+ BufferObject cursor_custom;
+ BufferObject cursor_default;
+ BufferObject cursor_empty;
+
+
+ ModeInfo originalMode;
+
+ public IntPtr Connector;
+ public IntPtr Crtc;
+ public IntPtr Encoder;
+ unsafe ModeConnector* pConnector { get { return (ModeConnector*)Connector; } }
+ unsafe ModeCrtc* pCrtc { get { return (ModeCrtc*)Crtc; } }
+ unsafe ModeEncoder* pEncoder { get { return (ModeEncoder*)Encoder; } }
+
+ Cairo.EGLDevice cairoDev;
+ Cairo.GLSurface cairoSurf;
+
+ public DrmDevice(string gpu_path = "/dev/dri/card0"){
+
+ PageFlip = HandlePageFlip;
+ PageFlipPtr = Marshal.GetFunctionPointerForDelegate(PageFlip);
+
+ gbm_device = IntPtr.Zero;
+ egl_display = IntPtr.Zero;
+
+ fd = Libc.open(gpu_path, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
+ if (fd < 0)
+ throw new NotSupportedException("[KMS] Failed to open gpu");
+ Console.WriteLine("[KMS] GPU '{0}' opened as fd:{1}", gpu_path, fd);
+
+ initDrm ();
+
+ initGbm ();
+
+ initEgl ();
+
+ initCairo ();
+
+ initInput ();
+ }
+
+ #region init
+ unsafe void initDrm(){
+ ModeRes* resources = (ModeRes*)Drm.ModeGetResources(fd);
+ if (resources == null)
+ throw new NotSupportedException("[KMS] Drm.ModeGetResources failed.");
+
+ 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_encoders > 0)
+ break;
+ Drm.ModeFreeConnector ((IntPtr)connector);
+ connector = null;
+ }
+ }
+ if (connector == null)
+ throw new NotSupportedException("[KMS] No connected screen found");
+
+ Connector = (IntPtr)connector;
+ Encoder = Drm.ModeGetEncoder (fd, connector->encoder_id);
+ Crtc = Drm.ModeGetCrtc(fd, pEncoder->crtc_id);
+
+ originalMode = pCrtc->mode;
+ Console.WriteLine ("[DRM]: current mode = {0} X {1} at {2} Hz", originalMode.hdisplay, originalMode.vdisplay, originalMode.vrefresh);
+ }
+ void initGbm (){
+ gbm_device = Gbm.CreateDevice(fd);
+ if (gbm_device == IntPtr.Zero)
+ throw new NotSupportedException("[GBM] Failed to create GBM device");
+
+ gbm_surface = Gbm.CreateSurface(gbm_device, originalMode.hdisplay, originalMode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Rendering | SurfaceFlags.Scanout);
+ if (gbm_surface == IntPtr.Zero)
+ throw new NotSupportedException("[GBM] Failed to create GBM surface for rendering");
+ }
+
+ unsafe void initEgl () {
+ IntPtr[] configs = new IntPtr[1];
+ int[] contextAttrib = new int[] {
+ Egl.CONTEXT_CLIENT_VERSION, 2,
+ Egl.NONE
+ };
+ int[] attribList = new int[]
+ {
+ Egl.SURFACE_TYPE, Egl.WINDOW_BIT,
+ Egl.RENDERABLE_TYPE, Egl.OPENGL_BIT,
+ Egl.RED_SIZE, 1,
+ Egl.GREEN_SIZE, 1,
+ Egl.BLUE_SIZE, 1,
+ Egl.ALPHA_SIZE, 0,
+
+ //Egl.DEPTH_SIZE, 24,
+ //Egl.STENCIL_SIZE, 0,
+
+ //Egl.SAMPLE_BUFFERS, 2,
+ //Egl.SAMPLES, 0,
+ Egl.NONE
+ };
+ int num_configs;
+
+ egl_display = Egl.GetDisplay(gbm_device);
+ if (egl_display == IntPtr.Zero)
+ throw new NotSupportedException("[KMS] Failed to create EGL display");
+ Console.WriteLine("[EGL] EGL display {0:x} created successfully", egl_display);
+
+ if (!Egl.Initialize(egl_display, out major, out minor))
+ throw new NotSupportedException("[EGL] Failed to initialize EGL display. Error code: " + Egl.GetError());
+
+ if (!Egl.BindAPI (RenderApi.GL))
+ throw new NotSupportedException("[EGL] Failed to bind EGL Api: " + Egl.GetError());
+
+ Console.WriteLine ("[EGL] Version: " + Marshal.PtrToStringAuto (Egl.QueryString (egl_display, Egl.VERSION)));
+ Console.WriteLine ("[EGL] Vendor: " + Marshal.PtrToStringAuto (Egl.QueryString (egl_display, Egl.VENDOR)));
+ Console.WriteLine ("[EGL] Extensions: " + Marshal.PtrToStringAuto (Egl.QueryString (egl_display, Egl.EXTENSIONS)));
+
+ if (!Egl.ChooseConfig(egl_display, attribList, configs, configs.Length, out num_configs) || num_configs == 0)
+ throw new NotSupportedException(String.Format("Failed to retrieve GraphicsMode, error {0}", Egl.GetError()));
+
+
+ // See what we really got
+ int d, s, sample_buffers, samples;
+ IntPtr active_config = configs[0];
+ Egl.GetConfigAttrib(egl_display, active_config, Egl.RED_SIZE, out r);
+ Egl.GetConfigAttrib(egl_display, active_config, Egl.GREEN_SIZE, out g);
+ Egl.GetConfigAttrib(egl_display, active_config, Egl.BLUE_SIZE, out b);
+ Egl.GetConfigAttrib(egl_display, active_config, Egl.ALPHA_SIZE, out a);
+ //Egl.GetConfigAttrib(egl_display, active_config, Egl.DEPTH_SIZE, out d);
+ //Egl.GetConfigAttrib(egl_display, active_config, Egl.STENCIL_SIZE, out s);
+ //Egl.GetConfigAttrib(egl_display, active_config, Egl.SAMPLE_BUFFERS, out sample_buffers);
+ //Egl.GetConfigAttrib(egl_display, active_config, Egl.SAMPLES, out samples);
+// Console.WriteLine ("EGL context: {0},{1},{2},{3} depth={4} stencil={5} samples={6} sample buffers={7}",
+// r, g, b, a, d, s, samples, sample_buffers);
+ egl_config = active_config;
+
+ egl_ctx = Egl.CreateContext(egl_display, egl_config, IntPtr.Zero, contextAttrib);
+
+ egl_surface = Egl.CreateWindowSurface(egl_display, egl_config, gbm_surface, IntPtr.Zero);
+
+ if (egl_surface==IntPtr.Zero)
+ throw new NotSupportedException(String.Format("[EGL] Failed to create window surface, error {0}.", Egl.GetError()));
+
+ if (!Egl.MakeCurrent(egl_display, egl_surface, egl_surface, egl_ctx))
+ throw new NotSupportedException(string.Format("Failed to make context {0} current. Error: {1}", gbm_surface, Egl.GetError()));
+
+ cursor_default = CreateCursor(gbm_device, Cursors.Default);
+ cursor_empty = CreateCursor(gbm_device, Cursors.Empty);
+
+ SetCursor(MouseCursor.Default);
+ unsafe {
+ Drm.MoveCursor (fd, pEncoder->crtc_id, 50, 50);
+ }
+ }
+
+ void initCairo (){
+ cairoDev = new Cairo.EGLDevice (egl_display, egl_ctx);
+
+ cairoSurf = new Cairo.GLSurface (cairoDev, egl_surface, originalMode.hdisplay, originalMode.vdisplay);
+ //cairoSurf = new Cairo.EGLSurface (cairoDev, egl_surface, 1600, 900);
+
+ cairoDev.SetThreadAware (false);
+
+ if (cairoDev.Acquire () != Cairo.Status.Success)
+ Console.WriteLine ("[Cairo]: Failed to acquire egl device.");
+ }
+ #endregion
+
+ #region cursor
+ static BufferObject CreateCursor(IntPtr gbm, MouseCursor cursor)
+ {
+ if (cursor.Width > 64 || cursor.Height > 64)
+ {
+ Debug.Print("[KMS] Cursor size {0}x{1} unsupported. Maximum is 64x64.",
+ cursor.Width, cursor.Height);
+ return default(BufferObject);
+ }
+
+ int width = 64;
+ int height = 64;
+ SurfaceFormat format = SurfaceFormat.ARGB8888;
+ SurfaceFlags usage = SurfaceFlags.Cursor64x64 | SurfaceFlags.Write;
+
+ Debug.Print("[KMS] Gbm.CreateBuffer({0:X}, {1}, {2}, {3}, {4}).",
+ gbm, width, height, format, usage);
+
+ BufferObject bo = Gbm.CreateBuffer(
+ gbm, width, height, format, usage);
+
+ if (bo == BufferObject.Zero)
+ {
+ Debug.Print("[KMS] Failed to create buffer.");
+ return bo;
+ }
+
+ // Copy cursor.Data into a new buffer of the correct size
+ byte[] cursor_data = new byte[width * height * 4];
+ for (int y = 0; y < cursor.Height; y++)
+ {
+ int dst_offset = y * width * 4;
+ int src_offset = y * cursor.Width * 4;
+ int src_length = cursor.Width * 4;
+ Array.Copy(
+ cursor.Data, src_offset,
+ cursor_data, dst_offset,
+ src_length);
+ }
+ bo.Write(cursor_data);
+
+ return bo;
+ }
+ void SetCursor(MouseCursor cursor)
+ {
+ BufferObject bo = default(BufferObject);
+ if (cursor == MouseCursor.Default)
+ {
+ bo = cursor_default;
+ }
+ else if (cursor == MouseCursor.Empty)
+ {
+ bo = cursor_empty;
+ }
+ else
+ {
+ if (cursor_custom != BufferObject.Zero)
+ cursor_custom.Dispose();
+ cursor_custom = CreateCursor(gbm_device, cursor);
+ bo = cursor_custom;
+ }
+
+ // If we failed to create a proper cursor, try falling back
+ // to the empty cursor. We do not want to crash here!
+ if (bo == BufferObject.Zero)
+ {
+ bo = cursor_empty;
+ }
+
+ if (bo != BufferObject.Zero)
+ {
+ unsafe {
+ Drm.SetCursor (fd, pEncoder->crtc_id,
+ bo.Handle, bo.Width, bo.Height, cursor.X, cursor.Y);
+ }
+ }
+ }
+ #endregion
+ int x, y;
+
+ void drawR (Cairo.Context ctx, int inc, double r, double g, double b){
+ ctx.Rectangle (x+inc, y+inc, 200, 200);
+ ctx.SetSourceRGB (r, g, b);
+ ctx.Fill ();
+ }
+ public void RenderingLoop(){
+ while (run){
+ if (updateMousePos) {
+ lock (Sync) {
+ updateMousePos = false;
+ unsafe {
+ Drm.MoveCursor (fd, pEncoder->crtc_id, MouseX, MouseY);
+ }
+ }
+ }
+
+ if (x > 700) {
+ x = y = 0;
+ } else {
+ x+=1;
+ y+=1;
+ }
+ using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) {
+ ctx.Rectangle (0, 0, 1024, 780);
+ ctx.SetSourceRGB (0, 0, 1);
+ ctx.Fill ();
+ drawR (ctx, 0, 0, 1, 0);
+ }
+ cairoSurf.Flush ();
+
+ cairoSurf.SwapBuffers ();
+
+// if (!Egl.SwapBuffers(egl_display, egl_surface))
+// throw new NotSupportedException(string.Format("Failed to swap buffers for context {0} current. Error: {1}", gbm_device, Egl.GetError()));
+
+ if (Gbm.HasFreeBuffers (gbm_surface) == 0)
+ throw new Exception ("[GBM]: Out of free buffers.");
+
+ next_bo = Gbm.LockFrontBuffer (gbm_surface);
+ if (next_bo == BufferObject.Zero)
+ throw new Exception ("[GBM]: Failed to lock front buffer.");
+
+ int width = next_bo.Width;
+ int height = next_bo.Height;
+ int bpp = 32;
+ int depth = 24;
+ int stride = next_bo.Stride;
+ int hndBO = next_bo.Handle;
+
+ int next_fb;
+ int ret = Drm.ModeAddFB (fd, width, height,(byte)depth, (byte)bpp, stride, hndBO, out next_fb);
+ if (ret != 0)
+ throw new Exception ("[DRM]: ModeAddFB failed.");
+
+ SetScanoutRegion (next_fb);
+
+ is_flip_queued = true;
+ unsafe{
+ ret = Drm.ModePageFlip (fd, pEncoder->crtc_id, next_fb, PageFlipFlags.FlipEvent, IntPtr.Zero);
+ }
+ if (ret < 0)
+ throw new Exception ("[DRM] Failed to enqueue framebuffer flip.");
+
+ PollFD fds = new PollFD();
+ fds.fd = fd;
+ fds.events = PollFlags.In;
+
+ EventContext evctx = new EventContext();
+ evctx.version = EventContext.Version;
+ evctx.page_flip_handler = PageFlipPtr;
+
+ int timeout = -1;//block ? -1 : 0;
+
+ while (is_flip_queued)
+ {
+ fds.revents = 0;
+ if (Libc.poll(ref fds, 1, timeout) < 0)
+ break;
+
+ if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0)
+ break;
+
+ if ((fds.revents & PollFlags.In) != 0)
+ Drm.HandleEvent(fd, ref evctx);
+ else
+ break;
+ }
+ }
+ }
+
+ #region rendering
+ BufferObject bo, next_bo;
+ int fb, next_fb;
+ bool is_flip_queued;
+ // We only support a SwapInterval of 0 (immediate)
+ // or 1 (vsynced).
+ // Todo: add support for SwapInterval of -1 (adaptive).
+ // This requires a small change in WaitFlip().
+ int swap_interval=0;
+
+ readonly IntPtr PageFlipPtr;
+ readonly PageFlipCallback PageFlip;
+
+ void HandlePageFlip(int fd, int sequence, int tv_sec, int tv_usec, IntPtr user_data)
+ {
+ is_flip_queued = false;
+ if (fb != 0)
+ Drm.ModeRmFB (fd, fb);
+ fb = next_fb;
+ next_fb = 0;
+ if (bo != BufferObject.Zero)
+ Gbm.ReleaseBuffer (gbm_surface, bo);
+ bo = next_bo;
+ next_bo = BufferObject.Zero;
+ }
+
+ static readonly DestroyUserDataCallback DestroyFB = HandleDestroyFB;
+ static void HandleDestroyFB(BufferObject bo, IntPtr data)
+ {
+ IntPtr gbm = bo.Device;
+ int fb = data.ToInt32();
+ Debug.Print("[KMS] Destroying framebuffer {0}", fb);
+
+ if (fb != 0)
+ Drm.ModeRmFB(Gbm.DeviceGetFD(gbm), fb);
+ }
+
+ public void SwapBuffers()
+ {
+ if (!Egl.SwapBuffers(egl_display, egl_surface))
+ throw new NotSupportedException(string.Format("Failed to swap buffers for context {0} current. Error: {1}", gbm_device, Egl.GetError()));
+
+ if (is_flip_queued)
+ {
+ // Todo: if we don't wait for the page flip,
+ // we drop all rendering buffers and get a crash
+ // in Egl.SwapBuffers(). We need to fix that
+ // before we can disable vsync.
+ WaitFlip(true); // WaitFlip(SwapInterval > 0)
+ if (is_flip_queued)
+ {
+ Debug.Print("[KMS] Dropping frame");
+ return;
+ }
+ }
+
+ next_bo = Gbm.LockFrontBuffer (gbm_surface);
+ int fb = GetFramebuffer(next_bo);
+ QueueFlip(fb);
+ }
+
+ public void Update()
+ {
+ WaitFlip(true);
+
+ if (!Egl.SwapBuffers(egl_display, egl_surface))
+ throw new NotSupportedException(string.Format("Failed to swap buffers for context {0} current. Error: {1}", gbm_device, Egl.GetError()));
+
+ bo = Gbm.LockFrontBuffer (gbm_surface);
+ int fb = GetFramebuffer(bo);
+ SetScanoutRegion(fb);
+ }
+
+
+ void WaitFlip(bool block)
+ {
+ PollFD fds = new PollFD();
+ fds.fd = fd;
+ fds.events = PollFlags.In;
+
+ EventContext evctx = new EventContext();
+ evctx.version = EventContext.Version;
+ evctx.page_flip_handler = PageFlipPtr;
+
+ int timeout = block ? -1 : 0;
+
+ while (is_flip_queued)
+ {
+ fds.revents = 0;
+ if (Libc.poll(ref fds, 1, timeout) < 0)
+ break;
+
+ if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0)
+ break;
+
+ if ((fds.revents & PollFlags.In) != 0)
+ Drm.HandleEvent(fd, ref evctx);
+ else
+ break;
+ }
+
+ // Page flip has taken place, update buffer objects
+ if (!is_flip_queued)
+ {
+ Gbm.ReleaseBuffer(gbm_surface, bo);
+ bo = next_bo;
+ }
+ }
+
+ void QueueFlip(int buffer)
+ {
+ unsafe
+ {
+ int ret = Drm.ModePageFlip (fd, pEncoder->crtc_id, buffer, PageFlipFlags.FlipEvent, IntPtr.Zero);
+ if (ret < 0)
+ Debug.Print("[KMS] Failed to enqueue framebuffer flip. Error: {0}", ret);
+
+ is_flip_queued = true;
+ }
+ }
+
+ void SetScanoutRegion(int buffer)
+ {
+ unsafe
+ {
+ ModeInfo* mode = pConnector->modes;
+ int connector_id = pConnector->connector_id;
+ int crtc_id = pEncoder->crtc_id;
+
+ int x = 0;
+ int y = 0;
+ int connector_count = 1;
+ int ret = Drm.ModeSetCrtc(fd, crtc_id, buffer, x, y, &connector_id, connector_count, mode);
+
+ if (ret != 0)
+ {
+ Debug.Print("[KMS] Drm.ModeSetCrtc{0}, {1}, {2}, {3}, {4:x}, {5}, {6:x}) failed. Error: {7}",
+ fd, crtc_id, buffer, x, y, (IntPtr)connector_id, connector_count, (IntPtr)mode, ret);
+ }
+ }
+ }
+
+ int GetFramebuffer(BufferObject bo)
+ {
+ if (bo == BufferObject.Zero)
+ goto fail;
+
+ int bo_handle = bo.Handle;
+ if (bo_handle == 0)
+ {
+ Debug.Print("[KMS] Gbm.BOGetHandle({0:x}) failed.", bo);
+ goto fail;
+ }
+
+ int width = bo.Width;
+ int height = bo.Height;
+ int bpp = 32;
+ int depth = 24;
+ int stride = bo.Stride;
+
+ if (width == 0 || height == 0 || bpp == 0)
+ {
+ Debug.Print("[KMS] Invalid framebuffer format: {0}x{1} {2} {3} {4}",
+ width, height, stride, bpp, depth);
+ goto fail;
+ }
+
+ int buffer;
+ int ret = Drm.ModeAddFB (fd, width, height,(byte)depth, (byte)bpp, stride, bo_handle,out buffer);
+ if (ret != 0)
+ {
+ Debug.Print("[KMS] Drm.ModeAddFB({0}, {1}, {2}, {3}, {4}, {5}, {6}) failed. Error: {7}",
+ fd, width, height, depth, bpp, stride, bo_handle, ret);
+ goto fail;
+ }
+
+ bo.SetUserData((IntPtr)buffer, DestroyFB);
+ return buffer;
+
+ fail:
+ Debug.Print("[Error] Failed to create framebuffer.");
+ return -1;
+ }
+ #endregion
+
+ #region IDisposable implementation
+ public void Dispose ()
+ {
+ cairoDev.Release ();
+ cairoSurf.Dispose ();
+ cairoDev.Dispose ();
+
+ if (fb != 0)
+ Drm.ModeRmFB (fd, fb);
+ if (bo != BufferObject.Zero)
+ Gbm.ReleaseBuffer (gbm_surface, bo);
+ if (next_fb != 0)
+ Drm.ModeRmFB (fd, next_fb);
+ if (next_bo != BufferObject.Zero)
+ Gbm.ReleaseBuffer (gbm_surface, next_bo);
+
+ if (Egl.GetCurrentContext () == egl_ctx) {
+ Console.WriteLine ("destroying context");
+ Egl.DestroyContext (egl_display, egl_ctx);
+ }else
+ Console.WriteLine ("not current");
+
+ cairoDev.Dispose ();
+
+ Drm.ModeFreeCrtc (Crtc);
+ Drm.ModeFreeConnector(Connector);
+ Drm.ModeFreeEncoder(Encoder);
+ Libc.close(fd);
+ }
+ #endregion
+
+ #region tests
+ unsafe void dumpDrmResources(){
+ ModeRes* resources = (ModeRes*)Drm.ModeGetResources(fd);
+ if (resources == null)
+ throw new NotSupportedException("[KMS] Drm.ModeGetResources failed.");
+ Console.WriteLine("[KMS] DRM found {0} connectors", resources->count_connectors);
+
+ Console.WriteLine ("[ENCODERS]");
+ for (int j = 0; j < resources->count_encoders; j++) {
+ ModeEncoder* e = (ModeEncoder*)Drm.ModeGetEncoder(fd, *(resources->encoders + j));
+
+ if (e == null)
+ continue;
+ Console.WriteLine ("{0}\t{1}\t{2}",e->encoder_id, e->encoder_type, e->crtc_id);
+
+ Drm.ModeFreeEncoder((IntPtr)e);
+ }
+
+ Console.WriteLine ("\n[CONNECTORS]");
+ ModeConnector* connector = null;
+ for (int i = 0; i < resources->count_connectors; i++)
+ {
+ connector = (ModeConnector*)Drm.ModeGetConnector(fd, *(resources->connectors + i));
+ if (connector != null)
+ {
+ Console.WriteLine ("{0}\t{1}\t{2}\t{3}",
+ connector->connector_id,
+ connector->connector_type,
+ connector->connection,
+ connector->encoder_id);
+
+ for (int j = 0; j < connector->count_modes; j++) {
+ ModeInfo* mode = connector->modes + j;
+ if (mode == null)
+ continue;
+ Console.WriteLine ("\t{0,-20}{1,5}{2,5}{3,4} hz",
+ new string(mode->name),
+ mode->hdisplay,
+ mode->vdisplay,
+ mode->vrefresh);
+ }
+ Drm.ModeFreeConnector((IntPtr)connector);
+ connector = null;
+ }
+ }
+ }
+
+ unsafe static void GetModes(LinuxDisplay display, DisplayResolution[] modes, out DisplayResolution current)
+ {
+ int mode_count = display.pConnector->count_modes;
+ Console.WriteLine("[KMS] Display supports {0} mode(s)", mode_count);
+ for (int i = 0; i < mode_count; i++)
+ {
+ ModeInfo* mode = display.pConnector->modes + i;
+ if (mode != null)
+ {
+ Console.WriteLine("Mode {0}: {1}x{2} @{3}", i,
+ mode->hdisplay, mode->vdisplay, mode->vrefresh);
+ DisplayResolution res = GetDisplayResolution(mode);
+ modes[i] = res;
+ }
+ }
+
+ if (display.pCrtc->mode_valid != 0)
+ {
+ ModeInfo cmode = display.pCrtc->mode;
+ current = GetDisplayResolution(&cmode);
+ }
+ else
+ {
+ current = GetDisplayResolution(display.pConnector->modes);
+ }
+ Console.WriteLine("Current mode: {0}", current.ToString());
+ }
+ unsafe static DisplayResolution GetDisplayResolution(ModeInfo* mode)
+ {
+ return new DisplayResolution(
+ 0, 0,
+ mode->hdisplay, mode->vdisplay,
+ 32, // This is actually part of the framebuffer, not the DisplayResolution
+ mode->vrefresh);
+ }
+
+ unsafe static ModeInfo* GetModeInfo(LinuxDisplay display, DisplayResolution resolution)
+ {
+ for (int i = 0; i < display.pConnector->count_modes; i++)
+ {
+ ModeInfo* mode = display.pConnector->modes + i;
+ if (mode != null &&
+ mode->hdisplay == resolution.Width &&
+ mode->vdisplay == resolution.Height)
+ {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ SurfaceFormat GetSurfaceFormat()
+ {
+ int format;
+ Egl.GetConfigAttrib(egl_display, egl_config,
+ Egl.NATIVE_VISUAL_ID, out format);
+ if (format == 0)
+ throw new Exception ("[KMS] Failed to retrieve EGL visual from GBM surface. Error: " + Egl.GetError());
+
+ return (SurfaceFormat)format;
+ }
+ #endregion
+
+ #region INPUT
+ Thread input_thread;
+ long exit;
+
+ static readonly object Sync = new object();
+ static readonly Crow.Key[] KeyMap = Evdev.KeyMap;
+ static long DeviceFDCount;
+
+ IntPtr udev;
+ IntPtr input_context;
+
+ int input_fd = 0;
+
+ InputInterface input_interface = new InputInterface(
+ OpenRestricted, CloseRestricted);
+ static CloseRestrictedCallback CloseRestricted = CloseRestrictedHandler;
+ static void CloseRestrictedHandler(int fd, IntPtr data)
+ {
+ Debug.Print("[Input] Closing fd {0}", fd);
+ int ret = Libc.close(fd);
+
+ if (ret < 0)
+ {
+ Debug.Print("[Input] Failed to close fd {0}. Error: {1}", fd, ret);
+ }
+ else
+ {
+ Interlocked.Decrement(ref DeviceFDCount);
+ }
+ }
+
+ static OpenRestrictedCallback OpenRestricted = OpenRestrictedHandler;
+ static int OpenRestrictedHandler(IntPtr path, int flags, IntPtr data)
+ {
+ int fd = Libc.open(path, (OpenFlags)flags);
+ Debug.Print("[Input] Opening '{0}' with flags {1}. fd:{2}",
+ Marshal.PtrToStringAnsi(path), (OpenFlags)flags, fd);
+
+ if (fd >= 0)
+ {
+ Interlocked.Increment(ref DeviceFDCount);
+ }
+
+ return fd;
+ }
+
+ void initInput (){
+ Semaphore ready = new Semaphore(0, 1);
+ input_thread = new Thread (InputThreadLoop);
+ input_thread.IsBackground = true;
+ input_thread.Start(ready);
+ }
+
+ void InputThreadLoop(object semaphore)
+ {
+ Debug.Print("[Input] Running on thread {0}", Thread.CurrentThread.ManagedThreadId);
+ Setup();
+
+ // Inform the parent thread that initialization has completed successfully
+ (semaphore as Semaphore).Release();
+ Debug.Print("[Input] Released main thread.", input_context);
+
+ // Use a blocking poll for input messages, in order to reduce CPU usage
+ PollFD poll_fd = new PollFD();
+ poll_fd.fd = input_fd;
+ poll_fd.events = PollFlags.In;
+ Debug.Print("[Input] Created PollFD({0}, {1})", poll_fd.fd, poll_fd.events);
+
+ Debug.Print("[Input] Entering input loop.", poll_fd.fd, poll_fd.events);
+ while (Interlocked.Read(ref exit) == 0)
+ {
+ int ret = Libc.poll(ref poll_fd, 1, -1);
+ ErrorNumber error = (ErrorNumber)Marshal.GetLastWin32Error();
+ bool is_error =
+ ret < 0 && !(error == ErrorNumber.Again || error == ErrorNumber.Interrupted) ||
+ (poll_fd.revents & (PollFlags.Hup | PollFlags.Error | PollFlags.Invalid)) != 0;
+
+ if (ret > 0 && (poll_fd.revents & (PollFlags.In | PollFlags.Pri)) != 0)
+ ProcessEvents(input_context);
+
+ if (is_error)
+ {
+ Debug.Print("[Input] Exiting input loop {0} due to poll error [ret:{1} events:{2}]. Error: {3}.",
+ input_thread.ManagedThreadId, ret, poll_fd.revents, error);
+ Interlocked.Increment(ref exit);
+ }
+ }
+ Debug.Print("[Input] Exited input loop.", poll_fd.fd, poll_fd.events);
+ }
+
+ void Setup()
+ {
+ // Todo: add static path fallback when udev is not installed.
+ udev = Udev.New();
+ if (udev == IntPtr.Zero)
+ {
+ Debug.Print("[Input] Udev.New() failed.");
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] Udev.New() = {0:x}", udev);
+
+ input_context = LibInput.CreateContext(input_interface, IntPtr.Zero, udev);
+ if (input_context == IntPtr.Zero)
+ {
+ Debug.Print("[Input] LibInput.CreateContext({0:x}) failed.", udev);
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] LibInput.CreateContext({0:x}) = {1:x}", udev, input_context);
+
+ string seat_id = "seat0";
+ int seat_assignment = LibInput.AssignSeat(input_context, seat_id);
+ if (seat_assignment == -1)
+ {
+ Debug.Print("[Input] LibInput.AssignSeat({0:x}) = {1} failed.", input_context, seat_id);
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] LibInput.AssignSeat({0:x}) = {1}", input_context, seat_id);
+
+ input_fd = LibInput.GetFD(input_context);
+ if (input_fd < 0)
+ {
+ Debug.Print("[Input] LibInput.GetFD({0:x}) failed.", input_context);
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] LibInput.GetFD({0:x}) = {1}.", input_context, input_fd);
+
+ ProcessEvents(input_context);
+ LibInput.Resume(input_context);
+ Debug.Print("[Input] LibInput.Resume({0:x})", input_context);
+
+ if (Interlocked.Read(ref DeviceFDCount) <= 0)
+ {
+ Debug.Print("[Error] Failed to open any input devices.");
+ Debug.Print("[Error] Ensure that you have access to '/dev/input/event*'.");
+ Interlocked.Increment(ref exit);
+ }
+ }
+
+ void ProcessEvents(IntPtr input_context)
+ {
+ // Process all events in the event queue
+ while (true)
+ {
+ // Data available
+ int ret = LibInput.Dispatch(input_context);
+ if (ret != 0)
+ {
+ Debug.Print("[Input] LibInput.Dispatch({0:x}) failed. Error: {1}",
+ input_context, ret);
+ break;
+ }
+
+ IntPtr pevent = LibInput.GetEvent(input_context);
+ if (pevent == IntPtr.Zero)
+ {
+ break;
+ }
+
+ IntPtr device = LibInput.GetDevice(pevent);
+ InputEventType type = LibInput.GetEventType(pevent);
+
+ lock (Sync)
+ {
+ switch (type)
+ {
+// case InputEventType.DeviceAdded:
+// HandleDeviceAdded(input_context, device);
+// break;
+//
+// case InputEventType.DeviceRemoved:
+// HandleDeviceRemoved(input_context, device);
+// break;
+//
+ case InputEventType.KeyboardKey:
+ run = false;
+ //HandleKeyboard(GetKeyboard(device), LibInput.GetKeyboardEvent(pevent));
+ break;
+//
+// case InputEventType.PointerAxis:
+// HandlePointerAxis(GetMouse(device), LibInput.GetPointerEvent(pevent));
+// break;
+//
+// case InputEventType.PointerButton:
+// HandlePointerButton(GetMouse(device), LibInput.GetPointerEvent(pevent));
+// break;
+
+ case InputEventType.PointerMotion:
+ HandlePointerMotion(LibInput.GetPointerEvent(pevent));
+ break;
+
+// case InputEventType.PointerMotionAbsolute:
+// HandlePointerMotionAbsolute(GetMouse(device), LibInput.GetPointerEvent(pevent));
+// break;
+ }
+ }
+
+ LibInput.DestroyEvent(pevent);
+ }
+ }
+ int MouseX = 0, MouseY = 0;
+ volatile bool updateMousePos = true;
+
+ void HandlePointerMotion(PointerEvent e)
+ {
+ MouseX += (int)e.DeltaX;
+ MouseY += (int)e.DeltaY;
+ updateMousePos = true;
+ }
+
+ #endregion
+ }
+}
+
--- /dev/null
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2011 the Open Toolkit library.
+//
+// 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.Collections.Generic;
+using System.Text;
+
+
+namespace OpenTK.Platform.Egl
+{
+ using EGLNativeDisplayType = IntPtr;
+ using EGLNativeWindowType = IntPtr;
+ using EGLNativePixmapType = IntPtr;
+ using EGLConfig = IntPtr;
+ using EGLContext = IntPtr;
+ using EGLDisplay = IntPtr;
+ using EGLSurface = IntPtr;
+ using EGLClientBuffer = IntPtr;
+
+ enum RenderApi
+ {
+ ES = Egl.OPENGL_ES_API,
+ GL = Egl.OPENGL_API,
+ VG = Egl.OPENVG_API
+ }
+
+ [Flags]
+ enum RenderableFlags
+ {
+ ES = Egl.OPENGL_ES_BIT,
+ ES2 = Egl.OPENGL_ES2_BIT,
+ ES3 = Egl.OPENGL_ES3_BIT,
+ GL = Egl.OPENGL_BIT,
+ VG = Egl.OPENVG_BIT,
+ }
+
+ public 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,
+ CONTEXT_LOST = 12302,
+ }
+
+ static partial class Egl
+ {
+ public const int VERSION_1_0 = 1;
+ public const int VERSION_1_1 = 1;
+ public const int VERSION_1_2 = 1;
+ public const int VERSION_1_3 = 1;
+ public const int VERSION_1_4 = 1;
+ public const int FALSE = 0;
+ public const int TRUE = 1;
+ public const int DONT_CARE = -1;
+ public const int CONTEXT_LOST = 12302;
+ public const int BUFFER_SIZE = 12320;
+ public const int ALPHA_SIZE = 12321;
+ public const int BLUE_SIZE = 12322;
+ public const int GREEN_SIZE = 12323;
+ public const int RED_SIZE = 12324;
+ public const int DEPTH_SIZE = 12325;
+ public const int STENCIL_SIZE = 12326;
+ public const int CONFIG_CAVEAT = 12327;
+ public const int CONFIG_ID = 12328;
+ public const int LEVEL = 12329;
+ public const int MAX_PBUFFER_HEIGHT = 12330;
+ public const int MAX_PBUFFER_PIXELS = 12331;
+ public const int MAX_PBUFFER_WIDTH = 12332;
+ public const int NATIVE_RENDERABLE = 12333;
+ public const int NATIVE_VISUAL_ID = 12334;
+ public const int NATIVE_VISUAL_TYPE = 12335;
+ public const int PRESERVED_RESOURCES = 12336;
+ public const int SAMPLES = 12337;
+ public const int SAMPLE_BUFFERS = 12338;
+ public const int SURFACE_TYPE = 12339;
+ public const int TRANSPARENT_TYPE = 12340;
+ public const int TRANSPARENT_BLUE_VALUE = 12341;
+ public const int TRANSPARENT_GREEN_VALUE = 12342;
+ public const int TRANSPARENT_RED_VALUE = 12343;
+ public const int NONE = 12344;
+ public const int BIND_TO_TEXTURE_RGB = 12345;
+ public const int BIND_TO_TEXTURE_RGBA = 12346;
+ public const int MIN_SWAP_INTERVAL = 12347;
+ public const int MAX_SWAP_INTERVAL = 12348;
+ public const int LUMINANCE_SIZE = 12349;
+ public const int ALPHA_MASK_SIZE = 12350;
+ public const int COLOR_BUFFER_TYPE = 12351;
+ public const int RENDERABLE_TYPE = 12352;
+ public const int MATCH_NATIVE_PIXMAP = 12353;
+ public const int CONFORMANT = 12354;
+ public const int SLOW_CONFIG = 12368;
+ public const int NON_CONFORMANT_CONFIG = 12369;
+ public const int TRANSPARENT_RGB = 12370;
+ public const int RGB_BUFFER = 12430;
+ public const int LUMINANCE_BUFFER = 12431;
+ public const int NO_TEXTURE = 12380;
+ public const int TEXTURE_RGB = 12381;
+ public const int TEXTURE_RGBA = 12382;
+ public const int TEXTURE_2D = 12383;
+ public const int PBUFFER_BIT = 1;
+ public const int PIXMAP_BIT = 2;
+ public const int WINDOW_BIT = 4;
+ public const int VG_COLORSPACE_LINEAR_BIT = 32;
+ public const int VG_ALPHA_FORMAT_PRE_BIT = 64;
+ public const int MULTISAMPLE_RESOLVE_BOX_BIT = 512;
+ public const int SWAP_BEHAVIOR_PRESERVED_BIT = 1024;
+ public const int OPENGL_ES_BIT = 1;
+ public const int OPENVG_BIT = 2;
+ public const int OPENGL_ES2_BIT = 4;
+ public const int OPENGL_BIT = 8;
+ public const int OPENGL_ES3_BIT = 64;
+ public const int VENDOR = 12371;
+ public const int VERSION = 12372;
+ public const int EXTENSIONS = 12373;
+ public const int CLIENT_APIS = 12429;
+ public const int HEIGHT = 12374;
+ public const int WIDTH = 12375;
+ public const int LARGEST_PBUFFER = 12376;
+ public const int TEXTURE_FORMAT = 12416;
+ public const int TEXTURE_TARGET = 12417;
+ public const int MIPMAP_TEXTURE = 12418;
+ public const int MIPMAP_LEVEL = 12419;
+ public const int RENDER_BUFFER = 12422;
+ public const int VG_COLORSPACE = 12423;
+ public const int VG_ALPHA_FORMAT = 12424;
+ public const int HORIZONTAL_RESOLUTION = 12432;
+ public const int VERTICAL_RESOLUTION = 12433;
+ public const int PIXEL_ASPECT_RATIO = 12434;
+ public const int SWAP_BEHAVIOR = 12435;
+ public const int MULTISAMPLE_RESOLVE = 12441;
+ public const int BACK_BUFFER = 12420;
+ public const int SINGLE_BUFFER = 12421;
+ public const int VG_COLORSPACE_sRGB = 12425;
+ public const int VG_COLORSPACE_LINEAR = 12426;
+ public const int VG_ALPHA_FORMAT_NONPRE = 12427;
+ public const int VG_ALPHA_FORMAT_PRE = 12428;
+ public const int DISPLAY_SCALING = 10000;
+ public const int UNKNOWN = -1;
+ public const int BUFFER_PRESERVED = 12436;
+ public const int BUFFER_DESTROYED = 12437;
+ public const int OPENVG_IMAGE = 12438;
+ public const int CONTEXT_CLIENT_TYPE = 12439;
+ public const int CONTEXT_CLIENT_VERSION = 12440;
+ public const int MULTISAMPLE_RESOLVE_DEFAULT = 12442;
+ public const int MULTISAMPLE_RESOLVE_BOX = 12443;
+ public const int OPENGL_ES_API = 12448;
+ public const int OPENVG_API = 12449;
+ public const int OPENGL_API = 12450;
+ public const int DRAW = 12377;
+ public const int READ = 12378;
+ public const int CORE_NATIVE_ENGINE = 12379;
+ public const int COLORSPACE = VG_COLORSPACE;
+ public const int ALPHA_FORMAT = VG_ALPHA_FORMAT;
+ public const int COLORSPACE_sRGB = VG_COLORSPACE_sRGB;
+ public const int COLORSPACE_LINEAR = VG_COLORSPACE_LINEAR;
+ public const int ALPHA_FORMAT_NONPRE = VG_ALPHA_FORMAT_NONPRE;
+ public const int ALPHA_FORMAT_PRE = VG_ALPHA_FORMAT_PRE;
+
+ // EGL_ANGLE_d3d_share_handle_client_buffer
+ public const int D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200;
+ // EGL_ANGLE_window_fixed_size
+ public const int FIXED_SIZE_ANGLE = 0x3201;
+ // EGL_ANGLE_query_surface_pointer
+ [DllImport("libEGL.dll", EntryPoint = "eglQuerySurfacePointerANGLE")]
+ public static extern bool QuerySurfacePointerANGLE(EGLDisplay display, EGLSurface surface, int attribute, out IntPtr value);
+ // EGL_ANGLE_software_display
+ public static readonly EGLNativeDisplayType SOFTWARE_DISPLAY_ANGLE = new EGLNativeDisplayType(-1);
+ // EGL_ANGLE_direct3d_display
+ public static readonly EGLNativeDisplayType D3D11_ELSE_D3D9_DISPLAY_ANGLE = new EGLNativeDisplayType(-2);
+ public static readonly EGLNativeDisplayType D3D11_ONLY_DISPLAY_ANGLE = new EGLNativeDisplayType(-3);
+ // EGL_ANGLE_device_d3d
+ public const int D3D9_DEVICE_ANGLE = 0x33A0;
+ public const int D3D11_DEVICE_ANGLE = 0x33A1;
+ // EGL_ANGLE_platform_angle
+ public const int PLATFORM_ANGLE_ANGLE = 0x3202;
+ public const int PLATFORM_ANGLE_TYPE_ANGLE = 0x3203;
+ public const int PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE = 0x3204;
+ public const int PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE = 0x3205;
+ public const int PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE = 0x3206;
+ // EGL_ANGLE_platform_angle_d3d
+ public const int PLATFORM_ANGLE_TYPE_D3D9_ANGLE = 0x3207;
+ public const int PLATFORM_ANGLE_TYPE_D3D11_ANGLE = 0x3208;
+ public const int PLATFORM_ANGLE_DEVICE_TYPE_ANGLE = 0x3209;
+ public const int PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE = 0x320A;
+ public const int PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE = 0x320B;
+ public const int PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE = 0x320C;
+ public const int PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE = 0x320F;
+ // EGL_ANGLE_platform_angle_opengl
+ public const int PLATFORM_ANGLE_TYPE_OPENGL_ANGLE = 0x320D;
+ public const int PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE = 0x320E;
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetError")]
+ public static extern ErrorCode GetError();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")]
+ public static extern EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglInitialize")]
+ //[return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool Initialize(EGLDisplay dpy, out int major, out int minor);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")]
+ //[return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool Terminate(EGLDisplay dpy);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryString")]
+ public static extern IntPtr QueryString(EGLDisplay dpy, int name);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetConfigs")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool GetConfigs(EGLDisplay dpy, EGLConfig[] configs, int config_size, out int num_config);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglChooseConfig")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool ChooseConfig(EGLDisplay dpy, int[] attrib_list, [In, Out] EGLConfig[] configs, int config_size, out int num_config);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetConfigAttrib")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool GetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute, out int value);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateWindowSurface")]
+ public static extern EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferSurface")]
+ public static extern EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePixmapSurface")]
+ public static extern EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroySurface")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool DestroySurface(EGLDisplay dpy, EGLSurface surface);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglQuerySurface")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool QuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglBindAPI")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool BindAPI(RenderApi api);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryAPI")]
+ public static extern int QueryAPI();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitClient")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool WaitClient();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglReleaseThread")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool ReleaseThread();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferFromClientBuffer")]
+ public static extern EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglSurfaceAttrib")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglBindTexImage")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool BindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglReleaseTexImage")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglSwapInterval")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool SwapInterval(EGLDisplay dpy, int interval);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateContext")]
+ static extern IntPtr eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list);
+
+ public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list)
+ {
+ IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list);
+ if (ptr == IntPtr.Zero)
+ throw new Exception(String.Format("Failed to create EGL context, error: {0}.", Egl.GetError()));
+ return ptr;
+ }
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroyContext")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool DestroyContext(EGLDisplay dpy, EGLContext ctx);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglMakeCurrent")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetCurrentContext")]
+ public static extern EGLContext GetCurrentContext();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetCurrentSurface")]
+ public static extern EGLSurface GetCurrentSurface(int readdraw);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetCurrentDisplay")]
+ public static extern EGLDisplay GetCurrentDisplay();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryContext")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool QueryContext(EGLDisplay dpy, EGLContext ctx, int attribute, out int value);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitGL")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool WaitGL();
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitNative")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool WaitNative(int engine);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglSwapBuffers")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool SwapBuffers(EGLDisplay dpy, EGLSurface surface);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglCopyBuffers")]
+ [return: MarshalAsAttribute(UnmanagedType.I1)]
+ public static extern bool CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetProcAddress")]
+ public static extern IntPtr GetProcAddress(string funcname);
+
+ [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetProcAddress")]
+ public static extern IntPtr GetProcAddress(IntPtr funcname);
+
+ // EGL_EXT_platform_base
+ [DllImport("libEGL.dll", EntryPoint = "eglGetPlatformDisplayEXT")]
+ public static extern EGLDisplay GetPlatformDisplayEXT(int platform, EGLNativeDisplayType native_display, int[] attrib_list);
+
+ [DllImport("libEGL.dll", EntryPoint = "eglCreatePlatformWindowSurfaceEXT")]
+ public static extern EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType native_window, int[] attrib_list);
+
+ [DllImport("libEGL.dll", EntryPoint = "eglCreatePlatformPixmapSurfaceEXT")]
+ public static extern EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType native_pixmap, int[] attrib_list);
+
+ // Returns true if Egl drivers exist on the system.
+ public static bool IsSupported
+ {
+ get
+ {
+ try { GetCurrentContext(); }
+ catch (Exception) { return false; }
+ return true;
+ }
+ }
+
+ }
+#pragma warning restore 0169
+}
\ No newline at end of file
--- /dev/null
+#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;
+
+#pragma warning disable 0649 // field is never assigned
+
+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 ModeConnectorType
+ {
+ Unknown = 0,
+ VGA=1,
+ DVII=2,
+ DVID=3,
+ DVIA=4,
+ Composite=5,
+ SVIDEO=6,
+ LVDS=7,
+ Component=8,
+ PinDIN9 = 9,
+ DisplayPort=10,
+ HDMIA=11,
+ HDMIB=12,
+ TV=13,
+ eDP=14,
+ VIRTUAL=15,
+ DSI=16,
+ DPI=17
+ }
+ enum ModeEncoderType
+ {
+ NONE=0,
+ DAC=1,
+ TMDS=2,
+ LVDS=3,
+ TVDAC=4,
+ VIRTUAL=5,
+ DSI=6,
+ DPMST=7,
+ DPI=8,
+ }
+ 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 ModeConnectorType 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 ModeEncoderType 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;
+ }
+}
+
--- /dev/null
+#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 System.Runtime.InteropServices;
+using Crow;
+
+namespace OpenTK.Platform.Linux
+{
+ // Bindings for linux/input.h
+ class Evdev
+ {
+ public const int KeyCount = 0x300;
+ public const int AxisCount = 0x40;
+ public const int EventCount = (int)EvdevType.CNT;
+
+ #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;
+ }
+ }
+
+ static uint IOCreate(DirectionFlags dir, int number, int length)
+ {
+ long v =
+ ((byte)dir << 30) |
+ ((byte)'E' << 8) |
+ (number << 0) |
+ (length << 16);
+ return (uint)v;
+ }
+
+ // Get absolute value / limits
+ public static int GetAbs(int fd, EvdevAxis axis, out InputAbsInfo info)
+ {
+ info = default(InputAbsInfo);
+ unsafe
+ {
+ fixed (InputAbsInfo* pinfo = &info)
+ {
+ // EVIOCGABS(abs) = _IOR('E', 0x40 + (abs), struct input_absinfo)
+ uint ioctl = IOCreate(DirectionFlags.Read, (int)axis + 0x40, BlittableValueType<InputAbsInfo>.Stride);
+ int retval = Libc.ioctl(fd, ioctl, new IntPtr(pinfo));
+ return retval;
+ }
+ }
+ }
+
+ // Get supported event bits
+ public static int GetBit(int fd, EvdevType ev, int length, IntPtr data)
+ {
+ // EVIOCGBIT = _IOC(_IOC_READ, 'E', 0x20 + (ev), len)
+ uint ioctl = IOCreate(DirectionFlags.Read, (int)ev + 0x20, length);
+ int retval = Libc.ioctl(fd, ioctl, data);
+ return retval;
+ }
+
+ public static int GetName(int fd, out string name)
+ {
+ unsafe
+ {
+ sbyte* pname = stackalloc sbyte[129];
+ int ret = Libc.ioctl(fd, EvdevIoctl.Name128, new IntPtr(pname));
+ name = new string(pname);
+ return ret;
+ }
+ }
+
+ public static int GetId(int fd, out EvdevInputId id)
+ {
+ id = default(EvdevInputId);
+ unsafe
+ {
+ fixed (EvdevInputId* pid = &id)
+ {
+ return Libc.ioctl(fd, EvdevIoctl.Id, new IntPtr(pid));
+ }
+ }
+ }
+ }
+
+ enum EvdevAxis
+ {
+ X = 0x00,
+ Y = 0x01,
+ Z = 0x02,
+ RX = 0x03,
+ RY = 0x04,
+ RZ = 0x05,
+ THROTTLE = 0x06,
+ RUDDER = 0x07,
+ WHEEL = 0x08,
+ GAS = 0x09,
+ BRAKE = 0x0a,
+ HAT0X = 0x10,
+ HAT0Y = 0x11,
+ HAT1X = 0x12,
+ HAT1Y = 0x13,
+ HAT2X = 0x14,
+ HAT2Y = 0x15,
+ HAT3X = 0x16,
+ HAT3Y = 0x17,
+ PRESSURE = 0x18,
+ DISTANCE = 0x19,
+ TILT_X = 0x1a,
+ TILT_Y = 0x1b,
+ TOOL_WIDTH = 0x1c,
+
+ VOLUME = 0x20,
+
+ MISC = 0x28,
+
+ MT_SLOT = 0x2f, /* MT slot being modified */
+ MT_TOUCH_MAJOR = 0x30, /* Major axis of touching ellipse */
+ MT_TOUCH_MINOR = 0x31, /* Minor axis (omit if circular) */
+ MT_WIDTH_MAJOR = 0x32, /* Major axis of approaching ellipse */
+ MT_WIDTH_MINOR = 0x33, /* Minor axis (omit if circular) */
+ MT_ORIENTATION = 0x34, /* Ellipse orientation */
+ MT_POSITION_X = 0x35, /* Center X touch position */
+ MT_POSITION_Y = 0x36, /* Center Y touch position */
+ MT_TOOL_TYPE = 0x37, /* Type of touching device */
+ MT_BLOB_ID = 0x38, /* Group a set of packets as a blob */
+ MT_TRACKING_ID = 0x39, /* Unique ID of initiated contact */
+ MT_PRESSURE = 0x3a, /* Pressure on contact area */
+ MT_DISTANCE = 0x3b, /* Contact hover distance */
+ MT_TOOL_X = 0x3c, /* Center X tool position */
+ MT_TOOL_Y = 0x3d, /* Center Y tool position */
+
+ MAX = 0x3f,
+ CNT = (MAX+1),
+ }
+
+ enum EvdevButton
+ {
+ 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,
+
+ DPAD_UP = 0x220,
+ DPAD_DOWN = 0x221,
+ DPAD_LEFT = 0x222,
+ DPAD_RIGHT = 0x223,
+
+ Last = 0x300,
+ }
+
+ enum EvdevType : byte
+ {
+ SYN = 0x00,
+ KEY = 0x01,
+ REL = 0x02,
+ ABS = 0x03,
+ MSC = 0x04,
+ SW = 0x05,
+ LED = 0x11,
+ SND = 0x12,
+ REP = 0x14,
+ FF = 0x15,
+ PWR = 0x16,
+ FF_STATUS = 0x17,
+ MAX = 0x1f,
+ CNT = (MAX+1),
+ }
+
+ enum EvdevIoctl : uint
+ {
+ Id = (2u << 30) | ((byte)'E' << 8) | (0x02u << 0) | (8u << 16), //EVIOCGID = _IOR('E', 0x02, struct input_id)
+ Name128 = (2u << 30) | ((byte)'E' << 8) | (0x06u << 0) | (128u << 16), //EVIOCGNAME(len) = _IOC(_IOC_READ, 'E', 0x06, len)
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct InputAbsInfo
+ {
+ public int Value;
+ public int Minimum;
+ public int Maximum;
+ public int Fuzz;
+ public int Flat;
+ public int Resolution;
+ };
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct InputId
+ {
+ public ushort BusType;
+ public ushort Vendor;
+ public ushort Product;
+ public ushort Version;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct InputEvent
+ {
+ public TimeVal Time;
+ ushort type;
+ public ushort Code;
+ public int Value;
+
+ public EvdevType Type { get { return (EvdevType)type; } }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct TimeVal
+ {
+ public IntPtr Seconds;
+ public IntPtr MicroSeconds;
+ }
+}
+
--- /dev/null
+#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);
+
+ [DllImport(lib, EntryPoint = "gbm_surface_has_free_buffers", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int HasFreeBuffers (Surface surface);
+
+ }
+
+ 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
+ }
+}
+
--- /dev/null
+#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);
+ }
+}
+
--- /dev/null
+#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_context", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr CreateContext(InputInterface @interface,
+ IntPtr user_data, IntPtr udev);
+
+ [DllImport(lib, EntryPoint = "libinput_udev_assign_seat", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int AssignSeat(IntPtr libinput, 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 bool HasAxis(PointerAxis axis) { return HasAxis(@event, axis) != 0; }
+ public double AxisValue(PointerAxis axis) { return GetAxisValue(@event, axis); }
+ public double DeltaX { get { return GetDX(@event); } }
+ public double DeltaY { get { return GetDY(@event); } }
+ public double X { get { return GetAbsX(@event); } }
+ public double Y { get { return GetAbsY(@event); } }
+ public double TransformedX(int width) { return GetAbsXTransformed(@event, width); }
+ public double 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_has_axis", CallingConvention = CallingConvention.Cdecl)]
+ static extern int HasAxis(IntPtr @event, PointerAxis axis);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_axis_value", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetAxisValue(IntPtr @event, PointerAxis axis);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_dx", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetDX(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_dy", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetDY(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_x", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetAbsX(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_y", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetAbsY(IntPtr @event);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_x_transformed", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetAbsXTransformed(IntPtr @event, int width);
+
+ [DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_y_transformed", CallingConvention = CallingConvention.Cdecl)]
+ static extern double GetAbsYTransformed(IntPtr @event, int height);
+ }
+}
+
--- /dev/null
+#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;
+
+#pragma warning disable 0649 // field is never assigned
+
+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, EvdevIoctl request, [Out] IntPtr data);
+
+ [DllImport(lib)]
+ public static extern int ioctl(int d, uint request, [Out] IntPtr 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 DirectionFlags
+ {
+ None = 0,
+ Write = 1,
+ Read = 2
+ }
+
+ [Flags]
+ enum OpenFlags
+ {
+ ReadOnly = 0x0000,
+ WriteOnly = 0x0001,
+ ReadWrite = 0x0002,
+ NonBlock = 0x0800,
+ CloseOnExec = 0x0080000
+ }
+
+ [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
+ }
+}
+
--- /dev/null
+#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;
+ }
+}
+
--- /dev/null
+#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)]
+ struct ControlCharacters
+ {
+ public byte VINTR;
+ public byte VQUIT;
+ public byte VERASE;
+ public byte VKILL;
+ public byte VEOF;
+ public byte VTIME;
+ public byte VMIN;
+ public byte VSWTC;
+ public byte VSTART;
+ public byte VSTOP;
+ public byte VSUSP;
+ public byte VEOL;
+ public byte VREPRINT;
+ public byte VDISCARD;
+ public byte VWERASE;
+ public byte VLNEXT;
+ public byte VEOL2;
+ public byte C17;
+ public byte C18;
+ public byte C19;
+ public byte C20;
+ public byte C21;
+ public byte C22;
+ public byte C23;
+ public byte C24;
+ public byte C25;
+ public byte C26;
+ public byte C27;
+ public byte C28;
+ public byte C29;
+ public byte C30;
+ public byte C31;
+
+ }
+}
+
--- /dev/null
+#region License
+//
+// Udev.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 Udev
+ {
+ const string lib = "libudev";
+
+ [DllImport(lib, EntryPoint = "udev_new", CallingConvention = CallingConvention.Cdecl)]
+ public static extern IntPtr New();
+
+ [DllImport(lib, EntryPoint = "udev_destroy", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void Destroy(IntPtr Udev);
+ }
+}
+
--- /dev/null
+#region License
+//
+// DefaultCursor.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;
+
+namespace OpenTK.Platform.Linux
+{
+ static class Cursors
+ {
+ public static readonly MouseCursor Default =
+ new MouseCursor(8, 4, 32, 32, new byte[]
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1A, 0x1A, 0x1A, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0xF1, 0xF1, 0xF1, 0xF3, 0x16, 0x16, 0x16, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xEC, 0xEC, 0xF4, 0x11, 0x11, 0x11, 0x37, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xE9, 0xE9, 0xF3, 0x0C, 0x0C, 0x0C, 0x33, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0xFF, 0xF7, 0xF7, 0xF7, 0xFF, 0xE4, 0xE4, 0xE4, 0xF0, 0x07, 0x07, 0x07, 0x2D, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x61, 0x61, 0x61, 0xFF, 0x52, 0x52, 0x52, 0xFF, 0xF9, 0xF9, 0xF9, 0xFF, 0xE0, 0xE0, 0xE0, 0xEC, 0x03, 0x03, 0x03, 0x29, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x5F, 0x5F, 0xFF, 0x13, 0x13, 0x13, 0xFF, 0x5C, 0x5C, 0x5C, 0xFF, 0xFC, 0xFC, 0xFC, 0xFF, 0xD9, 0xD9, 0xD9, 0xE7, 0x01, 0x01, 0x01, 0x26, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0x5C, 0x5C, 0xFF, 0x10, 0x10, 0x10, 0xFF, 0x19, 0x19, 0x19, 0xFF, 0x66, 0x66, 0x66, 0xFF, 0xFD, 0xFD, 0xFD, 0xFF, 0xD3, 0xD3, 0xD3, 0xE2, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x59, 0x59, 0x59, 0xFF, 0x0C, 0x0C, 0x0C, 0xFF, 0x15, 0x15, 0x15, 0xFF, 0x1E, 0x1E, 0x1E, 0xFF, 0x72, 0x72, 0x72, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xCA, 0xCA, 0xCA, 0xDB, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x08, 0x08, 0x08, 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x1A, 0x1A, 0x1A, 0xFF, 0x24, 0x24, 0x24, 0xFF, 0x7C, 0x7C, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC1, 0xC1, 0xD4, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x04, 0x04, 0x04, 0xFF, 0x0D, 0x0D, 0x0D, 0xFF, 0x16, 0x16, 0x16, 0xFF, 0x20, 0x20, 0x20, 0xFF, 0x29, 0x29, 0x29, 0xFF, 0x88, 0x88, 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xB7, 0xB7, 0xCD, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x09, 0x09, 0x09, 0xFF, 0x12, 0x12, 0x12, 0xFF, 0x1C, 0x1C, 0x1C, 0xFF, 0x25, 0x25, 0x25, 0xFF, 0x2F, 0x2F, 0x2F, 0xFF, 0x92, 0x92, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xAD, 0xAD, 0xC5, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x05, 0x05, 0x05, 0xFF, 0x0E, 0x0E, 0x0E, 0xFF, 0x18, 0x18, 0x18, 0xFF, 0x21, 0x21, 0x21, 0xFF, 0x2B, 0x2B, 0x2B, 0xFF, 0x34, 0x34, 0x34, 0xFF, 0x9C, 0x9C, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA1, 0xA1, 0xA1, 0xBC, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0xFF, 0x0A, 0x0A, 0x0A, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x1D, 0x1D, 0x1D, 0xFF, 0x27, 0x27, 0x27, 0xFF, 0x30, 0x30, 0x30, 0xFF, 0x39, 0x39, 0x39, 0xFF, 0xA7, 0xA7, 0xA7, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x96, 0x96, 0x96, 0xB3, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x07, 0x07, 0x07, 0xFF, 0x10, 0x10, 0x10, 0xFF, 0x19, 0x19, 0x19, 0xFF, 0x23, 0x23, 0x23, 0xFF, 0x2C, 0x2C, 0x2C, 0xFF, 0x35, 0x35, 0x35, 0xFF, 0x3F, 0x3F, 0x3F, 0xFF, 0xB0, 0xB0, 0xB0, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x8B, 0x8B, 0x8B, 0xAB, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x03, 0x03, 0xFF, 0x0C, 0x0C, 0x0C, 0xFF, 0x15, 0x15, 0x15, 0xFF, 0x1F, 0x1F, 0x1F, 0xFF, 0x28, 0x28, 0x28, 0xFF, 0x31, 0x31, 0x31, 0xFF, 0x3B, 0x3B, 0x3B, 0xFF, 0x45, 0x45, 0x45, 0xFF, 0xB7, 0xB7, 0xB7, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x80, 0x80, 0x80, 0xA2, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x1F, 0x1F, 0x1F, 0xFF, 0x61, 0x61, 0x61, 0xFF, 0x69, 0x69, 0x69, 0xFF, 0x6F, 0x6F, 0x6F, 0xFF, 0x76, 0x76, 0x76, 0xFF, 0x7D, 0x7D, 0x7D, 0xFF, 0xE1, 0xE1, 0xE1, 0xFF, 0xFD, 0xFD, 0xFD, 0xFF, 0x75, 0x75, 0x75, 0x97, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x04, 0x04, 0x04, 0xFF, 0x0D, 0x0D, 0x0D, 0xFF, 0x17, 0x17, 0x17, 0xFF, 0xCD, 0xCD, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x66, 0x66, 0x85, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x5B, 0x5B, 0x5B, 0xFF, 0x10, 0x10, 0x10, 0xFF, 0x13, 0x13, 0x13, 0xFF, 0x61, 0x61, 0x61, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x69, 0x69, 0x69, 0xBA, 0x1E, 0x1E, 0x1E, 0x83, 0x1E, 0x1E, 0x1E, 0x78, 0x1E, 0x1E, 0x1E, 0x77, 0x1E, 0x1E, 0x1E, 0x74, 0x1E, 0x1E, 0x1E, 0x6B, 0x15, 0x15, 0x15, 0x4A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x6D, 0x6D, 0x6D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x6D, 0x6D, 0x6D, 0xFF, 0x0F, 0x0F, 0x0F, 0xFF, 0x19, 0x19, 0x19, 0xFF, 0xDE, 0xDE, 0xDE, 0xFF, 0xDB, 0xDB, 0xDB, 0xEE, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x75, 0x75, 0x75, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xF7, 0xF7, 0xFC, 0xE6, 0xE6, 0xE6, 0xFF, 0x10, 0x10, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x71, 0x71, 0x71, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x36, 0x36, 0x36, 0x75, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x58, 0x58, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0xAF, 0xAF, 0xD9, 0x36, 0x36, 0x36, 0x8F, 0xFD, 0xFD, 0xFD, 0xFF, 0x67, 0x67, 0x67, 0xFF, 0x10, 0x10, 0x10, 0xFF, 0x1E, 0x1E, 0x1E, 0xFF, 0xEA, 0xEA, 0xEA, 0xFF, 0xCD, 0xCD, 0xCD, 0xE2, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xCC, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0xA7, 0xA7, 0xD5, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x3A, 0xD5, 0xD5, 0xD5, 0xE3, 0xE1, 0xE1, 0xE1, 0xFF, 0x0F, 0x0F, 0x0F, 0xFF, 0x16, 0x16, 0x16, 0xFF, 0x81, 0x81, 0x81, 0xFF, 0xFC, 0xFC, 0xFC, 0xFF, 0x20, 0x20, 0x20, 0x5E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x9F, 0x9F, 0x9F, 0xCF, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x12, 0x3D, 0x3D, 0x3D, 0x59, 0xFD, 0xFD, 0xFD, 0xFF, 0x61, 0x61, 0x61, 0xFF, 0x12, 0x12, 0x12, 0xFF, 0x25, 0x25, 0x25, 0xFF, 0xFA, 0xFA, 0xFA, 0xFF, 0x97, 0x97, 0x97, 0xC0, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x97, 0x97, 0xC1, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0xD9, 0xD9, 0xD9, 0xE5, 0xDC, 0xDC, 0xDC, 0xFF, 0x19, 0x19, 0x19, 0xFF, 0x34, 0x34, 0x34, 0xFF, 0xFB, 0xFB, 0xFB, 0xFF, 0xA2, 0xA2, 0xA2, 0xCB, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x8E, 0x8E, 0x8E, 0xA1, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x45, 0x45, 0x45, 0x5F, 0xFA, 0xFA, 0xFA, 0xFF, 0xF2, 0xF2, 0xF2, 0xFF, 0xFB, 0xFB, 0xFB, 0xFF, 0xF2, 0xF2, 0xF2, 0xFC, 0x30, 0x30, 0x30, 0x83, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x34, 0x34, 0x34, 0x5D, 0xBB, 0xBB, 0xBB, 0xD5, 0x95, 0x95, 0x95, 0xC4, 0x16, 0x16, 0x16, 0x72, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ });
+
+ public static readonly MouseCursor Empty = MouseCursor.Empty;
+ }
+}
+
--- /dev/null
+#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;
+#if !MINIMAL
+using System.Drawing;
+#endif
+
+namespace OpenTK.Platform.Linux
+{
+ // Stores platform-specific information about a display
+ class LinuxDisplay
+ {
+ public int FD;
+ public IntPtr Connector;
+ public IntPtr Crtc;
+ public IntPtr Encoder;
+
+ unsafe public ModeConnector* pConnector { get { return (ModeConnector*)Connector; } }
+ unsafe public ModeCrtc* pCrtc { get { return (ModeCrtc*)Crtc; } }
+ unsafe public ModeEncoder* pEncoder { get { return (ModeEncoder*)Encoder; } }
+ /*
+ public ModeInfo Mode
+ {
+ get
+ {
+ if (Crtc == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ unsafe
+ {
+ return pCrtc->mode;
+ }
+ }
+ }
+ */
+
+ public ModeInfo OriginalMode;
+
+ public int Id
+ {
+ get
+ {
+ if (Crtc == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ unsafe
+ {
+ return (int)pCrtc->crtc_id;
+ }
+ }
+ }
+
+ public LinuxDisplay(int fd, IntPtr c, IntPtr e, IntPtr r)
+ {
+ FD = fd;
+ Connector = c;
+ Encoder = e;
+ Crtc = r;
+ unsafe
+ {
+ OriginalMode = pCrtc->mode; // in case we change resolution later on
+ }
+ }
+ }
+
+ class LinuxDisplayDriver
+ {
+ readonly int FD;
+ readonly Dictionary<int, int> DisplayIds =
+ new Dictionary<int, int>();
+
+ public LinuxDisplayDriver(int fd)
+ {
+ Debug.Print("[KMS] Creating LinuxDisplayDriver for fd:{0}", fd);
+ Debug.Indent();
+ try
+ {
+ FD = fd;
+ UpdateDisplays(fd);
+ }
+ finally
+ {
+ Debug.Unindent();
+ }
+ }
+
+ /// \internal
+ /// <summary>
+ /// Queries the specified GPU for connected displays and, optionally,
+ /// returns the list of displays.
+ /// </summary>
+ /// <returns><c>true</c>, if at least one display is connected, <c>false</c> otherwise.</returns>
+ /// <param name="fd">The fd for the GPU to query, obtained through open("/dev/dri/card0").</param>
+ /// <param name="displays">
+ /// If not null, this will contain a list <see cref="LinuxDisplay"/> instances,
+ /// one for each connected display.
+ /// </param>
+ internal static bool QueryDisplays(int fd, List<LinuxDisplay> displays)
+ {
+ unsafe
+ {
+ bool has_displays = false;
+ if (displays != null)
+ {
+ displays.Clear();
+ }
+
+ ModeRes* resources = (ModeRes*)Drm.ModeGetResources(fd);
+ if (resources == null)
+ {
+ Debug.Print("[KMS] Drm.ModeGetResources failed.");
+ return false;
+ }
+ 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)
+ {
+ bool success = false;
+ LinuxDisplay display = null;
+ try
+ {
+ if (connector->connection == ModeConnection.Connected &&
+ connector->count_modes > 0)
+ {
+ success = QueryDisplay(fd, connector, out display);
+ has_displays |= success;
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Print("[KMS] Failed to add display. Error: {0}", e);
+ }
+
+ if (success && displays != null)
+ {
+ displays.Add(display);
+ }
+ else
+ {
+ Drm.ModeFreeConnector((IntPtr)connector);
+ connector = null;
+ }
+ }
+ }
+
+ return has_displays;
+ }
+ }
+
+ void UpdateDisplays(int fd)
+ {
+ unsafe
+ {
+ lock (this)
+ {
+ AvailableDevices.Clear();
+ DisplayIds.Clear();
+
+ List<LinuxDisplay> displays = new List<LinuxDisplay>();
+ if (QueryDisplays(fd, displays))
+ {
+ foreach (LinuxDisplay display in displays)
+ {
+ AddDisplay(display);
+ }
+ }
+
+ if (AvailableDevices.Count == 0)
+ {
+ Debug.Print("[KMS] Failed to find any active displays");
+ }
+ }
+ }
+ }
+
+ unsafe static ModeEncoder* GetEncoder(int fd, ModeConnector* c)
+ {
+ 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 encoder;
+ }
+
+ unsafe static ModeCrtc* GetCrtc(int fd, ModeEncoder* encoder)
+ {
+ 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 crtc;
+ }
+
+ unsafe static void GetModes(LinuxDisplay display, DisplayResolution[] modes, out DisplayResolution current)
+ {
+ int mode_count = display.pConnector->count_modes;
+ Debug.Print("[KMS] Display supports {0} mode(s)", mode_count);
+ for (int i = 0; i < mode_count; i++)
+ {
+ ModeInfo* mode = display.pConnector->modes + i;
+ if (mode != null)
+ {
+ Debug.Print("Mode {0}: {1}x{2} @{3}", i,
+ mode->hdisplay, mode->vdisplay, mode->vrefresh);
+ DisplayResolution res = GetDisplayResolution(mode);
+ modes[i] = res;
+ }
+ }
+
+ if (display.pCrtc->mode_valid != 0)
+ {
+ ModeInfo cmode = display.pCrtc->mode;
+ current = GetDisplayResolution(&cmode);
+ }
+ else
+ {
+ current = GetDisplayResolution(display.pConnector->modes);
+ }
+ Debug.Print("Current mode: {0}", current.ToString());
+ }
+
+ Rectangle GetBounds(DisplayResolution current)
+ {
+ // 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.
+ int x = AvailableDevices.Count == 0 ?
+ 0 : AvailableDevices[AvailableDevices.Count - 1].Bounds.Right;
+ int y = 0;
+
+ return new Rectangle(
+ x, y, current.Width, current.Height);
+ }
+
+ void UpdateDisplayIndices(LinuxDisplay display, DisplayDevice device)
+ {
+ if (!DisplayIds.ContainsKey(display.Id))
+ {
+ Debug.Print("[KMS] Adding display {0} as {1}", display.Id, AvailableDevices.Count);
+ DisplayIds.Add(display.Id, AvailableDevices.Count);
+ }
+ int index = DisplayIds[display.Id];
+ if (index >= AvailableDevices.Count)
+ {
+ AvailableDevices.Add(device);
+ }
+ else
+ {
+ AvailableDevices[index] = device;
+ }
+ }
+
+ unsafe static bool QueryDisplay(int fd, ModeConnector* c, out LinuxDisplay display)
+ {
+ display = null;
+
+ // Find corresponding encoder
+ ModeEncoder* encoder = GetEncoder(fd, c);
+ if (encoder == null)
+ return false;
+
+ ModeCrtc* crtc = GetCrtc(fd, encoder);
+ if (crtc == null)
+ return false;
+
+ display = new LinuxDisplay(fd, (IntPtr)c, (IntPtr)encoder, (IntPtr)crtc);
+ return true;
+ }
+
+ unsafe void AddDisplay(LinuxDisplay display)
+ {
+ DisplayResolution[] modes = new DisplayResolution[display.pConnector->count_modes];
+ DisplayResolution current;
+ GetModes(display, modes, out current);
+
+ bool is_primary = AvailableDevices.Count == 0;
+ DisplayDevice device = new DisplayDevice(current, is_primary,
+ modes, GetBounds(current), display);
+
+ if (is_primary)
+ {
+ Primary = device;
+ }
+
+ UpdateDisplayIndices(display, device);
+
+ Debug.Print("[KMS] Added DisplayDevice {0}", device);
+ }
+
+ unsafe static DisplayResolution GetDisplayResolution(ModeInfo* mode)
+ {
+ return new DisplayResolution(
+ 0, 0,
+ mode->hdisplay, mode->vdisplay,
+ 32, // This is actually part of the framebuffer, not the DisplayResolution
+ mode->vrefresh);
+ }
+
+ unsafe static ModeInfo* GetModeInfo(LinuxDisplay display, DisplayResolution resolution)
+ {
+ for (int i = 0; i < display.pConnector->count_modes; i++)
+ {
+ ModeInfo* mode = display.pConnector->modes + i;
+ if (mode != null &&
+ mode->hdisplay == resolution.Width &&
+ mode->vdisplay == resolution.Height)
+ {
+ return mode;
+ }
+ }
+ return null;
+ }
+
+ #region IDisplayDeviceDriver
+
+ public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
+ {
+ unsafe
+ {
+ LinuxDisplay display = (LinuxDisplay)device.Id;
+ ModeInfo* mode = GetModeInfo(display, resolution);
+ int connector_id = display.pConnector->connector_id;
+ if (mode != null)
+ {
+ return Drm.ModeSetCrtc(FD, display.Id, 0, 0, 0,
+ &connector_id, 1, mode) == 0;
+ }
+ return false;
+ }
+ }
+
+ public bool TryRestoreResolution(DisplayDevice device)
+ {
+ unsafe
+ {
+ LinuxDisplay display = (LinuxDisplay)device.Id;
+ ModeInfo mode = display.OriginalMode;
+ int connector_id = display.pConnector->connector_id;
+ return Drm.ModeSetCrtc(FD, display.Id, 0, 0, 0,
+ &connector_id, 1, &mode) == 0;
+ }
+ }
+
+ #endregion
+ }
+}
+
--- /dev/null
+#region License
+//
+// LinuxFactory.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.Diagnostics;
+using System.IO;
+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;
+ IntPtr gbm_device;
+ IntPtr egl_display;
+
+ IJoystickDriver2 JoystickDriver;
+ LinuxInput MouseKeyboardDriver;
+
+ const string gpu_path = "/dev/dri"; // card0, card1, ...
+
+ public LinuxFactory()
+ {
+ Debug.Print("[KMS] Using Linux/KMS backend.");
+ }
+
+ #region Private Members
+
+ int gpu_fd
+ {
+ get
+ {
+ lock (this)
+ {
+ if (_fd == 0)
+ {
+ _fd = CreateDisplay(out gbm_device, out egl_display);
+ }
+ return _fd;
+ }
+ }
+ }
+
+ static int CreateDisplay(out IntPtr gbm_device, out IntPtr egl_display)
+ {
+ // Query all GPUs until we find one that has a connected display.
+ // This is necessary in multi-gpu systems, where only one GPU
+ // can output a signal.
+ // Todo: allow OpenTK to drive multiple GPUs
+ // Todo: allow OpenTK to run on an offscreen GPU
+ // Todo: allow the user to pick a GPU
+ int fd = 0;
+ gbm_device = IntPtr.Zero;
+ egl_display = IntPtr.Zero;
+
+ var files = Directory.GetFiles(gpu_path);
+ foreach (var gpu in files)
+ {
+ if (Path.GetFileName(gpu).StartsWith("card"))
+ {
+ int test_fd = SetupDisplay(gpu, out gbm_device, out egl_display);
+ if (test_fd >= 0)
+ {
+ try
+ {
+ if (LinuxDisplayDriver.QueryDisplays(test_fd, null))
+ {
+ fd = test_fd;
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine(e.ToString());
+ }
+
+ Debug.Print("[KMS] GPU '{0}' is not connected, skipping.", gpu);
+ Libc.close(test_fd);
+ }
+ }
+ }
+
+ if (fd == 0)
+ {
+ Debug.Print("[Error] No valid GPU found, bailing out.");
+ throw new PlatformNotSupportedException();
+ }
+
+ return fd;
+ }
+
+ static int SetupDisplay(string gpu, out IntPtr gbm_device, out IntPtr egl_display)
+ {
+ Debug.Print("[KMS] Attempting to use gpu '{0}'.", gpu);
+
+ gbm_device = IntPtr.Zero;
+ egl_display = IntPtr.Zero;
+
+ int fd = Libc.open(gpu, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
+ if (fd < 0)
+ {
+ Debug.Print("[KMS] Failed to open gpu");
+ return fd;
+ }
+ Debug.Print("[KMS] GPU '{0}' opened as fd:{1}", gpu, fd);
+
+ gbm_device = Gbm.CreateDevice(fd);
+ if (gbm_device == IntPtr.Zero)
+ {
+ throw new NotSupportedException("[KMS] Failed to create GBM device");
+ }
+ Debug.Print("[KMS] GBM {0:x} created successfully; ", gbm_device);
+
+ egl_display = Egl.GetDisplay(gbm_device);
+ if (egl_display == IntPtr.Zero)
+ {
+ throw new NotSupportedException("[KMS] Failed to create EGL display");
+ }
+ Debug.Print("[KMS] EGL display {0:x} created successfully", egl_display);
+
+ int major, minor;
+ if (!Egl.Initialize(egl_display, out major, out minor))
+ {
+ ErrorCode error = Egl.GetError();
+ throw new NotSupportedException("[KMS] Failed to initialize EGL display. Error code: " + error);
+ }
+ Debug.Print("[KMS] EGL {0}.{1} initialized successfully on display {2:x}", major, minor, egl_display);
+
+ return fd;
+ }
+
+ #endregion
+
+ #region Protected Members
+
+ protected override void Dispose(bool manual)
+ {
+ if (egl_display != IntPtr.Zero)
+ {
+ Debug.Print("[KMS] Terminating EGL.");
+ Egl.Terminate(egl_display);
+ egl_display = IntPtr.Zero;
+ }
+ if (gbm_device != IntPtr.Zero)
+ {
+ Debug.Print("[KMS] Destroying GBM device.");
+ Gbm.DestroyDevice(gbm_device);
+ gbm_device = IntPtr.Zero;
+ }
+ if (_fd >= 0)
+ {
+ Debug.Print("[KMS] Closing GPU fd.");
+ Libc.close(_fd);
+ }
+
+ base.Dispose(manual);
+ }
+
+ #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(egl_display, gbm_device, gpu_fd, x, y, width, height, title, mode, options, display_device);
+ }
+
+ public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
+ {
+ return new LinuxDisplayDriver(gpu_fd);
+ }
+
+ public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
+ {
+ return new LinuxGraphicsContext(mode, (LinuxWindowInfo)window, shareContext, major, minor, flags);
+ }
+
+ public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
+ {
+ return (GraphicsContext.GetCurrentContextDelegate)delegate
+ {
+ return new ContextHandle(Egl.GetCurrentContext());
+ };
+ }
+
+ public override IKeyboardDriver2 CreateKeyboardDriver()
+ {
+ lock (this)
+ {
+ MouseKeyboardDriver = MouseKeyboardDriver ?? new LinuxInput();
+ return MouseKeyboardDriver;
+ }
+ }
+
+ public override IMouseDriver2 CreateMouseDriver()
+ {
+ lock (this)
+ {
+ MouseKeyboardDriver = MouseKeyboardDriver ?? new LinuxInput();
+ return MouseKeyboardDriver;
+ }
+ }
+
+ public override IJoystickDriver2 CreateJoystickDriver()
+ {
+ lock (this)
+ {
+ JoystickDriver = JoystickDriver ?? new LinuxJoystick();
+ return JoystickDriver;
+ }
+ }
+
+ public override OpenTK.Input.IGamePadDriver CreateGamePadDriver()
+ {
+ return new MappedGamePadDriver();
+ }
+
+ #endregion
+ }
+}
+
--- /dev/null
+#region License
+//
+// LinuxGraphicsContext.cs
+//
+// Author:
+// thefiddler <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 System.Runtime.InteropServices;
+using OpenTK.Graphics;
+
+namespace OpenTK.Platform.Linux
+{
+ /// \internal
+ /// <summary>
+ /// Defines an IGraphicsContext implementation for the Linux KMS framebuffer.
+ /// For Linux/X11 and other Unix operating systems, use the more generic
+ /// <see cref="OpenTK.Platform.Egl.EglUnixContext"/> instead.
+ /// </summary>
+ /// <remarks>
+ /// Note: to display our results, we need to allocate a GBM framebuffer
+ /// and point the scanout address to that via Drm.ModeSetCrtc.
+ /// </remarks>
+ class LinuxGraphicsContext : Egl.EglUnixContext
+ {
+ BufferObject bo, bo_next;
+ int fd;
+ bool is_flip_queued;
+ int swap_interval;
+
+ public LinuxGraphicsContext(GraphicsMode mode, LinuxWindowInfo window, IGraphicsContext sharedContext,
+ int major, int minor, GraphicsContextFlags flags)
+ : base(mode, window, sharedContext, major, minor, flags)
+ {
+ if (mode.Buffers < 1)
+ throw new ArgumentException();
+ fd = window.FD;
+
+ PageFlip = HandlePageFlip;
+ PageFlipPtr = Marshal.GetFunctionPointerForDelegate(PageFlip);
+ }
+
+ public override void SwapBuffers()
+ {
+ base.SwapBuffers();
+
+ if (is_flip_queued)
+ {
+ // Todo: if we don't wait for the page flip,
+ // we drop all rendering buffers and get a crash
+ // in Egl.SwapBuffers(). We need to fix that
+ // before we can disable vsync.
+ WaitFlip(true); // WaitFlip(SwapInterval > 0)
+ if (is_flip_queued)
+ {
+ Debug.Print("[KMS] Dropping frame");
+ return;
+ }
+ }
+
+ bo_next = LockSurface();
+ int fb = GetFramebuffer(bo_next);
+ QueueFlip(fb);
+ }
+
+ public override void Update(IWindowInfo window)
+ {
+ WaitFlip(true);
+
+ base.SwapBuffers();
+
+ bo = LockSurface();
+ int fb = GetFramebuffer(bo);
+ SetScanoutRegion(fb);
+ }
+
+ public override int SwapInterval
+ {
+ get
+ {
+ return swap_interval;
+ }
+ set
+ {
+ // We only support a SwapInterval of 0 (immediate)
+ // or 1 (vsynced).
+ // Todo: add support for SwapInterval of -1 (adaptive).
+ // This requires a small change in WaitFlip().
+ swap_interval = MathHelper.Clamp(value, 0, 1);
+ }
+ }
+
+ void WaitFlip(bool block)
+ {
+ PollFD fds = new PollFD();
+ fds.fd = fd;
+ fds.events = PollFlags.In;
+
+ EventContext evctx = new EventContext();
+ evctx.version = EventContext.Version;
+ evctx.page_flip_handler = PageFlipPtr;
+
+ int timeout = block ? -1 : 0;
+
+ while (is_flip_queued)
+ {
+ fds.revents = 0;
+ if (Libc.poll(ref fds, 1, timeout) < 0)
+ break;
+
+ if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0)
+ break;
+
+ if ((fds.revents & PollFlags.In) != 0)
+ Drm.HandleEvent(fd, ref evctx);
+ else
+ break;
+ }
+
+ // Page flip has taken place, update buffer objects
+ if (!is_flip_queued)
+ {
+ IntPtr gbm_surface = WindowInfo.Handle;
+ Gbm.ReleaseBuffer(gbm_surface, bo);
+ bo = bo_next;
+ }
+ }
+
+ void QueueFlip(int buffer)
+ {
+ LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
+ if (wnd == null)
+ throw new InvalidOperationException();
+
+ unsafe
+ {
+ int ret = Drm.ModePageFlip(fd, wnd.DisplayDevice.Id, buffer,
+ PageFlipFlags.FlipEvent, IntPtr.Zero);
+
+ if (ret < 0)
+ {
+ Debug.Print("[KMS] Failed to enqueue framebuffer flip. Error: {0}", ret);
+ }
+
+ is_flip_queued = true;
+ }
+ }
+
+ void SetScanoutRegion(int buffer)
+ {
+ LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
+ if (wnd == null)
+ throw new InvalidOperationException();
+
+ unsafe
+ {
+ ModeInfo* mode = wnd.DisplayDevice.pConnector->modes;
+ int connector_id = wnd.DisplayDevice.pConnector->connector_id;
+ int crtc_id = wnd.DisplayDevice.Id;
+
+ int x = 0;
+ int y = 0;
+ int connector_count = 1;
+ int ret = Drm.ModeSetCrtc(fd, crtc_id, buffer, x, y,
+ &connector_id, connector_count, mode);
+
+ if (ret != 0)
+ {
+ Debug.Print("[KMS] Drm.ModeSetCrtc{0}, {1}, {2}, {3}, {4:x}, {5}, {6:x}) failed. Error: {7}",
+ fd, crtc_id, buffer, x, y, (IntPtr)connector_id, connector_count, (IntPtr)mode, ret);
+ }
+ }
+ }
+
+ BufferObject LockSurface()
+ {
+ IntPtr gbm_surface = WindowInfo.Handle;
+ return Gbm.LockFrontBuffer(gbm_surface);
+ }
+
+ int GetFramebuffer(BufferObject bo)
+ {
+ if (bo == BufferObject.Zero)
+ goto fail;
+
+ int bo_handle = bo.Handle;
+ if (bo_handle == 0)
+ {
+ Debug.Print("[KMS] Gbm.BOGetHandle({0:x}) failed.", bo);
+ goto fail;
+ }
+
+ int width = bo.Width;
+ int height = bo.Height;
+ int bpp = Mode.ColorFormat.BitsPerPixel;
+ int depth = Mode.Depth;
+ int stride = bo.Stride;
+
+ if (width == 0 || height == 0 || bpp == 0)
+ {
+ Debug.Print("[KMS] Invalid framebuffer format: {0}x{1} {2} {3} {4}",
+ width, height, stride, bpp, depth);
+ goto fail;
+ }
+
+ int buffer;
+ int ret = Drm.ModeAddFB(
+ fd, width, height,
+ (byte)depth, (byte)bpp, stride, bo_handle,
+ out buffer);
+ if (ret != 0)
+ {
+ Debug.Print("[KMS] Drm.ModeAddFB({0}, {1}, {2}, {3}, {4}, {5}, {6}) failed. Error: {7}",
+ fd, width, height, depth, bpp, stride, bo_handle, ret);
+ goto fail;
+ }
+
+ bo.SetUserData((IntPtr)buffer, DestroyFB);
+ return buffer;
+
+ fail:
+ Debug.Print("[Error] Failed to create framebuffer.");
+ return -1;
+ }
+
+ readonly IntPtr PageFlipPtr;
+ readonly PageFlipCallback PageFlip;
+ void HandlePageFlip(int fd,
+ int sequence,
+ int tv_sec,
+ int tv_usec,
+ IntPtr user_data)
+ {
+ is_flip_queued = false;
+ }
+
+ static readonly DestroyUserDataCallback DestroyFB = HandleDestroyFB;
+ static void HandleDestroyFB(BufferObject bo, IntPtr data)
+ {
+ IntPtr gbm = bo.Device;
+ int fb = data.ToInt32();
+ Debug.Print("[KMS] Destroying framebuffer {0}", fb);
+
+ if (fb != 0)
+ {
+ Drm.ModeRmFB(Gbm.DeviceGetFD(gbm), fb);
+ }
+ }
+
+ protected override void Dispose(bool manual)
+ {
+ if (manual)
+ {
+ // Reset the scanout region
+ LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
+ if (wnd != null)
+ {
+ unsafe
+ {
+ int connector_id = wnd.DisplayDevice.pConnector->connector_id;
+ ModeInfo mode = wnd.DisplayDevice.OriginalMode;
+ Drm.ModeSetCrtc(fd,
+ wnd.DisplayDevice.pCrtc->crtc_id,
+ wnd.DisplayDevice.pCrtc->buffer_id,
+ wnd.DisplayDevice.pCrtc->x,
+ wnd.DisplayDevice.pCrtc->y,
+ &connector_id,
+ 1,
+ &mode);
+ }
+ }
+ }
+ base.Dispose(manual);
+ }
+ }
+}
+
+
+
--- /dev/null
+#region License
+//
+// LinuxKeyboardLibInput.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;
+#if !MINIMAL
+using System.Drawing;
+#endif
+using System.Runtime.InteropServices;
+using System.Threading;
+using OpenTK.Input;
+
+namespace OpenTK.Platform.Linux
+{
+ class LinuxInput : IKeyboardDriver2, IMouseDriver2, IDisposable
+ {
+ class DeviceBase
+ {
+ readonly IntPtr Device;
+ string name;
+ string output;
+ string logical_seat;
+ string physical_seat;
+
+ public DeviceBase(IntPtr device, int id)
+ {
+ Device = device;
+ Id = id;
+ }
+
+ public int Id
+ {
+ get
+ {
+ return GetId(Device);
+ }
+ set
+ {
+ LibInput.DeviceSetData(Device, (IntPtr)value);
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ name = name ?? LibInput.DeviceGetName(Device);
+ return name;
+ }
+ }
+
+ public IntPtr Seat
+ {
+ get
+ {
+ return LibInput.DeviceGetSeat(Device);
+ }
+ }
+
+ public string LogicalSeatName
+ {
+ get
+ {
+ logical_seat = logical_seat ?? LibInput.SeatGetLogicalName(Seat);
+ return logical_seat;
+ }
+ }
+
+ public string PhysicalSeatName
+ {
+ get
+ {
+ physical_seat = physical_seat ?? LibInput.SeatGetPhysicalName(Seat);
+ return physical_seat;
+ }
+ }
+
+ public string Output
+ {
+ get
+ {
+ output = output ?? LibInput.DeviceGetOutputName(Device);
+ return output;
+ }
+ }
+ }
+
+ class KeyboardDevice : DeviceBase
+ {
+ public KeyboardState State;
+
+ public KeyboardDevice(IntPtr device, int id)
+ : base(device, id)
+ {
+ }
+ }
+
+ class MouseDevice : DeviceBase
+ {
+ public MouseState State;
+
+ public MouseDevice(IntPtr device, int id)
+ : base(device, id)
+ {
+ }
+ }
+
+ static readonly object Sync = new object();
+ static readonly Key[] KeyMap = Evdev.KeyMap;
+ static long DeviceFDCount;
+
+ // libinput returns various devices with keyboard/pointer even though
+ // they are not traditional keyboards/mice (for example "Integrated Camera"
+ // can be detected as a keyboard.)
+ // Since there is no API to retrieve actual device capabilities,
+ // we add all detected devices to a "candidate" list and promote them
+ // to an actual keyboard/mouse only when we receive a valid input event.
+ // This is far from optimal, but it appears to be the only viable solution
+ // unless a new API is added to libinput.
+ DeviceCollection<KeyboardDevice> KeyboardCandidates = new DeviceCollection<KeyboardDevice>();
+ DeviceCollection<MouseDevice> MouseCandidates = new DeviceCollection<MouseDevice>();
+ DeviceCollection<KeyboardDevice> Keyboards = new DeviceCollection<KeyboardDevice>();
+ DeviceCollection<MouseDevice> Mice = new DeviceCollection<MouseDevice>();
+
+ // Todo: do we need to maintain the geometry of each display separately?
+ Rectangle bounds;
+
+ // Global mouse cursor state
+ Vector2 CursorPosition = Vector2.Zero;
+ // Global mouse cursor offset (used for emulating SetPosition)
+ Vector2 CursorOffset = Vector2.Zero;
+
+ IntPtr udev;
+ IntPtr input_context;
+ InputInterface input_interface = new InputInterface(
+ OpenRestricted, CloseRestricted);
+ int fd;
+ Thread input_thread;
+ long exit;
+
+ public LinuxInput()
+ {
+ Debug.Print("[Linux] Initializing {0}", GetType().Name);
+ Debug.Indent();
+ try
+ {
+ Semaphore ready = new Semaphore(0, 1);
+ input_thread = new Thread(InputThreadLoop);
+ input_thread.IsBackground = true;
+ input_thread.Start(ready);
+
+ // Wait until the input thread is ready.
+ // Note: it would be nicer if we could avoid this.
+ // however we need to marshal errors back to the caller
+ // as exceptions.
+ // Todo: in a future version, we should add an "Application" object
+ // to handle all communication with the OS (including event processing.)
+ // Once we do that, we can remove all separate input threads.
+ ready.WaitOne();
+ if (exit != 0)
+ {
+ throw new NotSupportedException();
+ }
+ }
+ finally
+ {
+ Debug.Print("Initialization {0}", exit == 0 ?
+ "complete" : "failed");
+ Debug.Unindent();
+ }
+ }
+
+ #region Private Members
+
+ static CloseRestrictedCallback CloseRestricted = CloseRestrictedHandler;
+ static void CloseRestrictedHandler(int fd, IntPtr data)
+ {
+ Debug.Print("[Input] Closing fd {0}", fd);
+ int ret = Libc.close(fd);
+
+ if (ret < 0)
+ {
+ Debug.Print("[Input] Failed to close fd {0}. Error: {1}", fd, ret);
+ }
+ else
+ {
+ Interlocked.Decrement(ref DeviceFDCount);
+ }
+ }
+
+ static OpenRestrictedCallback OpenRestricted = OpenRestrictedHandler;
+ static int OpenRestrictedHandler(IntPtr path, int flags, IntPtr data)
+ {
+ int fd = Libc.open(path, (OpenFlags)flags);
+ Debug.Print("[Input] Opening '{0}' with flags {1}. fd:{2}",
+ Marshal.PtrToStringAnsi(path), (OpenFlags)flags, fd);
+
+ if (fd >= 0)
+ {
+ Interlocked.Increment(ref DeviceFDCount);
+ }
+
+ return fd;
+ }
+
+ void InputThreadLoop(object semaphore)
+ {
+ Debug.Print("[Input] Running on thread {0}", Thread.CurrentThread.ManagedThreadId);
+ Setup();
+
+ // Inform the parent thread that initialization has completed successfully
+ (semaphore as Semaphore).Release();
+ Debug.Print("[Input] Released main thread.", input_context);
+
+ // Use a blocking poll for input messages, in order to reduce CPU usage
+ PollFD poll_fd = new PollFD();
+ poll_fd.fd = fd;
+ poll_fd.events = PollFlags.In;
+ Debug.Print("[Input] Created PollFD({0}, {1})", poll_fd.fd, poll_fd.events);
+
+ Debug.Print("[Input] Entering input loop.", poll_fd.fd, poll_fd.events);
+ while (Interlocked.Read(ref exit) == 0)
+ {
+ int ret = Libc.poll(ref poll_fd, 1, -1);
+ ErrorNumber error = (ErrorNumber)Marshal.GetLastWin32Error();
+ bool is_error =
+ ret < 0 && !(error == ErrorNumber.Again || error == ErrorNumber.Interrupted) ||
+ (poll_fd.revents & (PollFlags.Hup | PollFlags.Error | PollFlags.Invalid)) != 0;
+
+ // We need to query the desktop bounds in order to position the mouse cursor correctly.
+ // This value will be used for the current bunch of input events. If a monitor changes
+ // resolution in the meantime, we might be slightly off in our calculations - this error
+ // will be corrected when the next bunch of input events arrives.
+ UpdateDisplayBounds();
+
+ if (ret > 0 && (poll_fd.revents & (PollFlags.In | PollFlags.Pri)) != 0)
+ {
+ ProcessEvents(input_context);
+ }
+
+ if (is_error)
+ {
+ Debug.Print("[Input] Exiting input loop {0} due to poll error [ret:{1} events:{2}]. Error: {3}.",
+ input_thread.ManagedThreadId, ret, poll_fd.revents, error);
+ Interlocked.Increment(ref exit);
+ }
+ }
+ Debug.Print("[Input] Exited input loop.", poll_fd.fd, poll_fd.events);
+ }
+
+ void UpdateDisplayBounds()
+ {
+ bounds = Rectangle.Empty;
+ for (DisplayIndex i = DisplayIndex.First; i < DisplayIndex.Sixth; i++)
+ {
+ DisplayDevice display = DisplayDevice.GetDisplay(i);
+ if (display != null)
+ {
+ bounds = Rectangle.Union(bounds, display.Bounds);
+ }
+ }
+ }
+
+ void UpdateCursor()
+ {
+ Point p = new Point(
+ (int)Math.Round(CursorPosition.X + CursorOffset.X),
+ (int)Math.Round(CursorPosition.Y + CursorOffset.Y));
+
+ DisplayDevice display = DisplayDevice.FromPoint(p.X, p.Y) ?? DisplayDevice.Default;
+ if (display != null)
+ {
+ LinuxDisplay d = (LinuxDisplay)display.Id;
+ Drm.MoveCursor(d.FD, d.Id, p.X, p.Y);
+ }
+ }
+
+ void Setup()
+ {
+ // Todo: add static path fallback when udev is not installed.
+ udev = Udev.New();
+ if (udev == IntPtr.Zero)
+ {
+ Debug.Print("[Input] Udev.New() failed.");
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] Udev.New() = {0:x}", udev);
+
+ input_context = LibInput.CreateContext(input_interface, IntPtr.Zero, udev);
+ if (input_context == IntPtr.Zero)
+ {
+ Debug.Print("[Input] LibInput.CreateContext({0:x}) failed.", udev);
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] LibInput.CreateContext({0:x}) = {1:x}", udev, input_context);
+
+ string seat_id = "seat0";
+ int seat_assignment = LibInput.AssignSeat(input_context, seat_id);
+ if (seat_assignment == -1)
+ {
+ Debug.Print("[Input] LibInput.AssignSeat({0:x}) = {1} failed.", input_context, seat_id);
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] LibInput.AssignSeat({0:x}) = {1}", input_context, seat_id);
+
+ fd = LibInput.GetFD(input_context);
+ if (fd < 0)
+ {
+ Debug.Print("[Input] LibInput.GetFD({0:x}) failed.", input_context);
+ Interlocked.Increment(ref exit);
+ return;
+ }
+ Debug.Print("[Input] LibInput.GetFD({0:x}) = {1}.", input_context, fd);
+
+ ProcessEvents(input_context);
+ LibInput.Resume(input_context);
+ Debug.Print("[Input] LibInput.Resume({0:x})", input_context);
+
+ if (Interlocked.Read(ref DeviceFDCount) <= 0)
+ {
+ Debug.Print("[Error] Failed to open any input devices.");
+ Debug.Print("[Error] Ensure that you have access to '/dev/input/event*'.");
+ Interlocked.Increment(ref exit);
+ }
+ }
+
+ void ProcessEvents(IntPtr input_context)
+ {
+ // Process all events in the event queue
+ while (true)
+ {
+ // Data available
+ int ret = LibInput.Dispatch(input_context);
+ if (ret != 0)
+ {
+ Debug.Print("[Input] LibInput.Dispatch({0:x}) failed. Error: {1}",
+ input_context, ret);
+ break;
+ }
+
+ IntPtr pevent = LibInput.GetEvent(input_context);
+ if (pevent == IntPtr.Zero)
+ {
+ break;
+ }
+
+ IntPtr device = LibInput.GetDevice(pevent);
+ InputEventType type = LibInput.GetEventType(pevent);
+
+ lock (Sync)
+ {
+ switch (type)
+ {
+ case InputEventType.DeviceAdded:
+ HandleDeviceAdded(input_context, device);
+ break;
+
+ case InputEventType.DeviceRemoved:
+ HandleDeviceRemoved(input_context, device);
+ break;
+
+ case InputEventType.KeyboardKey:
+ HandleKeyboard(GetKeyboard(device), LibInput.GetKeyboardEvent(pevent));
+ break;
+
+ case InputEventType.PointerAxis:
+ HandlePointerAxis(GetMouse(device), LibInput.GetPointerEvent(pevent));
+ break;
+
+ case InputEventType.PointerButton:
+ HandlePointerButton(GetMouse(device), LibInput.GetPointerEvent(pevent));
+ break;
+
+ case InputEventType.PointerMotion:
+ HandlePointerMotion(GetMouse(device), LibInput.GetPointerEvent(pevent));
+ break;
+
+ case InputEventType.PointerMotionAbsolute:
+ HandlePointerMotionAbsolute(GetMouse(device), LibInput.GetPointerEvent(pevent));
+ break;
+ }
+ }
+
+ LibInput.DestroyEvent(pevent);
+ }
+ }
+
+ void HandleDeviceAdded(IntPtr context, IntPtr device)
+ {
+ if (LibInput.DeviceHasCapability(device, DeviceCapability.Keyboard))
+ {
+ KeyboardDevice keyboard = new KeyboardDevice(device, Keyboards.Count);
+ KeyboardCandidates.Add(keyboard.Id, keyboard);
+ Debug.Print("[Input] Added keyboard device {0} '{1}' on '{2}' ('{3}')",
+ keyboard.Id, keyboard.Name, keyboard.LogicalSeatName, keyboard.PhysicalSeatName);
+ }
+
+ if (LibInput.DeviceHasCapability(device, DeviceCapability.Mouse))
+ {
+ MouseDevice mouse = new MouseDevice(device, Mice.Count);
+ MouseCandidates.Add(mouse.Id, mouse);
+ Debug.Print("[Input] Added mouse device {0} '{1}' on '{2}' ('{3}')",
+ mouse.Id, mouse.Name, mouse.LogicalSeatName, mouse.PhysicalSeatName);
+ }
+
+ if (LibInput.DeviceHasCapability(device, DeviceCapability.Touch))
+ {
+ Debug.Print("[Input] Todo: touch device.");
+ }
+ }
+
+ void HandleDeviceRemoved(IntPtr context, IntPtr device)
+ {
+ if (LibInput.DeviceHasCapability(device, DeviceCapability.Keyboard))
+ {
+ int id = GetId(device);
+ Keyboards.TryRemove(id);
+ KeyboardCandidates.TryRemove(id);
+ }
+
+ if (LibInput.DeviceHasCapability(device, DeviceCapability.Mouse))
+ {
+ int id = GetId(device);
+ Mice.TryRemove(id);
+ MouseCandidates.TryRemove(id);
+ }
+ }
+
+ void HandleKeyboard(KeyboardDevice device, KeyboardEvent e)
+ {
+ if (device != null)
+ {
+ device.State.SetIsConnected(true);
+ Debug.Print("[Input] Added keyboard {0}", device.Id);
+
+ Key key = Key.Unknown;
+ uint raw = e.Key;
+ if (raw >= 0 && raw < KeyMap.Length)
+ {
+ key = KeyMap[raw];
+ }
+
+ if (key == Key.Unknown)
+ {
+ Debug.Print("[Linux] Unknown key with code '{0}'", raw);
+ }
+
+ device.State.SetKeyState(key, e.KeyState == KeyState.Pressed);
+ }
+ }
+
+ void HandlePointerAxis(MouseDevice mouse, PointerEvent e)
+ {
+ if (mouse != null)
+ {
+ mouse.State.SetIsConnected(true);
+
+ if (e.HasAxis(PointerAxis.HorizontalScroll))
+ {
+ mouse.State.SetScrollRelative((float)e.AxisValue(PointerAxis.HorizontalScroll), 0);
+ }
+ if (e.HasAxis(PointerAxis.VerticalScroll))
+ {
+ mouse.State.SetScrollRelative(0, (float)e.AxisValue(PointerAxis.VerticalScroll));
+ }
+ }
+ }
+
+ void HandlePointerButton(MouseDevice mouse, PointerEvent e)
+ {
+ if (mouse != null)
+ {
+ mouse.State.SetIsConnected(true);
+
+ MouseButton button = Evdev.GetMouseButton(e.Button);
+ ButtonState state = e.ButtonState;
+ mouse.State[(MouseButton)button] = state == ButtonState.Pressed;
+ }
+ }
+
+ void HandlePointerMotion(MouseDevice mouse, PointerEvent e)
+ {
+ Vector2 delta = new Vector2((float)e.DeltaX, (float)e.DeltaY);
+ if (mouse != null)
+ {
+ mouse.State.SetIsConnected(true);
+ mouse.State.Position += delta;
+ }
+
+ CursorPosition = new Vector2(
+ MathHelper.Clamp(CursorPosition.X + delta.X, bounds.Left, bounds.Right - 1),
+ MathHelper.Clamp(CursorPosition.Y + delta.Y, bounds.Top, bounds.Bottom - 1));
+ UpdateCursor();
+ }
+
+ void HandlePointerMotionAbsolute(MouseDevice mouse, PointerEvent e)
+ {
+ if (mouse != null)
+ {
+ mouse.State.SetIsConnected(true);
+ mouse.State.Position = new Vector2((float)e.X, (float)e.Y);
+ }
+
+ CursorPosition = new Vector2(
+ (float)e.TransformedX(bounds.Width),
+ (float)e.TransformedY(bounds.Height));
+ UpdateCursor();
+ }
+
+ static int GetId(IntPtr device)
+ {
+ return LibInput.DeviceGetData(device).ToInt32();
+ }
+
+ KeyboardDevice GetKeyboard(IntPtr device)
+ {
+ int id = GetId(device);
+ KeyboardDevice keyboard = KeyboardCandidates.FromHardwareId(id);
+ if (keyboard != null)
+ {
+ Keyboards.Add(id, keyboard);
+ }
+ else
+ {
+ Debug.Print("[Input] Keyboard {0} does not exist in device list.", id);
+ }
+ return keyboard;
+ }
+
+ MouseDevice GetMouse(IntPtr device)
+ {
+ int id = GetId(device);
+ MouseDevice mouse = MouseCandidates.FromHardwareId(id);
+ if (mouse != null)
+ {
+ Mice.Add(id, mouse);
+ }
+ else
+ {
+ Debug.Print("[Input] Mouse {0} does not exist in device list.", id);
+ }
+ return mouse;
+ }
+
+ #endregion
+
+ #region IKeyboardDriver2 implementation
+
+ KeyboardState IKeyboardDriver2.GetState()
+ {
+ lock (Sync)
+ {
+ KeyboardState state = new KeyboardState();
+ foreach (KeyboardDevice keyboard in Keyboards)
+ {
+ state.MergeBits(keyboard.State);
+ }
+ return state;
+ }
+ }
+
+ KeyboardState IKeyboardDriver2.GetState(int index)
+ {
+ lock (Sync)
+ {
+ KeyboardDevice device = Keyboards.FromIndex(index);
+ if (device != null)
+ {
+ return device.State;
+ }
+ else
+ {
+ return new KeyboardState();
+ }
+ }
+ }
+
+ string IKeyboardDriver2.GetDeviceName(int index)
+ {
+ lock (Sync)
+ {
+ KeyboardDevice device = Keyboards.FromIndex(index);
+ if (device != null)
+ {
+ return device.Name;
+ }
+ else
+ {
+ return String.Empty;
+ }
+ }
+ }
+
+ #endregion
+
+ #region IMouseDriver2 implementation
+
+ MouseState IMouseDriver2.GetState()
+ {
+ lock (Sync)
+ {
+ MouseState state = new MouseState();
+ foreach (MouseDevice mouse in Mice)
+ {
+ state.MergeBits(mouse.State);
+ }
+ return state;
+ }
+ }
+
+ MouseState IMouseDriver2.GetState(int index)
+ {
+ lock (Sync)
+ {
+ MouseDevice device = Mice.FromIndex(index);
+ if (device != null)
+ {
+ return device.State;
+ }
+ else
+ {
+ return new MouseState();
+ }
+ }
+ }
+
+ void IMouseDriver2.SetPosition(double x, double y)
+ {
+ // Todo: this does not appear to be supported in libinput.
+ // We will have to emulate this in the KMS mouse rendering code.
+ CursorOffset = new Vector2(
+ (float)x - CursorPosition.X,
+ (float)y - CursorPosition.Y);
+ UpdateCursor();
+ }
+
+ MouseState IMouseDriver2.GetCursorState()
+ {
+ MouseState state = (this as IMouseDriver2).GetState();
+ state.Position = CursorPosition + CursorOffset;
+ return state;
+ }
+
+ #endregion
+
+ #region IDisposable implementation
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (input_context != IntPtr.Zero)
+ {
+ Debug.Print("[Input] Destroying libinput context");
+ LibInput.Suspend(input_context);
+ Interlocked.Increment(ref exit);
+
+ LibInput.DestroyContext(input_context);
+ input_context = IntPtr.Zero;
+ }
+
+ if (udev != IntPtr.Zero)
+ {
+ Debug.Print("[Input] Destroying udev context");
+ Udev.Destroy(udev);
+ udev = IntPtr.Zero;
+ }
+
+ input_interface = null;
+ }
+ else
+ {
+ Debug.Print("[Input] {0} leaked. Did you forget to call Dispose()?", GetType().FullName);
+ }
+ }
+
+ ~LinuxInput()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+ }
+}
+
--- /dev/null
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
+//
+// 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 System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using OpenTK.Input;
+
+namespace OpenTK.Platform.Linux
+{
+ struct AxisInfo
+ {
+ public JoystickAxis Axis;
+ public InputAbsInfo Info;
+ }
+
+ class LinuxJoystickDetails
+ {
+ public Guid Guid;
+ public string Name;
+ public int FileDescriptor;
+ public int PathIndex; // e.g. "0" for "/dev/input/event0". Used as a hardware id
+ public JoystickState State;
+ public JoystickCapabilities Caps;
+
+ public readonly Dictionary<EvdevAxis, AxisInfo> AxisMap =
+ new Dictionary<EvdevAxis, AxisInfo>();
+ public readonly Dictionary<EvdevButton, int> ButtonMap =
+ new Dictionary<EvdevButton, int>();
+ }
+
+ sealed class LinuxJoystick : IJoystickDriver2
+ {
+ #region Fields
+
+ static readonly HatPosition[,] HatPositions = new HatPosition[,]
+ {
+ { HatPosition.UpLeft, HatPosition.Up, HatPosition.UpRight },
+ { HatPosition.Left, HatPosition.Centered, HatPosition.Right },
+ { HatPosition.DownLeft, HatPosition.Down, HatPosition.DownRight }
+ };
+
+ readonly object sync = new object();
+
+ readonly FileSystemWatcher watcher = new FileSystemWatcher();
+
+ readonly DeviceCollection<LinuxJoystickDetails> Sticks =
+ new DeviceCollection<LinuxJoystickDetails>();
+
+ bool disposed;
+
+ #endregion
+
+ #region Constructors
+
+ public LinuxJoystick()
+ {
+ string path =
+ Directory.Exists(JoystickPath) ? JoystickPath :
+ Directory.Exists(JoystickPathLegacy) ? JoystickPathLegacy :
+ String.Empty;
+
+ if (!String.IsNullOrEmpty(path))
+ {
+ watcher.Path = path;
+
+ watcher.Created += JoystickAdded;
+ watcher.Deleted += JoystickRemoved;
+ watcher.EnableRaisingEvents = true;
+
+ OpenJoysticks(path);
+ }
+ }
+
+ #endregion
+
+ #region Private Members
+
+ void OpenJoysticks(string path)
+ {
+ lock (sync)
+ {
+ foreach (string file in Directory.GetFiles(path))
+ {
+ LinuxJoystickDetails stick = OpenJoystick(file);
+ if (stick != null)
+ {
+ Sticks.Add(stick.PathIndex, stick);
+ }
+ }
+ }
+ }
+
+ int GetJoystickNumber(string path)
+ {
+ const string evdev = "event";
+ if (path.StartsWith(evdev))
+ {
+ int num;
+ if (Int32.TryParse(path.Substring(evdev.Length), out num))
+ {
+ return num;
+ }
+ }
+ return -1;
+ }
+
+ void JoystickAdded(object sender, FileSystemEventArgs e)
+ {
+ lock (sync)
+ {
+ OpenJoystick(e.FullPath);
+ }
+ }
+
+ void JoystickRemoved(object sender, FileSystemEventArgs e)
+ {
+ lock (sync)
+ {
+ string file = Path.GetFileName(e.FullPath);
+ int number = GetJoystickNumber(file);
+ if (number != -1)
+ {
+ var stick = Sticks.FromHardwareId(number);
+ if (stick != null)
+ {
+ CloseJoystick(stick);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region Private Members
+
+ Guid CreateGuid(EvdevInputId id, string name)
+ {
+ // Note: the first 8bytes of the Guid are byteswapped
+ // in three parts when using `new Guid(byte[])`:
+ // (int, short, short).
+ // We need to take that into account to match the expected
+ // Guid in the database. Ugh.
+
+ byte[] bytes = new byte[16];
+
+ int i = 0;
+ byte[] bus = BitConverter.GetBytes((int)id.BusType);
+ bytes[i++] = bus[3];
+ bytes[i++] = bus[2];
+ bytes[i++] = bus[1];
+ bytes[i++] = bus[0];
+
+ if (id.Vendor != 0 && id.Product != 0 && id.Version != 0)
+ {
+ byte[] vendor = BitConverter.GetBytes(id.Vendor);
+ byte[] product = BitConverter.GetBytes(id.Product);
+ byte[] version = BitConverter.GetBytes(id.Version);
+ bytes[i++] = vendor[1];
+ bytes[i++] = vendor[0];
+ bytes[i++] = 0;
+ bytes[i++] = 0;
+ bytes[i++] = product[0]; // no byteswapping
+ bytes[i++] = product[1];
+ bytes[i++] = 0;
+ bytes[i++] = 0;
+ bytes[i++] = version[0]; // no byteswapping
+ bytes[i++] = version[1];
+ bytes[i++] = 0;
+ bytes[i++] = 0;
+ }
+ else
+ {
+ for (int j = 0; j < bytes.Length - i; j++)
+ {
+ bytes[i + j] = (byte)name[j];
+ }
+ }
+
+ return new Guid(bytes);
+ }
+
+ unsafe static bool TestBit(byte* ptr, int bit)
+ {
+ int byte_offset = bit / 8;
+ int bit_offset = bit % 8;
+ return (*(ptr + byte_offset) & (1 << bit_offset)) != 0;
+ }
+
+ unsafe static void QueryCapabilities(LinuxJoystickDetails stick,
+ byte* axisbit, int axisbytes,
+ byte* keybit, int keybytes,
+ out int axes, out int buttons, out int hats)
+ {
+ // Note: since we are trying to be compatible with the SDL2 gamepad database,
+ // we have to match SDL2 behavior bug-for-bug. This means:
+ // HAT0-HAT3 are all reported as hats (even if the docs say that HAT1 and HAT2 can be analogue triggers)
+ // DPAD buttons are reported as buttons, not as hats (unlike Windows and Mac OS X)
+
+ axes = buttons = hats = 0;
+ for (EvdevAxis axis = 0; axis < EvdevAxis.CNT && (int)axis < axisbytes * 8; axis++)
+ {
+ InputAbsInfo info;
+ bool is_valid = true;
+ is_valid &= TestBit(axisbit, (int)axis);
+ is_valid &= Evdev.GetAbs(stick.FileDescriptor, axis, out info) >= 0;
+ if (is_valid)
+ {
+ if (axis >= EvdevAxis.HAT0X && axis <= EvdevAxis.HAT3Y)
+ {
+ // Analogue hat
+ stick.AxisMap.Add(axis, new AxisInfo
+ {
+ Axis = (JoystickAxis)(JoystickHat)hats++,
+ Info = info
+ });
+ }
+ else
+ {
+ // Regular axis
+ stick.AxisMap.Add(axis, new AxisInfo
+ {
+ Axis = (JoystickAxis)axes++,
+ Info = info
+ });
+ }
+ }
+ }
+
+ for (EvdevButton button = 0; button < EvdevButton.Last && (int)button < keybytes * 8; button++)
+ {
+ if (TestBit(keybit, (int)button))
+ {
+ stick.ButtonMap.Add(button, buttons++);
+ }
+ }
+ }
+
+ LinuxJoystickDetails OpenJoystick(string path)
+ {
+ LinuxJoystickDetails stick = null;
+
+ int number = GetJoystickNumber(Path.GetFileName(path));
+ if (number >= 0)
+ {
+ int fd = -1;
+ try
+ {
+ fd = Libc.open(path, OpenFlags.NonBlock);
+ if (fd == -1)
+ return null;
+
+ unsafe
+ {
+ const int evsize = Evdev.EventCount / 8;
+ const int axissize = Evdev.AxisCount / 8;
+ const int keysize = Evdev.KeyCount / 8;
+ byte* evbit = stackalloc byte[evsize];
+ byte* axisbit = stackalloc byte[axissize];
+ byte* keybit = stackalloc byte[keysize];
+
+ string name;
+ EvdevInputId id;
+
+ // Ensure this is a joystick device
+ bool is_valid = true;
+
+ is_valid &= Evdev.GetBit(fd, 0, evsize, new IntPtr(evbit)) >= 0;
+ is_valid &= Evdev.GetBit(fd, EvdevType.ABS, axissize, new IntPtr(axisbit)) >= 0;
+ is_valid &= Evdev.GetBit(fd, EvdevType.KEY, keysize, new IntPtr(keybit)) >= 0;
+
+ is_valid &= TestBit(evbit, (int)EvdevType.KEY);
+ is_valid &= TestBit(evbit, (int)EvdevType.ABS);
+ is_valid &= TestBit(axisbit, (int)EvdevAxis.X);
+ is_valid &= TestBit(axisbit, (int)EvdevAxis.Y);
+
+ is_valid &= Evdev.GetName(fd, out name) >= 0;
+ is_valid &= Evdev.GetId(fd, out id) >= 0;
+
+ if (is_valid)
+ {
+ stick = new LinuxJoystickDetails
+ {
+ FileDescriptor = fd,
+ PathIndex = number,
+ State = new JoystickState(),
+ Name = name,
+ Guid = CreateGuid(id, name),
+ };
+
+ int axes, buttons, hats;
+ QueryCapabilities(stick, axisbit, axissize, keybit, keysize,
+ out axes, out buttons, out hats);
+
+ stick.Caps = new JoystickCapabilities(axes, buttons, hats, false);
+
+ // Poll the joystick once, to initialize its state
+ PollJoystick(stick);
+ }
+ }
+
+ Debug.Print("Found joystick on path {0}", path);
+ }
+ catch (Exception e)
+ {
+ Debug.Print("Error opening joystick: {0}", e.ToString());
+ }
+ finally
+ {
+ if (stick == null && fd != -1)
+ {
+ // Not a joystick
+ Libc.close(fd);
+ }
+ }
+ }
+
+ return stick;
+ }
+
+ void CloseJoystick(LinuxJoystickDetails js)
+ {
+ Sticks.Remove(js.FileDescriptor);
+
+ Libc.close(js.FileDescriptor);
+ js.FileDescriptor = -1;
+ js.State = new JoystickState(); // clear joystick state
+ js.Caps = new JoystickCapabilities();
+ }
+
+ JoystickHatState TranslateHat(int x, int y)
+ {
+ return new JoystickHatState(HatPositions[x, y]);
+ }
+
+ void PollJoystick(LinuxJoystickDetails js)
+ {
+ unsafe
+ {
+ const int EventCount = 32;
+ InputEvent* events = stackalloc InputEvent[EventCount];
+
+ long length = 0;
+ while (true)
+ {
+ length = (long)Libc.read(js.FileDescriptor, (void*)events, (UIntPtr)(sizeof(InputEvent) * EventCount));
+ if (length <= 0)
+ break;
+
+ // Only mark the joystick as connected when we actually start receiving events.
+ // Otherwise, the Xbox wireless receiver will register 4 joysticks even if no
+ // actual joystick is connected to the receiver.
+ js.Caps.SetIsConnected(true);
+ js.State.SetIsConnected(true);
+
+ length /= sizeof(InputEvent);
+ for (int i = 0; i < length; i++)
+ {
+ InputEvent *e = events + i;
+ switch (e->Type)
+ {
+ case EvdevType.ABS:
+ {
+ AxisInfo axis;
+ if (js.AxisMap.TryGetValue((EvdevAxis)e->Code, out axis))
+ {
+ if (axis.Info.Maximum > axis.Info.Minimum)
+ {
+ if (e->Code >= (int)EvdevAxis.HAT0X && e->Code <= (int)EvdevAxis.HAT3Y)
+ {
+ // We currently treat analogue hats as digital hats
+ // to maintain compatibility with SDL2. We can do
+ // better than this, however.
+ JoystickHat hat = JoystickHat.Hat0 + (e->Code - (int)EvdevAxis.HAT0X) / 2;
+ JoystickHatState pos = js.State.GetHat(hat);
+ int xy_axis = (int)axis.Axis & 0x1;
+ switch (xy_axis)
+ {
+ case 0:
+ // X-axis
+ pos = TranslateHat(
+ e->Value.CompareTo(0) + 1,
+ pos.IsUp ? 0 : pos.IsDown ? 2 : 1);
+ break;
+
+ case 1:
+ // Y-axis
+ pos = TranslateHat(
+ pos.IsLeft ? 0 : pos.IsRight ? 2 : 1,
+ e->Value.CompareTo(0) + 1);
+ break;
+ }
+
+ js.State.SetHat(hat, pos);
+ }
+ else
+ {
+ // This axis represents a regular axis or trigger
+ js.State.SetAxis(
+ axis.Axis,
+ (short)Common.HidHelper.ScaleValue(e->Value,
+ axis.Info.Minimum, axis.Info.Maximum,
+ short.MinValue, short.MaxValue));
+ }
+ }
+ }
+ break;
+ }
+
+ case EvdevType.KEY:
+ {
+ int button;
+ if (js.ButtonMap.TryGetValue((EvdevButton)e->Code, out button))
+ {
+ js.State.SetButton(button, e->Value != 0);
+ }
+ break;
+ }
+ }
+
+ // Create a serial number (total seconds in 24.8 fixed point format)
+ int sec = (int)((long)e->Time.Seconds & 0xffffffff);
+ int msec = (int)e->Time.MicroSeconds / 1000;
+ int packet =
+ ((sec & 0x00ffffff) << 24) |
+ Common.HidHelper.ScaleValue(msec, 0, 1000, 0, 255);
+ js.State.SetPacketNumber(packet);
+ }
+ }
+ }
+ }
+
+ static readonly string JoystickPath = "/dev/input";
+ static readonly string JoystickPathLegacy = "/dev";
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ }
+
+ watcher.Dispose();
+ foreach (LinuxJoystickDetails js in Sticks)
+ {
+ CloseJoystick(js);
+ }
+
+ disposed = true;
+ }
+ }
+
+ ~LinuxJoystick()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+
+ #region IJoystickDriver2 Members
+
+ JoystickState IJoystickDriver2.GetState(int index)
+ {
+ LinuxJoystickDetails js = Sticks.FromIndex(index);
+ if (js != null)
+ {
+ PollJoystick(js);
+ return js.State;
+ }
+ return new JoystickState();
+ }
+
+ JoystickCapabilities IJoystickDriver2.GetCapabilities(int index)
+ {
+ LinuxJoystickDetails js = Sticks.FromIndex(index);
+ if (js != null)
+ {
+ return js.Caps;
+ }
+ return new JoystickCapabilities();
+ }
+
+ Guid IJoystickDriver2.GetGuid(int index)
+ {
+ LinuxJoystickDetails js = Sticks.FromIndex(index);
+ if (js != null)
+ {
+ return js.Guid;
+ }
+ return Guid.Empty;
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+#region License
+//
+// LinuxKeyboardTTY.cs
+//
+// Author:
+// thefiddler <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 System.IO;
+using System.Threading;
+using OpenTK.Input;
+
+namespace OpenTK.Platform.Linux
+{
+ // Todo: this has terrible side-effects on process exit
+ // (the keyboard remains tied up.) We need to find a
+ // proper way to clean up after ourselves, even in case
+ // of a crash.
+ #if EXPERIMENTAL
+ class LinuxKeyboardTTY : IKeyboardDriver2, IDisposable
+ {
+ const int stdin = 0; // STDIN_FILENO
+ readonly object sync = new object();
+ Thread input_thread;
+ long exit;
+ KeyboardState state;
+
+ TerminalState original_state;
+ TerminalState current_state;
+
+ IntPtr original_mode = new IntPtr(-1);
+ int original_stdin;
+
+ public LinuxKeyboardTTY()
+ {
+ Debug.Print("[Linux] Using TTY keyboard input.");
+
+ if (!SetupTTY(stdin))
+ {
+ throw new NotSupportedException();
+ }
+
+ input_thread = new Thread(ProcessEvents);
+ input_thread.IsBackground = true;
+ input_thread.Start();
+ }
+
+ #region Private Members
+
+ bool SetupTTY(int stdin)
+ {
+ // Ensure that we are using a real terminal,
+ // rather than some short of file redirection.thing.
+ if (!Terminal.IsTerminal(stdin))
+ {
+ Debug.Print("[Linux] Terminal.IsTerminal({0}) returned false.", stdin);
+ return false;
+ }
+
+ //original_stdin = Libc.dup(stdin);
+
+ int ret = Terminal.GetAttributes(stdin, out original_state);
+ if (ret < 0)
+ {
+ Debug.Print("[Linux] Terminal.GetAttributes({0}) failed. Error: {1}",
+ stdin, ret);
+ return false;
+ }
+
+ // Retrieve current keyboard mode
+ ret = Libc.ioctl(stdin, KeyboardIoctlCode.GetMode, ref original_mode);
+ if (ret != 0)
+ {
+ Debug.Print("[Linux] Libc.ioctl({0}, KeyboardIoctlCode.GetMode) failed. Error: {1}",
+ stdin, ret);
+ return false;
+ }
+
+ // Update terminal state
+ current_state = original_state;
+ current_state.LocalMode &= ~(/*LocalFlags.ECHO |*/ LocalFlags.ICANON | LocalFlags.ISIG);
+ current_state.InputMode &= ~(
+ InputFlags.ISTRIP | InputFlags.IGNCR | InputFlags.ICRNL |
+ InputFlags.INLCR | InputFlags.IXOFF | InputFlags.IXON);
+ current_state.ControlCharacters.VMIN = 0;
+ current_state.ControlCharacters.VTIME = 0;
+ Terminal.SetAttributes(stdin, OptionalActions.FLUSH, ref current_state);
+
+ // Request keycodes
+ int mode = 0x02; // K_MEDIUMRAW
+ ret = Libc.ioctl(stdin, KeyboardIoctlCode.SetMode, mode);
+ if (ret != 0)
+ {
+ Debug.Print("[Linux] Libc.ioctl({0}, KeyboardIoctlCode.SetMode, {1}) failed. Error: {2}",
+ stdin, mode, ret);
+ ExitTTY(this, EventArgs.Empty);
+ return false;
+ }
+
+ // Ensure we reset the original keyboard/terminal state on exit,
+ // even if we crash.
+ HookEvents();
+
+ return true;
+ }
+
+ void ExitTTY(object sender, EventArgs e)
+ {
+ if (original_mode != new IntPtr(-1))
+ {
+ Debug.Print("[Linux] Exiting TTY keyboard input.");
+
+ Libc.ioctl(stdin, KeyboardIoctlCode.SetMode, ref original_mode);
+ Terminal.SetAttributes(stdin, OptionalActions.FLUSH, ref original_state);
+ original_mode = new IntPtr(-1);
+
+ UnhookEvents();
+ }
+ }
+
+ void HookEvents()
+ {
+ Process.GetCurrentProcess().Exited += ExitTTY;
+ Console.CancelKeyPress += ExitTTY;
+ }
+
+ void UnhookEvents()
+ {
+ Process.GetCurrentProcess().Exited -= ExitTTY;
+ Console.CancelKeyPress -= ExitTTY;
+ }
+
+ void ProcessEvents()
+ {
+ state.SetIsConnected(true);
+
+ while (Interlocked.Read(ref exit) == 0)
+ {
+ byte scancode;
+ short extended;
+
+ while (Libc.read(stdin, out scancode) > 0)
+ {
+ bool pressed = (scancode & 0x80) == 0;
+ int key = scancode & ~0x80;
+ KeyModifiers mods;
+ Debug.Print("{0}:{1} is {2}", key, (int)TranslateKey(key, out mods), pressed);
+
+ if (key == 0)
+ {
+ // This is an extended scancode, ignore
+ Libc.read(stdin, out extended);
+ }
+ else
+ {
+ lock (sync)
+ {
+ state[(Key)key] = pressed;
+ }
+ }
+
+ }
+ }
+
+ input_thread = null;
+ }
+
+ Key TranslateKey(int key, out KeyModifiers mods)
+ {
+ int k = MathHelper.Clamp((int)key, 0, KeyMap.Length);
+ Key result = KeyMap[k];
+ mods = 0;
+ mods |= (result == Key.AltLeft || result == Key.AltRight) ? KeyModifiers.Alt : 0;
+ mods |= (result == Key.ControlLeft || result == Key.ControlRight) ? KeyModifiers.Control : 0;
+ mods |= (result == Key.ShiftLeft || result == Key.ShiftRight) ? KeyModifiers.Shift : 0;
+ return KeyMap[k];
+ }
+
+ static readonly Key[] KeyMap = Evdev.KeyMap;
+
+ #endregion
+
+ #region IKeyboardDriver2 implementation
+
+ public KeyboardState GetState()
+ {
+ lock (this)
+ {
+ return state;
+ }
+ }
+
+ public KeyboardState GetState(int index)
+ {
+ lock (this)
+ {
+ if (index == 0)
+ return state;
+ else
+ return new KeyboardState();
+ }
+ }
+
+ public string GetDeviceName(int index)
+ {
+ if (index == 0)
+ return "Standard Input";
+ else
+ return String.Empty;
+ }
+
+ #endregion
+
+ #region IDisposable Implementation
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ void Dispose(bool disposing)
+ {
+ Interlocked.Increment(ref exit);
+
+ if (disposing)
+ {
+ ExitTTY(this, EventArgs.Empty);
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", typeof(LinuxKeyboardTTY).FullName);
+ }
+ }
+
+ ~LinuxKeyboardTTY()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+ }
+ #endif
+}
+
--- /dev/null
+#region License
+//
+// LinuxNativeWindow.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.Diagnostics;
+#if !MINIMAL
+using System.Drawing;
+#endif
+using System.Runtime.InteropServices;
+using OpenTK.Graphics;
+using OpenTK.Input;
+using OpenTK.Platform.Egl;
+
+namespace OpenTK.Platform.Linux
+{
+ using Egl = OpenTK.Platform.Egl.Egl;
+
+ class LinuxNativeWindow : NativeWindowBase
+ {
+ LinuxWindowInfo window;
+ string title;
+ Icon icon;
+ Rectangle bounds;
+ Size client_size;
+ bool exists;
+ bool is_focused;
+ bool is_cursor_visible = true;
+
+ KeyboardState previous_keyboard;
+ MouseState previous_mouse;
+
+ MouseCursor cursor_current;
+ BufferObject cursor_custom;
+ BufferObject cursor_default;
+ BufferObject cursor_empty;
+
+ public LinuxNativeWindow(IntPtr display, IntPtr gbm, int fd,
+ int x, int y, int width, int height, string title,
+ GraphicsMode mode, GameWindowFlags options,
+ DisplayDevice display_device)
+ {
+ Debug.Print("[KMS] Creating window on display {0:x}", display);
+
+ Title = title;
+
+ display_device = display_device ?? DisplayDevice.Default;
+ if (display_device == null)
+ {
+ throw new NotSupportedException("[KMS] Driver does not currently support headless systems");
+ }
+
+ window = new LinuxWindowInfo(display, fd, gbm, display_device.Id as LinuxDisplay);
+
+ // Note: we only support fullscreen windows on KMS.
+ // We implicitly override the requested width and height
+ // by the width and height of the DisplayDevice, if any.
+ width = display_device.Width;
+ height = display_device.Height;
+ bounds = new Rectangle(0, 0, width, height);
+ client_size = bounds.Size;
+
+ if (!mode.Index.HasValue)
+ {
+ mode = new EglGraphicsMode().SelectGraphicsMode(window, mode, 0);
+ }
+ Debug.Print("[KMS] Selected EGL mode {0}", mode);
+
+ SurfaceFormat format = GetSurfaceFormat(display, mode);
+ SurfaceFlags usage = SurfaceFlags.Rendering | SurfaceFlags.Scanout;
+ if (!Gbm.IsFormatSupported(gbm, format, usage))
+ {
+ Debug.Print("[KMS] Failed to find suitable surface format, using XRGB8888");
+ format = SurfaceFormat.XRGB8888;
+ }
+
+ Debug.Print("[KMS] Creating GBM surface on {0:x} with {1}x{2} {3} [{4}]",
+ gbm, width, height, format, usage);
+ IntPtr gbm_surface = Gbm.CreateSurface(gbm,
+ width, height, format, usage);
+ if (gbm_surface == IntPtr.Zero)
+ {
+ throw new NotSupportedException("[KMS] Failed to create GBM surface for rendering");
+ }
+
+ window.Handle = gbm_surface;
+ Debug.Print("[KMS] Created GBM surface {0:x}", window.Handle);
+
+ window.CreateWindowSurface(mode.Index.Value);
+ Debug.Print("[KMS] Created EGL surface {0:x}", window.Surface);
+
+ cursor_default = CreateCursor(gbm, Cursors.Default);
+ cursor_empty = CreateCursor(gbm, Cursors.Empty);
+ Cursor = MouseCursor.Default;
+ exists = true;
+ }
+
+ #region Private Members
+
+ static BufferObject CreateCursor(IntPtr gbm, MouseCursor cursor)
+ {
+ if (cursor.Width > 64 || cursor.Height > 64)
+ {
+ Debug.Print("[KMS] Cursor size {0}x{1} unsupported. Maximum is 64x64.",
+ cursor.Width, cursor.Height);
+ return default(BufferObject);
+ }
+
+ int width = 64;
+ int height = 64;
+ SurfaceFormat format = SurfaceFormat.ARGB8888;
+ SurfaceFlags usage = SurfaceFlags.Cursor64x64 | SurfaceFlags.Write;
+
+ Debug.Print("[KMS] Gbm.CreateBuffer({0:X}, {1}, {2}, {3}, {4}).",
+ gbm, width, height, format, usage);
+
+ BufferObject bo = Gbm.CreateBuffer(
+ gbm, width, height, format, usage);
+
+ if (bo == BufferObject.Zero)
+ {
+ Debug.Print("[KMS] Failed to create buffer.");
+ return bo;
+ }
+
+ // Copy cursor.Data into a new buffer of the correct size
+ byte[] cursor_data = new byte[width * height * 4];
+ for (int y = 0; y < cursor.Height; y++)
+ {
+ int dst_offset = y * width * 4;
+ int src_offset = y * cursor.Width * 4;
+ int src_length = cursor.Width * 4;
+ Array.Copy(
+ cursor.Data, src_offset,
+ cursor_data, dst_offset,
+ src_length);
+ }
+ bo.Write(cursor_data);
+
+ return bo;
+ }
+
+ void SetCursor(MouseCursor cursor)
+ {
+ BufferObject bo = default(BufferObject);
+ if (cursor == MouseCursor.Default)
+ {
+ bo = cursor_default;
+ }
+ else if (cursor == MouseCursor.Empty)
+ {
+ bo = cursor_empty;
+ }
+ else
+ {
+ if (cursor_custom != BufferObject.Zero)
+ cursor_custom.Dispose();
+ cursor_custom = CreateCursor(window.BufferManager, cursor);
+ bo = cursor_custom;
+ }
+
+ // If we failed to create a proper cursor, try falling back
+ // to the empty cursor. We do not want to crash here!
+ if (bo == BufferObject.Zero)
+ {
+ bo = cursor_empty;
+ }
+
+ if (bo != BufferObject.Zero)
+ {
+ Drm.SetCursor(window.FD, window.DisplayDevice.Id,
+ bo.Handle, bo.Width, bo.Height, cursor.X, cursor.Y);
+ }
+ }
+
+ static SurfaceFormat GetSurfaceFormat(IntPtr display, GraphicsMode mode)
+ {
+ // Use EGL 1.4 EGL_NATIVE_VISUAL_ID to retrieve
+ // the corresponding surface format. If that fails
+ // fall back to a manual algorithm.
+ int format;
+ Egl.GetConfigAttrib(display, mode.Index.Value,
+ Egl.NATIVE_VISUAL_ID, out format);
+ if ((SurfaceFormat)format != 0)
+ return (SurfaceFormat)format;
+
+ Debug.Print("[KMS] Failed to retrieve EGL visual from GBM surface. Error: {0}",
+ Egl.GetError());
+ Debug.Print("[KMS] Falling back to hardcoded formats.");
+
+ int r = mode.ColorFormat.Red;
+ int g = mode.ColorFormat.Green;
+ int b = mode.ColorFormat.Blue;
+ int a = mode.ColorFormat.Alpha;
+
+ if (mode.ColorFormat.IsIndexed)
+ return SurfaceFormat.C8;
+ if (r == 3 && g == 3 && b == 2 && a == 0)
+ return SurfaceFormat.RGB332;
+ if (r == 5 && g == 6 && b == 5 && a == 0)
+ return SurfaceFormat.RGB565;
+ if (r == 5 && g == 6 && b == 5 && a == 0)
+ return SurfaceFormat.RGB565;
+ if (r == 8 && g == 8 && b == 8 && a == 0)
+ return SurfaceFormat.RGB888;
+ if (r == 5 && g == 5 && b == 5 && a == 1)
+ return SurfaceFormat.RGBA5551;
+ if (r == 10 && g == 10 && b == 10 && a == 2)
+ return SurfaceFormat.RGBA1010102;
+ if (r == 4 && g == 4 && b == 4 && a == 4)
+ return SurfaceFormat.RGBA4444;
+ if (r == 8 && g == 8 && b == 8 && a == 8)
+ return SurfaceFormat.RGBA8888;
+
+ return SurfaceFormat.RGBA8888;
+ }
+
+ KeyboardState ProcessKeyboard(KeyboardState keyboard)
+ {
+ for (Key i = 0; i < Key.LastKey; i++)
+ {
+ if (keyboard[i])
+ {
+ OnKeyDown(i, previous_keyboard[i]);
+ // Todo: implement libxkb-common binding for text input
+ }
+
+ if (!keyboard[i] && previous_keyboard[i])
+ {
+ OnKeyUp(i);
+ }
+ }
+ return keyboard;
+ }
+
+ MouseState ProcessMouse(MouseState mouse)
+ {
+ // Handle mouse buttons
+ for (MouseButton i = 0; i < MouseButton.LastButton; i++)
+ {
+ if (mouse[i] && !previous_mouse[i])
+ {
+ OnMouseDown(i);
+ }
+
+ if (!mouse[i] && previous_mouse[i])
+ {
+ OnMouseUp(i);
+ }
+ }
+
+ // Handle mouse movement
+ {
+ int x = mouse.X;
+ int y = mouse.Y;
+
+ // Make sure the mouse cannot leave the GameWindow when captured
+ if (!CursorVisible)
+ {
+ x = MathHelper.Clamp(mouse.X, Bounds.Left, Bounds.Right - 1);
+ y = MathHelper.Clamp(mouse.Y, Bounds.Top, Bounds.Bottom - 1);
+ if (x != mouse.X || y != mouse.Y)
+ {
+ Mouse.SetPosition(x, y);
+ }
+ }
+
+ if (x != previous_mouse.X || y != previous_mouse.Y)
+ {
+ OnMouseMove(x, y);
+ }
+ }
+
+ // Handle mouse scroll
+ if (mouse.Scroll != previous_mouse.Scroll)
+ {
+ float dx = mouse.Scroll.X - previous_mouse.Scroll.X;
+ float dy = mouse.Scroll.Y - previous_mouse.Scroll.Y;
+ OnMouseWheel(dx, dy);
+ }
+
+ // Handle mouse focus
+ // Note: focus follows mouse. Literally.
+ bool cursor_in = Bounds.Contains(new Point(mouse.X, mouse.Y));
+ if (!cursor_in && Focused)
+ {
+ OnMouseLeave(EventArgs.Empty);
+ SetFocus(false);
+ }
+ else if (cursor_in && !Focused)
+ {
+ OnMouseEnter(EventArgs.Empty);
+ SetFocus(true);
+ }
+
+ return mouse;
+ }
+
+ void SetFocus(bool focus)
+ {
+ if (is_focused != focus)
+ {
+ is_focused = focus;
+ OnFocusedChanged(EventArgs.Empty);
+ }
+ }
+
+ #endregion
+
+ #region INativeWindow Members
+
+ public override void ProcessEvents()
+ {
+ // Note: there is no event-based keyboard/mouse input available.
+ // We will fake that by polling OpenTK.Input.
+ previous_keyboard = ProcessKeyboard(Keyboard.GetState());
+ previous_mouse = ProcessMouse(Mouse.GetCursorState());
+
+ base.ProcessEvents();
+ }
+
+ public override void Close()
+ {
+ exists = false;
+ }
+
+ public override Point PointToClient(Point point)
+ {
+ var client = Location;
+ return new Point(point.X - client.X, point.Y - client.Y);
+ }
+
+ public override Point PointToScreen(Point point)
+ {
+ var client = Location;
+ return new Point(point.X + client.X, point.Y + client.Y);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Debug.Print("[KMS] Destroying window {0}.", window.Handle);
+ Drm.SetCursor(window.FD, window.DisplayDevice.Id, 0, 0, 0, 0, 0);
+ window.Dispose();
+ Gbm.DestroySurface(window.Handle);
+ }
+ else
+ {
+ Debug.Print("[KMS] {0} leaked. Did you forget to call Dispose()?", GetType().FullName);
+ }
+ }
+
+ public override Icon Icon
+ {
+ get
+ {
+ return icon;
+ }
+ set
+ {
+ if (icon != value)
+ {
+ icon = value;
+ OnIconChanged(EventArgs.Empty);
+ }
+ }
+ }
+
+ public override string Title
+ {
+ get
+ {
+ return title;
+ }
+ set
+ {
+ if (title != value)
+ {
+ title = value;
+ OnTitleChanged(EventArgs.Empty);
+ }
+ }
+ }
+
+ public override bool Focused
+ {
+ get
+ {
+ return is_focused;
+ }
+ }
+
+ public override bool Visible
+ {
+ get
+ {
+ return true;
+ }
+ set
+ {
+ }
+ }
+
+ public override bool Exists
+ {
+ get
+ {
+ return exists;
+ }
+ }
+
+ public override IWindowInfo WindowInfo
+ {
+ get
+ {
+ return window;
+ }
+ }
+
+ public override WindowState WindowState
+ {
+ get
+ {
+ return WindowState.Fullscreen;
+ }
+ set
+ {
+ }
+ }
+
+ public override WindowBorder WindowBorder
+ {
+ get
+ {
+ return WindowBorder.Hidden;
+ }
+ set
+ {
+ }
+ }
+
+ public override Rectangle Bounds
+ {
+ get
+ {
+ return bounds;
+ }
+ set
+ {
+ }
+ }
+
+ public override Size ClientSize
+ {
+ get
+ {
+ return client_size;
+ }
+ set
+ {
+ }
+ }
+
+ public override bool CursorVisible
+ {
+ get
+ {
+ return is_cursor_visible;
+ }
+ set
+ {
+ if (value && !is_cursor_visible)
+ {
+ SetCursor(cursor_current);
+ }
+ else if (!value && is_cursor_visible)
+ {
+ SetCursor(MouseCursor.Empty);
+ }
+ is_cursor_visible = value;
+ }
+ }
+
+ public override MouseCursor Cursor
+ {
+ get
+ {
+ return cursor_current;
+ }
+ set
+ {
+ if (cursor_current != value)
+ {
+ if (cursor_custom != BufferObject.Zero)
+ {
+ cursor_custom.Dispose();
+ }
+
+ if (CursorVisible)
+ {
+ SetCursor(value);
+ }
+ cursor_current = value;
+ }
+ }
+ }
+
+ #endregion
+ }
+}
+
--- /dev/null
+#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 System.Diagnostics;
+using OpenTK.Platform.Egl;
+
+namespace OpenTK.Platform.Linux
+{
+ class LinuxWindowInfo : EglWindowInfo
+ {
+ public int FD { get; private set; }
+ public LinuxDisplay DisplayDevice { get; private set; }
+ public IntPtr BufferManager { get; private set; }
+
+ public LinuxWindowInfo(IntPtr display, int fd, IntPtr gbm, LinuxDisplay display_device)
+ : base(IntPtr.Zero, display, IntPtr.Zero)
+ {
+ if (display_device == null)
+ throw new ArgumentNullException();
+
+ FD = fd;
+ BufferManager = gbm;
+ DisplayDevice = display_device;
+ // The window handle and surface handle must
+ // be filled in manually once they are known.
+ }
+ }
+}
+
--- /dev/null
+#region License
+//
+// Cursor.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;
+
+namespace OpenTK
+{
+ /// <summary>
+ /// Represents a predefined or custom mouse cursor.
+ /// </summary>
+ public sealed class MouseCursor : WindowIcon
+ {
+ static readonly MouseCursor default_cursor = new MouseCursor();
+ static readonly MouseCursor empty_cursor = new MouseCursor(
+ 0, 0, 16, 16, new byte[16 * 16 * 4]);
+
+ int x;
+ int y;
+
+ MouseCursor()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new <see cref="MouseCursor"/> instance from a
+ /// contiguous array of BGRA pixels.
+ /// Each pixel is composed of 4 bytes, representing B, G, R and A values,
+ /// respectively. For correct antialiasing of translucent cursors,
+ /// the B, G and R components should be premultiplied with the A component:
+ /// <code>
+ /// B = (byte)((B * A) / 255)
+ /// G = (byte)((G * A) / 255)
+ /// R = (byte)((R * A) / 255)
+ /// </code>
+ /// </summary>
+ /// <param name="hotx">The x-coordinate of the cursor hotspot, in the range [0, width]</param>
+ /// <param name="hoty">The y-coordinate of the cursor hotspot, in the range [0, height]</param>
+ /// <param name="width">The width of the cursor data, in pixels.</param>
+ /// <param name="height">The height of the cursor data, in pixels.</param>
+ /// <param name="data">
+ /// A byte array representing the cursor image,
+ /// laid out as a contiguous array of BGRA pixels.
+ /// </param>
+ public MouseCursor(int hotx, int hoty, int width, int height, byte[] data)
+ : base(width, height, data)
+ {
+ if (hotx < 0 || hotx >= Width || hoty < 0 || hoty >= Height)
+ throw new ArgumentOutOfRangeException();
+
+ x = hotx;
+ y = hoty;
+ }
+
+ /// <summary>
+ /// Initializes a new <see cref="MouseCursor"/> instance from a
+ /// contiguous array of BGRA pixels.
+ /// Each pixel is composed of 4 bytes, representing B, G, R and A values,
+ /// respectively. For correct antialiasing of translucent cursors,
+ /// the B, G and R components should be premultiplied with the A component:
+ /// <code>
+ /// B = (byte)((B * A) / 255)
+ /// G = (byte)((G * A) / 255)
+ /// R = (byte)((R * A) / 255)
+ /// </code>
+ /// </summary>
+ /// <param name="hotx">The x-coordinate of the cursor hotspot, in the range [0, width]</param>
+ /// <param name="hoty">The y-coordinate of the cursor hotspot, in the range [0, height]</param>
+ /// <param name="width">The width of the cursor data, in pixels.</param>
+ /// <param name="height">The height of the cursor data, in pixels.</param>
+ /// <param name="data">
+ /// A pointer to the cursor image, laid out as a contiguous array of BGRA pixels.
+ /// </param>
+ public MouseCursor(int hotx, int hoty, int width, int height, IntPtr data)
+ : base(width, height, data)
+ {
+ if (hotx < 0 || hotx >= Width || hoty < 0 || hoty >= Height)
+ throw new ArgumentOutOfRangeException();
+
+ x = hotx;
+ y = hoty;
+ }
+
+ internal int X { get { return x; } }
+ internal int Y { get { return y; } }
+
+ /// <summary>
+ /// Gets the default mouse cursor for this platform.
+ /// </summary>
+ public static MouseCursor Default
+ {
+ get
+ {
+ return default_cursor;
+ }
+ }
+
+ /// <summary>
+ /// Gets an empty (invisible) mouse cursor.
+ /// </summary>
+ public static MouseCursor Empty
+ {
+ get
+ {
+ return empty_cursor;
+ }
+ }
+ }
+}
+
--- /dev/null
+#region License
+//
+// WindowIcon.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
+{
+ /// <summary>
+ /// Stores a window icon. A window icon is defined
+ /// as a 2-dimensional buffer of RGBA values.
+ /// </summary>
+ public class WindowIcon
+ {
+ byte[] data;
+ int width;
+ int height;
+
+ /// \internal
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OpenTK.WindowIcon"/> class.
+ /// </summary>
+ internal protected WindowIcon()
+ {
+ }
+
+ WindowIcon(int width, int height)
+ {
+ if (width < 0 || width > 256 || height < 0 || height > 256)
+ throw new ArgumentOutOfRangeException();
+
+ this.width = width;
+ this.height = height;
+ }
+
+ internal WindowIcon(int width, int height, byte[] data)
+ : this(width, height)
+ {
+ if (data == null)
+ throw new ArgumentNullException();
+ if (data.Length < Width * Height * 4)
+ throw new ArgumentOutOfRangeException();
+
+ this.data = data;
+ }
+
+ internal WindowIcon(int width, int height, IntPtr data)
+ : this(width, height)
+ {
+ if (data == IntPtr.Zero)
+ throw new ArgumentNullException();
+
+ // We assume that width and height are correctly set.
+ // If they are not, we will read garbage and probably
+ // crash.
+ this.data = new byte[width * height * 4];
+ Marshal.Copy(data, this.data, 0, this.data.Length);
+ }
+
+ internal byte[] Data { get { return data; } }
+ internal int Width { get { return width; } }
+ internal int Height { get { return height; } }
+ }
+}
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4B57740A-75FB-4978-A8E8-8B1793B7474F}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>testDrm</RootNamespace>
+ <AssemblyName>testDrm</AssemblyName>
+ <ReleaseVersion>0.5</ReleaseVersion>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <OutputPath>$(SolutionDir)build/$(Configuration)</OutputPath>
+ <IntermediateOutputPath>$(SolutionDir)build/obj/$(Configuration)</IntermediateOutputPath>
+ <CustomCommands>
+ <CustomCommands>
+ <Command type="Execute" command="${TargetName}" workingdir="${SolutionDir}/build/${ProjectConfigName}" />
+ </CustomCommands>
+ </CustomCommands>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <DefineConstants>DEBUG;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
+ <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>full</DebugType>
+ <Optimize>true</Optimize>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <ConsolePause>false</ConsolePause>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
+ <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ItemGroup>
+ <Compile Include="Main.cs" />
+ <Compile Include="src\Linux\Bindings\Drm.cs" />
+ <Compile Include="src\Linux\Bindings\Evdev.cs" />
+ <Compile Include="src\Linux\Bindings\Gbm.cs" />
+ <Compile Include="src\Linux\Bindings\Kms.cs" />
+ <Compile Include="src\Linux\Bindings\Libc.cs" />
+ <Compile Include="src\Linux\Bindings\LibInput.cs" />
+ <Compile Include="src\Linux\Bindings\Poll.cs" />
+ <Compile Include="src\Linux\Bindings\Terminal.cs" />
+ <Compile Include="src\Linux\Bindings\Udev.cs" />
+ <Compile Include="src\BlittableValueType.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="src\DisplayResolution.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="src\Egl.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="src\DrmDevice.cs" />
+ <Compile Include="src\Linux\DefaultCursor.cs" />
+ <Compile Include="src\MouseCursor.cs" />
+ <Compile Include="src\WindowIcon.cs" />
+ <Compile Include="Mono.Cairo\Antialias.cs" />
+ <Compile Include="Mono.Cairo\Cairo.cs" />
+ <Compile Include="Mono.Cairo\CairoDebug.cs" />
+ <Compile Include="Mono.Cairo\Color.cs" />
+ <Compile Include="Mono.Cairo\Content.cs" />
+ <Compile Include="Mono.Cairo\Context.cs" />
+ <Compile Include="Mono.Cairo\DirectFBSurface.cs" />
+ <Compile Include="Mono.Cairo\Distance.cs" />
+ <Compile Include="Mono.Cairo\Extend.cs" />
+ <Compile Include="Mono.Cairo\FillRule.cs" />
+ <Compile Include="Mono.Cairo\Filter.cs" />
+ <Compile Include="Mono.Cairo\FontExtents.cs" />
+ <Compile Include="Mono.Cairo\FontFace.cs" />
+ <Compile Include="Mono.Cairo\FontOptions.cs" />
+ <Compile Include="Mono.Cairo\FontSlant.cs" />
+ <Compile Include="Mono.Cairo\FontType.cs" />
+ <Compile Include="Mono.Cairo\FontWeight.cs" />
+ <Compile Include="Mono.Cairo\Format.cs" />
+ <Compile Include="Mono.Cairo\GlitzSurface.cs" />
+ <Compile Include="Mono.Cairo\Glyph.cs" />
+ <Compile Include="Mono.Cairo\Gradient.cs" />
+ <Compile Include="Mono.Cairo\HintMetrics.cs" />
+ <Compile Include="Mono.Cairo\HintStyle.cs" />
+ <Compile Include="Mono.Cairo\ImageSurface.cs" />
+ <Compile Include="Mono.Cairo\LineCap.cs" />
+ <Compile Include="Mono.Cairo\LineJoin.cs" />
+ <Compile Include="Mono.Cairo\LinearGradient.cs" />
+ <Compile Include="Mono.Cairo\Matrix.cs" />
+ <Compile Include="Mono.Cairo\NativeMethods.cs" />
+ <Compile Include="Mono.Cairo\Operator.cs" />
+ <Compile Include="Mono.Cairo\PSSurface.cs" />
+ <Compile Include="Mono.Cairo\Path.cs" />
+ <Compile Include="Mono.Cairo\Pattern.cs" />
+ <Compile Include="Mono.Cairo\PatternType.cs" />
+ <Compile Include="Mono.Cairo\PdfSurface.cs" />
+ <Compile Include="Mono.Cairo\Point.cs" />
+ <Compile Include="Mono.Cairo\PointD.cs" />
+ <Compile Include="Mono.Cairo\RadialGradient.cs" />
+ <Compile Include="Mono.Cairo\Rectangle.cs" />
+ <Compile Include="Mono.Cairo\Region.cs" />
+ <Compile Include="Mono.Cairo\ScaledFont.cs" />
+ <Compile Include="Mono.Cairo\SolidPattern.cs" />
+ <Compile Include="Mono.Cairo\Status.cs" />
+ <Compile Include="Mono.Cairo\SubpixelOrder.cs" />
+ <Compile Include="Mono.Cairo\Surface.cs" />
+ <Compile Include="Mono.Cairo\SurfacePattern.cs" />
+ <Compile Include="Mono.Cairo\SurfaceType.cs" />
+ <Compile Include="Mono.Cairo\SvgSurface.cs" />
+ <Compile Include="Mono.Cairo\SvgVersion.cs" />
+ <Compile Include="Mono.Cairo\TextExtents.cs" />
+ <Compile Include="Mono.Cairo\Win32Surface.cs" />
+ <Compile Include="Mono.Cairo\XcbSurface.cs" />
+ <Compile Include="Mono.Cairo\XlibSurface.cs" />
+ <Compile Include="Mono.Cairo\Device.cs" />
+ <Compile Include="Mono.Cairo\GLSurface.cs" />
+ <Compile Include="Mono.Cairo\GLXDevice.cs" />
+ <Compile Include="Mono.Cairo\WGLDevice.cs" />
+ <Compile Include="Mono.Cairo\EGLDevice.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="src\" />
+ <Folder Include="Mono.Cairo\" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="src\Linux\LinuxFactory.cs" />
+ <None Include="src\Linux\LinuxGraphicsContext.cs" />
+ <None Include="src\Linux\LinuxInput.cs" />
+ <None Include="src\Linux\LinuxJoystick.cs">
+ <SubType>Code</SubType>
+ </None>
+ <None Include="src\Linux\LinuxKeyboardTTY.cs" />
+ <None Include="src\Linux\LinuxNativeWindow.cs" />
+ <None Include="src\Linux\LinuxWindowInfo.cs" />
+ <None Include="src\Linux\LinuxDisplayDriver.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Crow.csproj">
+ <Project>{C2980F9B-4798-4C05-99E2-E174810F7C7B}</Project>
+ <Name>Crow</Name>
+ </ProjectReference>
+ </ItemGroup>
+</Project>
\ No newline at end of file