]> O.S.I.I.S - jp/crow.git/commitdiff
restructured classes for Linux platform
authorjpbruyere <jp.bruyere@hotmail.com>
Wed, 17 May 2017 14:59:57 +0000 (16:59 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Wed, 17 May 2017 14:59:57 +0000 (16:59 +0200)
36 files changed:
Crow.csproj
src/GraphicObjects/Container.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/TemplatedContainer.cs
src/GraphicObjects/TemplatedControl.cs
src/GraphicObjects/TemplatedGroup.cs
src/Interface.cs
src/Mono.Cairo/DRMDevice.cs [new file with mode: 0644]
src/Mono.Cairo/DRMSurface.cs [new file with mode: 0644]
src/Mono.Cairo/NativeMethods.cs
testDrm/src/Application.cs
testDrm/src/DRMContext.cs
testDrm/src/Egl/Context.cs [new file with mode: 0644]
testDrm/src/Egl/EGL.cs [new file with mode: 0644]
testDrm/src/Egl/Surface.cs [new file with mode: 0644]
testDrm/src/Linux/Bindings/Egl.cs
testDrm/src/Linux/Bindings/Evdev.cs
testDrm/src/Linux/Bindings/Gbm.cs
testDrm/src/Linux/Bindings/LibInput.cs
testDrm/src/Linux/Bindings/Libc.cs
testDrm/src/Linux/Bindings/Poll.cs
testDrm/src/Linux/DRI.cs [new file with mode: 0644]
testDrm/src/Linux/DRI/Connector.cs [new file with mode: 0644]
testDrm/src/Linux/DRI/Crtc.cs [new file with mode: 0644]
testDrm/src/Linux/DRI/Encoder.cs [new file with mode: 0644]
testDrm/src/Linux/DRI/Plane.cs [new file with mode: 0644]
testDrm/src/Linux/DRI/Resources.cs [new file with mode: 0644]
testDrm/src/Linux/DRM.cs [deleted file]
testDrm/src/Linux/GBM/BufferObject.cs [new file with mode: 0644]
testDrm/src/Linux/GBM/Device.cs [new file with mode: 0644]
testDrm/src/Linux/GBM/Surface.cs [new file with mode: 0644]
testDrm/src/Linux/VT.cs
testDrm/testDrm.csproj
testDrm/tests.cs
testDrm/ui/menu.crow

index a434dc87dabe42cdd67592b9498ff8abeb799ba2..3e8bcd553743293bc3f6f2fbb87b67a1d16be7a1 100644 (file)
     <Compile Include="src\Mono.Cairo\Device.cs" />
     <Compile Include="src\Mono.Cairo\DirectFBSurface.cs" />
     <Compile Include="src\Mono.Cairo\Distance.cs" />
-    <Compile Include="src\Mono.Cairo\EGLDevice.cs" />
     <Compile Include="src\Mono.Cairo\Extend.cs" />
     <Compile Include="src\Mono.Cairo\FillRule.cs" />
     <Compile Include="src\Mono.Cairo\Filter.cs" />
     <Compile Include="src\Mono.Cairo\Win32Surface.cs" />
     <Compile Include="src\Mono.Cairo\XcbSurface.cs" />
     <Compile Include="src\Mono.Cairo\XlibSurface.cs" />
+    <Compile Include="src\Mono.Cairo\EGLDevice.cs" />
+    <Compile Include="src\Mono.Cairo\DRMDevice.cs" />
+    <Compile Include="src\Mono.Cairo\DRMSurface.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
index aac3594607ebe21b2f983bccfaa7bf1204f27cc1..df14b8e213104c99a2340e5ddbfe97aa39b498f5 100644 (file)
@@ -33,7 +33,7 @@ using System.Threading;
 
 namespace Crow
 {
-    public class Container : PrivateContainer, IXmlSerializable
+    public class Container : PrivateContainer
     {
                #region CTOR
                public Container()
@@ -51,59 +51,6 @@ namespace Crow
                {
                        base.SetChild (_child);
                }
-
-               #region IXmlSerializable
-
-        public override System.Xml.Schema.XmlSchema GetSchema()
-        {
-            return null;
-        }
-        public override void ReadXml(System.Xml.XmlReader reader)
-        {
-                       //only read attributes in GraphicObject IXmlReader implementation
-            base.ReadXml(reader);
-
-
-            using (System.Xml.XmlReader subTree = reader.ReadSubtree())
-            {
-                subTree.Read(); //skip current node
-                subTree.Read(); //read first child
-
-                if (!subTree.IsStartElement())
-                    return;
-
-                Type t = Type.GetType("Crow." + subTree.Name);
-                               if (t == null) {
-                                       Assembly a = Assembly.GetEntryAssembly ();
-                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                               if (expT.Name == subTree.Name) {
-                                                       t = expT;
-                                                       break;
-                                               }
-                                       }
-                               }
-                               GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
-
-                               (go as IXmlSerializable).ReadXml(subTree);
-
-                               SetChild(go);
-
-                subTree.Read();//closing tag
-            }
-        }
-        public override void WriteXml(System.Xml.XmlWriter writer)
-        {
-            base.WriteXml(writer);
-
-            if (Child == null)
-                return;
-
-            writer.WriteStartElement(Child.GetType().Name);
-            (Child as IXmlSerializable).WriteXml(writer);
-            writer.WriteEndElement();
-        }
-    
-               #endregion
        }
 }
 
index bfed68b42500e77cea4453b9cf10f47f6d642f00..5de94f6092c44702042b3a2a01618d83676a77f4 100644 (file)
@@ -38,7 +38,7 @@ using System.IO;
 
 namespace Crow
 {
-       public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable
+       public class GraphicObject : ILayoutable, IValueChange
        {
                internal static ulong currentUid = 0;
                internal ulong uid = 0;
@@ -1339,195 +1339,6 @@ namespace Crow
                protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
                        LogicalParentChanged.Raise (this, e);
                }
-               #region IXmlSerializable
-               public virtual System.Xml.Schema.XmlSchema GetSchema ()
-               {
-                       return null;
-               }
-//             void affectMember(string name, string value){
-//                     Type thisType = this.GetType ();
-//
-//                     if (string.IsNullOrEmpty (value))
-//                             return;
-//
-//                     MemberInfo mi = thisType.GetMember (name).FirstOrDefault();
-//                     if (mi == null) {
-//                             Debug.WriteLine ("XML: Unknown attribute in " + thisType.ToString() + " : " + name);
-//                             return;
-//                     }
-//                     if (mi.MemberType == MemberTypes.Event) {
-//                             this.Bindings.Add (new Binding (new MemberReference(this, mi), value));
-//                             return;
-//                     }
-//                     if (mi.MemberType == MemberTypes.Property) {
-//                             PropertyInfo pi = mi as PropertyInfo;
-//
-//                             if (pi.GetSetMethod () == null) {
-//                                     Debug.WriteLine ("XML: Read only property in " + thisType.ToString() + " : " + name);
-//                                     return;
-//                             }
-//
-//                             XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
-//                             if (xaa != null) {
-//                                     if (!string.IsNullOrEmpty (xaa.AttributeName))
-//                                             name = xaa.AttributeName;
-//                             }
-//                             if (value.StartsWith("{",StringComparison.Ordinal)) {
-//                                     //binding
-//                                     if (!value.EndsWith("}", StringComparison.Ordinal))
-//                                             throw new Exception (string.Format("XML:Malformed binding: {0}", value));
-//
-//                                     this.Bindings.Add (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2)));
-//                                     return;
-//                             }
-//                             if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null)
-//                                     return;
-//                             if (xaa == null)//not define as xmlAttribute
-//                                     return;
-//
-//                             if (pi.PropertyType == typeof(string)) {
-//                                     pi.SetValue (this, value, null);
-//                                     return;
-//                             }
-//
-//                             if (pi.PropertyType.IsEnum) {
-//                                     pi.SetValue (this, Enum.Parse (pi.PropertyType, value), null);
-//                             } else {
-//                                     MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
-//                                     pi.SetValue (this, me.Invoke (null, new string[] { value }), null);
-//                             }
-//                     }
-//             }
-               public virtual void ReadXml (System.Xml.XmlReader reader)
-               {
-                       if (reader.HasAttributes) {
-
-                               style = reader.GetAttribute ("Style");
-
-                               loadDefaultValues ();
-
-                               while (reader.MoveToNextAttribute ()) {
-                                       if (reader.Name == "Style")
-                                               continue;
-
-                                       //affectMember (reader.Name, reader.Value);
-                               }
-                               reader.MoveToElement ();
-                       }else
-                               loadDefaultValues ();
-               }
-               public virtual void WriteXml (System.Xml.XmlWriter writer)
-               {
-                       foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
-                               if (pi.GetSetMethod () == null)
-                                       continue;
-
-                               bool isAttribute = false;
-                               bool hasDefaultValue = false;
-                               bool ignore = false;
-                               string name = "";
-                               object value = null;
-                               Type valueType = null;
-
-
-                               MemberInfo mi = pi.GetGetMethod ();
-
-                               if (mi == null)
-                                       continue;
-
-                               value = pi.GetValue (this, null);
-                               valueType = pi.PropertyType;
-                               name = pi.Name;
-
-
-
-                               object[] att = pi.GetCustomAttributes (false);
-
-                               foreach (object o in att) {
-                                       XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
-                                       if (xaa != null) {
-                                               isAttribute = true;
-                                               if (string.IsNullOrEmpty (xaa.AttributeName))
-                                                       name = pi.Name;
-                                               else
-                                                       name = xaa.AttributeName;
-                                               continue;
-                                       }
-
-                                       XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
-                                       if (xia != null) {
-                                               ignore = true;
-                                               continue;
-                                       }
-
-                                       DefaultValueAttribute dv = o as DefaultValueAttribute;
-                                       if (dv != null) {
-                                               if (dv.Value.Equals (value))
-                                                       hasDefaultValue = true;
-                                               if (dv.Value.ToString () == value.ToString ())
-                                                       hasDefaultValue = true;
-
-                                               continue;
-                                       }
-
-
-                               }
-
-                               if (hasDefaultValue || ignore || value==null)
-                                       continue;
-
-                               if (isAttribute)
-                                       writer.WriteAttributeString (name, value.ToString ());
-                               else {
-                                       if (valueType.GetInterface ("IXmlSerializable") == null)
-                                               continue;
-
-                                       (pi.GetValue (this, null) as IXmlSerializable).WriteXml (writer);
-                               }
-                       }
-                       foreach (EventInfo ei in this.GetType().GetEvents()) {
-                               FieldInfo fi = this.GetType().GetField(ei.Name,
-                                       BindingFlags.NonPublic |
-                                       BindingFlags.Instance |
-                                       BindingFlags.GetField);
-
-                               Delegate dg = (System.Delegate)fi.GetValue (this);
-
-                               if (dg == null)
-                                       continue;
-
-                               foreach (Delegate d in dg.GetInvocationList()) {
-                                       if (!d.Method.Name.StartsWith ("<"))//Skipping empty handler, not clear it's trikky
-                                               writer.WriteAttributeString (ei.Name, d.Method.Name);
-                               }
-                       }
-               }
-               #endregion
-
-               #region ICloneable implementation
-               public object Clone ()
-               {
-                       Type type = this.GetType ();
-                       GraphicObject result = (GraphicObject)Activator.CreateInstance (type);
-                       result.CurrentInterface = CurrentInterface;
-
-                       foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
-                               if (pi.GetSetMethod () == null)
-                                       continue;
-
-                               if (pi.GetCustomAttribute<XmlIgnoreAttribute> () != null)
-                                       continue;
-                               if (pi.Name == "DataSource")
-                                       continue;
-
-                               pi.SetValue(result, pi.GetValue(this));
-                       }
-                       return result;
-               }
-               #endregion
-               /// <summary>
-               /// full GraphicTree clone with binding definition
-               /// </summary>
 
                public override string ToString ()
                {
index a71c53a01fa6d3900958e2078bcc2d9b1bc234e3..0739d48054275815fcdf8cdacd50a72745b6a9cd 100644 (file)
@@ -35,7 +35,7 @@ using System.Reflection;
 
 namespace Crow
 {
-       public class Group : GraphicObject, IXmlSerializable
+       public class Group : GraphicObject
     {
                #region CTOR
                public Group()
@@ -336,7 +336,6 @@ namespace Crow
                                }
                        }
                }
-
        
                #region Mouse handling
                public override void checkHoverWidget (MouseMoveEventArgs e)
@@ -355,60 +354,5 @@ namespace Crow
                        base.checkHoverWidget (e);
                }
                #endregion
-
-
-               #region IXmlSerializable
-
-        public override System.Xml.Schema.XmlSchema GetSchema()
-        {
-            return null;
-        }
-        public override void ReadXml(System.Xml.XmlReader reader)
-        {
-            base.ReadXml(reader);
-
-            using (System.Xml.XmlReader subTree = reader.ReadSubtree())
-            {
-                subTree.Read();
-
-                while (!subTree.EOF)
-                {
-                    subTree.Read();
-
-                    if (!subTree.IsStartElement())
-                        break;
-
-                    Type t = Type.GetType("Crow." + subTree.Name);
-                                       if (t == null) {
-                                               Assembly a = Assembly.GetEntryAssembly ();
-                                               foreach (Type expT in a.GetExportedTypes ()) {
-                                                       if (expT.Name == subTree.Name) {
-                                                               t = expT;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       if (t == null)
-                                               throw new Exception (subTree.Name + " type not found");
-                    GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
-                    (go as IXmlSerializable).ReadXml(subTree);                    
-                    AddChild(go);
-                }
-            }
-        }
-        public override void WriteXml(System.Xml.XmlWriter writer)
-        {
-            base.WriteXml(writer);
-
-            foreach (GraphicObject go in Children)
-            {
-                writer.WriteStartElement(go.GetType().Name);
-                (go as IXmlSerializable).WriteXml(writer);
-                writer.WriteEndElement();
-            }
-        }
-    
-               #endregion
-
        }
 }
index 1ab8cf7db158aa3741589350d915d73c3da2cd66..b8a321670c75bb07171d9dac561bdd3543f1c67d 100644 (file)
@@ -57,72 +57,6 @@ namespace Crow
                        return Content.Contains (goToFind);
                }
                #endregion
-
-               #region IXmlSerialisation Overrides
-               public override void ReadXml(System.Xml.XmlReader reader)
-               {
-                       using (System.Xml.XmlReader subTree = reader.ReadSubtree ()) {
-                               subTree.Read ();
-                               string tmp = subTree.ReadOuterXml ();
-
-                               //seek for template tag
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read ();
-                                       base.ReadXml (xr);
-                               }
-                               //process content
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read (); //skip current node
-
-                                       while (!xr.EOF) {
-                                               xr.Read (); //read first child
-
-                                               if (!xr.IsStartElement ())
-                                                       continue;
-
-                                               if (xr.Name == "Template"){
-                                                       xr.Skip ();
-                                                       if (!xr.IsStartElement ())
-                                                               continue;
-                                               }
-
-                                               Type t = Type.GetType ("Crow." + xr.Name);
-                                               if (t == null) {
-                                                       Assembly a = Assembly.GetEntryAssembly ();
-                                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                                               if (expT.Name == xr.Name) {
-                                                                       t = expT;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                               if (t == null)
-                                                       throw new Exception (xr.Name + " type not found");
-
-                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
-
-                                               (go as IXmlSerializable).ReadXml (xr);
-
-                                               Content = go;
-
-                                               xr.Read (); //closing tag
-                                       }
-
-                               }
-                       }
-               }
-               public override void WriteXml(System.Xml.XmlWriter writer)
-               {
-                       base.WriteXml(writer);
-
-                       if (Content == null)
-                               return;
-                       //TODO: if template is not the default one, we have to save it
-                       writer.WriteStartElement(Content.GetType().Name);
-                       (Content as IXmlSerializable).WriteXml(writer);
-                       writer.WriteEndElement();
-               }
-               #endregion
        }
 }
 
index 082d04269ae2f320de23b7157193790533c68ca4..0461a8eedf8a5bcb69cecca65a6d8946fd392073 100644 (file)
@@ -37,7 +37,7 @@ using System.Reflection;
 
 namespace Crow
 {
-       public abstract class TemplatedControl : PrivateContainer, IXmlSerializable
+       public abstract class TemplatedControl : PrivateContainer
        {
                #region CTOR
                public TemplatedControl () : base()
@@ -111,100 +111,6 @@ namespace Crow
                        }else
                                this.SetChild (template);
                }
