From a4be468bb4df28213bee49af6d72463b8becde4a Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Sat, 6 May 2017 09:52:22 +0200 Subject: [PATCH] first tests with KMS, Mono.Cairo is embeded --- Crow.sln | 10 + Tests/BasicTests.cs | 2 +- Tests/CrowWindow.cs | 2 +- Tests/OpenGL/Shader.cs | 18 +- Tests/Tests.csproj | 11 +- Tests/test.cs | 81 ++ src/GraphicObjects/GraphicObject.cs | 3 +- src/GraphicObjects/Group.cs | 1 - src/GraphicObjects/Popper.cs | 1 - src/GraphicObjects/ScrollBar.cs | 1 - src/Input/Buttons.cs | 2 +- src/XCursor.cs | 1 - testDrm/Main.cs | 363 +++++++++ testDrm/Mono.Cairo/Antialias.cs | 43 + testDrm/Mono.Cairo/Cairo.cs | 53 ++ testDrm/Mono.Cairo/CairoDebug.cs | 82 ++ testDrm/Mono.Cairo/Color.cs | 75 ++ testDrm/Mono.Cairo/Content.cs | 43 + testDrm/Mono.Cairo/Context.cs | 911 +++++++++++++++++++++ testDrm/Mono.Cairo/Device.cs | 101 +++ testDrm/Mono.Cairo/DirectFBSurface.cs | 43 + testDrm/Mono.Cairo/Distance.cs | 58 ++ testDrm/Mono.Cairo/EGLDevice.cs | 41 + testDrm/Mono.Cairo/Extend.cs | 45 + testDrm/Mono.Cairo/FillRule.cs | 41 + testDrm/Mono.Cairo/Filter.cs | 45 + testDrm/Mono.Cairo/FontExtents.cs | 104 +++ testDrm/Mono.Cairo/FontFace.cs | 108 +++ testDrm/Mono.Cairo/FontOptions.cs | 143 ++++ testDrm/Mono.Cairo/FontSlant.cs | 42 + testDrm/Mono.Cairo/FontType.cs | 41 + testDrm/Mono.Cairo/FontWeight.cs | 41 + testDrm/Mono.Cairo/Format.cs | 48 ++ testDrm/Mono.Cairo/GLSurface.cs | 61 ++ testDrm/Mono.Cairo/GLXDevice.cs | 49 ++ testDrm/Mono.Cairo/GlitzSurface.cs | 43 + testDrm/Mono.Cairo/Glyph.cs | 96 +++ testDrm/Mono.Cairo/Gradient.cs | 66 ++ testDrm/Mono.Cairo/HintMetrics.cs | 41 + testDrm/Mono.Cairo/HintStyle.cs | 43 + testDrm/Mono.Cairo/ImageSurface.cs | 104 +++ testDrm/Mono.Cairo/LineCap.cs | 41 + testDrm/Mono.Cairo/LineJoin.cs | 42 + testDrm/Mono.Cairo/LinearGradient.cs | 59 ++ testDrm/Mono.Cairo/Matrix.cs | 193 +++++ testDrm/Mono.Cairo/NativeMethods.cs | 948 ++++++++++++++++++++++ testDrm/Mono.Cairo/Operator.cs | 56 ++ testDrm/Mono.Cairo/PSSurface.cs | 64 ++ testDrm/Mono.Cairo/Path.cs | 73 ++ testDrm/Mono.Cairo/Pattern.cs | 155 ++++ testDrm/Mono.Cairo/PatternType.cs | 42 + testDrm/Mono.Cairo/PdfSurface.cs | 50 ++ testDrm/Mono.Cairo/Point.cs | 57 ++ testDrm/Mono.Cairo/PointD.cs | 58 ++ testDrm/Mono.Cairo/RadialGradient.cs | 46 ++ testDrm/Mono.Cairo/Rectangle.cs | 99 +++ testDrm/Mono.Cairo/Region.cs | 196 +++++ testDrm/Mono.Cairo/ScaledFont.cs | 123 +++ testDrm/Mono.Cairo/SolidPattern.cs | 72 ++ testDrm/Mono.Cairo/Status.cs | 64 ++ testDrm/Mono.Cairo/SubpixelOrder.cs | 42 + testDrm/Mono.Cairo/Surface.cs | 234 ++++++ testDrm/Mono.Cairo/SurfacePattern.cs | 57 ++ testDrm/Mono.Cairo/SurfaceType.cs | 61 ++ testDrm/Mono.Cairo/SvgSurface.cs | 50 ++ testDrm/Mono.Cairo/SvgVersion.cs | 41 + testDrm/Mono.Cairo/TextExtents.cs | 98 +++ testDrm/Mono.Cairo/WGLDevice.cs | 45 + testDrm/Mono.Cairo/Win32Surface.cs | 44 + testDrm/Mono.Cairo/XcbSurface.cs | 54 ++ testDrm/Mono.Cairo/XlibSurface.cs | 95 +++ testDrm/src/BlittableValueType.cs | 291 +++++++ testDrm/src/DisplayDevice.cs | 565 +++++++++++++ testDrm/src/DisplayResolution.cs | 232 ++++++ testDrm/src/DrmDevice.cs | 927 +++++++++++++++++++++ testDrm/src/Egl.cs | 385 +++++++++ testDrm/src/Linux/Bindings/Drm.cs | 243 ++++++ testDrm/src/Linux/Bindings/Evdev.cs | 635 +++++++++++++++ testDrm/src/Linux/Bindings/Gbm.cs | 282 +++++++ testDrm/src/Linux/Bindings/Kms.cs | 46 ++ testDrm/src/Linux/Bindings/LibInput.cs | 333 ++++++++ testDrm/src/Linux/Bindings/Libc.cs | 186 +++++ testDrm/src/Linux/Bindings/Poll.cs | 65 ++ testDrm/src/Linux/Bindings/Terminal.cs | 170 ++++ testDrm/src/Linux/Bindings/Udev.cs | 46 ++ testDrm/src/Linux/DefaultCursor.cs | 76 ++ testDrm/src/Linux/LinuxDisplayDriver.cs | 415 ++++++++++ testDrm/src/Linux/LinuxFactory.cs | 253 ++++++ testDrm/src/Linux/LinuxGraphicsContext.cs | 302 +++++++ testDrm/src/Linux/LinuxInput.cs | 721 ++++++++++++++++ testDrm/src/Linux/LinuxJoystick.cs | 533 ++++++++++++ testDrm/src/Linux/LinuxKeyboardTTY.cs | 268 ++++++ testDrm/src/Linux/LinuxNativeWindow.cs | 537 ++++++++++++ testDrm/src/Linux/LinuxWindowInfo.cs | 56 ++ testDrm/src/MouseCursor.cs | 135 +++ testDrm/src/WindowIcon.cs | 91 +++ testDrm/testDrm.csproj | 156 ++++ 97 files changed, 14294 insertions(+), 21 deletions(-) create mode 100644 Tests/test.cs create mode 100644 testDrm/Main.cs create mode 100644 testDrm/Mono.Cairo/Antialias.cs create mode 100644 testDrm/Mono.Cairo/Cairo.cs create mode 100644 testDrm/Mono.Cairo/CairoDebug.cs create mode 100644 testDrm/Mono.Cairo/Color.cs create mode 100644 testDrm/Mono.Cairo/Content.cs create mode 100644 testDrm/Mono.Cairo/Context.cs create mode 100644 testDrm/Mono.Cairo/Device.cs create mode 100644 testDrm/Mono.Cairo/DirectFBSurface.cs create mode 100644 testDrm/Mono.Cairo/Distance.cs create mode 100644 testDrm/Mono.Cairo/EGLDevice.cs create mode 100644 testDrm/Mono.Cairo/Extend.cs create mode 100644 testDrm/Mono.Cairo/FillRule.cs create mode 100644 testDrm/Mono.Cairo/Filter.cs create mode 100644 testDrm/Mono.Cairo/FontExtents.cs create mode 100644 testDrm/Mono.Cairo/FontFace.cs create mode 100644 testDrm/Mono.Cairo/FontOptions.cs create mode 100644 testDrm/Mono.Cairo/FontSlant.cs create mode 100644 testDrm/Mono.Cairo/FontType.cs create mode 100644 testDrm/Mono.Cairo/FontWeight.cs create mode 100644 testDrm/Mono.Cairo/Format.cs create mode 100644 testDrm/Mono.Cairo/GLSurface.cs create mode 100644 testDrm/Mono.Cairo/GLXDevice.cs create mode 100644 testDrm/Mono.Cairo/GlitzSurface.cs create mode 100644 testDrm/Mono.Cairo/Glyph.cs create mode 100644 testDrm/Mono.Cairo/Gradient.cs create mode 100644 testDrm/Mono.Cairo/HintMetrics.cs create mode 100644 testDrm/Mono.Cairo/HintStyle.cs create mode 100644 testDrm/Mono.Cairo/ImageSurface.cs create mode 100644 testDrm/Mono.Cairo/LineCap.cs create mode 100644 testDrm/Mono.Cairo/LineJoin.cs create mode 100644 testDrm/Mono.Cairo/LinearGradient.cs create mode 100644 testDrm/Mono.Cairo/Matrix.cs create mode 100644 testDrm/Mono.Cairo/NativeMethods.cs create mode 100644 testDrm/Mono.Cairo/Operator.cs create mode 100644 testDrm/Mono.Cairo/PSSurface.cs create mode 100644 testDrm/Mono.Cairo/Path.cs create mode 100644 testDrm/Mono.Cairo/Pattern.cs create mode 100644 testDrm/Mono.Cairo/PatternType.cs create mode 100644 testDrm/Mono.Cairo/PdfSurface.cs create mode 100644 testDrm/Mono.Cairo/Point.cs create mode 100644 testDrm/Mono.Cairo/PointD.cs create mode 100644 testDrm/Mono.Cairo/RadialGradient.cs create mode 100644 testDrm/Mono.Cairo/Rectangle.cs create mode 100644 testDrm/Mono.Cairo/Region.cs create mode 100644 testDrm/Mono.Cairo/ScaledFont.cs create mode 100644 testDrm/Mono.Cairo/SolidPattern.cs create mode 100644 testDrm/Mono.Cairo/Status.cs create mode 100644 testDrm/Mono.Cairo/SubpixelOrder.cs create mode 100644 testDrm/Mono.Cairo/Surface.cs create mode 100644 testDrm/Mono.Cairo/SurfacePattern.cs create mode 100644 testDrm/Mono.Cairo/SurfaceType.cs create mode 100644 testDrm/Mono.Cairo/SvgSurface.cs create mode 100644 testDrm/Mono.Cairo/SvgVersion.cs create mode 100644 testDrm/Mono.Cairo/TextExtents.cs create mode 100644 testDrm/Mono.Cairo/WGLDevice.cs create mode 100644 testDrm/Mono.Cairo/Win32Surface.cs create mode 100644 testDrm/Mono.Cairo/XcbSurface.cs create mode 100644 testDrm/Mono.Cairo/XlibSurface.cs create mode 100644 testDrm/src/BlittableValueType.cs create mode 100644 testDrm/src/DisplayDevice.cs create mode 100644 testDrm/src/DisplayResolution.cs create mode 100644 testDrm/src/DrmDevice.cs create mode 100644 testDrm/src/Egl.cs create mode 100644 testDrm/src/Linux/Bindings/Drm.cs create mode 100644 testDrm/src/Linux/Bindings/Evdev.cs create mode 100644 testDrm/src/Linux/Bindings/Gbm.cs create mode 100644 testDrm/src/Linux/Bindings/Kms.cs create mode 100644 testDrm/src/Linux/Bindings/LibInput.cs create mode 100644 testDrm/src/Linux/Bindings/Libc.cs create mode 100644 testDrm/src/Linux/Bindings/Poll.cs create mode 100644 testDrm/src/Linux/Bindings/Terminal.cs create mode 100644 testDrm/src/Linux/Bindings/Udev.cs create mode 100644 testDrm/src/Linux/DefaultCursor.cs create mode 100644 testDrm/src/Linux/LinuxDisplayDriver.cs create mode 100644 testDrm/src/Linux/LinuxFactory.cs create mode 100644 testDrm/src/Linux/LinuxGraphicsContext.cs create mode 100644 testDrm/src/Linux/LinuxInput.cs create mode 100644 testDrm/src/Linux/LinuxJoystick.cs create mode 100644 testDrm/src/Linux/LinuxKeyboardTTY.cs create mode 100644 testDrm/src/Linux/LinuxNativeWindow.cs create mode 100644 testDrm/src/Linux/LinuxWindowInfo.cs create mode 100644 testDrm/src/MouseCursor.cs create mode 100644 testDrm/src/WindowIcon.cs create mode 100644 testDrm/testDrm.csproj diff --git a/Crow.sln b/Crow.sln index ba1b6741..9edb890b 100644 --- a/Crow.sln +++ b/Crow.sln @@ -7,16 +7,26 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj 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 diff --git a/Tests/BasicTests.cs b/Tests/BasicTests.cs index 3e8bb716..44c33fd3 100644 --- a/Tests/BasicTests.cs +++ b/Tests/BasicTests.cs @@ -39,7 +39,7 @@ namespace Tests class BasicTests : CrowWindow { public BasicTests () - : base(800, 600,"test: press to toogle test files") + : base(1600, 900,"test: press to toogle test files") { } diff --git a/Tests/CrowWindow.cs b/Tests/CrowWindow.cs index b1308d1e..c5a544ac 100644 --- a/Tests/CrowWindow.cs +++ b/Tests/CrowWindow.cs @@ -89,7 +89,7 @@ namespace Crow #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), diff --git a/Tests/OpenGL/Shader.cs b/Tests/OpenGL/Shader.cs index 6ae99b89..e77230d8 100644 --- a/Tests/OpenGL/Shader.cs +++ b/Tests/OpenGL/Shader.cs @@ -51,7 +51,7 @@ namespace Crow GeomSourcePath; #region Sources protected string _vertSource = @" - #version 330 + #version 300 es precision lowp float; uniform mat4 mvp; @@ -68,7 +68,7 @@ namespace Crow }"; protected string _fragSource = @" - #version 330 + #version 300 es precision lowp float; uniform sampler2D tex; @@ -209,8 +209,8 @@ namespace Crow GL.GetProgramInfoLog(pgmId, out info); if (!string.IsNullOrEmpty (info)) { - Debug.WriteLine ("Linkage:"); - Debug.WriteLine (info); + Console.WriteLine ("Linkage:"); + Console.WriteLine (info); } info = null; @@ -218,8 +218,8 @@ namespace Crow 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); @@ -302,14 +302,14 @@ namespace Crow 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 () diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 16c851a3..04344a40 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -8,7 +8,7 @@ Exe Tests Tests - Tests.Showcase + Tests.BasicTests v4.5 AnyCPU 0.5 @@ -28,12 +28,16 @@ 4 false DEBUG;TRACE;MEASURE_TIME + $(SolutionDir)build\obj\$(Configuration) + $(SolutionDir)build\$(Configuration) none true 0 false + $(SolutionDir)build\obj\$(Configuration) + $(SolutionDir)build\$(Configuration) @@ -43,9 +47,8 @@ gtk-sharp-3.0 - - $(SolutionDir)packages\OpenTK.2.0.0\lib\net20\OpenTK.dll - opentk + + ..\..\..\src\opentk-git\src\OpenTK\bin\Release\OpenTK.dll diff --git a/Tests/test.cs b/Tests/test.cs new file mode 100644 index 00000000..436fa67c --- /dev/null +++ b/Tests/test.cs @@ -0,0 +1,81 @@ +// +// HelloWorld.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 0db8fb54..bfed68b4 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -136,8 +136,9 @@ namespace Crow public Rectangle LastPaintedSlot; /// Prevent requeuing multiple times the same widget public bool IsQueueForRedraw = false; - /// drawing Cache, if null, a redraw is done, cached or not + /// drawing Cache bitmap public byte[] bmp; + /// if true, content has to be recreated public bool IsDirty = true; /// /// This size is computed on each child' layout changes. diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 549ca219..a71c53a0 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -29,7 +29,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Xml.Serialization; using Cairo; -using OpenTK.Input; using System.Diagnostics; using System.Reflection; diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index d3f2e7c8..0e5364d6 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -27,7 +27,6 @@ using System; using System.Xml.Serialization; using System.ComponentModel; -using OpenTK.Input; namespace Crow { diff --git a/src/GraphicObjects/ScrollBar.cs b/src/GraphicObjects/ScrollBar.cs index 91ce50ef..ca258aae 100644 --- a/src/GraphicObjects/ScrollBar.cs +++ b/src/GraphicObjects/ScrollBar.cs @@ -27,7 +27,6 @@ using System; using System.Xml.Serialization; using System.ComponentModel; -using OpenTK.Input; namespace Crow { diff --git a/src/Input/Buttons.cs b/src/Input/Buttons.cs index a80f5040..ebf3bc42 100644 --- a/src/Input/Buttons.cs +++ b/src/Input/Buttons.cs @@ -25,7 +25,7 @@ // THE SOFTWARE. using System; -namespace OpenTK.Input +namespace Crow { /// /// Enumerates available buttons for a GamePad device. diff --git a/src/XCursor.cs b/src/XCursor.cs index 0d7c244e..627e2afd 100644 --- a/src/XCursor.cs +++ b/src/XCursor.cs @@ -27,7 +27,6 @@ using System; using System.IO; using System.Diagnostics; -using OpenTK; using System.Collections.Generic; namespace Crow diff --git a/testDrm/Main.cs b/testDrm/Main.cs new file mode 100644 index 00000000..77e0d405 --- /dev/null +++ b/testDrm/Main.cs @@ -0,0 +1,363 @@ +// +// Main.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 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; + } + } +} + diff --git a/testDrm/Mono.Cairo/Antialias.cs b/testDrm/Mono.Cairo/Antialias.cs new file mode 100644 index 00000000..9ea64f75 --- /dev/null +++ b/testDrm/Mono.Cairo/Antialias.cs @@ -0,0 +1,43 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/Cairo.cs b/testDrm/Mono.Cairo/Cairo.cs new file mode 100644 index 00000000..c0a5f2ab --- /dev/null +++ b/testDrm/Mono.Cairo/Cairo.cs @@ -0,0 +1,53 @@ +// +// 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); + } + } + } +} diff --git a/testDrm/Mono.Cairo/CairoDebug.cs b/testDrm/Mono.Cairo/CairoDebug.cs new file mode 100644 index 00000000..d694bbb5 --- /dev/null +++ b/testDrm/Mono.Cairo/CairoDebug.cs @@ -0,0 +1,82 @@ +// +// 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 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 (); + } + + public static void OnAllocated (IntPtr obj) + { + if (!Enabled) + throw new InvalidOperationException (); + + traces[obj] = Environment.StackTrace; + } + + public static void OnDisposed (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); + } + } + +} diff --git a/testDrm/Mono.Cairo/Color.cs b/testDrm/Mono.Cairo/Color.cs new file mode 100644 index 00000000..030089e8 --- /dev/null +++ b/testDrm/Mono.Cairo/Color.cs @@ -0,0 +1,75 @@ +// +// 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; } + } + } +} diff --git a/testDrm/Mono.Cairo/Content.cs b/testDrm/Mono.Cairo/Content.cs new file mode 100644 index 00000000..a88d35a9 --- /dev/null +++ b/testDrm/Mono.Cairo/Content.cs @@ -0,0 +1,43 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/Context.cs b/testDrm/Mono.Cairo/Context.cs new file mode 100644 index 00000000..7ca0dee4 --- /dev/null +++ b/testDrm/Mono.Cairo/Context.cs @@ -0,0 +1,911 @@ +// +// 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 (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; + } + } +} diff --git a/testDrm/Mono.Cairo/Device.cs b/testDrm/Mono.Cairo/Device.cs new file mode 100644 index 00000000..06715bc9 --- /dev/null +++ b/testDrm/Mono.Cairo/Device.cs @@ -0,0 +1,101 @@ +// +// 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 (handle, disposing); + + if (!disposing || handle == IntPtr.Zero) + return; + + NativeMethods.cairo_device_destroy (handle); + handle = IntPtr.Zero; + } + } +} + diff --git a/testDrm/Mono.Cairo/DirectFBSurface.cs b/testDrm/Mono.Cairo/DirectFBSurface.cs new file mode 100644 index 00000000..afa57b7d --- /dev/null +++ b/testDrm/Mono.Cairo/DirectFBSurface.cs @@ -0,0 +1,43 @@ +// +// 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) + { + } + } +} diff --git a/testDrm/Mono.Cairo/Distance.cs b/testDrm/Mono.Cairo/Distance.cs new file mode 100644 index 00000000..7cba3729 --- /dev/null +++ b/testDrm/Mono.Cairo/Distance.cs @@ -0,0 +1,58 @@ +// +// 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; } + } + } +} diff --git a/testDrm/Mono.Cairo/EGLDevice.cs b/testDrm/Mono.Cairo/EGLDevice.cs new file mode 100644 index 00000000..45c988a3 --- /dev/null +++ b/testDrm/Mono.Cairo/EGLDevice.cs @@ -0,0 +1,41 @@ +// +// 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) + { + } + } +} + diff --git a/testDrm/Mono.Cairo/Extend.cs b/testDrm/Mono.Cairo/Extend.cs new file mode 100644 index 00000000..0ffee3fb --- /dev/null +++ b/testDrm/Mono.Cairo/Extend.cs @@ -0,0 +1,45 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/FillRule.cs b/testDrm/Mono.Cairo/FillRule.cs new file mode 100644 index 00000000..6d8c0626 --- /dev/null +++ b/testDrm/Mono.Cairo/FillRule.cs @@ -0,0 +1,41 @@ +// +// 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 + } +} diff --git a/testDrm/Mono.Cairo/Filter.cs b/testDrm/Mono.Cairo/Filter.cs new file mode 100644 index 00000000..d602ed7d --- /dev/null +++ b/testDrm/Mono.Cairo/Filter.cs @@ -0,0 +1,45 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/FontExtents.cs b/testDrm/Mono.Cairo/FontExtents.cs new file mode 100644 index 00000000..76c7e658 --- /dev/null +++ b/testDrm/Mono.Cairo/FontExtents.cs @@ -0,0 +1,104 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/FontFace.cs b/testDrm/Mono.Cairo/FontFace.cs new file mode 100644 index 00000000..19d8163c --- /dev/null +++ b/testDrm/Mono.Cairo/FontFace.cs @@ -0,0 +1,108 @@ +// +// 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 (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); } + } + } +} + diff --git a/testDrm/Mono.Cairo/FontOptions.cs b/testDrm/Mono.Cairo/FontOptions.cs new file mode 100644 index 00000000..5269d54d --- /dev/null +++ b/testDrm/Mono.Cairo/FontOptions.cs @@ -0,0 +1,143 @@ +// +// 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 (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); } + } + } +} + diff --git a/testDrm/Mono.Cairo/FontSlant.cs b/testDrm/Mono.Cairo/FontSlant.cs new file mode 100644 index 00000000..c4e1af78 --- /dev/null +++ b/testDrm/Mono.Cairo/FontSlant.cs @@ -0,0 +1,42 @@ +// +// 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 + } +} diff --git a/testDrm/Mono.Cairo/FontType.cs b/testDrm/Mono.Cairo/FontType.cs new file mode 100644 index 00000000..0c71fcb2 --- /dev/null +++ b/testDrm/Mono.Cairo/FontType.cs @@ -0,0 +1,41 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/FontWeight.cs b/testDrm/Mono.Cairo/FontWeight.cs new file mode 100644 index 00000000..9d1927d8 --- /dev/null +++ b/testDrm/Mono.Cairo/FontWeight.cs @@ -0,0 +1,41 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/Format.cs b/testDrm/Mono.Cairo/Format.cs new file mode 100644 index 00000000..f0bded3c --- /dev/null +++ b/testDrm/Mono.Cairo/Format.cs @@ -0,0 +1,48 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/GLSurface.cs b/testDrm/Mono.Cairo/GLSurface.cs new file mode 100644 index 00000000..9486c9cd --- /dev/null +++ b/testDrm/Mono.Cairo/GLSurface.cs @@ -0,0 +1,61 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/GLXDevice.cs b/testDrm/Mono.Cairo/GLXDevice.cs new file mode 100644 index 00000000..189872a2 --- /dev/null +++ b/testDrm/Mono.Cairo/GLXDevice.cs @@ -0,0 +1,49 @@ +// +// 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); } + } + } +} + diff --git a/testDrm/Mono.Cairo/GlitzSurface.cs b/testDrm/Mono.Cairo/GlitzSurface.cs new file mode 100644 index 00000000..6da1ac6a --- /dev/null +++ b/testDrm/Mono.Cairo/GlitzSurface.cs @@ -0,0 +1,43 @@ +// +// 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) + { + } + } +} diff --git a/testDrm/Mono.Cairo/Glyph.cs b/testDrm/Mono.Cairo/Glyph.cs new file mode 100644 index 00000000..ec9c2ff3 --- /dev/null +++ b/testDrm/Mono.Cairo/Glyph.cs @@ -0,0 +1,96 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/Gradient.cs b/testDrm/Mono.Cairo/Gradient.cs new file mode 100644 index 00000000..0fb617e4 --- /dev/null +++ b/testDrm/Mono.Cairo/Gradient.cs @@ -0,0 +1,66 @@ +// +// 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; + } + } +} + diff --git a/testDrm/Mono.Cairo/HintMetrics.cs b/testDrm/Mono.Cairo/HintMetrics.cs new file mode 100644 index 00000000..d4341424 --- /dev/null +++ b/testDrm/Mono.Cairo/HintMetrics.cs @@ -0,0 +1,41 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/HintStyle.cs b/testDrm/Mono.Cairo/HintStyle.cs new file mode 100644 index 00000000..bb848206 --- /dev/null +++ b/testDrm/Mono.Cairo/HintStyle.cs @@ -0,0 +1,43 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/ImageSurface.cs b/testDrm/Mono.Cairo/ImageSurface.cs new file mode 100644 index 00000000..98143fe8 --- /dev/null +++ b/testDrm/Mono.Cairo/ImageSurface.cs @@ -0,0 +1,104 @@ +// +// 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); } + } + } +} diff --git a/testDrm/Mono.Cairo/LineCap.cs b/testDrm/Mono.Cairo/LineCap.cs new file mode 100644 index 00000000..57cfdec2 --- /dev/null +++ b/testDrm/Mono.Cairo/LineCap.cs @@ -0,0 +1,41 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/LineJoin.cs b/testDrm/Mono.Cairo/LineJoin.cs new file mode 100644 index 00000000..439b2a51 --- /dev/null +++ b/testDrm/Mono.Cairo/LineJoin.cs @@ -0,0 +1,42 @@ +// +// 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 + } +} + diff --git a/testDrm/Mono.Cairo/LinearGradient.cs b/testDrm/Mono.Cairo/LinearGradient.cs new file mode 100644 index 00000000..85fdea84 --- /dev/null +++ b/testDrm/Mono.Cairo/LinearGradient.cs @@ -0,0 +1,59 @@ +// +// 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; + } + } + } +} + diff --git a/testDrm/Mono.Cairo/Matrix.cs b/testDrm/Mono.Cairo/Matrix.cs new file mode 100644 index 00000000..83ffce49 --- /dev/null +++ b/testDrm/Mono.Cairo/Matrix.cs @@ -0,0 +1,193 @@ +// +// 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 (); + } + + } +} diff --git a/testDrm/Mono.Cairo/NativeMethods.cs b/testDrm/Mono.Cairo/NativeMethods.cs new file mode 100644 index 00000000..9726cb8c --- /dev/null +++ b/testDrm/Mono.Cairo/NativeMethods.cs @@ -0,0 +1,948 @@ +// +// 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 diff --git a/testDrm/Mono.Cairo/Operator.cs b/testDrm/Mono.Cairo/Operator.cs new file mode 100644 index 00000000..c1ced71d --- /dev/null +++ b/testDrm/Mono.Cairo/Operator.cs @@ -0,0 +1,56 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/PSSurface.cs b/testDrm/Mono.Cairo/PSSurface.cs new file mode 100644 index 00000000..9d6b73be --- /dev/null +++ b/testDrm/Mono.Cairo/PSSurface.cs @@ -0,0 +1,64 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/Path.cs b/testDrm/Mono.Cairo/Path.cs new file mode 100644 index 00000000..184c606c --- /dev/null +++ b/testDrm/Mono.Cairo/Path.cs @@ -0,0 +1,73 @@ +// +// 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 (handle, disposing); + + if (!disposing|| handle == IntPtr.Zero) + return; + + NativeMethods.cairo_path_destroy (handle); + handle = IntPtr.Zero; + } + } +} diff --git a/testDrm/Mono.Cairo/Pattern.cs b/testDrm/Mono.Cairo/Pattern.cs new file mode 100644 index 00000000..bc0a962a --- /dev/null +++ b/testDrm/Mono.Cairo/Pattern.cs @@ -0,0 +1,155 @@ +// +// 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 (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); } + } + } +} + diff --git a/testDrm/Mono.Cairo/PatternType.cs b/testDrm/Mono.Cairo/PatternType.cs new file mode 100644 index 00000000..002469ff --- /dev/null +++ b/testDrm/Mono.Cairo/PatternType.cs @@ -0,0 +1,42 @@ +// +// 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, + } +} + diff --git a/testDrm/Mono.Cairo/PdfSurface.cs b/testDrm/Mono.Cairo/PdfSurface.cs new file mode 100644 index 00000000..c980f249 --- /dev/null +++ b/testDrm/Mono.Cairo/PdfSurface.cs @@ -0,0 +1,50 @@ +// +// 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); + } + } +} + diff --git a/testDrm/Mono.Cairo/Point.cs b/testDrm/Mono.Cairo/Point.cs new file mode 100644 index 00000000..e72ca6c5 --- /dev/null +++ b/testDrm/Mono.Cairo/Point.cs @@ -0,0 +1,57 @@ +// +// 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; } + } + } +} diff --git a/testDrm/Mono.Cairo/PointD.cs b/testDrm/Mono.Cairo/PointD.cs new file mode 100644 index 00000000..c2e3587d --- /dev/null +++ b/testDrm/Mono.Cairo/PointD.cs @@ -0,0 +1,58 @@ +// +// 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; } + } + } +} diff --git a/testDrm/Mono.Cairo/RadialGradient.cs b/testDrm/Mono.Cairo/RadialGradient.cs new file mode 100644 index 00000000..6422e00d --- /dev/null +++ b/testDrm/Mono.Cairo/RadialGradient.cs @@ -0,0 +1,46 @@ +// +// 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) + { + } + } +} + diff --git a/testDrm/Mono.Cairo/Rectangle.cs b/testDrm/Mono.Cairo/Rectangle.cs new file mode 100644 index 00000000..233a1bac --- /dev/null +++ b/testDrm/Mono.Cairo/Rectangle.cs @@ -0,0 +1,99 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/Region.cs b/testDrm/Mono.Cairo/Region.cs new file mode 100644 index 00000000..cd0ba33f --- /dev/null +++ b/testDrm/Mono.Cairo/Region.cs @@ -0,0 +1,196 @@ +// 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 (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); + } + } +} diff --git a/testDrm/Mono.Cairo/ScaledFont.cs b/testDrm/Mono.Cairo/ScaledFont.cs new file mode 100644 index 00000000..93719460 --- /dev/null +++ b/testDrm/Mono.Cairo/ScaledFont.cs @@ -0,0 +1,123 @@ +// +// 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 (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); + } + } +} + diff --git a/testDrm/Mono.Cairo/SolidPattern.cs b/testDrm/Mono.Cairo/SolidPattern.cs new file mode 100644 index 00000000..875b3fbf --- /dev/null +++ b/testDrm/Mono.Cairo/SolidPattern.cs @@ -0,0 +1,72 @@ +// +// 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); + } + } + } +} + diff --git a/testDrm/Mono.Cairo/Status.cs b/testDrm/Mono.Cairo/Status.cs new file mode 100644 index 00000000..6e5fbe01 --- /dev/null +++ b/testDrm/Mono.Cairo/Status.cs @@ -0,0 +1,64 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/SubpixelOrder.cs b/testDrm/Mono.Cairo/SubpixelOrder.cs new file mode 100644 index 00000000..e8ab6581 --- /dev/null +++ b/testDrm/Mono.Cairo/SubpixelOrder.cs @@ -0,0 +1,42 @@ +// +// 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, + } +} diff --git a/testDrm/Mono.Cairo/Surface.cs b/testDrm/Mono.Cairo/Surface.cs new file mode 100644 index 00000000..d38b7555 --- /dev/null +++ b/testDrm/Mono.Cairo/Surface.cs @@ -0,0 +1,234 @@ +// +// 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 (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); } + } + } +} diff --git a/testDrm/Mono.Cairo/SurfacePattern.cs b/testDrm/Mono.Cairo/SurfacePattern.cs new file mode 100644 index 00000000..4422b11d --- /dev/null +++ b/testDrm/Mono.Cairo/SurfacePattern.cs @@ -0,0 +1,57 @@ +// +// 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); } + } + } +} + diff --git a/testDrm/Mono.Cairo/SurfaceType.cs b/testDrm/Mono.Cairo/SurfaceType.cs new file mode 100644 index 00000000..ae86d134 --- /dev/null +++ b/testDrm/Mono.Cairo/SurfaceType.cs @@ -0,0 +1,61 @@ +// +// 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 + } +} diff --git a/testDrm/Mono.Cairo/SvgSurface.cs b/testDrm/Mono.Cairo/SvgSurface.cs new file mode 100644 index 00000000..41829501 --- /dev/null +++ b/testDrm/Mono.Cairo/SvgSurface.cs @@ -0,0 +1,50 @@ +// +// 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); + } + } +} + diff --git a/testDrm/Mono.Cairo/SvgVersion.cs b/testDrm/Mono.Cairo/SvgVersion.cs new file mode 100644 index 00000000..99cee289 --- /dev/null +++ b/testDrm/Mono.Cairo/SvgVersion.cs @@ -0,0 +1,41 @@ +// +// 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, + } +} + diff --git a/testDrm/Mono.Cairo/TextExtents.cs b/testDrm/Mono.Cairo/TextExtents.cs new file mode 100644 index 00000000..f9cd560f --- /dev/null +++ b/testDrm/Mono.Cairo/TextExtents.cs @@ -0,0 +1,98 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/WGLDevice.cs b/testDrm/Mono.Cairo/WGLDevice.cs new file mode 100644 index 00000000..03f7e3a4 --- /dev/null +++ b/testDrm/Mono.Cairo/WGLDevice.cs @@ -0,0 +1,45 @@ +// +// 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); } + } + } +} + diff --git a/testDrm/Mono.Cairo/Win32Surface.cs b/testDrm/Mono.Cairo/Win32Surface.cs new file mode 100644 index 00000000..dd244286 --- /dev/null +++ b/testDrm/Mono.Cairo/Win32Surface.cs @@ -0,0 +1,44 @@ +// +// 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) + { + } + } +} diff --git a/testDrm/Mono.Cairo/XcbSurface.cs b/testDrm/Mono.Cairo/XcbSurface.cs new file mode 100644 index 00000000..142ebf9e --- /dev/null +++ b/testDrm/Mono.Cairo/XcbSurface.cs @@ -0,0 +1,54 @@ +// +// 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); + } + } +} diff --git a/testDrm/Mono.Cairo/XlibSurface.cs b/testDrm/Mono.Cairo/XlibSurface.cs new file mode 100644 index 00000000..c0003a49 --- /dev/null +++ b/testDrm/Mono.Cairo/XlibSurface.cs @@ -0,0 +1,95 @@ +// +// 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); } + } + + } +} diff --git a/testDrm/src/BlittableValueType.cs b/testDrm/src/BlittableValueType.cs new file mode 100644 index 00000000..1c3e1213 --- /dev/null +++ b/testDrm/src/BlittableValueType.cs @@ -0,0 +1,291 @@ +#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 + + /// + /// Checks whether the specified type parameter is a blittable value type. + /// + /// + /// A blittable value type is a struct that only references other value types recursively, + /// which allows it to be passed to unmanaged code directly. + /// + public static class BlittableValueType + { + #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 + + /// + /// Gets the size of the type in bytes or 0 for non-blittable types. + /// + /// + /// This property returns 0 for non-blittable types. + /// + public static int Stride { get { return stride; } } + + #region Check + + /// + /// Checks whether the current typename T is blittable. + /// + /// True if T is blittable; false otherwise. + public static bool Check() + { + return Check(Type); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// A System.Type to check. + /// True if T is blittable; false otherwise. + 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 + + /// + /// Checks whether the specified type parameter is a blittable value type. + /// + /// + /// A blittable value type is a struct that only references other value types recursively, + /// which allows it to be passed to unmanaged code directly. + /// + public static class BlittableValueType + { + #region Check + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + /// True if T is blittable; false otherwise. + public static bool Check(T type) + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + /// True if T is blittable; false otherwise. + [CLSCompliant(false)] + public static bool Check(T[] type) + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + /// True if T is blittable; false otherwise. + [CLSCompliant(false)] + public static bool Check(T[,] type) + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + /// True if T is blittable; false otherwise. + [CLSCompliant(false)] + public static bool Check(T[, ,] type) + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + /// True if T is blittable; false otherwise. + [CLSCompliant(false)] + public static bool Check(T[][] type) + { + return BlittableValueType.Check(); + } + + #endregion + + #region StrideOf + + /// + /// Returns the size of the specified value type in bytes or 0 if the type is not blittable. + /// + /// The value type. Must be blittable. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + public static int StrideOf(T type) + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + /// + /// Returns the size of a single array element in bytes or 0 if the element is not blittable. + /// + /// The value type. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + [CLSCompliant(false)] + public static int StrideOf(T[] type) + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + /// + /// Returns the size of a single array element in bytes or 0 if the element is not blittable. + /// + /// The value type. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + [CLSCompliant(false)] + public static int StrideOf(T[,] type) + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + /// + /// Returns the size of a single array element in bytes or 0 if the element is not blittable. + /// + /// The value type. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + [CLSCompliant(false)] + public static int StrideOf(T[, ,] type) + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + #endregion + } + + #endregion +} diff --git a/testDrm/src/DisplayDevice.cs b/testDrm/src/DisplayDevice.cs new file mode 100644 index 00000000..bfd3960a --- /dev/null +++ b/testDrm/src/DisplayDevice.cs @@ -0,0 +1,565 @@ +#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 +{ + /// + /// Defines a display device on the underlying system, and provides + /// methods to query and change its display parameters. + /// + 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 available_resolutions = new List(); + IList 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 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 + + /// + /// Gets the bounds of this instance in pixel coordinates.. + /// + 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 + + /// Gets a System.Int32 that contains the width of this display in pixels. + public int Width { get { return current_resolution.Width; } } + + #endregion + + #region public int Height + + /// Gets a System.Int32 that contains the height of this display in pixels. + public int Height { get { return current_resolution.Height; } } + + #endregion + + #region public int BitsPerPixel + + /// Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32. + public int BitsPerPixel + { + get { return current_resolution.BitsPerPixel; } + internal set { current_resolution.BitsPerPixel = value; } + } + + #endregion + + #region public float RefreshRate + + /// + /// Gets a System.Single representing the vertical refresh rate of this display. + /// + public float RefreshRate + { + get { return current_resolution.RefreshRate; } + internal set { current_resolution.RefreshRate = value; } + } + + #endregion + + #region public bool IsPrimary + + /// Gets a System.Boolean that indicates whether this Display is the primary Display in systems with multiple Displays. + 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) + + /// + /// Selects an available resolution that matches the specified parameters. + /// + /// The width of the requested resolution in pixels. + /// The height of the requested resolution in pixels. + /// The bits per pixel of the requested resolution. + /// The refresh rate of the requested resolution in hertz. + /// The requested DisplayResolution or null if the parameters cannot be met. + /// + /// 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. + /// 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). + /// This function allocates memory. + /// + 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 AvailableResolutions + + /// + /// Gets the list of objects available on this device. + /// + public IList AvailableResolutions + { + get { return available_resolutions_readonly; } + internal set + { + available_resolutions = (List)value; + available_resolutions_readonly = available_resolutions.AsReadOnly(); + } + } + + #endregion + + #region public void ChangeResolution(DisplayResolution resolution) + + /// Changes the resolution of the DisplayDevice. + /// The resolution to set. + /// Thrown if the requested resolution could not be set. + /// If the specified resolution is null, this function will restore the original DisplayResolution. + 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) + + /// Changes the resolution of the DisplayDevice. + /// The new width of the DisplayDevice. + /// The new height of the DisplayDevice. + /// The new bits per pixel of the DisplayDevice. + /// The new refresh rate of the DisplayDevice. + /// Thrown if the requested resolution could not be set. + public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate) + { + this.ChangeResolution(this.SelectResolution(width, height, bitsPerPixel, refreshRate)); + } + + #endregion + + #region public void RestoreResolution() + + /// Restores the original resolution of the DisplayDevice. + /// Thrown if the original resolution could not be restored. + 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 AvailableDisplays + + /// + /// Gets the list of available objects. + /// This function allocates memory. + /// + [Obsolete("Use GetDisplay(DisplayIndex) instead.")] + public static IList AvailableDisplays + { + get + { + List displays = new List(); + 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 + + /// Gets the default (primary) display of this system. + public static DisplayDevice Default + { + get { return implementation.GetDisplay(DisplayIndex.Primary); } + } + + #endregion + + #region GetDisplay + + /// + /// Gets the for the specified . + /// + /// The that defines the desired display. + /// A or null, if no device corresponds to the specified index. + public static DisplayDevice GetDisplay(DisplayIndex index) + { + return implementation.GetDisplay(index); + } + + #endregion + + #endregion + + #region --- Internal Methods --- + + #region internal DisplayResolution OriginalResolution + + /// + /// Gets the original resolution of this instance. + /// + 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() + + /// + /// Returns a System.String representing this DisplayDevice. + /// + /// A System.String representing this DisplayDevice. + 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) + + ///// Determines whether the specified DisplayDevices are equal. + ///// The System.Object to check against. + ///// True if the System.Object is an equal DisplayDevice; false otherwise. + //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() + + ///// Returns a unique hash representing this DisplayDevice. + ///// A System.Int32 that may serve as a hash code for this DisplayDevice. + ////public override int GetHashCode() + //{ + // return current_resolution.GetHashCode() ^ IsPrimary.GetHashCode() ^ available_resolutions.Count; + //} + + #endregion + + #endregion + } + + #region --- FadeEffect --- +#if false + class FadeEffect : IDisposable + { + List
forms = new List(); + 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 +} diff --git a/testDrm/src/DisplayResolution.cs b/testDrm/src/DisplayResolution.cs new file mode 100644 index 00000000..43419408 --- /dev/null +++ b/testDrm/src/DisplayResolution.cs @@ -0,0 +1,232 @@ +#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 +{ + /// Contains information regarding a monitor's display resolution. + 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 + + /// + /// Creates a new DisplayResolution object for the specified DisplayDevice. + /// + /// The requested width in pixels. + /// The requested height in pixels. + /// The requested bits per pixel in bits. + /// The requested refresh rate in hertz. + /// OpenTK will select the closest match between all available resolutions on the specified DisplayDevice. + /// + 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 + + /// + /// Gets a System.Drawing.Rectangle that contains the bounds of this display device. + /// + [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 + + /// Gets a System.Int32 that contains the width of this display in pixels. + public int Width + { + get { return bounds.Width; } + internal set { bounds.Width = value; } + } + + #endregion + + #region public int Height + + /// Gets a System.Int32 that contains the height of this display in pixels. + public int Height + { + get { return bounds.Height; } + internal set { bounds.Height = value; } + } + + #endregion + + #region public int BitsPerPixel + + /// Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32. + public int BitsPerPixel + { + get { return bits_per_pixel; } + internal set { bits_per_pixel = value; } + } + + #endregion + + #region public float RefreshRate + + /// + /// Gets a System.Single representing the vertical refresh rate of this display. + /// + public float RefreshRate + { + get { return refresh_rate; } + internal set { refresh_rate = value; } + } + + #endregion + + #endregion + + #region --- Overrides --- + + #region public override string ToString() + + /// + /// Returns a System.String representing this DisplayResolution. + /// + /// A System.String representing this DisplayResolution. + 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) + + /// Determines whether the specified resolutions are equal. + /// The System.Object to check against. + /// True if the System.Object is an equal DisplayResolution; false otherwise. + 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() + + /// Returns a unique hash representing this resolution. + /// A System.Int32 that may serve as a hash code for this resolution. + 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 --- + + /// + /// Compares two instances for equality. + /// + /// The first instance. + /// The second instance. + /// True, if left equals right; false otherwise. + 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); + } + + /// + /// Compares two instances for inequality. + /// + /// The first instance. + /// The second instance. + /// True, if left does not equal right; false otherwise. + public static bool operator !=(DisplayResolution left, DisplayResolution right) + { + return !(left == right); + } + + #endregion + } +} diff --git a/testDrm/src/DrmDevice.cs b/testDrm/src/DrmDevice.cs new file mode 100644 index 00000000..82697ba9 --- /dev/null +++ b/testDrm/src/DrmDevice.cs @@ -0,0 +1,927 @@ +// +// DrmKms.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 + } +} + diff --git a/testDrm/src/Egl.cs b/testDrm/src/Egl.cs new file mode 100644 index 00000000..434a54e7 --- /dev/null +++ b/testDrm/src/Egl.cs @@ -0,0 +1,385 @@ +#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 diff --git a/testDrm/src/Linux/Bindings/Drm.cs b/testDrm/src/Linux/Bindings/Drm.cs new file mode 100644 index 00000000..449dc0b4 --- /dev/null +++ b/testDrm/src/Linux/Bindings/Drm.cs @@ -0,0 +1,243 @@ +#region License +// +// Drm.cs +// +// Author: +// Stefanos A. +// +// 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; + } +} + diff --git a/testDrm/src/Linux/Bindings/Evdev.cs b/testDrm/src/Linux/Bindings/Evdev.cs new file mode 100644 index 00000000..fa4f725f --- /dev/null +++ b/testDrm/src/Linux/Bindings/Evdev.cs @@ -0,0 +1,635 @@ +#region License +// +// Evdev.cs +// +// Author: +// Stefanos A. +// +// 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.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; + } +} + diff --git a/testDrm/src/Linux/Bindings/Gbm.cs b/testDrm/src/Linux/Bindings/Gbm.cs new file mode 100644 index 00000000..03925742 --- /dev/null +++ b/testDrm/src/Linux/Bindings/Gbm.cs @@ -0,0 +1,282 @@ +#region License +// +// Gbm.cs +// +// Author: +// Stefanos A. +// +// 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 + { + 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 + } +} + diff --git a/testDrm/src/Linux/Bindings/Kms.cs b/testDrm/src/Linux/Bindings/Kms.cs new file mode 100644 index 00000000..a5c7f48b --- /dev/null +++ b/testDrm/src/Linux/Bindings/Kms.cs @@ -0,0 +1,46 @@ +#region License +// +// Kms.cs +// +// Author: +// Stefanos A. +// +// 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); + } +} + diff --git a/testDrm/src/Linux/Bindings/LibInput.cs b/testDrm/src/Linux/Bindings/LibInput.cs new file mode 100644 index 00000000..d45f55de --- /dev/null +++ b/testDrm/src/Linux/Bindings/LibInput.cs @@ -0,0 +1,333 @@ +#region License +// +// LibInput.cs +// +// Author: +// Stefanos A. +// +// 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 + /// + /// Signals the end of a set of touchpoints at one device sample + /// time. This event has no coordinate information attached. + /// + 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); + } +} + diff --git a/testDrm/src/Linux/Bindings/Libc.cs b/testDrm/src/Linux/Bindings/Libc.cs new file mode 100644 index 00000000..11318756 --- /dev/null +++ b/testDrm/src/Linux/Bindings/Libc.cs @@ -0,0 +1,186 @@ +#region License +// +// Linux.cs +// +// Author: +// Stefanos A. +// +// 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 + } +} + diff --git a/testDrm/src/Linux/Bindings/Poll.cs b/testDrm/src/Linux/Bindings/Poll.cs new file mode 100644 index 00000000..f78d6d73 --- /dev/null +++ b/testDrm/src/Linux/Bindings/Poll.cs @@ -0,0 +1,65 @@ +#region License +// +// Poll.cs +// +// Author: +// Stefanos A. +// +// 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; + } +} + diff --git a/testDrm/src/Linux/Bindings/Terminal.cs b/testDrm/src/Linux/Bindings/Terminal.cs new file mode 100644 index 00000000..e72ad741 --- /dev/null +++ b/testDrm/src/Linux/Bindings/Terminal.cs @@ -0,0 +1,170 @@ +#region License +// +// Terminal.cs +// +// Author: +// Stefanos A. +// +// 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; + + } +} + diff --git a/testDrm/src/Linux/Bindings/Udev.cs b/testDrm/src/Linux/Bindings/Udev.cs new file mode 100644 index 00000000..4c341b70 --- /dev/null +++ b/testDrm/src/Linux/Bindings/Udev.cs @@ -0,0 +1,46 @@ +#region License +// +// Udev.cs +// +// Author: +// Stefanos A. +// +// 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); + } +} + diff --git a/testDrm/src/Linux/DefaultCursor.cs b/testDrm/src/Linux/DefaultCursor.cs new file mode 100644 index 00000000..40e58e57 --- /dev/null +++ b/testDrm/src/Linux/DefaultCursor.cs @@ -0,0 +1,76 @@ +#region License +// +// DefaultCursor.cs +// +// Author: +// Stefanos A. +// +// 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; + } +} + diff --git a/testDrm/src/Linux/LinuxDisplayDriver.cs b/testDrm/src/Linux/LinuxDisplayDriver.cs new file mode 100644 index 00000000..74aed632 --- /dev/null +++ b/testDrm/src/Linux/LinuxDisplayDriver.cs @@ -0,0 +1,415 @@ +#region License +// +// LinuxDisplayDriver.cs +// +// Author: +// Stefanos A. +// +// 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 DisplayIds = + new Dictionary(); + + public LinuxDisplayDriver(int fd) + { + Debug.Print("[KMS] Creating LinuxDisplayDriver for fd:{0}", fd); + Debug.Indent(); + try + { + FD = fd; + UpdateDisplays(fd); + } + finally + { + Debug.Unindent(); + } + } + + /// \internal + /// + /// Queries the specified GPU for connected displays and, optionally, + /// returns the list of displays. + /// + /// true, if at least one display is connected, false otherwise. + /// The fd for the GPU to query, obtained through open("/dev/dri/card0"). + /// + /// If not null, this will contain a list instances, + /// one for each connected display. + /// + internal static bool QueryDisplays(int fd, List 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 displays = new List(); + 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 + } +} + diff --git a/testDrm/src/Linux/LinuxFactory.cs b/testDrm/src/Linux/LinuxFactory.cs new file mode 100644 index 00000000..37d108a2 --- /dev/null +++ b/testDrm/src/Linux/LinuxFactory.cs @@ -0,0 +1,253 @@ +#region License +// +// LinuxFactory.cs +// +// Author: +// Stefanos A. +// +// 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 + } +} + diff --git a/testDrm/src/Linux/LinuxGraphicsContext.cs b/testDrm/src/Linux/LinuxGraphicsContext.cs new file mode 100644 index 00000000..779fd36d --- /dev/null +++ b/testDrm/src/Linux/LinuxGraphicsContext.cs @@ -0,0 +1,302 @@ +#region License +// +// LinuxGraphicsContext.cs +// +// Author: +// thefiddler +// +// 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 + /// + /// Defines an IGraphicsContext implementation for the Linux KMS framebuffer. + /// For Linux/X11 and other Unix operating systems, use the more generic + /// instead. + /// + /// + /// Note: to display our results, we need to allocate a GBM framebuffer + /// and point the scanout address to that via Drm.ModeSetCrtc. + /// + 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); + } + } +} + + + diff --git a/testDrm/src/Linux/LinuxInput.cs b/testDrm/src/Linux/LinuxInput.cs new file mode 100644 index 00000000..ce5457c3 --- /dev/null +++ b/testDrm/src/Linux/LinuxInput.cs @@ -0,0 +1,721 @@ +#region License +// +// LinuxKeyboardLibInput.cs +// +// Author: +// Stefanos A. +// +// 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 KeyboardCandidates = new DeviceCollection(); + DeviceCollection MouseCandidates = new DeviceCollection(); + DeviceCollection Keyboards = new DeviceCollection(); + DeviceCollection Mice = new DeviceCollection(); + + // 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 + } +} + diff --git a/testDrm/src/Linux/LinuxJoystick.cs b/testDrm/src/Linux/LinuxJoystick.cs new file mode 100644 index 00000000..fa47bdff --- /dev/null +++ b/testDrm/src/Linux/LinuxJoystick.cs @@ -0,0 +1,533 @@ +#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 AxisMap = + new Dictionary(); + public readonly Dictionary ButtonMap = + new Dictionary(); + } + + 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 Sticks = + new DeviceCollection(); + + 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 + } +} diff --git a/testDrm/src/Linux/LinuxKeyboardTTY.cs b/testDrm/src/Linux/LinuxKeyboardTTY.cs new file mode 100644 index 00000000..afe66bc1 --- /dev/null +++ b/testDrm/src/Linux/LinuxKeyboardTTY.cs @@ -0,0 +1,268 @@ +#region License +// +// LinuxKeyboardTTY.cs +// +// Author: +// thefiddler +// +// 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 +} + diff --git a/testDrm/src/Linux/LinuxNativeWindow.cs b/testDrm/src/Linux/LinuxNativeWindow.cs new file mode 100644 index 00000000..46ff13be --- /dev/null +++ b/testDrm/src/Linux/LinuxNativeWindow.cs @@ -0,0 +1,537 @@ +#region License +// +// LinuxNativeWindow.cs +// +// Author: +// Stefanos A. +// +// 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 + } +} + diff --git a/testDrm/src/Linux/LinuxWindowInfo.cs b/testDrm/src/Linux/LinuxWindowInfo.cs new file mode 100644 index 00000000..e1d91e9a --- /dev/null +++ b/testDrm/src/Linux/LinuxWindowInfo.cs @@ -0,0 +1,56 @@ +#region License +// +// LinuxWindowInfo.cs +// +// Author: +// Stefanos A. +// +// 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. + } + } +} + diff --git a/testDrm/src/MouseCursor.cs b/testDrm/src/MouseCursor.cs new file mode 100644 index 00000000..df8cd0cf --- /dev/null +++ b/testDrm/src/MouseCursor.cs @@ -0,0 +1,135 @@ +#region License +// +// Cursor.cs +// +// Author: +// Stefanos A. +// +// 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 +{ + /// + /// Represents a predefined or custom mouse cursor. + /// + 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() + { + } + + /// + /// Initializes a new 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: + /// + /// B = (byte)((B * A) / 255) + /// G = (byte)((G * A) / 255) + /// R = (byte)((R * A) / 255) + /// + /// + /// The x-coordinate of the cursor hotspot, in the range [0, width] + /// The y-coordinate of the cursor hotspot, in the range [0, height] + /// The width of the cursor data, in pixels. + /// The height of the cursor data, in pixels. + /// + /// A byte array representing the cursor image, + /// laid out as a contiguous array of BGRA pixels. + /// + 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; + } + + /// + /// Initializes a new 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: + /// + /// B = (byte)((B * A) / 255) + /// G = (byte)((G * A) / 255) + /// R = (byte)((R * A) / 255) + /// + /// + /// The x-coordinate of the cursor hotspot, in the range [0, width] + /// The y-coordinate of the cursor hotspot, in the range [0, height] + /// The width of the cursor data, in pixels. + /// The height of the cursor data, in pixels. + /// + /// A pointer to the cursor image, laid out as a contiguous array of BGRA pixels. + /// + 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; } } + + /// + /// Gets the default mouse cursor for this platform. + /// + public static MouseCursor Default + { + get + { + return default_cursor; + } + } + + /// + /// Gets an empty (invisible) mouse cursor. + /// + public static MouseCursor Empty + { + get + { + return empty_cursor; + } + } + } +} + diff --git a/testDrm/src/WindowIcon.cs b/testDrm/src/WindowIcon.cs new file mode 100644 index 00000000..53d2d1f8 --- /dev/null +++ b/testDrm/src/WindowIcon.cs @@ -0,0 +1,91 @@ +#region License +// +// WindowIcon.cs +// +// Author: +// Stefanos A. +// +// 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 +{ + /// + /// Stores a window icon. A window icon is defined + /// as a 2-dimensional buffer of RGBA values. + /// + public class WindowIcon + { + byte[] data; + int width; + int height; + + /// \internal + /// + /// Initializes a new instance of the class. + /// + 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; } } + } +} + diff --git a/testDrm/testDrm.csproj b/testDrm/testDrm.csproj new file mode 100644 index 00000000..21b5bf37 --- /dev/null +++ b/testDrm/testDrm.csproj @@ -0,0 +1,156 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {4B57740A-75FB-4978-A8E8-8B1793B7474F} + Exe + testDrm + testDrm + 0.5 + v4.5 + $(SolutionDir)build/$(Configuration) + $(SolutionDir)build/obj/$(Configuration) + + + + + + + + true + full + false + DEBUG; + prompt + 4 + false + true + $(SolutionDir)build\obj\$(Configuration) + $(SolutionDir)build\$(Configuration) + + + full + true + prompt + 4 + false + true + $(SolutionDir)build\obj\$(Configuration) + $(SolutionDir)build\$(Configuration) + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + {C2980F9B-4798-4C05-99E2-E174810F7C7B} + Crow + + + \ No newline at end of file -- 2.47.3