-
-               //TODO:IXmlSerializable is not used anymore
-               #region IXmlSerializable
-               public override System.Xml.Schema.XmlSchema GetSchema(){ return null; }
-               public override void ReadXml(System.Xml.XmlReader reader)
-               {
-                       //Template could be either an attribute containing path or expressed inlined
-                       //as a Template Element
-                       using (System.Xml.XmlReader subTree = reader.ReadSubtree())
-                       {
-                               subTree.Read ();
-
-                               string template = reader.GetAttribute ("Template");
-                               string tmp = subTree.ReadOuterXml ();
-
-                               //Load template from path set as attribute in templated control
-                               if (string.IsNullOrEmpty (template)) {
-                                       //seek for template tag first
-                                       using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                               //load template first if inlined
-
-                                               xr.Read (); //read first child
-                                               xr.Read (); //skip root node
-
-                                               while (!xr.EOF) {
-                                                       if (!xr.IsStartElement ()) {
-                                                               xr.Read ();
-                                                               continue;
-                                                       }
-                                                       if (xr.Name == "ItemTemplate") {
-                                                               string dataType = "default", datas = "", itemTmp;
-                                                               while (xr.MoveToNextAttribute ()) {
-                                                                       if (xr.Name == "DataType")
-                                                                               dataType = xr.Value;
-                                                                       else if (xr.Name == "Data")
-                                                                               datas = xr.Value;
-                                                               }
-                                                               xr.MoveToElement ();
-                                                               itemTmp = xr.ReadInnerXml ();
-
-//                                                             if (ItemTemplates == null)
-//                                                                     ItemTemplates = new Dictionary<string, ItemTemplate> ();
-//
-//                                                             using (IMLReader iTmp = new IMLReader (null, itemTmp)) {
-//                                                                     ItemTemplates [dataType] =
-//                                                                             new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas);
-//                                                             }
-//                                                             if (!string.IsNullOrEmpty (datas))
-//                                                                     ItemTemplates [dataType].CreateExpandDelegate(this);
-
-                                                               continue;
-                                                       }
-                                                       if (xr.Name == "Template") {
-                                                               xr.Read ();
-
-                                                               Type t = Type.GetType ("Crow." + xr.Name);
-                                                               if (t == null) {
-                                                                       Assembly a = Assembly.GetEntryAssembly ();
-                                                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                                                               if (expT.Name == xr.Name) {
-                                                                                       t = expT;
-                                                                                       break;
-                                                                               }
-                                                                       }
-                                                               }
-                                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
-                                                               (go as IXmlSerializable).ReadXml (xr);
-
-                                                               loadTemplate (go);
-                                                               continue;
-                                                       }
-                                                       xr.ReadInnerXml ();
-                                               }
-                                       }
-                               } else
-                                       loadTemplate (CurrentInterface.Load (template));
-
-                               //if no template found, load default one
-                               if (this.child == null)
-                                       loadTemplate ();
-
-                               //normal xml read
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read ();
-                                       base.ReadXml(xr);
-                               }
-                       }
-               }
-               public override void WriteXml(System.Xml.XmlWriter writer)
-               {
-                       //TODO:
-                       throw new NotImplementedException();
-               }
-               #endregion
        }
 }
 
index e444716870bcd5a257bcc490fc417804765f92f3..eea3a18477393d31ae20eb6fbb36b3054bb65d61 100644 (file)
@@ -267,65 +267,6 @@ namespace Crow
 //             }
                #endregion
 
-               #region IXmlSerialisation Overrides
-               public override void ReadXml(System.Xml.XmlReader reader)
-               {
-                       using (System.Xml.XmlReader subTree = reader.ReadSubtree ()) {
-                               subTree.Read ();
-                               string tmp = subTree.ReadOuterXml ();
-
-                               //seek for template tag
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read ();
-                                       base.ReadXml (xr);
-                               }
-                               //process content
-                               using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
-                                       xr.Read (); //skip current node
-
-                                       while (!xr.EOF) {
-                                               xr.Read (); //read first child
-
-                                               if (!xr.IsStartElement ())
-                                                       continue;
-
-                                               if (xr.Name == "Template" || Name == "ItemTemplate"){
-                                                       xr.Skip ();
-                                                       if (!xr.IsStartElement ())
-                                                               continue;
-                                               }
-
-                                               Type t = Type.GetType ("Crow." + xr.Name);
-                                               if (t == null) {
-                                                       Assembly a = Assembly.GetEntryAssembly ();
-                                                       foreach (Type expT in a.GetExportedTypes ()) {
-                                                               if (expT.Name == xr.Name) {
-                                                                       t = expT;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                               if (t == null)
-                                                       throw new Exception (xr.Name + " type not found");
-
-                                               GraphicObject go = (GraphicObject)Activator.CreateInstance (t);
-
-                                               (go as IXmlSerializable).ReadXml (xr);
-
-                                               AddItem (go);
-
-                                               xr.Read (); //closing tag
-                                       }
-
-                               }
-                       }
-               }
-               public override void WriteXml(System.Xml.XmlWriter writer)
-               {
-                       throw new NotImplementedException ();
-               }
-               #endregion
-
                void loading(){
                        if (ItemTemplates == null)
                                ItemTemplates = new Dictionary<string, ItemTemplate> ();
index 6c7d99c4d3e85db15f997c653fce511967589f3f..df6a5c670d9068611db73be316e56c980d24094b 100644 (file)
@@ -511,30 +511,30 @@ namespace Crow
                                                clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
                                                #endif
                                                lock (RenderMutex) {
-                                                       Array.Copy (bmp, dirtyBmp, bmp.Length);
+//                                                     Array.Copy (bmp, dirtyBmp, bmp.Length);
                                                        IsDirty = true;
-//                                                     if (IsDirty)
-//                                                             DirtyRect += clipping.Bounds;
-//                                                     else
-//                                                             DirtyRect = clipping.Bounds;
-//
-//                                                     DirtyRect.Left = Math.Max (0, DirtyRect.Left);
-//                                                     DirtyRect.Top = Math.Max (0, DirtyRect.Top);
-//                                                     DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
-//                                                     DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
-//                                                     DirtyRect.Width = Math.Max (0, DirtyRect.Width);
-//                                                     DirtyRect.Height = Math.Max (0, DirtyRect.Height);
-//
-//                                                     if (DirtyRect.Width > 0 && DirtyRect.Height >0) {
-//                                                             dirtyBmp = new byte[4 * DirtyRect.Width * DirtyRect.Height];
-//                                                             for (int y = 0; y < DirtyRect.Height; y++) {
-//                                                                     Array.Copy (bmp,
-//                                                                             ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4,
-//                                                                             dirtyBmp, y * DirtyRect.Width * 4, DirtyRect.Width * 4);
-//                                                             }
-//
-//                                                     } else
-//                                                             IsDirty = false;
+                                                       if (IsDirty)
+                                                               DirtyRect += clipping.Bounds;
+                                                       else
+                                                               DirtyRect = clipping.Bounds;
+
+                                                       DirtyRect.Left = Math.Max (0, DirtyRect.Left);
+                                                       DirtyRect.Top = Math.Max (0, DirtyRect.Top);
+                                                       DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
+                                                       DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
+                                                       DirtyRect.Width = Math.Max (0, DirtyRect.Width);
+                                                       DirtyRect.Height = Math.Max (0, DirtyRect.Height);
+
+                                                       if (DirtyRect.Width > 0 && DirtyRect.Height >0) {
+                                                               dirtyBmp = new byte[4 * DirtyRect.Width * DirtyRect.Height];
+                                                               for (int y = 0; y < DirtyRect.Height; y++) {
+                                                                       Array.Copy (bmp,
+                                                                               ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4,
+                                                                               dirtyBmp, y * DirtyRect.Width * 4, DirtyRect.Width * 4);
+                                                               }
+
+                                                       } else
+                                                               IsDirty = false;
                                                }
                                                clipping.Reset ();
                                        }
@@ -644,7 +644,6 @@ namespace Crow
                public void ProcessResize(Rectangle bounds){
                        lock (UpdateMutex) {
                                clientRectangle = bounds;
-
                                int stride = 4 * ClientRectangle.Width;
                                int bmpSize = Math.Abs (stride) * ClientRectangle.Height;
                                bmp = new byte[bmpSize];
diff --git a/src/Mono.Cairo/DRMDevice.cs b/src/Mono.Cairo/DRMDevice.cs
new file mode 100644 (file)
index 0000000..a03195f
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// 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 DRMDevice : Device
+       {
+               public DRMDevice () : base (NativeMethods.cairo_drm_device_default (), true)
+               {
+               }
+               public DRMDevice (int fd) : base (NativeMethods.cairo_drm_device_get_for_fd (fd), true)
+               {
+               }
+               public DRMDevice (IntPtr udev_device) : base (NativeMethods.cairo_drm_device_get (udev_device), true)
+               {
+               }
+
+               public int FileDescriptor {
+                       get { return NativeMethods.cairo_drm_device_get_fd (Handle); }
+               }
+
+               public void DeviceThrottle () { NativeMethods.cairo_drm_device_throttle (Handle);}
+       }
+}
+
diff --git a/src/Mono.Cairo/DRMSurface.cs b/src/Mono.Cairo/DRMSurface.cs
new file mode 100644 (file)
index 0000000..248541c
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// 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 DRMSurface : Surface
+       {
+               
+               public DRMSurface (IntPtr ptr, bool own) : base (ptr, own)
+               {}
+
+               public DRMSurface (DRMDevice device, Format format, int width, int height)
+                       : base (NativeMethods.cairo_drm_surface_create (device.Handle, format, width, height), true)
+               {}
+
+               public DRMSurface (DRMDevice device, uint name, Format format, int width, int height, int stride)
+                       : base (NativeMethods.cairo_drm_surface_create_for_name (device.Handle, name, format, width, height, stride), true)
+               {}
+
+               public DRMSurface (DRMDevice device, IntPtr imageSurface)
+                       : base (NativeMethods.cairo_drm_surface_create_from_cacheable_image (device.Handle, imageSurface), true)
+               {}
+       }
+}
index 9726cb8c4e74ccbcefefd7102ba295952331953a..ab36a40ca14a672f4c28034f6b53e8e01e281db3 100644 (file)
@@ -925,6 +925,59 @@ namespace Cairo
                internal static extern IntPtr cairo_gl_surface_create_for_egl (IntPtr device, IntPtr eglSurface, int width, int height);
                #endregion
 
+               #region DRM Functions
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_device_get (IntPtr udev_device);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_device_get_for_fd (int fd);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_device_default ();
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern int cairo_drm_device_get_fd (IntPtr cairo_device);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern  void cairo_drm_device_throttle (IntPtr cairo_device);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_surface_create (IntPtr cairo_device, Format format,     int width, int height);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_surface_create_for_name (IntPtr cairo_device, uint name, Format format, int width, int height, int stride);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_surface_create_from_cacheable_image (IntPtr cairo_device, IntPtr imageSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern Status cairo_drm_surface_enable_scan_out (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_surface_get_handle (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_surface_get_name (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern Format cairo_drm_surface_get_format (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern int cairo_drm_surface_get_width (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern int cairo_drm_surface_get_height (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern int cairo_drm_surface_get_stride (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern IntPtr cairo_drm_surface_map_to_image (IntPtr drmSurface);
+
+               [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
+               internal static extern void     cairo_drm_surface_unmap (IntPtr drmSurface,     IntPtr imageSurface);
+               #endregion
+
                #region Device
                [DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
                internal static extern IntPtr cairo_device_reference (IntPtr device);
index 63edaae8e529860baf33b3f69c8a07c020b5fb73..43330e03dc3af997e5dc0599a308b004019dafed 100644 (file)
 // 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 System.Runtime.InteropServices;
 using System.Threading;
 
-namespace Crow.Linux
+using VT = Linux.VT;
+using DRI = Linux.DRI;
+
+using Linux;
+using System.Text;
+using OpenTK.Platform.Linux;
+
+namespace Crow
 {
        public class Application : IDisposable
-       {
-               DRMContext drm;
+       {               
+               DRI.GPUControler gpu;
+               Cairo.GLSurface cairoSurf;
+
                public Interface CrowInterface;
+
                public bool mouseIsInInterface = false;
 
                void interfaceThread()
@@ -50,36 +58,444 @@ namespace Crow.Linux
                                Thread.Sleep (1);
                        }
                }
+//
+               Crow.XCursor cursor;
+               int previousVT = -1, appVT = -1;
+//
+               public Application(){                   
+
+                       if (Kernel.signal (Signal.SIGUSR1, switch_request_handle) < 0)
+                               throw new Exception ("signal handler registation failed");                      
+                       if (Kernel.signal (Signal.SIGINT, sigint_handler) < 0)
+                               throw new Exception ("SIGINT handler registation failed");
+
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               previousVT = master.CurrentVT;
+                               appVT = master.FirstAvailableVT;
+                               master.SwitchTo (appVT);
+                               try {
+                                       master.KDMode = VT.KDMode.GRAPHICS;
+                               } catch (Exception ex) {
+                                       Console.WriteLine (ex.ToString ());     
+                               }
+                       }
+
+                       gpu = new DRI.GPUControler();
+                       cairoSurf = gpu.CairoSurf;
 
+                       cursor = Crow.XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0];
 
-               public Application(){
-                       drm = new DRMContext();
                        CrowInterface = new Interface ();
-                       drm.CrowInterface = CrowInterface;
 
                        Thread t = new Thread (interfaceThread);
                        t.IsBackground = true;
                        t.Start ();
 
-                       CrowInterface.ProcessResize (new Size (drm.width, drm.height));
-                       drm.updateCursor (XCursor.Default);
+                       initInput ();
+
+                       CrowInterface.ProcessResize (new Size (gpu.Width, gpu.Height));
+                       gpu.updateCursor (cursor);
+                       //CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged;
+               }
+               void switch_request_handle (Signal s){
+                       Console.WriteLine ("switch request catched: " + s.ToString());
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               Libc.write (master.fd, Encoding.ASCII.GetBytes ("this is a test string"));
+                               master.AcknoledgeSwitchRequest ();
+                       }                       
+               }
+               void sigint_handler (Signal s){
+                       Console.WriteLine ("SIGINT catched");
+                       //Running = false;
+               }
+//             void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e)
+//             {
+//                     gpu.updateCursor (e.NewCursor);
+//             }
+
+               public GraphicObject Load (string path){
+                       return CrowInterface.LoadInterface (path);
+               }
+               public virtual void Run (){
+                       updateCrow ();
+               }
+
+               public void updateCrow (){
+                       bool update = false;
+
+                       if (updateMousePos) {
+                               lock (Sync) {
+                                       updateMousePos = false;
+                                       gpu.moveCursor ((uint)MouseX - 8, (uint)MouseY - 4);
+                               }
+                       }
+
+//                     using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) {
+//                             ctx.Rectangle (0, 0, gpu.Width, gpu.Height);
+//                             ctx.SetSourceRGB (0, 0, 0.1);
+//                             ctx.Fill ();
+//                     }
+                       if (Monitor.TryEnter (CrowInterface.RenderMutex)) {
+                               if (CrowInterface.IsDirty) {
+                                       CrowInterface.IsDirty = false;
+                                       update = true;
+                                       Rectangle r = CrowInterface.DirtyRect;
+                                       using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) {
+                                               using (Cairo.Surface d = new Cairo.ImageSurface (CrowInterface.dirtyBmp, Cairo.Format.ARGB32,
+                                                       r.Width, r.Height, r.Width * 4)) {
+                                                       ctx.SetSourceSurface (d, 0, 0);
+                                                       ctx.Operator = Cairo.Operator.Source;
+                                                       ctx.Paint ();
+                                               }
+                                       }
+                               }
+                               Monitor.Exit (CrowInterface.RenderMutex);
+                       }
+
+//                     if (!update)
+//                             return;
+//                     update = false;
+
+                       cairoSurf.Flush ();
+                       cairoSurf.SwapBuffers ();
+
+                       gpu.Update ();
+               }
+
+
+               #region INPUT
+               Thread input_thread;
+               long exit;
 
-                       CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged;
+               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);
+                       }
                }
 
-               void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e)
+               static OpenRestrictedCallback OpenRestricted = OpenRestrictedHandler;
+               static int OpenRestrictedHandler(IntPtr path, int flags, IntPtr data) 
                {
-                       drm.updateCursor (e.NewCursor);
+                       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;
                }
 
-               public void Run (){
-                       drm.Run ();
+               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)
+                       {
+                               //drmTimeOut.Restart ();
+
+                               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(LibInput.GetKeyboardEvent(pevent));
+                                               break;
+                                               //
+                                               //                                      case InputEventType.PointerAxis:
+                                               //                                              HandlePointerAxis(GetMouse(device), LibInput.GetPointerEvent(pevent));
+                                               //                                              break;
+                                               //
+                                       case InputEventType.PointerButton:
+                                               handlePointerButton (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;
+
+               int roundDelta (double d){
+                       return d > 0 ? (int)Math.Ceiling(d) : (int)Math.Floor (d);
+               }
+
+               void handlePointerMotion(PointerEvent e)
+               {
+                       MouseX += roundDelta (e.DeltaX);
+                       MouseY += roundDelta (e.DeltaY);
+
+                       Rectangle bounds = CrowInterface.ClientRectangle;
+                       if (MouseX < bounds.Left)
+                               MouseX = bounds.Left;
+                       else if (MouseX > bounds.Right)
+                               MouseX = bounds.Right;
+
+                       if (MouseY < bounds.Top)
+                               MouseY = bounds.Top;
+                       else if (MouseY > bounds.Bottom)
+                               MouseY = bounds.Bottom;
+
+                       CrowInterface.ProcessMouseMove (MouseX, MouseY);
+
+                       updateMousePos = true;
+               }
+               void handlePointerButton (PointerEvent e)
+               {                       
+                       int but = 0;
+                       switch (e.Button) {
+                       case EvdevButton.LEFT:
+                               but = 0;
+                               break;
+                       case EvdevButton.MIDDLE:
+                               but = 1;
+                               break;
+                       case EvdevButton.RIGHT:
+                               but = 2;
+                               break;
+                       }
+                       if (e.ButtonState == global::Linux.ButtonState.Pressed)
+                               CrowInterface.ProcessMouseButtonDown (but);
+                       else
+                               CrowInterface.ProcessMouseButtonUp (but);
+               }
+
+               KeyModifiers curModifiers = KeyModifiers.None;
+
+               void handleKeyboard(KeyboardEvent e)
+               {
+                       return;
+                       int key = (int)Evdev.KeyMap [e.Key];
+                       Key k = (Key)key;
+                       if (e.KeyState == KeyState.Pressed) {
+                               CrowInterface.ProcessKeyDown (key);
+                               switch (k) {
+                               case Key.ShiftLeft:
+                               case Key.ShiftRight:
+                                       curModifiers |= KeyModifiers.Shift;
+                                       break;
+                               case Key.ControlLeft:
+                               case Key.ControlRight:
+                                       curModifiers |= KeyModifiers.Control;
+                                       break;
+                               case Key.AltLeft:
+                                       curModifiers |= KeyModifiers.Alt;
+                                       break;
+                               case Key.AltRight:
+                                       curModifiers |= KeyModifiers.AltGr;
+                                       break;
+                               }
+                       }else {
+                               CrowInterface.ProcessKeyUp (key);
+                               switch (k) {
+                               case Key.ShiftLeft:
+                               case Key.ShiftRight:
+                                       curModifiers &= ~KeyModifiers.Shift;
+                                       break;
+                               case Key.ControlLeft:
+                               case Key.ControlRight:
+                                       curModifiers &= ~KeyModifiers.Control;
+                                       break;
+                               case Key.AltLeft:
+                                       curModifiers &= ~KeyModifiers.Alt;
+                                       break;
+                               case Key.AltRight:
+                                       curModifiers &= ~KeyModifiers.AltGr;
+                                       break;
+                               }
+//                             if (!keymap.ContainsKey (curModifiers)) {
+//                                     Console.WriteLine ("keymap not found for: " + curModifiers + " " + (int)curModifiers);
+//                                     return;
+//                             }
+                               //                              string tmp = keymap [curModifiers] [e.Key];
+                               //                              if (string.IsNullOrEmpty (tmp))
+                               //                                      return;
+                               //                              if (char.IsControl (tmp[0]))
+                               //                                      return;
+                               //                              CrowInterface.ProcessKeyPress (tmp [0]);
+                       }                       
+               }
+
+               #endregion
+
                #region IDisposable implementation
+               ~Application(){
+                       Dispose (false);
+               }
                public void Dispose ()
                {
-                       drm.Dispose ();
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (gpu != null)
+                               gpu.Dispose ();
+                       gpu = null;
+
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               //                              try {
+                               //                                      master.KDMode = VT.KDMode.TEXT;
+                               //                              } catch (Exception ex) {
+                               //                                      Console.WriteLine (ex.ToString ());     
+                               //                              }
+                               master.SwitchTo (previousVT);
+                       }
+
                }
                #endregion
        }
index 720d4ed96eef44374b94c4de77a88044af979b7b..07e3bbff9e19a79e47dfa3b752a2597e4af17214 100644 (file)
@@ -33,7 +33,7 @@ using OpenTK;
 using OpenTK.Platform.Linux;
 using System.IO.Compression;
 
-namespace Crow.Linux
+namespace Linux
 {
        
        internal class DRMContext : IDisposable
@@ -173,6 +173,7 @@ namespace Crow.Linux
                unsafe void initEgl () {
                        int major, minor;
                        IntPtr[] configs = new IntPtr[1];
+
                        int[] contextAttrib = new int[] {
                                Egl.CONTEXT_CLIENT_VERSION, 2,
                                Egl.NONE
@@ -223,6 +224,7 @@ namespace Crow.Linux
                        // See what we really got
                        int r, g, b, a, 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);
@@ -407,6 +409,7 @@ namespace Crow.Linux
                                                        Drm.HandleEvent (fd_gpu, ref evctx);
                                                else
                                                        break;
+                                               Thread.Sleep (1);
                                        }
                                        if (is_flip_queued != 0)
                                                Console.WriteLine ("flip canceled");
diff --git a/testDrm/src/Egl/Context.cs b/testDrm/src/Egl/Context.cs
new file mode 100644 (file)
index 0000000..122f2e7
--- /dev/null
@@ -0,0 +1,738 @@
+//
+// Context.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+using Linux;
+using GBM = Linux.GBM;
+
+namespace 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;
+
+       public enum RenderApi
+       {
+               ES = Egl.OPENGL_ES_API,
+               GL = Egl.OPENGL_API,
+               VG = Egl.OPENVG_API
+       }
+       [Flags]public 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,
+       }
+
+       #region consts
+       public static 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;
+       }
+       #endregion
+
+       unsafe public class Context : IDisposable
+       {
+               #region pinvoke
+               [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")]
+               public static extern bool Initialize(EGLDisplay dpy, out int major, out int minor);
+               [DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")]
+               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 = "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 = "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}.", 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;
+                       }
+               }
+               #endregion
+
+               int fd_gpu;
+               internal EGLDisplay dpy;
+               internal EGLContext ctx;
+               internal EGLConfig currentCfg;
+
+               int major, minor;
+
+               public string Version { get { return Marshal.PtrToStringAuto (QueryString (dpy, Egl.VERSION)); }}
+               public string Vendor { get { return Marshal.PtrToStringAuto (QueryString (dpy, Egl.VENDOR)); }}
+               public string Extensions { get { return Marshal.PtrToStringAuto (QueryString (dpy, Egl.EXTENSIONS)); }} 
+               public string OffScreenExtensions { get { return Marshal.PtrToStringAuto (QueryString (IntPtr.Zero, Egl.EXTENSIONS)); }}        
+
+               #region ctor
+               public Context (GBM.Device gbmDev)
+               {
+                       dpy = GetDisplay(gbmDev.handle);
+
+                       if (dpy == IntPtr.Zero)
+                               throw new NotSupportedException("[EGL] GetDisplay failed.: " + GetError());
+
+                       if (!Initialize(dpy, out major, out minor))
+                               throw new NotSupportedException("[EGL] Failed to initialize EGL display. Error code: " + GetError());
+
+                       if (!BindAPI (RenderApi.GL))
+                               throw new NotSupportedException("[EGL] Failed to bind EGL Api: " + GetError());
+
+                       int[] contextAttrib = new int[] {
+                               Egl.CONTEXT_CLIENT_VERSION, 2,
+                               Egl.NONE
+                       };
+                       int[] desiredConfig = 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;
+                       IntPtr[] configs = new IntPtr[1];
+                       if (!ChooseConfig(dpy, desiredConfig, configs, 1, out num_configs))
+                               throw new NotSupportedException(String.Format("[EGL] Failed to retrieve GraphicsMode, error {0}", GetError()));
+
+                       currentCfg = configs [0];
+
+                       ctx = CreateContext(dpy, currentCfg, IntPtr.Zero, contextAttrib);
+                       if (ctx == IntPtr.Zero)
+                               throw new NotSupportedException(String.Format("[EGL] Failed to create egl context, error {0}.", GetError()));
+                       
+//                     int[] attribs = new int[] {
+//                             (int)Attribute.BufferSize,
+//                             Egl.RED_SIZE,
+//                             Egl.GREEN_SIZE,
+//                             Egl.BLUE_SIZE,
+//                             Egl.ALPHA_SIZE,
+//                             (int)Attribute.DepthSize,
+//                             //(int)Attribute.Height,
+//                             Egl.WIDTH,
+//                             (int)Attribute.Width,
+//                             (int)Attribute.Samples,
+//                             (int)Attribute.SampleBuffers,
+//                             (int)Attribute.RenderableType,
+//                             (int)Attribute.SurfaceType,
+//                             (int)Attribute.Level,
+//                             (int)Attribute.ConfigCaveat,
+//                     };
+//
+//                     for (int i = 0; i < configs.Length; i++) {
+//                             IntPtr conf = configs[i];
+//                             Console.Write ("{0,-3}:", i);
+//                             for (int j = 0; j < attribs.Length; j++) {
+//                                     int value;
+//                                     GetConfigAttrib (dpy, conf, attribs[j], out value);     
+//                                     Console.Write ("\t{0} = {1}, ", EglConstToString ((int)attribs[j]), value);
+//                             }
+//                             Console.Write ("\n");
+//                     }
+
+               }
+               #endregion
+
+               enum ConfigAttribute {
+                       RedSize ,
+                       GreenSize,
+                       BlueSize,
+                       AlphaSize
+               }
+
+               #region IDisposable implementation
+               ~Context(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (GetCurrentContext () == ctx) {
+                               Console.WriteLine ("destroying context");
+                               DestroyContext (dpy, ctx);
+                       }else
+                               Console.WriteLine ("not current");
+                       
+                       if (dpy != IntPtr.Zero)
+                               Terminate (dpy);
+                       dpy = IntPtr.Zero;
+               }
+               #endregion
+
+
+               static string EglConstToString (int cst){
+                       switch (cst) {
+/*                     not hex value: EGL_DONT_CARE                     ((EGLint)-1)
+                       not hex value: EGL_FALSE                         0
+                       not hex value: EGL_NO_CONTEXT                    ((EGLContext)0)
+                       not hex value: EGL_NO_DISPLAY                    ((EGLDisplay)0)
+                       not hex value: EGL_NO_SURFACE                    ((EGLSurface)0)
+                       not hex value: EGL_TRUE                          1
+                       not hex value: EGL_VERSION_1_1 1
+                       not hex value: EGL_VERSION_1_2 1
+                       not hex value: EGL_DISPLAY_SCALING               10000
+                       not hex value: EGL_UNKNOWN                       ((EGLint)-1)
+                       not hex value: EGL_VERSION_1_3 1
+                       not hex value: EGL_VERSION_1_4 1
+                       not hex value: EGL_DEFAULT_DISPLAY               ((EGLNativeDisplayType)0)
+                       not hex value: EGL_VERSION_1_5 1
+                       parsing error: EGL_FOREVER                       0xFFFFFFFFFFFFFFFFull
+                       not hex value: EGL_NO_SYNC                       ((EGLSync)0)
+                       not hex value: EGL_NO_IMAGE                      ((EGLImage)0)*/
+                       case 1:
+                               return "PBUFFER_BIT|OPENGL_ES_BIT|CONTEXT_OPENGL_CORE_PROFILE_BIT|SYNC_FLUSH_COMMANDS_BIT";
+                       case 2:
+                               return "PIXMAP_BIT|OPENVG_BIT|CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT";
+                       case 4:
+                               return "WINDOW_BIT|OPENGL_ES2_BIT";
+                       case 8:
+                               return "OPENGL_BIT";
+                       case 32:
+                               return "VG_COLORSPACE_LINEAR_BIT";
+                       case 64:
+                               return "VG_ALPHA_FORMAT_PRE_BIT|OPENGL_ES3_BIT";
+                       case 512:
+                               return "MULTISAMPLE_RESOLVE_BOX_BIT";
+                       case 1024:
+                               return "SWAP_BEHAVIOR_PRESERVED_BIT";
+                       case 12288:
+                               return "SUCCESS";
+                       case 12289:
+                               return "NOT_INITIALIZED";
+                       case 12290:
+                               return "BAD_ACCESS";
+                       case 12291:
+                               return "BAD_ALLOC";
+                       case 12292:
+                               return "BAD_ATTRIBUTE";
+                       case 12293:
+                               return "BAD_CONFIG";
+                       case 12294:
+                               return "BAD_CONTEXT";
+                       case 12295:
+                               return "BAD_CURRENT_SURFACE";
+                       case 12296:
+                               return "BAD_DISPLAY";
+                       case 12297:
+                               return "BAD_MATCH";
+                       case 12298:
+                               return "BAD_NATIVE_PIXMAP";
+                       case 12299:
+                               return "BAD_NATIVE_WINDOW";
+                       case 12300:
+                               return "BAD_PARAMETER";
+                       case 12301:
+                               return "BAD_SURFACE";
+                       case 12302:
+                               return "CONTEXT_LOST";
+                       case 12320:
+                               return "BUFFER_SIZE";
+                       case 12321:
+                               return "ALPHA_SIZE";
+                       case 12322:
+                               return "BLUE_SIZE";
+                       case 12323:
+                               return "GREEN_SIZE";
+                       case 12324:
+                               return "RED_SIZE";
+                       case 12325:
+                               return "DEPTH_SIZE";
+                       case 12326:
+                               return "STENCIL_SIZE";
+                       case 12327:
+                               return "CONFIG_CAVEAT";
+                       case 12328:
+                               return "CONFIG_ID";
+                       case 12329:
+                               return "LEVEL";
+                       case 12330:
+                               return "MAX_PBUFFER_HEIGHT";
+                       case 12331:
+                               return "MAX_PBUFFER_PIXELS";
+                       case 12332:
+                               return "MAX_PBUFFER_WIDTH";
+                       case 12333:
+                               return "NATIVE_RENDERABLE";
+                       case 12334:
+                               return "NATIVE_VISUAL_ID";
+                       case 12335:
+                               return "NATIVE_VISUAL_TYPE";
+                       case 12337:
+                               return "SAMPLES";
+                       case 12338:
+                               return "SAMPLE_BUFFERS";
+                       case 12339:
+                               return "SURFACE_TYPE";
+                       case 12340:
+                               return "TRANSPARENT_TYPE";
+                       case 12341:
+                               return "TRANSPARENT_BLUE_VALUE";
+                       case 12342:
+                               return "TRANSPARENT_GREEN_VALUE";
+                       case 12343:
+                               return "TRANSPARENT_RED_VALUE";
+                       case 12344:
+                               return "NONE";
+                       case 12345:
+                               return "BIND_TO_TEXTURE_RGB";
+                       case 12346:
+                               return "BIND_TO_TEXTURE_RGBA";
+                       case 12347:
+                               return "MIN_SWAP_INTERVAL";
+                       case 12348:
+                               return "MAX_SWAP_INTERVAL";
+                       case 12349:
+                               return "LUMINANCE_SIZE";
+                       case 12350:
+                               return "ALPHA_MASK_SIZE";
+                       case 12351:
+                               return "COLOR_BUFFER_TYPE";
+                       case 12352:
+                               return "RENDERABLE_TYPE";
+                       case 12353:
+                               return "MATCH_NATIVE_PIXMAP";
+                       case 12354:
+                               return "CONFORMANT";
+                       case 12368:
+                               return "SLOW_CONFIG";
+                       case 12369:
+                               return "NON_CONFORMANT_CONFIG";
+                       case 12370:
+                               return "TRANSPARENT_RGB";
+                       case 12371:
+                               return "VENDOR";
+                       case 12372:
+                               return "VERSION";
+                       case 12373:
+                               return "EXTENSIONS";
+                       case 12374:
+                               return "HEIGHT";
+                       case 12375:
+                               return "WIDTH";
+                       case 12376:
+                               return "LARGEST_PBUFFER";
+                       case 12377:
+                               return "DRAW";
+                       case 12378:
+                               return "READ";
+                       case 12379:
+                               return "CORE_NATIVE_ENGINE";
+                       case 12380:
+                               return "NO_TEXTURE";
+                       case 12381:
+                               return "TEXTURE_RGB";
+                       case 12382:
+                               return "TEXTURE_RGBA";
+                       case 12383:
+                               return "TEXTURE_2D";
+                       case 12416:
+                               return "TEXTURE_FORMAT";
+                       case 12417:
+                               return "TEXTURE_TARGET";
+                       case 12418:
+                               return "MIPMAP_TEXTURE";
+                       case 12419:
+                               return "MIPMAP_LEVEL";
+                       case 12420:
+                               return "BACK_BUFFER";
+                       case 12421:
+                               return "SINGLE_BUFFER";
+                       case 12422:
+                               return "RENDER_BUFFER";
+                       case 12423:
+                               return "COLORSPACE|VG_COLORSPACE";
+                       case 12424:
+                               return "ALPHA_FORMAT|VG_ALPHA_FORMAT";
+                       case 12425:
+                               return "COLORSPACE_sRGB|VG_COLORSPACE_sRGB|GL_COLORSPACE_SRGB";
+                       case 12426:
+                               return "COLORSPACE_LINEAR|VG_COLORSPACE_LINEAR|GL_COLORSPACE_LINEAR";
+                       case 12427:
+                               return "ALPHA_FORMAT_NONPRE|VG_ALPHA_FORMAT_NONPRE";
+                       case 12428:
+                               return "ALPHA_FORMAT_PRE|VG_ALPHA_FORMAT_PRE";
+                       case 12429:
+                               return "CLIENT_APIS";
+                       case 12430:
+                               return "RGB_BUFFER";
+                       case 12431:
+                               return "LUMINANCE_BUFFER";
+                       case 12432:
+                               return "HORIZONTAL_RESOLUTION";
+                       case 12433:
+                               return "VERTICAL_RESOLUTION";
+                       case 12434:
+                               return "PIXEL_ASPECT_RATIO";
+                       case 12435:
+                               return "SWAP_BEHAVIOR";
+                       case 12436:
+                               return "BUFFER_PRESERVED";
+                       case 12437:
+                               return "BUFFER_DESTROYED";
+                       case 12438:
+                               return "OPENVG_IMAGE";
+                       case 12439:
+                               return "CONTEXT_CLIENT_TYPE";
+                       case 12440:
+                               return "CONTEXT_CLIENT_VERSION|CONTEXT_MAJOR_VERSION";
+                       case 12441:
+                               return "MULTISAMPLE_RESOLVE";
+                       case 12442:
+                               return "MULTISAMPLE_RESOLVE_DEFAULT";
+                       case 12443:
+                               return "MULTISAMPLE_RESOLVE_BOX";
+                       case 12444:
+                               return "CL_EVENT_HANDLE";
+                       case 12445:
+                               return "GL_COLORSPACE";
+                       case 12448:
+                               return "OPENGL_ES_API";
+                       case 12449:
+                               return "OPENVG_API";
+                       case 12450:
+                               return "OPENGL_API";
+                       case 12465:
+                               return "GL_TEXTURE_2D";
+                       case 12466:
+                               return "GL_TEXTURE_3D";
+                       case 12467:
+                               return "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
+                       case 12468:
+                               return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
+                       case 12469:
+                               return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
+                       case 12470:
+                               return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
+                       case 12471:
+                               return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
+                       case 12472:
+                               return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
+                       case 12473:
+                               return "GL_RENDERBUFFER";
+                       case 12476:
+                               return "GL_TEXTURE_LEVEL";
+                       case 12477:
+                               return "GL_TEXTURE_ZOFFSET";
+                       case 12498:
+                               return "IMAGE_PRESERVED";
+                       case 12528:
+                               return "SYNC_PRIOR_COMMANDS_COMPLETE";
+                       case 12529:
+                               return "SYNC_STATUS";
+                       case 12530:
+                               return "SIGNALED";
+                       case 12531:
+                               return "UNSIGNALED";
+                       case 12533:
+                               return "TIMEOUT_EXPIRED";
+                       case 12534:
+                               return "CONDITION_SATISFIED";
+                       case 12535:
+                               return "SYNC_TYPE";
+                       case 12536:
+                               return "SYNC_CONDITION";
+                       case 12537:
+                               return "SYNC_FENCE";
+                       case 12539:
+                               return "CONTEXT_MINOR_VERSION";
+                       case 12541:
+                               return "CONTEXT_OPENGL_PROFILE_MASK";
+                       case 12542:
+                               return "SYNC_CL_EVENT";
+                       case 12543:
+                               return "SYNC_CL_EVENT_COMPLETE";
+                       case 12720:
+                               return "CONTEXT_OPENGL_DEBUG";
+                       case 12721:
+                               return "CONTEXT_OPENGL_FORWARD_COMPATIBLE";
+                       case 12722:
+                               return "CONTEXT_OPENGL_ROBUST_ACCESS";
+                       case 12733:
+                               return "CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY";
+                       case 12734:
+                               return "NO_RESET_NOTIFICATION";
+                       case 12735:
+                               return "LOSE_CONTEXT_ON_RESET";
+                       default:
+                               return "unknown";
+                       }
+               }
+       }
+}
+
diff --git a/testDrm/src/Egl/EGL.cs b/testDrm/src/Egl/EGL.cs
new file mode 100644 (file)
index 0000000..c8608a9
--- /dev/null
@@ -0,0 +1,257 @@
+//
+// EGL.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+
+namespace EGL
+{
+       public enum Error {
+               NoContext       = 0,
+               NoDisplay       = 0,
+               NoSurface       = 0,
+
+               NotInitialized  = 0x3001,
+               BadAccess               = 0x3002,
+               BadAlloc                = 0x3003,
+               BadAttribute    = 0x3004,
+               BadConfig               = 0x3005,
+               BadContext              = 0x3006,
+               BadCurrentSurface= 0x3007,
+               BadDisplay              = 0x3008,
+               BadMatch                = 0x3009,
+               BadNativePixmap = 0x300A,
+               BadNativeWindow = 0x300B,
+               BadParameter    = 0x300C,
+               BadSurface              = 0x300D,
+
+               ContextLost             = 0x300E,
+
+       }
+       public enum Attribute {
+               BufferSize      = 0x3020,
+               AlphaSize       = 0x3021,
+               BlueSize        = 0x3022,
+               GreenSize       = 0x3023,
+               RedSize         = 0x3024,
+               DepthSize       = 0x3025,
+               StencilSize     = 0x3026,
+               ConfigCaveat= 0x3027,
+               ConfigId        = 0x3028,
+               Level           = 0x3029,
+               Samples                 = 0x3031,
+               SampleBuffers   = 0x3032,
+               Height                  = 0x3056,
+               Width                   = 0x3057,
+               LargestPbuffer  = 0x3058,
+               MaxPbufferHeight        = 0x302A,
+               MaxPbufferPixels        = 0x302B,
+               MaxPbufferWidth         = 0x302C,
+               SurfaceType                             = 0x3033,
+               TransparentType                 = 0x3034,
+               TransparentBlueValue    = 0x3035,
+               TransparentGreenValue   = 0x3036,
+               TransparentRedValue             = 0x3037,
+               BindToTextureRgb        = 0x3039,
+               RenderableType          = 0x3040,
+               BindToTextureRgba       = 0x303A,
+               MinSwapInterval         = 0x303B,
+               MaxSwapInterval         = 0x303C,
+               AlphaMaskSize           = 0x303E,
+               ColorBufferType         = 0x303F,
+               MatchNativePixmap       = 0x3041,
+               TransparentRgb          = 0x3052,
+       }
+
+       [Flags]public enum SurfaceType {
+               DontCare        = -1,
+               None            = 0x3038,
+
+               Pbuffer         = 0x0001,
+               Pixmap          = 0x0002,
+               Window          = 0x0004,
+               VgColorspaceLinear              = 0x0020,
+               VgAlphaFormatPre                = 0x0040,
+               MultisampleResolveBox   = 0x0200,
+               SwapBehaviorPreserved   = 0x0400,
+       }
+       [Flags]public enum RenderableType {
+               DontCare        = -1,
+               None            = 0x3038,
+
+               OpenglEs        = 0x0001,
+               Openvg          = 0x0002,
+               OpenglEs2       = 0x0004,
+               Opengl          = 0x0008,
+               OpenglEs3       = 0x00000040,
+       }
+       [Flags]enum ConformantType {
+               DontCare        = -1,
+               None    = 0x3038,
+
+               SlowConfig      = 0x3050,
+               NonConformantConfig     = 0x3051,
+       }
+       [Flags]enum ColorBufferType {
+               RgbBuffer               = 0x308E,
+               LuminanceBuffer = 0x308F,
+       }
+
+       [Flags]public enum EglConsts {
+               Version10       = 1,
+
+               CoreNativeEngine        = 0x305B,
+
+
+               Draw    = 0x3059,
+               Extensions      = 0x3055,
+               False   = 0,
+               NativeRenderable        = 0x302D,
+               NativeVisualId  = 0x302E,
+               NativeVisualType        = 0x302F,
+
+
+               Read    = 0x305A,
+
+
+               Success = 0x3000,
+
+
+               True    = 1,
+
+               Vendor  = 0x3053,
+               Version = 0x3054,
+
+
+               Version11       = 1,
+
+               BackBuffer      = 0x3084,
+
+
+               MipmapTexture   = 0x3082,
+               MipmapLevel     = 0x3083,
+               NoTexture       = 0x305C,
+               Texture2d       = 0x305F,
+               TextureFormat   = 0x3080,
+               TextureRgb      = 0x305D,
+               TextureRgba     = 0x305E,
+               TextureTarget   = 0x3081,
+               Version12       = 1,
+               AlphaFormat     = 0x3088,
+               AlphaFormatNonpre       = 0x308B,
+               AlphaFormatPre  = 0x308C,
+
+               BufferPreserved = 0x3094,
+               BufferDestroyed = 0x3095,
+               ClientApis      = 0x308D,
+               Colorspace      = 0x3087,
+               ColorspaceSrgb  = 0x3089,
+               ColorspaceLinear        = 0x308A,
+
+               ContextClientType       = 0x3097,
+               DisplayScaling  = 10000,
+               HorizontalResolution    = 0x3090,
+               LuminanceSize   = 0x303D,
+
+               OpenglEsApi     = 0x30A0,
+               OpenvgApi       = 0x30A1,
+               OpenvgImage     = 0x3096,
+               PixelAspectRatio        = 0x3092,
+
+               RenderBuffer    = 0x3086,
+
+
+
+               SingleBuffer    = 0x3085,
+               SwapBehavior    = 0x3093,
+               Unknown = -1,
+               VerticalResolution      = 0x3091,
+               Version13       = 1,
+               Conformant      = 0x3042,
+               ContextClientVersion    = 0x3098,
+
+               VgAlphaFormat   = 0x3088,
+               VgAlphaFormatNonpre     = 0x308B,
+               VgAlphaFormatPre        = 0x308C,
+
+               VgColorspace    = 0x3087,
+               VgColorspaceSrgb        = 0x3089,
+               VgColorspaceLinear      = 0x308A,
+
+               Version14       = 1,
+
+               DefaultDisplay  = 0,
+
+               MultisampleResolve      = 0x3099,
+               MultisampleResolveDefault       = 0x309A,
+               MultisampleResolveBox   = 0x309B,
+               OpenglApi       = 0x30A2,
+               Version15       = 1,
+               ContextMajorVersion     = 0x3098,
+               ContextMinorVersion     = 0x30FB,
+               ContextOpenglProfileMask        = 0x30FD,
+               ContextOpenglResetNotificationStrategy  = 0x31BD,
+               NoResetNotification     = 0x31BE,
+               LoseContextOnReset      = 0x31BF,
+               ContextOpenglCoreProfileBit     = 0x00000001,
+               ContextOpenglCompatibilityProfileBit    = 0x00000002,
+               ContextOpenglDebug      = 0x31B0,
+               ContextOpenglForwardCompatible  = 0x31B1,
+               ContextOpenglRobustAccess       = 0x31B2,
+
+               ClEventHandle   = 0x309C,
+               SyncClEvent     = 0x30FE,
+               SyncClEventComplete     = 0x30FF,
+               SyncPriorCommandsComplete       = 0x30F0,
+               SyncType        = 0x30F7,
+               SyncStatus      = 0x30F1,
+               SyncCondition   = 0x30F8,
+               Signaled        = 0x30F2,
+               Unsignaled      = 0x30F3,
+               SyncFlushCommandsBit    = 0x0001,
+               Forever = int.MinValue,
+               TimeoutExpired  = 0x30F5,
+               ConditionSatisfied      = 0x30F6,
+               NoSync  = 0,
+               SyncFence       = 0x30F9,
+
+               GlColorspace    = 0x309D,
+               GlColorspaceSrgb        = 0x3089,
+               GlColorspaceLinear      = 0x308A,
+               GlRenderbuffer  = 0x30B9,
+               GlTexture2d     = 0x30B1,
+               GlTextureLevel  = 0x30BC,
+               GlTexture3d     = 0x30B2,
+               GlTextureZoffset        = 0x30BD,
+               GlTextureCubeMapPositiveX       = 0x30B3,
+               GlTextureCubeMapNegativeX       = 0x30B4,
+               GlTextureCubeMapPositiveY       = 0x30B5,
+               GlTextureCubeMapNegativeY       = 0x30B6,
+               GlTextureCubeMapPositiveZ       = 0x30B7,
+               GlTextureCubeMapNegativeZ       = 0x30B8,
+               ImagePreserved  = 0x30D2,
+               NoImage = 0,            
+       }
+}
+
diff --git a/testDrm/src/Egl/Surface.cs b/testDrm/src/Egl/Surface.cs
new file mode 100644 (file)
index 0000000..ccfcaa9
--- /dev/null
@@ -0,0 +1,97 @@
+//
+// Surface.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+
+namespace 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;
+
+       public class Surface : IDisposable
+       {
+               #region pinvoke
+               [DllImportAttribute("libEGL.dll")]
+               public static extern  EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list);
+               [DllImportAttribute("libEGL.dll")]
+               public static extern EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
+               [DllImportAttribute("libEGL.dll")]
+               public static extern EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list);
+               [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
+               public static extern bool eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
+               [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
+               public static extern bool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value);
+               [DllImportAttribute("libEGL.dll")]
+               public static extern EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list);
+               [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
+               public static extern bool eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value);
+               [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
+               public static extern bool eglBindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+               [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
+               public static extern bool eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+               #endregion
+
+               Context ctx;
+               internal EGLSurface handle;
+
+               public Surface (Context _ctx, Linux.GBM.Surface gbmSurf)
+               {
+                       ctx = _ctx;
+                       handle = eglCreateWindowSurface(ctx.dpy, ctx.currentCfg, gbmSurf.handle, IntPtr.Zero);
+                       if (handle == IntPtr.Zero)
+                               throw new NotSupportedException(String.Format("[EGL] Failed to create surface, error {0}.", EGL.Context.GetError()));
+               }
+
+               public void MakeCurrent (){
+                       if (!Context.MakeCurrent(ctx.dpy, handle, handle, ctx.ctx))
+                               throw new NotSupportedException(string.Format("eglMakeCurrent on surface Failed: {0}",Context.GetError()));                     
+               }
+
+               #region IDisposable implementation
+               ~Surface(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (handle != IntPtr.Zero)
+                               eglDestroySurface (ctx.dpy, handle);
+                       handle = IntPtr.Zero;
+               }
+               #endregion
+
+       }
+}
+
index f99192655648cde3683b858c3ff82332d2d04f38..754a12d5988c394efda48e10b61b3a63ba418af1 100644 (file)
@@ -44,21 +44,19 @@ namespace Crow.Linux
 
     enum RenderApi
     {
-        ES = Egl.OPENGL_ES_API,
-        GL = Egl.OPENGL_API,
-        VG = Egl.OPENVG_API
+               ES = Egl.OPENGL_ES_API,
+               GL = Egl.OPENGL_API,
+               VG = Egl.OPENVG_API
     }
 
-    [Flags]
-    enum RenderableFlags
+    [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,
+               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,
@@ -312,7 +310,7 @@ namespace Crow.Linux
         {
             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()));
+                throw new Exception(String.Format("Failed to create EGL context, error: {0}.", GetError()));
             return ptr;
         }
 
index d162c0717e1fb2fdc93e107b304fe1ae80d5cff9..96bbd18c6cd11aa565e2c87f5d0dc4d5f63f22c6 100644 (file)
@@ -26,6 +26,8 @@
 // THE SOFTWARE.
 //
 using OpenTK;
+using Linux;
+using Crow;
 
 
 #endregion
@@ -33,9 +35,8 @@ using OpenTK;
 using System;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
-using Crow;
 
-namespace Crow.Linux
+namespace Linux
 {
     // Bindings for linux/input.h
     class Evdev
index a0659461307e04d0c74532252545ff07a5927028..22fb26a924c60d313747bc217942a4864f1909da 100644 (file)
 using System;
 using System.Runtime.InteropServices;
 
-namespace Crow.Linux
+namespace Linux.gbm
 {
     using Device = IntPtr; // struct gbm_device*
     using Surface = IntPtr;
     using BufferObjectHandle = IntPtr;
 
-    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-    delegate void DestroyUserDataCallback(BufferObject bo, IntPtr data);
+//    [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_create", CallingConvention = CallingConvention.Cdecl)]
+               unsafe public static extern gbm_bo* CreateBO (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);
+               unsafe public static extern void DestroyBuffer (gbm_bo* bo);
 
         [DllImport(lib, EntryPoint = "gbm_bo_write", CallingConvention = CallingConvention.Cdecl)]
         public static extern int BOWrite(IntPtr bo, IntPtr buf, IntPtr count);
@@ -58,6 +58,9 @@ namespace Crow.Linux
         [DllImport(lib, EntryPoint = "gbm_bo_get_handle", CallingConvention = CallingConvention.Cdecl)]
         public static extern BufferObjectHandle BOGetHandle(IntPtr bo);
 
+               [DllImport(lib, EntryPoint = "gbm_bo_get_handle", CallingConvention = CallingConvention.Cdecl)]
+               public static extern ulong BOGetHandle(ref gbm_bo bo);
+
         [DllImport(lib, EntryPoint = "gbm_bo_get_height", CallingConvention = CallingConvention.Cdecl)]
         public static extern int BOGetHeight(IntPtr bo);
 
@@ -67,8 +70,11 @@ namespace Crow.Linux
         [DllImport(lib, EntryPoint = "gbm_bo_get_stride", CallingConvention = CallingConvention.Cdecl)]
         public static extern int BOGetStride(IntPtr bo);
 
+               [DllImport(lib, EntryPoint = "gbm_bo_get_stride", CallingConvention = CallingConvention.Cdecl)]
+               public static extern uint BOGetStride (ref gbm_bo bo);
+
         [DllImport(lib, EntryPoint = "gbm_bo_set_user_data", CallingConvention = CallingConvention.Cdecl)]
-               public static extern void BOSetUserData(IntPtr bo, IntPtr data, IntPtr callback);
+               public static extern void BOSetUserData(ref gbm_bo bo, IntPtr data, IntPtr callback);
 
 //             [DllImport(lib, EntryPoint = "gbm_bo_get_user_data", CallingConvention = CallingConvention.Cdecl)]
 //             public static extern IntPtr BOGetUserData (IntPtr bo);
@@ -93,19 +99,25 @@ namespace Crow.Linux
         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);
+        unsafe public static extern gbm_bo* LockFrontBuffer(Surface surface);
 
         [DllImport(lib, EntryPoint = "gbm_surface_release_buffer", CallingConvention = CallingConvention.Cdecl)]
-        public static extern void ReleaseBuffer(Surface surface, BufferObject buffer);
+        unsafe public static extern void ReleaseBuffer(Surface surface, gbm_bo* buffer);
 
                [DllImport(lib, EntryPoint = "gbm_surface_has_free_buffers", CallingConvention = CallingConvention.Cdecl)]
                public static extern int HasFreeBuffers (Surface surface);
 
+               [DllImport(lib, EntryPoint = "gbm_bo_map", CallingConvention = CallingConvention.Cdecl)]
+               unsafe public static extern IntPtr      Map (gbm_bo* bo, uint x, uint y, uint width, uint height, TransferFlags flags, ref uint stride, out IntPtr data);
+
+               [DllImport(lib, EntryPoint = "gbm_bo_unmap", CallingConvention = CallingConvention.Cdecl)]
+               unsafe public static extern void Unmap (gbm_bo* bo, IntPtr data);
+
     }
 
-    enum SurfaceFormat
+    public enum SurfaceFormat : uint
     {
-        BigEndian = 1 << 31,
+        BigEndian = 1u << 31,
         C8 = ((int)('C') | ((int)('8') << 8) | ((int)(' ') << 16) | ((int)(' ') << 24)),
 
         RGB332 = ((int)('R') | ((int)('G') << 8) | ((int)('B') << 16) | ((int)('8') << 24)),
@@ -180,106 +192,134 @@ namespace Crow.Linux
         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
+    
+       [Flags]public enum SurfaceFlags : uint
     {
         Scanout = (1 << 0),
         Cursor64x64 = (1 << 1),
         Rendering = (1 << 2),
         Write = (1 << 3),
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct BufferObject : IEquatable<BufferObject>
-    {
-        IntPtr buffer;
-
-        public static readonly BufferObject Zero =
-            default(BufferObject);
-
-        public int Write(byte[] data)
-        {
-            unsafe
-            {
-                fixed (byte* pdata = data)
-                {
-                    return Gbm.BOWrite(buffer, (IntPtr)pdata, (IntPtr)data.Length);
-                }
-            }
-        }
-
+               Linear = (1 << 4),
+       }
+       [Flags]public enum TransferFlags : uint {
+               /// <summary> Buffer contents read back (or accessed directly) at transfer create time.</summary>
+               Read  = 1 << 0,
+               /// <summary> Buffer contents will be written back at unmap time (or modified as a result of being accessed directly).</summary>
+               Write = 1 << 1,
+               /// <summary>Read/modify/write</summary>
+               ReadWrite = Read | Write,
+       }
+
+       [StructLayout(LayoutKind.Sequential)]
+       public struct gbm_bo {
+               IntPtr device;
+               public uint Width, Height;
+               public SurfaceFormat Format;
+               public SurfaceFlags Flags;
+
+               public uint Handle32
+               {
+                       get { return (uint)Gbm.BOGetHandle(ref this); }
+               }
+               public uint Stride
+               {
+                       get { return Gbm.BOGetStride(ref this); }
+               }
                public void SetUserData(IntPtr data, IntPtr 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
-    }
+               {
+                       Gbm.BOSetUserData(ref this, data, destroyFB);
+               }
+       }
+//    [StructLayout(LayoutKind.Sequential)]
+//    public struct BufferObject : IEquatable<BufferObject>
+//    {
+//        IntPtr buffer;
+//
+//        public static readonly BufferObject Zero =
+//            default(BufferObject);
+//
+//        public int Write(byte[] data)
+//        {
+//            unsafe
+//            {
+//                fixed (byte* pdata = data)
+//                {
+//                    return Gbm.BOWrite(buffer, (IntPtr)pdata, (IntPtr)data.Length);
+//                }
+//            }
+//        }
+//
+//             public void SetUserData(IntPtr data, IntPtr 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
+//    }
 }
 
index b7c05f6e08a6b6e2d451d334300e47667fd92a68..c1a56ad55de1d9d7023591218347ec11946dc390 100644 (file)
@@ -33,7 +33,7 @@ using System;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
-namespace Crow.Linux
+namespace Linux
 {
     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
     delegate int OpenRestrictedCallback(IntPtr path, int flags, IntPtr data);
index c39330c22f8d6bc8886229be2ff88fd22230f8a6..c3a07094f9402078e9cde6c4d0ed0612490ff691 100644 (file)
@@ -33,7 +33,7 @@ using System.Text;
 
 #pragma warning disable 0649 // field is never assigned
 
-namespace Crow.Linux
+namespace Linux
 {
     partial class Libc
     {
index cdd9c4123a12d2e7ac3a0287145ebfe0190057e3..d3a663b5d9716631e98642271a82560d8029f399 100644 (file)
@@ -30,7 +30,7 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Crow.Linux
+namespace Linux
 {
     partial class Libc
     {
diff --git a/testDrm/src/Linux/DRI.cs b/testDrm/src/Linux/DRI.cs
new file mode 100644 (file)
index 0000000..c1f60a4
--- /dev/null
@@ -0,0 +1,524 @@
+//
+// DRM.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Linux.DRI {
+       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+       public delegate void VBlankCallback(int fd, int sequence, int tv_sec, int tv_usec, IntPtr user_data);
+       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+       public delegate void PageFlipCallback(int fd, int sequence, int tv_sec, int tv_usec, ref int user_data);
+
+       public enum EncoderType : uint
+       {
+               NONE=0,
+               DAC=1,
+               TMDS=2,
+               LVDS=3,
+               TVDAC=4,
+               VIRTUAL=5,
+               DSI=6,
+               DPMST=7,
+               DPI=8,
+       }
+       public enum PlaneType {
+               Overlay = 0,
+               Primary = 1,
+               Cursor = 2
+       }
+
+       [Flags]public enum PageFlipFlags
+       {
+               FlipEvent = 0x01,
+               FlipAsync = 0x02,
+               FlipFlags = FlipEvent | FlipAsync
+       }
+       /// <summary>Video mode flags, bit compatible with the xorg definitions. </summary>
+       [Flags]public enum VideoMode
+       {
+               PHSYNC = 0x01,
+               NHSYNC = 0x02,
+               PVSYNC = 0x04,
+               NVSYNC = 0x08,
+               INTERLACE = 0x10,
+               DBLSCAN = 0x20,
+               CSYNC = 0x40,
+               PCSYNC = 0x80,
+               NCSYNC = 0x10,
+               HSKEW = 0x0200,
+               BCAST = 0x0400,
+               PIXMUX = 0x0800,
+               DBLCLK = 0x1000,
+               CLKDIV2 = 0x2000,
+               //              FLAG_3D_MASK                    (0x1f<<14)
+               //              FLAG_3D_NONE = 0x0;
+               //              FLAG_3D_FRAME_PACKING = 0x4000,
+               //              FLAG_3D_FIELD_ALTERNATIVE = 0x8000,
+               //              FLAG_3D_LINE_ALTERNATIVE        (3<<14)
+               //              FLAG_3D_SIDE_BY_SIDE_FULL       (4<<14)
+               //              FLAG_3D_L_DEPTH         (5<<14)
+               //              FLAG_3D_L_DEPTH_GFX_GFX_DEPTH   (6<<14)
+               //              FLAG_3D_TOP_AND_BOTTOM  (7<<14)
+               //              FLAG_3D_SIDE_BY_SIDE_HALF       (8<<14)         
+       }
+
+       [StructLayout(LayoutKind.Sequential)]
+       public struct EventContext
+       {
+               public int version;
+               public IntPtr vblank_handler;
+               public IntPtr page_flip_handler;
+               public static readonly int Version = 2;
+       }
+       [StructLayout(LayoutKind.Sequential)]
+       unsafe public struct drmFrameBuffer {
+               public uint fb_id;
+               public uint width, height;
+               public uint pitch;
+               public uint bpp;
+               public uint depth;
+               /* driver specific handle */
+               public uint handle;
+       }
+       [StructLayout(LayoutKind.Sequential)]
+       unsafe internal struct drmPlaneRes {
+               public uint count_planes;
+               public uint *planes;
+       }
+
+       public class GPUControler : IDisposable {
+               int fd_gpu = -1;
+               GBM.Device gbmDev;
+               GBM.Surface gbmSurf;
+               EGL.Context eglctx;
+               EGL.Surface eglSurf;
+
+               Cairo.EGLDevice cairoDev;
+               public Cairo.GLSurface CairoSurf;
+
+               Resources resources = null;
+               Connector connector = null;
+               Crtc currentCrtc = null;
+               ModeInfo currentMode;
+
+               public GPUControler(string gpu_path = "/dev/dri/card0"){
+                       fd_gpu = Libc.open(gpu_path, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
+                       if (fd_gpu < 0)
+                               throw new NotSupportedException("[DRI] Failed to open gpu");
+                       
+                       resources = new Resources (fd_gpu);
+                       gbmDev = new GBM.Device (fd_gpu);
+                       eglctx = new EGL.Context (gbmDev);
+
+                       try {
+                               if (defaultConfiguration ())
+                                       Console.WriteLine ("default config ok");                                
+                       } catch (Exception ex) {
+                               Console.WriteLine (ex.ToString());
+                       }
+               }
+
+               byte bpp = 32;
+               byte depth = 24;
+
+               public int Width { get { return (int)currentMode.hdisplay; }}
+               public int Height { get { return (int)currentMode.vdisplay; }}
+
+               bool defaultConfiguration (){
+                       //select the first connected connector
+                       foreach (Connector c in resources.Connectors) {
+                               if (c.State == ConnectionStatus.Connected) {
+                                       connector = c;
+                                       break;
+                               }                               
+                       }
+                       if (connector == null)
+                               return false;
+                       
+                       currentCrtc = connector.CurrentEncoder.CurrentCrtc;
+                       currentMode = currentCrtc.CurrentMode;
+                       
+                       //configure a rendering stack
+                       gbmSurf = new GBM.Surface (gbmDev, Width, Height,
+                               GBM.SurfaceFlags.Rendering | GBM.SurfaceFlags.Scanout);
+
+                       eglSurf = new EGL.Surface (eglctx, gbmSurf);
+                       eglSurf.MakeCurrent ();
+
+                       cairoDev = new Cairo.EGLDevice (eglctx.dpy, eglctx.ctx);
+
+                       CairoSurf = new Cairo.GLSurface (cairoDev, eglSurf.handle, Width, Height);
+                       //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.");
+                       
+                       return true;
+               }
+               void handleDestroyFB(ref GBM.gbm_bo bo, IntPtr data)
+               {
+                       int fb = data.ToInt32();
+
+                       if (fb != 0) {
+                               if (drmModeRmFB (fd_gpu, fb) != 0)
+                                       Console.WriteLine ("DestroyFB failed");
+                               else
+                                       Console.WriteLine ("DestroyFB ok fd={0}", fd_gpu);
+                       }
+               }
+
+
+
+               unsafe public void Update(){
+                       GBM.gbm_bo* bo; 
+                       uint fb;
+
+//                     PollFD fds = new PollFD();
+//                     fds.fd = fd_gpu;
+//                     fds.events = PollFlags.In;
+//
+//                     EventContext evctx = new EventContext();
+//                     evctx.version = EventContext.Version;
+//                     evctx.page_flip_handler = PageFlipPtr;
+
+//                     int timeout = -1;//block ? -1 : 0;
+//
+
+                       if (!gbmSurf.HasFreeBuffers)
+                               throw new NotSupportedException("[GBM] Out of free buffer");
+                               
+                       bo = gbmSurf.Lock ();
+                       //fb = getFbFromBo (bo);
+                       //unsafe {
+                               //Console.WriteLine ("current fb: {0}", currentCrtc.CurrentFbId);
+                               //if (currentCrtc.CurrentFbId == 0)
+
+                               int ret = drmModeAddFB (fd_gpu, currentMode.hdisplay, currentMode.vdisplay, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb);
+                               if (ret != 0)
+                                       Console.WriteLine ("addFb failed: {0}", ret);                           
+                               //else
+                               //      fb = currentCrtc.CurrentFbId;
+                               bo->SetUserData ((IntPtr)fb, handleDestroyFB);
+
+                               uint connId = connector.Id;
+                               ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode);
+                               if (ret != 0)
+                                       Console.WriteLine ("setCrtc failed: {0}", ret);
+                       //}
+                       gbmSurf.Release (bo);
+
+                       //bo.Dispose ();
+//
+//                     SetScanoutRegion (fb);
+//                     drmTimeOut.Restart();
+//
+//                     while (run && drmTimeOut.ElapsedMilliseconds < 10000){                          
+//                             BufferObject next_bo;
+//                             bool update = false;
+//
+//                             if (updateMousePos) {
+//                                     lock (Sync) {
+//                                             updateMousePos = false;
+//                                             unsafe {        
+//                                                     Drm.MoveCursor (fd_gpu, pEncoder->crtc_id, MouseX-8, MouseY-4);
+//                                             }
+//                                     }
+//                             }
+//
+//                             if (Monitor.TryEnter (CrowInterface.RenderMutex)) {
+//                                     if (CrowInterface.IsDirty) {
+//                                             CrowInterface.IsDirty = false;
+//                                             update = true;
+//                                             using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) {
+//                                                     using (Cairo.Surface d = new Cairo.ImageSurface (CrowInterface.dirtyBmp, Cairo.Format.Argb32,
+//                                                             width, height, width * 4)) {
+//                                                             ctx.SetSourceSurface (d, 0, 0);
+//                                                             ctx.Operator = Cairo.Operator.Source;
+//                                                             ctx.Paint ();
+//                                                     }
+//                                             }
+//                                     }
+//                                     Monitor.Exit (CrowInterface.RenderMutex);
+//                             }
+//
+//                             if (!update)
+//                                     continue;
+//                             update = false;
+//
+//                             cairoSurf.Flush ();
+//                             cairoSurf.SwapBuffers ();
+//
+//                             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.");
+//
+//                             fb = getFbFromBo (next_bo);
+//
+//                             unsafe{
+//                                     int is_flip_queued = 1;
+//
+//                                     while (Drm.ModePageFlip (fd_gpu, pEncoder->crtc_id, fb, PageFlipFlags.FlipEvent, ref is_flip_queued) < 0) {
+//                                             //Console.WriteLine ("[DRM] Failed to enqueue framebuffer flip.");                              
+//                                             continue;
+//                                     }
+//
+//                                     while (is_flip_queued != 0)
+//                                     {
+//                                             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_gpu, ref evctx);
+//                                             else
+//                                                     break;
+//                                             Thread.Sleep (1);
+//                                     }
+//                                     if (is_flip_queued != 0)
+//                                             Console.WriteLine ("flip canceled");
+//
+//                                     Gbm.ReleaseBuffer (gbm_surface, bo);
+//                                     //Drm.ModeRmFB(fd_gpu, fb);
+//
+//                                     bo = next_bo;
+//                                     next_bo = BufferObject.Zero;
+//
+//                             }
+//                     }
+               }
+
+               #region cursor
+               GBM.BufferObject boMouseCursor;
+
+               internal void updateCursor (Crow.XCursor cursor) {
+                       uint width = 64, height = 64;
+                       if (cursor.Width > width || cursor.Height > height){
+                               Debug.Print("[DRM] Cursor size {0}x{1} unsupported. Maximum is 64x64.",
+                                       cursor.Width, cursor.Height);
+                               return;
+                       }
+                       boMouseCursor = new GBM.BufferObject (gbmDev, width, height, GBM.SurfaceFormat.ARGB8888,
+                               GBM.SurfaceFlags.Cursor64x64 | GBM.SurfaceFlags.Write);
+                       
+                       // Copy cursor.Data into a new buffer of the correct size
+                       byte[] cursor_data = new byte[width * height * 4];
+                       for (uint y = 0; y < cursor.Height; y++)
+                       {
+                               uint dst_offset = y * width * 4;
+                               uint src_offset = y * cursor.Width * 4;
+                               uint src_length = cursor.Width * 4;
+                               Array.Copy(
+                                       cursor.data, src_offset,
+                                       cursor_data, dst_offset,
+                                       src_length);
+                       }
+
+                       boMouseCursor.Data = cursor_data;
+                       uint crtcid = currentCrtc.Id;
+
+                       unsafe {
+                               drmModeSetCursor2 (fd_gpu, crtcid,
+                                       (uint)boMouseCursor.handle->Handle32, width, height, (int)cursor.Xhot, (int)cursor.Yhot);
+                               drmModeMoveCursor (fd_gpu, crtcid, 0, 0);
+                       }
+               }
+               internal void moveCursor (uint x, uint y){
+                       drmModeMoveCursor (fd_gpu, currentCrtc.Id, x, y);
+               }
+               #endregion
+//             void initGbm (){
+//                     gbm_surface =  Gbm.CreateSurface(gbm_device, mode.hdisplay, mode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Rendering | SurfaceFlags.Scanout);
+//                     if (gbm_surface == IntPtr.Zero)
+//                             throw new NotSupportedException("[GBM] Failed to create GBM surface for rendering");                                            
+//
+//                     unsafe {
+//                             gbm_bo* bo = Gbm.CreateBO (gbm_device, mode.hdisplay, mode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Scanout);
+//                             if (bo == null)
+//                                     Console.WriteLine ("failed to create a BufferObject for screen 0");
+//                             else {
+//                                     uint fb_id = screens [0].BindBuffer (bo);
+//                                     //                                              if (paint (bo))
+//                                     //                                                      Console.WriteLine ("[DRI] bo paint succeed");
+//                                     //                                              ModeDirtyFB (fd_gpu, fb_id, IntPtr.Zero, 0);
+//                             }
+//                             //                                      //Gbm.DestroyBuffer (bo);
+//                             ModeAddFB (fd_gpu, bo->Width, bo->Height,(byte)depth, (byte)bpp, bo->Stride, bo->Handle32, out fb_id);
+//                             bo->SetUserData ((IntPtr)fb_id, IntPtr.Zero);
+//
+//                             int ret = ModeSetCrtc(fd_gpu, crtc_id, fb_id, x, y, &connector_id, 1, ref mode);
+//                     }
+//             }
+//             unsafe public drmPlane GetPlane (uint id) {
+//                     drmPlane p = new drmPlane();
+//                     drmPlane* pPlane = ModeGetPlane (fd_gpu, id);
+//                     if (pPlane != null) {
+//                             p = *pPlane;
+//                             ModeFreePlane (pPlane);
+//                     }
+//                     return p;
+//             }
+//             public void SetPlane (drmPlane p, uint flags, uint crtc_w, uint crtc_h, uint src_w, uint src_h) {
+//                     ModeSetPlane (fd_gpu, p.plane_id, p.crtc_id, p.fb_id, flags,
+//                             (int)p.crtc_x, (int)p.crtc_y,
+//                             crtc_w, crtc_h,
+//                             p.x, p.y,
+//                             src_w, src_h);
+//
+//                             
+//             }
+
+               #region IDisposable implementation
+               ~GPUControler(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (cairoDev != null) {
+                               cairoDev.Release ();
+                               CairoSurf.Dispose ();
+                               cairoDev.Dispose ();
+                               cairoDev = null;
+                               CairoSurf = null;
+                       }
+
+                       if (boMouseCursor != null)
+                               boMouseCursor.Dispose ();
+                       boMouseCursor = null;
+                       if (eglctx != null)
+                               eglctx.Dispose ();
+                       eglctx = null;
+
+                       if (gbmSurf != null)
+                               gbmSurf.Dispose ();
+                       if (gbmDev != null)
+                               gbmDev.Dispose ();                      
+                       if (currentCrtc != null)
+                               currentCrtc.Dispose ();                 
+                       if (connector != null)
+                               connector.Dispose ();                   
+                       if (resources != null)
+                               resources.Dispose ();
+                       resources = null;
+                       if (fd_gpu > 0)
+                               Libc.close (fd_gpu);
+                       fd_gpu = -1;
+                       Console.WriteLine ("disposing ok");
+               }
+               #endregion
+
+               #region dllimports
+               const string lib = "libdrm";
+               [DllImport(lib, EntryPoint = "drmHandleEvent", CallingConvention = CallingConvention.Cdecl)]
+               public static extern int HandleEvent(int fd, ref EventContext evctx);
+               [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+               public static extern int drmModeAddFB(int fd, uint width, uint height, byte depth,
+                       byte bpp, uint stride, uint bo_handle, out uint buf_id);
+               [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+               public static extern int drmModeRmFB(int fd, int bufferId);
+               [DllImport(lib, EntryPoint = "drmModeDirtyFB", CallingConvention = CallingConvention.Cdecl)]
+               public static extern int ModeDirtyFB(int fd, uint bufferId, IntPtr clips, uint num_clips);
+               
+
+               [DllImport(lib, EntryPoint = "drmModeGetFB", CallingConvention = CallingConvention.Cdecl)]
+               unsafe internal static extern drmFrameBuffer* ModeGetFB(int fd, uint fb_id);
+               [DllImport(lib, EntryPoint = "drmModeGetPlaneResources", CallingConvention = CallingConvention.Cdecl)]
+               unsafe internal static extern drmPlaneRes* ModeGetPlaneResources(int fd);
+
+               [DllImport(lib, EntryPoint = "drmModeFreeFB", CallingConvention = CallingConvention.Cdecl)]
+               unsafe internal static extern void ModeFreeFB(drmFrameBuffer* ptr);
+               [DllImport(lib, EntryPoint = "drmModeFreePlaneResources", CallingConvention = CallingConvention.Cdecl)]
+               unsafe internal static extern void ModeFreePlaneResources(drmPlaneRes* ptr);
+
+               [DllImport(lib, EntryPoint = "drmModeSetPlane", CallingConvention = CallingConvention.Cdecl)]
+               unsafe static extern int ModeSetPlane(int fd, uint plane_id, uint crtc_id,
+                       uint fb_id, uint flags,
+                       int crtc_x, int crtc_y,
+                       uint crtc_w, uint crtc_h,
+                       uint src_x, uint src_y,
+                       uint src_w, uint src_h);
+
+               [DllImport(lib, EntryPoint = "drmModePageFlip", CallingConvention = CallingConvention.Cdecl)]
+               static extern int ModePageFlip(int fd, int crtc_id, int fb_id,
+                       PageFlipFlags flags, ref int user_data);
+
+               [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+               unsafe static extern int drmModeSetCrtc(int fd, uint crtcId, uint bufferId,     uint x, uint y, uint* connectors, int count, ref ModeInfo mode);
+
+               [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+               internal static extern int drmModeSetCursor2(int fd, uint crtcId, uint bo_handle, uint width, uint height, int hot_x, int hot_y);
+
+               [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+               internal static extern int drmModeMoveCursor(int fd, uint crtcId, uint x, uint y);
+               #endregion
+
+
+//             unsafe static bool paint(gbm_bo * bo)
+//             {
+//                     uint w = (uint)bo->Width;
+//                     uint h = (uint)bo->Height;
+//                     uint stride = (uint)bo->Stride;
+//
+//                     Console.WriteLine ("trying to map bo: {0}x{1} stride:{2}", w, h, stride);
+//                     bool success = false;
+//                     try {
+//                             unsafe {
+//                                     IntPtr map_data = IntPtr.Zero;
+//                                     IntPtr addr = Gbm.Map (bo, 0, 0, w, h, TransferFlags.Write, ref stride, out map_data);
+//                                     if (addr == IntPtr.Zero || map_data == IntPtr.Zero) {
+//                                             Console.WriteLine ("failed to mmap gbm bo");
+//                                             return false;
+//                                     }
+//                                     Console.WriteLine ("addr = {0}", addr.ToString());
+//                                     byte* b = (byte*)addr;
+//                                     for (int y = 0; y < h; y++) {
+//                                             for (int x = 0; x < w; x++) {                                                   
+//                                                     *(b + x + y * stride) = 0xff;
+//                                             }
+//                                     }
+//                                     Gbm.Unmap (bo, map_data);
+//                                     success = true;
+//                             }
+//                     } catch (Exception ex) {
+//                             Console.WriteLine (ex.ToString ());
+//                     }
+//                     return success;
+//             }
+       }
+}
\ No newline at end of file
diff --git a/testDrm/src/Linux/DRI/Connector.cs b/testDrm/src/Linux/DRI/Connector.cs
new file mode 100644 (file)
index 0000000..97acf4b
--- /dev/null
@@ -0,0 +1,190 @@
+//
+// Connector.cs
+//
+// Author:
+//              Stefanos Apostolopoulos <stapostol@gmail.com>
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+// 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.Runtime.InteropServices;
+
+namespace Linux.DRI
+{
+       #region Enums
+       public enum ConnectionStatus
+       {
+               Connected = 1,
+               Disconnected = 2,
+               Unknown = 3
+       }
+       public enum ConnectorType
+       {
+               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
+       }
+       public enum SubPixel
+       {
+               Unknown = 1,
+               HorizontalRgb = 2,
+               HorizontalBgr = 3,
+               VerticalRgb = 4,
+               VerticalBgr = 5,
+               None = 6
+       }
+       #endregion
+
+       [StructLayout(LayoutKind.Sequential)]
+       unsafe internal struct drmConnector
+       {
+               public uint connector_id;
+               public uint encoder_id;
+               public ConnectorType connector_type;
+               public uint connector_type_id;
+               public ConnectionStatus connection;
+               public uint mmWidth, mmHeight;
+               public SubPixel subpixel;
+
+               public int count_modes;
+               public ModeInfo* modes;
+
+               public int count_props;
+               public uint *props;
+               public ulong *prop_values;
+
+               public int count_encoders;
+               public uint *encoders;
+       }
+       [StructLayout(LayoutKind.Sequential)]
+       unsafe public 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];
+
+               public string Name {
+                       get {
+                               fixed( sbyte* bytes = name)
+                                       return new string (bytes);
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       return string.Format ("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}",
+                               Name, clock, hdisplay, hsync_start, hsync_end, htotal, hskew,
+                               vdisplay, vsync_start, vsync_end, vtotal, vscan, vrefresh);
+               }
+       }
+
+       unsafe public class Connector : IDisposable
+       {
+               #region pinvoke
+               [DllImport("libdrm", EntryPoint = "drmModeGetConnector", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern drmConnector* ModeGetConnector(int fd, uint connector_id);
+               [DllImport("libdrm", EntryPoint = "drmModeFreeConnector", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void ModeFreeConnector(drmConnector* ptr);
+               #endregion
+
+               int fd_gpu;
+               drmConnector* handle;
+
+               #region ctor
+               public Connector (int _fd_gpu, uint _id)
+               {
+                       fd_gpu = _fd_gpu;
+                       handle = ModeGetConnector (fd_gpu, _id);
+
+                       if (handle == null)
+                               throw new NotSupportedException("[DRI] drmModeGetConnector failed.");
+               }
+               #endregion
+
+               public uint Id { get { return handle->connector_id; }}
+               public ConnectionStatus State { get { return handle->connection; }}
+               public ConnectorType Type { get { return handle->connector_type; }}
+               public SubPixel SubPixel { get { return handle->subpixel; }}
+
+               public Encoder CurrentEncoder {
+                       get { 
+                               return handle->encoder_id == 0 ? null : new Encoder (fd_gpu, handle->encoder_id);
+                       }
+               }
+
+               public ModeInfo[] Modes {
+                       get { 
+                               ModeInfo[] tmp = new ModeInfo[handle->count_modes];
+                               for (int i = 0; i < handle->count_modes; i++) {
+                                       ModeInfo m = *(handle->modes + i);
+                                       tmp [i] = m;
+                               }
+                               return tmp;
+                       }
+               }
+
+               #region IDisposable implementation
+               ~Connector(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       unsafe {
+                               if (handle != null)
+                                       ModeFreeConnector (handle);
+                               handle = null;
+                       }
+               }
+               #endregion
+
+               public override string ToString ()
+               {
+                       return string.Format ("Connector: Id={0}, State={1}, Type={2}, SubPixel={3}", Id, State, Type, SubPixel);
+               }
+       }
+}
+
diff --git a/testDrm/src/Linux/DRI/Crtc.cs b/testDrm/src/Linux/DRI/Crtc.cs
new file mode 100644 (file)
index 0000000..0ec316e
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// Crtc.cs
+//
+// Author:
+//              Stefanos Apostolopoulos <stapostol@gmail.com>
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+// 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.Runtime.InteropServices;
+
+namespace Linux.DRI 
+{
+       [StructLayout(LayoutKind.Sequential)]
+       internal struct drmCrtc
+       {
+               public uint crtc_id;
+               public uint buffer_id;
+
+               public uint x, y;
+               public uint width, height;
+               public int mode_valid;
+               public ModeInfo mode;
+
+               public int gamma_size;
+       }
+
+       unsafe public class Crtc : IDisposable
+       {
+               #region pinvoke
+               [DllImport("libdrm", EntryPoint = "drmModeGetCrtc", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern drmCrtc* ModeGetCrtc(int fd, uint crtcId);
+               [DllImport("libdrm", EntryPoint = "drmModeFreeCrtc", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void ModeFreeCrtc(drmCrtc* ptr);
+               #endregion
+
+               int fd_gpu;
+               internal drmCrtc* handle;
+
+               #region ctor
+               internal Crtc (int _fd_gpu, uint _id)
+               {
+                       fd_gpu = _fd_gpu;
+                       handle = ModeGetCrtc (fd_gpu, _id);
+
+                       if (handle == null)
+                               throw new NotSupportedException("[DRI] drmModeGetCrtc failed.");
+               }
+               #endregion
+
+               public uint Id { get { return handle->crtc_id; }}
+               public ModeInfo CurrentMode { get { return handle->mode; }}
+               public uint CurrentFbId { get { return handle->buffer_id; }}
+               public bool ModeIsValid { get { return handle->mode_valid == 0 ? false : true; }}
+               public uint X { get { return handle->x; }}
+               public uint Y { get { return handle->x; }}
+               public uint Height { get { return handle->height; }}
+               public uint Width { get { return handle->width; }}
+               public int GammaSize { get { return handle->gamma_size; }}
+
+               #region IDisposable implementation
+               ~Crtc(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       unsafe {
+                               if (handle != null)
+                                       ModeFreeCrtc (handle);
+                               handle = null;
+                       }
+               }
+               #endregion
+
+               public override string ToString ()
+               {
+                       return string.Format ("[Crtc: Id={0}, CurrentMode={1}, CurrentFbId={2}, ModeIsValid={3}, X={4}, Y={5}, Height={6}, Width={7}, GammaSize={8}]", Id, CurrentMode, CurrentFbId, ModeIsValid, X, Y, Height, Width, GammaSize);
+               }
+       }
+}
+
diff --git a/testDrm/src/Linux/DRI/Encoder.cs b/testDrm/src/Linux/DRI/Encoder.cs
new file mode 100644 (file)
index 0000000..a3b3b70
--- /dev/null
@@ -0,0 +1,101 @@
+//
+// Encoder.cs
+//
+// Author:
+//              Stefanos Apostolopoulos <stapostol@gmail.com>
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+// 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.Runtime.InteropServices;
+
+namespace Linux.DRI 
+{
+       [StructLayout(LayoutKind.Sequential)]
+       public struct drmEncoder
+       {
+               public uint encoder_id;
+               public EncoderType encoder_type;
+               public uint crtc_id;
+               public uint possible_crtcs;
+               public uint possible_clones;
+       }
+
+       unsafe public class Encoder : IDisposable
+       {
+               #region pinvoke
+               [DllImport("libdrm", EntryPoint = "drmModeGetEncoder", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern drmEncoder* ModeGetEncoder(int fd, uint encoder_id);
+               [DllImport("libdrm", EntryPoint = "drmModeFreeEncoder", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void ModeFreeEncoder(drmEncoder* ptr);
+               #endregion
+
+               int fd_gpu;
+               drmEncoder* handle;
+
+               #region ctor
+               unsafe internal Encoder (int _fd_gpu, uint _id)
+               {
+                       fd_gpu = _fd_gpu;
+                       handle = ModeGetEncoder (fd_gpu, _id);
+
+                       if (handle == null)
+                               throw new NotSupportedException("[DRI] drmModeGetEncoder failed.");
+               }
+               #endregion
+                       
+               public uint Id { get { return handle->encoder_id; }}
+               public EncoderType Type { get { return handle->encoder_type; }}
+               public uint PossibleCrtcs { get { return handle->possible_crtcs; }}
+               public uint PossibleClones { get { return handle->possible_clones; }}
+
+               public Crtc CurrentCrtc {
+                       get {
+                               return handle->crtc_id == 0 ? null : new Crtc (fd_gpu, handle->crtc_id);
+                       }
+               }
+
+               #region IDisposable implementation
+               ~Encoder(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       unsafe {
+                               if (handle != null)
+                                       ModeFreeEncoder (handle);
+                               handle = null;
+                       }
+               }
+               #endregion
+
+               public override string ToString ()
+               {
+                       return string.Format ("[Encoder: Id={0}, Type={1}, PossibleCrtcs={2}, PossibleClones={3}]", Id, Type, PossibleCrtcs, PossibleClones);
+               }
+       }
+}
+
diff --git a/testDrm/src/Linux/DRI/Plane.cs b/testDrm/src/Linux/DRI/Plane.cs
new file mode 100644 (file)
index 0000000..80b4945
--- /dev/null
@@ -0,0 +1,84 @@
+//
+// Plane.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+
+namespace Linux.DRI
+{
+       [StructLayout(LayoutKind.Sequential)]
+       unsafe public struct drmPlane {
+               public uint count_formats;
+               public uint *formats;
+               public uint plane_id;
+
+               public uint crtc_id;
+               public uint fb_id;
+
+               public uint crtc_x, crtc_y;
+               public uint x, y;
+
+               public uint possible_crtcs;
+               public uint gamma_size;
+       }
+
+       unsafe public class Plane : IDisposable
+       {
+               #region pinvoke
+               [DllImport("libdrm", EntryPoint = "drmModeGetPlane", CallingConvention = CallingConvention.Cdecl)]
+               unsafe internal static extern drmPlane* ModeGetPlane(int fd, uint id);
+               [DllImport("libdrm", EntryPoint = "drmModeFreePlane", CallingConvention = CallingConvention.Cdecl)]
+               unsafe internal static extern void ModeFreePlane(drmPlane* ptr);
+               #endregion
+
+               drmPlane* handle;
+
+               internal Plane (drmPlane* _handle)
+               {
+                       handle = _handle;
+               }
+                       
+               public uint Id { get { return handle->plane_id; }}
+
+               #region IDisposable implementation
+               ~Plane(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       unsafe {
+                               if (handle != null)
+                                       ModeFreePlane (handle);
+                               handle = null;
+                       }
+               }
+               #endregion
+       }
+}
+
diff --git a/testDrm/src/Linux/DRI/Resources.cs b/testDrm/src/Linux/DRI/Resources.cs
new file mode 100644 (file)
index 0000000..d4b136d
--- /dev/null
@@ -0,0 +1,117 @@
+//
+// Resources.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+
+namespace Linux.DRI
+{
+       [StructLayout(LayoutKind.Sequential)]
+       unsafe internal struct drmResources
+       {
+               public int count_fbs;
+               public uint* fbs;
+               public int count_crtcs;
+               public uint* crtcs;
+               public int count_connectors;
+               public uint* connectors;
+               public int count_encoders;
+               public uint* encoders;
+               public uint min_width, max_width;
+               public uint min_height, max_height;
+       }
+
+       unsafe public class Resources: IDisposable
+       {
+               #region pinvoke
+               [DllImport("libdrm", EntryPoint = "drmModeGetResources", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern drmResources* ModeGetResources(int fd);
+               [DllImport("libdrm", EntryPoint = "drmModeFreeResources", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void ModeFreeResources(drmResources* ptr);
+               #endregion
+
+               int gpu_fd;
+               drmResources* handle;
+                       
+               #region ctor
+               public Resources (int fd_gpu)
+               {
+                       gpu_fd = fd_gpu;
+                       handle = ModeGetResources (fd_gpu);
+
+                       if (handle == null)
+                               throw new NotSupportedException("[DRI] drmModeGetResources failed.");
+               }
+               #endregion
+
+               public uint min_width { get { return handle->min_width; }}
+               public uint max_width { get { return handle->max_width; }}
+               public uint min_height { get { return handle->min_height; }}
+               public uint max_height { get { return handle->max_height; }}
+
+               public Connector[] Connectors {
+                       get {
+                               Connector[] tmp = new Connector[handle->count_connectors];
+                               for (int i = 0; i < handle->count_connectors; i++)
+                                       tmp [i] = new Connector (gpu_fd, *(handle->connectors + i));
+                               return tmp;
+                       }
+               }
+               public Encoder[] Encoders {
+                       get {
+                               Encoder[] tmp = new Encoder[handle->count_encoders];
+                               for (int i = 0; i < handle->count_encoders; i++)
+                                       tmp [i] = new Encoder (gpu_fd, *(handle->encoders + i));
+                               return tmp;
+                       }
+               }
+               public Crtc[] Crtcs {
+                       get {
+                               Crtc[] tmp = new Crtc[handle->count_encoders];
+                               for (int i = 0; i < handle->count_crtcs; i++)
+                                       tmp [i] = new Crtc (gpu_fd, *(handle->crtcs + i));
+                               return tmp;
+                       }
+               }
+
+               #region IDisposable implementation
+               ~Resources(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (handle != null)
+                               ModeFreeResources (handle);
+                       handle = null;
+               }
+               #endregion
+
+       }
+}
+
diff --git a/testDrm/src/Linux/DRM.cs b/testDrm/src/Linux/DRM.cs
deleted file mode 100644 (file)
index 3bdd950..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-//
-// DRM.cs
-//
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-using System;
-using System.Runtime.InteropServices;
-
-namespace Crow.Linux.DRI {
-       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-       public delegate void VBlankCallback(int fd, int sequence, int tv_sec, int tv_usec, IntPtr user_data);
-       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-       public delegate void PageFlipCallback(int fd, int sequence, int tv_sec, int tv_usec, ref int user_data);
-
-       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
-       }
-
-       [Flags]
-       enum ModeFlags
-       {
-               /* Video mode flags */
-               /* bit compatible with the xorg definitions. */
-               PHSYNC = 0x01,
-               NHSYNC = 0x02,
-               PVSYNC = 0x04,
-               NVSYNC = 0x08,
-               INTERLACE = 0x10,
-               DBLSCAN = 0x20,
-               CSYNC = 0x40,
-               PCSYNC = 0x80,
-               NCSYNC = 0x10,
-               HSKEW = 0x0200,
-               BCAST = 0x0400,
-               PIXMUX = 0x0800,
-               DBLCLK = 0x1000,
-               CLKDIV2 = 0x2000,
-               //              FLAG_3D_MASK                    (0x1f<<14)
-               //              FLAG_3D_NONE = 0x0;
-               //              FLAG_3D_FRAME_PACKING = 0x4000,
-               //              FLAG_3D_FIELD_ALTERNATIVE = 0x8000,
-               //              FLAG_3D_LINE_ALTERNATIVE        (3<<14)
-               //              FLAG_3D_SIDE_BY_SIDE_FULL       (4<<14)
-               //              FLAG_3D_L_DEPTH         (5<<14)
-               //              FLAG_3D_L_DEPTH_GFX_GFX_DEPTH   (6<<14)
-               //              FLAG_3D_TOP_AND_BOTTOM  (7<<14)
-               //              FLAG_3D_SIDE_BY_SIDE_HALF       (8<<14)         
-       }
-
-       [StructLayout(LayoutKind.Sequential)]
-       public 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;
-       }
-
-       [StructLayout(LayoutKind.Sequential)]
-       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;
-       }
-
-       [StructLayout(LayoutKind.Sequential)]
-       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 uint* fbs;
-               public int count_crtcs;
-               public uint* crtcs;
-               public int count_connectors;
-               public uint* connectors;
-               public int count_encoders;
-               public uint* encoders;
-               public uint min_width, max_width;
-               public uint min_height, max_height;
-       }
-
-
-
-       public class GPUControler : IDisposable {
-               int fd_gpu = -1;
-               ModeRes resources = new ModeRes ();
-
-               public GPUControler(string gpu_path = "/dev/dri/card0"){
-                       fd_gpu = Libc.open(gpu_path, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
-                       if (fd_gpu < 0)
-                               throw new NotSupportedException("[KMS] Failed to open gpu");
-                       
-                       unsafe {
-                               ModeRes* ptrRes = ModeGetResources (fd_gpu);
-                               resources = *ptrRes;
-                               ModeFreeResources (ptrRes);
-                       }
-
-//                     if (resources == null)
-//                             throw new NotSupportedException("[KMS] Drm.ModeGetResources failed.");
-               }
-
-               #region IDisposable implementation
-               ~GPUControler(){
-                       Dispose (false);
-               }
-               public void Dispose ()
-               {
-                       Dispose (true);
-                       GC.SuppressFinalize (this);
-               }
-               protected virtual void Dispose (bool disposing){
-                       if (fd_gpu > 0)
-                               Libc.close (fd_gpu);
-                       fd_gpu = -1;
-               }
-               #endregion
-
-               #region ioctl overrides
-               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 = "drmModeGetResources", CallingConvention = CallingConvention.Cdecl)]
-               unsafe static extern ModeRes* ModeGetResources(int fd);
-               [DllImport(lib, EntryPoint = "drmModeGetCrtc", CallingConvention = CallingConvention.Cdecl)]
-               public static extern IntPtr ModeGetCrtc(int fd, int crtcId);
-               [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 = "drmModeFreeResources", CallingConvention = CallingConvention.Cdecl)]
-               unsafe static extern void ModeFreeResources(ModeRes* ptr);
-               [DllImport(lib, EntryPoint = "drmModeFreeCrtc", CallingConvention = CallingConvention.Cdecl)]
-               public static extern void ModeFreeCrtc(IntPtr ptr);
-               [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 = "drmModePageFlip", CallingConvention = CallingConvention.Cdecl)]
-               static extern int ModePageFlip(int fd, int crtc_id, int fb_id,
-                       PageFlipFlags flags, ref int user_data);
-
-               [DllImport(lib, EntryPoint = "drmModeSetCrtc", CallingConvention = CallingConvention.Cdecl)]
-               unsafe 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);
-               #endregion
-       }
-}
\ No newline at end of file
diff --git a/testDrm/src/Linux/GBM/BufferObject.cs b/testDrm/src/Linux/GBM/BufferObject.cs
new file mode 100644 (file)
index 0000000..fd6adcb
--- /dev/null
@@ -0,0 +1,123 @@
+//
+// Device.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+
+namespace Linux.GBM 
+{
+       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+       public delegate void DestroyUserDataCallback(ref GBM.gbm_bo bo, IntPtr data);
+
+       [StructLayout(LayoutKind.Sequential)]
+       public struct gbm_bo {
+               IntPtr device;
+               public uint Width, Height;
+               public SurfaceFormat Format;
+               public SurfaceFlags Flags;
+
+               public uint Handle32
+               {
+                       get { return (uint)BufferObject.gbm_bo_get_handle(ref this); }
+               }
+               public uint Stride
+               {
+                       get { return BufferObject.gbm_bo_get_stride(ref this); }
+               }
+               public void SetUserData(IntPtr data, DestroyUserDataCallback destroyFB)
+               {
+                       BufferObject.gbm_bo_set_user_data(ref this, data, destroyFB);
+               }
+       }
+       unsafe public class BufferObject : IDisposable
+       {
+               #region pinvoke
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               static extern gbm_bo* gbm_bo_create (IntPtr gbm, uint width, uint height, SurfaceFormat format, SurfaceFlags flags);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void gbm_bo_destroy (gbm_bo* bo);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern int gbm_bo_write(gbm_bo* bo, IntPtr buf, IntPtr count);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern Device gbm_bo_get_device(ref gbm_bo bo);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern ulong gbm_bo_get_handle(ref gbm_bo bo);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern int gbm_bo_get_height(ref gbm_bo bo);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern int gbm_bo_get_width(ref gbm_bo bo);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern uint gbm_bo_get_stride (ref gbm_bo bo);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void gbm_bo_set_user_data(ref gbm_bo bo, IntPtr data, DestroyUserDataCallback callback);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern IntPtr gbm_bo_get_user_data (IntPtr bo);
+               [DllImport("gbm",  CallingConvention = CallingConvention.Cdecl)]
+               internal static extern IntPtr   gbm_bo_map (ref gbm_bo bo, uint x, uint y, uint width, uint height, TransferFlags flags, ref uint stride, out IntPtr data);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               internal static extern void gbm_bo_unmap (ref gbm_bo bo, IntPtr data);
+               #endregion
+
+               internal gbm_bo* handle;
+
+               #region ctor
+               public BufferObject (gbm_bo* _handle){
+                       handle = _handle;
+               }
+               public BufferObject (Device dev, uint _width, uint _height, SurfaceFormat format, SurfaceFlags flags)
+               {
+                       handle = gbm_bo_create (dev.handle, _width, _height, format, flags);
+                       if (handle == null)
+                               throw new NotSupportedException("[GBM] BO creation failed.");
+               }
+               #endregion
+
+               public uint Stride { get { return handle->Stride; }}
+               public byte[] Data {
+                       set {                           
+                               fixed (byte* pdata = value) {
+                                       gbm_bo_write (handle, (IntPtr)pdata, (IntPtr)value.Length);
+                               }
+                       }
+               }
+                       
+               #region IDisposable implementation
+               ~BufferObject(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (handle != null)
+                               gbm_bo_destroy (handle);
+                       handle = null;
+               }
+               #endregion
+       }
+}
+
diff --git a/testDrm/src/Linux/GBM/Device.cs b/testDrm/src/Linux/GBM/Device.cs
new file mode 100644 (file)
index 0000000..a52b06c
--- /dev/null
@@ -0,0 +1,76 @@
+//
+// Device.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Runtime.InteropServices;
+
+namespace Linux.GBM
+{
+       unsafe public class Device : IDisposable
+       {
+               #region pinvoke
+               [DllImport("gbm", EntryPoint = "gbm_create_device", CallingConvention = CallingConvention.Cdecl)]
+               static extern IntPtr CreateDevice(int fd);
+               [DllImport("gbm", EntryPoint = "gbm_device_destroy", CallingConvention = CallingConvention.Cdecl)]
+               static extern void DestroyDevice(IntPtr gbm);
+               [DllImport("gbm", EntryPoint = "gbm_device_get_fd", CallingConvention = CallingConvention.Cdecl)]
+               static extern int DeviceGetFD(IntPtr gbm);
+               [DllImport("gbm", EntryPoint = "gbm_device_is_format_supported", CallingConvention = CallingConvention.Cdecl)]
+               [return: MarshalAs(UnmanagedType.Bool)]
+               static extern bool IsFormatSupported(IntPtr gbm, SurfaceFormat format, SurfaceFlags usage);
+               #endregion
+
+               int fd_gpu;
+               internal IntPtr handle;
+
+               #region ctor
+               public Device (int _fd_gpu)
+               {
+                       fd_gpu = _fd_gpu;
+                       handle = CreateDevice(fd_gpu);
+
+                       if (handle == IntPtr.Zero)
+                               throw new NotSupportedException("[GBM] device creation failed.");
+               }
+               #endregion
+                       
+               #region IDisposable implementation
+               ~Device(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (handle != IntPtr.Zero)
+                               DestroyDevice (handle);
+                       handle = IntPtr.Zero;
+               }
+               #endregion
+       }
+}
+
diff --git a/testDrm/src/Linux/GBM/Surface.cs b/testDrm/src/Linux/GBM/Surface.cs
new file mode 100644 (file)
index 0000000..9257e14
--- /dev/null
@@ -0,0 +1,183 @@
+//
+// Surface.cs
+//
+// Author:
+//              Stefanos Apostolopoulos <stapostol@gmail.com>
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2006-2014 Stefanos Apostolopoulos
+// 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.Runtime.InteropServices;
+
+namespace Linux.GBM
+{
+       public enum SurfaceFormat : uint
+       {
+               BigEndian = 1u << 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]public enum SurfaceFlags : uint
+       {
+               Scanout = (1 << 0),
+               Cursor64x64 = (1 << 1),
+               Rendering = (1 << 2),
+               Write = (1 << 3),
+               Linear = (1 << 4),
+       }
+       [Flags]public enum TransferFlags : uint {
+               /// <summary> Buffer contents read back (or accessed directly) at transfer create time.</summary>
+               Read  = 1 << 0,
+               /// <summary> Buffer contents will be written back at unmap time (or modified as a result of being accessed directly).</summary>
+               Write = 1 << 1,
+               /// <summary>Read/modify/write</summary>
+               ReadWrite = Read | Write,
+       }
+
+       unsafe public class Surface : IDisposable
+       {
+               #region pinvoke
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               static extern IntPtr gbm_surface_create (IntPtr gbm, int width, int height, SurfaceFormat format, SurfaceFlags flags);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               static extern void gbm_surface_destroy (IntPtr surface);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               static extern gbm_bo* gbm_surface_lock_front_buffer (IntPtr surface);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               static extern void gbm_surface_release_buffer (IntPtr surface, gbm_bo* buffer);
+               [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
+               static extern int gbm_surface_has_free_buffers (IntPtr surface);
+               #endregion
+
+               internal IntPtr handle;
+
+               #region ctor
+               public Surface (Device gbmDev, int width, int height, SurfaceFlags flags, SurfaceFormat format = SurfaceFormat.ARGB8888)
+               {
+                       handle =  gbm_surface_create(gbmDev.handle, width, height, format, flags);
+
+                       if (handle == IntPtr.Zero)
+                               throw new NotSupportedException("[GBM] Failed to create GBM surface");
+               }
+               #endregion
+
+               public bool HasFreeBuffers { get { return gbm_surface_has_free_buffers (handle) > 0; }}
+
+               public gbm_bo* Lock (){
+                       gbm_bo* bo = gbm_surface_lock_front_buffer (handle);
+                       if (bo == null)
+                               throw new Exception ("[GBM]: Failed to lock front buffer.");
+                       return bo;
+               }
+               public void Release (gbm_bo* bo) {
+                       gbm_surface_release_buffer (handle, bo);
+               }
+
+               #region IDisposable implementation
+               ~Surface(){
+                       Dispose (false);
+               }
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               protected virtual void Dispose (bool disposing){
+                       if (handle != IntPtr.Zero)
+                               gbm_surface_destroy (handle);
+                       handle = IntPtr.Zero;
+               }
+               #endregion
+       }
+}
+
index a9402c85ca00a0387acfc6c329665bbc88810c2b..c555fe2a92bb6d0e4a46a09915e913634794e4c0 100644 (file)
@@ -26,7 +26,7 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Crow.Linux.VT {
+namespace Linux.VT {
        public enum KDMode : byte {
                TEXT    = 0x00,
                GRAPHICS= 0x01,
index b033b0bc3a0691038aa3708124c904355937084b..5b4f7f840b37100f9258f1df302c3315f0cc2cc7 100644 (file)
@@ -44,7 +44,6 @@
   </PropertyGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
-    <Compile Include="Main.cs" />
     <Compile Include="src\Linux\Bindings\Drm.cs" />
     <Compile Include="src\Linux\Bindings\Evdev.cs" />
     <Compile Include="src\Linux\Bindings\Gbm.cs" />
@@ -62,8 +61,6 @@
     </Compile>
     <Compile Include="src\MouseCursor.cs" />
     <Compile Include="src\WindowIcon.cs" />
-    <Compile Include="src\Application.cs" />
-    <Compile Include="src\DRMContext.cs" />
     <Compile Include="src\Linux\Bindings\Egl.cs">
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="src\Linux\TTY.cs" />
     <Compile Include="src\Linux\Signal.cs" />
     <Compile Include="src\Linux\VT.cs" />
-    <Compile Include="src\Linux\DRM.cs" />
+    <Compile Include="src\Linux\DRI.cs" />
+    <Compile Include="src\Linux\DRI\Connector.cs" />
+    <Compile Include="src\Linux\DRI\Encoder.cs" />
+    <Compile Include="src\Linux\DRI\Resources.cs" />
+    <Compile Include="src\Linux\DRI\Crtc.cs" />
+    <Compile Include="src\Linux\DRI\Plane.cs" />
+    <Compile Include="src\Egl\EGL.cs" />
+    <Compile Include="src\Egl\Surface.cs" />
+    <Compile Include="src\Egl\Context.cs" />
+    <Compile Include="src\Linux\GBM\Surface.cs" />
+    <Compile Include="src\Linux\GBM\BufferObject.cs" />
+    <Compile Include="src\Linux\GBM\Device.cs" />
+    <Compile Include="src\Application.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="src\" />
     <Folder Include="ui\" />
+    <Folder Include="src\Linux\DRI\" />
+    <Folder Include="src\Egl\" />
+    <Folder Include="src\Linux\GBM\" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\Crow.csproj">
   <ItemGroup>
     <EmbeddedResource Include="ui\menu.crow" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="src\DRMContext.cs" />
+    <None Include="Main.cs" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
index 026ce1995c4326a860203c8862ff05466983120f..1098c10c13d5d79c604f68fb2cef032a17989c49 100644 (file)
@@ -31,21 +31,191 @@ using System.Runtime.InteropServices;
 using System.Text;
 
 //using static Crow.Linux.VT.VTControler;
-using VT = Crow.Linux.VT;
-using Crow.Linux.DRI;
+using VT = Linux.VT;
+using DRI = Linux.DRI;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using Crow;
+
+
 
 namespace testDrm
 {
+       public class TestApp : Application {
+
+               public bool Running = true;
+
+               public TestApp () : base () {
+                       
+               }
+               public override void Run ()
+               {
+                       Load ("#testDrm.ui.menu.crow").DataSource = this;
+                       Load (@"/mnt/data2/devel/crow/Tests/Interfaces/Divers/0.crow");
+
+                       while(Running){
+                               try {
+                                       base.Run ();
+                               } catch (Exception ex) {
+                                       Console.WriteLine (ex.ToString());
+                               }
+                       }
+               }
+               void onQuitClick(object send, Crow.MouseButtonEventArgs e)
+               {
+                       Running = false;
+               }
+       }
        static class Tests
        {
                static void signal_handler (Signal s){
                        Console.WriteLine ("signal catched: " + s.ToString());
                }
+               static void genEglConstCase (){
+                       Dictionary<int,string> dic = new Dictionary<int, string> ();
+
+                       //parseEglConsts ("/home/jp/tmp/EGL/eglplatform.h", ref dic);
+                       parseEglConsts ("/home/jp/tmp/EGL/egl.h", ref dic);
+
+                       IOrderedEnumerable<KeyValuePair<int,string>> result = dic.OrderBy (p => p.Key);
+
+                       foreach (KeyValuePair<int,string> kv in result) {
+                               Console.WriteLine ("case {0}:\n\treturn \"{1}\";", kv.Key, kv.Value);
+                       }
+               }
+               static void parseEglConsts (string path, ref Dictionary<int,string> dic){
+                       using (Stream s = new FileStream (path, FileMode.Open)) {
+                               using (StreamReader sr = new StreamReader (s)) {
+                                       while (!sr.EndOfStream) {
+                                               string l = sr.ReadLine ();
+                                               if (!l.StartsWith ("#define"))
+                                                       continue;
+                                               l = l.Substring (8);
+                                               string[] ll = l.Split (new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
+                                               string[] cn = ll [0].Split ('_');
+                                               try {
+                                                       string constName = "";
+
+                                                       for (int i = 1; i < cn.Length; i++) {
+                                                               cn [i] = cn [i].ToLowerInvariant ();
+                                                               constName += char.ToUpperInvariant (cn [i] [0]) + cn [i].Substring (1);                                                  
+                                                       }
+
+                                                       int value = 0;
+                                                       if (ll [1].StartsWith ("0x")) {
+                                                               if (int.TryParse (ll [1].Substring (2), System.Globalization.NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.CurrentCulture, out value)) {
+                                                                       if (dic.ContainsKey (value))
+                                                                               dic [value] += "|" + ll [0].Substring (4);
+                                                                       else
+                                                                               dic [value] = ll [0].Substring (4);
+                                                                       continue;
+                                                               } else
+                                                                       Console.WriteLine ("parsing error: " + l);
+                                                       } else
+                                                               Console.WriteLine ("not hex value: " + l);
+                                                       //Console.WriteLine ("{0}\t= {1},", constName, ll [1]);
+                                               } catch (Exception ex) {
+                                                       Console.WriteLine ("failed: " + l);
+                                               }
+                                       }
+                               }
+                       }
+               }
                static void Main ()
                {
-                       using (GPUControler gpu = new GPUControler ()) {
+                       try {
+                               using (TestApp crowApp = new TestApp ()) {
+                                       crowApp.Run ();
+                               }
+                       } catch (Exception ex) {
+                               Console.WriteLine (ex.ToString ());
+                       }
+               }
+               static void testApp () {
+                       int previousVT = -1, appVT = -1;
+
+                       if (Kernel.signal (Signal.SIGUSR1, switch_request_handle) < 0)
+                               throw new Exception ("signal handler registation failed");                      
+                       if (Kernel.signal (Signal.SIGINT, sigint_handler) < 0)
+                               throw new Exception ("SIGINT handler registation failed");
+
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               previousVT = master.CurrentVT;
+                               appVT = master.FirstAvailableVT;
+                               master.SwitchTo (appVT);
+                               try {
+                                       master.KDMode = VT.KDMode.GRAPHICS;
+                               } catch (Exception ex) {
+                                       Console.WriteLine (ex.ToString ());     
+                               }
+                       }
+                       try {
+                               using (TestApp crowApp = new TestApp ()) {
+                                       crowApp.Run ();
+                               }
+                       } catch (Exception ex) {
+                               Console.WriteLine (ex.ToString ());
+                       }
+
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               //                              try {
+                               //                                      master.KDMode = VT.KDMode.TEXT;
+                               //                              } catch (Exception ex) {
+                               //                                      Console.WriteLine (ex.ToString ());     
+                               //                              }
+                               master.SwitchTo (previousVT);
                        }
                }
+
+               static void testKMS(){
+                       int previousVT = -1, appVT = -1;
+
+                       if (Kernel.signal (Signal.SIGUSR1, switch_request_handle) < 0)
+                               throw new Exception ("signal handler registation failed");                      
+                       if (Kernel.signal (Signal.SIGINT, sigint_handler) < 0)
+                               throw new Exception ("SIGINT handler registation failed");
+
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               previousVT = master.CurrentVT;
+                               appVT = master.FirstAvailableVT;
+                               master.SwitchTo (appVT);
+                               try {
+                                       master.KDMode = VT.KDMode.GRAPHICS;
+                               } catch (Exception ex) {
+                                       Console.WriteLine (ex.ToString ());     
+                               }
+                       }
+                       try {
+                               using (DRI.GPUControler gpu = new DRI.GPUControler ()) {
+                                       
+//                                     int i = 0;
+//                                     while(running && i < 1000){
+//                                             try {
+//                                                     gpu.Update ();
+//                                                     i++;
+//                                             } catch (Exception ex) {
+//                                                     Console.WriteLine (ex.ToString());
+//                                             }
+//
+//                                     }
+                                               
+
+                               }
+                       } catch (Exception ex) {
+                               Console.WriteLine (ex.ToString ());
+                       }
+
+                       using (VT.VTControler master = new VT.VTControler ()) {
+                               //                              try {
+                               //                                      master.KDMode = VT.KDMode.TEXT;
+                               //                              } catch (Exception ex) {
+                               //                                      Console.WriteLine (ex.ToString ());     
+                               //                              }
+                               master.SwitchTo (previousVT);
+                       }
+               }
+
                static void signalTest (){
                        if (Kernel.signal (Signal.SIGINT, signal_handler) < 0)
                                throw new Exception ("signal handler registation failed");
@@ -148,7 +318,51 @@ namespace testDrm
                        Console.WriteLine ("SIGINT catched");
                        running = false;
                }
+               static void dumpDrmResources(){
+                       string gpu_path = "/dev/dri/card0";
+                       int fd_gpu = Libc.open(gpu_path, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
+                       if (fd_gpu < 0)
+                               throw new NotSupportedException("[DRI] Failed to open gpu");
 
+                       using (DRI.Resources resources = new DRI.Resources (fd_gpu)) {
+                               foreach (DRI.Connector e in resources.Connectors) {                                     
+                                       Console.WriteLine (e.ToString ());
+                               }
+                               foreach (DRI.Encoder e in resources.Encoders)
+                                       Console.WriteLine (e.ToString ());
+                               foreach (DRI.Crtc e in resources.Crtcs)
+                                       Console.WriteLine (e.ToString ());
+                       }
+                       
+                       Libc.close (fd_gpu);    
+               }
+//             static void dumpDrm(){
+//                     using (DRI.GPUControler gpu = new DRI.GPUControler ()) {
+//
+//
+//                             if (gpu.PlanesIds.Length > 0){
+//                                     DRI.drmPlane plane = gpu.GetPlane (gpu.PlanesIds [0]);
+//                             }
+//
+//                             Console.WriteLine ("DRI Resources:");
+//                             Console.WriteLine ("\t- Connectors\t({0})", gpu.ConnectorIds.Length);
+//                             for (int i = 0; i < gpu.ConnectorIds.Length; i++) {
+//                                     DRI.Connector mc = gpu.GetConnector (gpu.ConnectorIds [i]);
+//                                     Console.WriteLine ("\t\t{0}. {1,-11} ({2})",i, mc.Type, mc.State);
+//                                     //DRI.Encoder e = mc.CurrentEncoder;
+//                                     //DRI.Crtc c = gpu.GetCrtc (e.crtc_id);
+//                                     //DRI.FrameBuffer fb = gpu.GetFB (c.buffer_id);
+//
+//                             }
+//                             Console.WriteLine ("\t- Encoderds\t({0})", gpu.EncoderIds.Length);
+//                             Console.WriteLine ("\t- Crtcs\t\t({0})", gpu.CrtcIds.Length);
+//                             Console.WriteLine ("\t- FrameBuffers\t({0})", gpu.FbIds.Length);
+//                             Console.WriteLine ("\t- Planes\t({0})", gpu.PlanesIds.Length);
+//                             //                              foreach (Crow.Linux.DRI.ModeConnector c in gpu.Connectors) {
+//                             //                                      Console.WriteLine ("connector id: {0}\tType: {1}", c.connector_id, c.connector_type);
+//                             //                              }
+//                     }                       
+//             }
        }
 }
 
index 92cd224bba0716faead8bdab99f1c724058752af..67e5d604d8bcdfbfaeba4452e9b151ce6d6fb826 100755 (executable)
@@ -4,7 +4,7 @@
                <MenuItem Caption="New" />
                <MenuItem Caption="Open"/>
                <MenuItem Caption="Save"/>
-               <MenuItem Caption="Quit"/>
+               <MenuItem Caption="Quit" MouseClick="onQuitClick"/>
        </MenuItem>
        <MenuItem Caption="Edit" Name="edit" Width="Fit">
                <MenuItem Caption="Cut"/>