diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4125f898..57cd1348b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,3 +37,13 @@ jobs: if: ${{ matrix.os == 'ubuntu-latest' }} run: dotnet run -- --release --xml-documentation --targets integrationTest samples working-directory: './Build' + + - name: (Failure) Upload Generated Files + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.os }}-generated + path: | + ${{ github.workspace }} + !**/bin + !**/obj \ No newline at end of file diff --git a/Build/Projects.cs b/Build/Projects.cs index b1cd00775..b650d4037 100644 --- a/Build/Projects.cs +++ b/Build/Projects.cs @@ -35,16 +35,18 @@ public static class Projects private const string GTK3_WINDOW = SAMPLE + "Gtk3/Window"; private const string GTK3_DECLARATIVE_UI = SAMPLE + "Gtk3/DeclarativeUi"; private const string GTK3_ABOUT_DIALOG = SAMPLE + "Gtk3/AboutDialog"; - + private const string GTK3_QUICKSTART = SAMPLE + "Gtk3/QuickStart"; + private const string GTK3_DRAWINGAREA = SAMPLE + "Gtk3/DrawingArea"; + private const string GTK3_TEXTEDITOR = SAMPLE + "Gtk3/TextEditor"; + // private const string DBUS_SAMPLE = SAMPLE + "DBus/"; // private const string GSTREAMER_SAMPLE = SAMPLE + "GStreamer/"; // private const string GTK3_APP_SAMPLE = SAMPLE + "Gtk3/GtkApp/"; // private const string GTK3_BUILDER_SAMPLE = SAMPLE + "Gtk3/Builder"; - // private const string GTK3_QUICKSTART = SAMPLE + "Gtk3/QuickStart"; + // private const string GTK3_COMPOSITE_TEMPLATE_SOURCEGENERATOR = SAMPLE + "Gtk3/CompositeTemplates/UsingSourceGenerator"; // private const string GTK3_COMPOSITE_TEMPLATE_NO_SOURCEGENERATOR = SAMPLE + "Gtk3/CompositeTemplates/NoSourceGenerator"; // private const string GTK4_SIMPLE_WINDOW_SAMPLE = SAMPLE + "Gtk4/SimpleWindow/"; - // private const string GDKPIXBUF_TEST_MEMORY_LEAKS = SAMPLE + "GdkPixbuf/TestMemoryLeaks"; private const string INTEGRATION = "../Integration/"; @@ -65,7 +67,10 @@ public static class Projects GDK_PIXBUF_TEST_MEMORY_LEAKS, GTK3_WINDOW, GTK3_DECLARATIVE_UI, - GTK3_ABOUT_DIALOG + GTK3_ABOUT_DIALOG, + GTK3_QUICKSTART, + GTK3_DRAWINGAREA, + GTK3_TEXTEDITOR }; public static IEnumerable AllLibraries = new[] diff --git a/Generator/Convert.cs b/Generator/Convert.cs index c3214e404..5065ff904 100644 --- a/Generator/Convert.cs +++ b/Generator/Convert.cs @@ -73,13 +73,13 @@ internal static string NativeToManaged(TransferableAnyType transferable, string // Record Conversions (safe handles) ArrayTypeReference { Type: Record r, TypeReference: { CTypeReference: { IsPointer: true } } } when useSafeHandle => $"{fromParam}.Select(x => new {r.Write(Target.Managed, currentNamespace)}(x)).ToArray()", ResolveableTypeReference { Type: Record r, CTypeReference: { IsPointer: true } } when useSafeHandle => $"new {r.Write(Target.Managed, currentNamespace)}({fromParam})", - + // Record Conversions (raw pointers) ArrayTypeReference { Type: Record r, TypeReference: { CTypeReference: { IsPointer: true } } } when !useSafeHandle => $"{fromParam}.Select(x => new {r.Write(Target.Managed, currentNamespace)}(new {SafeHandleFromRecord(r)}(x))).ToArray()", ResolveableTypeReference { Type: Record r, CTypeReference: { IsPointer: true } } when !useSafeHandle => $"new {r.Write(Target.Managed, currentNamespace)}(new {SafeHandleFromRecord(r)}({fromParam}))", //Record Conversions without pointers are not working yet - ArrayTypeReference { Type: Record r, TypeReference: { CTypeReference: { IsPointer: false } } } => $"({r.Write(Target.Managed, currentNamespace)}[]) default!; //TODO: Fixme", + ArrayTypeReference { Type: Record r, TypeReference: { CTypeReference: { IsPointer: false } } } => $"({qualifiedType}[]) {fromParam}.Select(x => new {qualifiedType}({SafeHandleFromRecord(r, true)}(x))).ToArray();", ResolveableTypeReference { Type: Record r, CTypeReference: { IsPointer: false } } => $"({r.Write(Target.Managed, currentNamespace)}) default!; //TODO: Fixme", // Class Conversions @@ -97,9 +97,9 @@ internal static string NativeToManaged(TransferableAnyType transferable, string }; } - private static string SafeHandleFromRecord(Record r) + private static string SafeHandleFromRecord(Record r, bool managedHandle = false) { - var type = r.GetMetadataString("SafeHandleRefName"); + var type = r.GetMetadataString(managedHandle ? "SafeHandleRefManagedFunc" : "SafeHandleRefName"); var nspace = $"{r.Repository.Namespace}.Native"; return nspace + "." + type; } diff --git a/Generator/Extensions/AnyTypeExtension.cs b/Generator/Extensions/AnyTypeExtension.cs index de288bd2c..4a786ec2f 100644 --- a/Generator/Extensions/AnyTypeExtension.cs +++ b/Generator/Extensions/AnyTypeExtension.cs @@ -34,16 +34,24 @@ private static string WriteNativeType(AnyType anyType, Namespace currentNamespac // Arrays of byte can be marshalled automatically, no IntPtr needed { TypeReference: ArrayTypeReference { Type: { } s } } when s.Name == "byte" => "byte[]", - //References to records which are not using a pointer + // References to records which are not using a pointer { TypeReference: ArrayTypeReference { Type: Record r, TypeReference: { CTypeReference: { IsPointer: false } } } } => GetStructName(r, currentNamespace) + "[]", { TypeReference: ArrayTypeReference { Type: Record r, TypeReference: { CTypeReference: null } } } => GetStructName(r, currentNamespace) + "[]", { TypeReference: { Type: Record r, CTypeReference: { IsPointer: false } } } => GetStructName(r, currentNamespace), - - - //References to records which are using a pointer + + // References to records which are using a pointer { TypeReference: ArrayTypeReference { Type: Record, TypeReference: { CTypeReference: { IsPointer: true } } } } => "IntPtr[]", //Array of SafeHandle not supported by runtime { TypeReference: ResolveableTypeReference { Type: Record r, CTypeReference: { IsPointer: true } } } => GetSafeHandleName(r, currentNamespace, useSafeHandle), - + + // References to unions which are not using a pointer + { TypeReference: ArrayTypeReference { Type: Union u, TypeReference: { CTypeReference: { IsPointer: false } } } } => GetStructName(u, currentNamespace) + "[]", + { TypeReference: ArrayTypeReference { Type: Union u, TypeReference: { CTypeReference: null } } } => GetStructName(u, currentNamespace) + "[]", + { TypeReference: { Type: Union u, CTypeReference: { IsPointer: false } } } => GetStructName(u, currentNamespace), + + // References to unions which are using a pointer + { TypeReference: ArrayTypeReference { Type: Union, TypeReference: { CTypeReference: { IsPointer: true } } } } => "IntPtr[]", //Array of SafeHandle not supported by runtime + { TypeReference: ResolveableTypeReference { Type: Union, CTypeReference: { IsPointer: true } } } => "IntPtr", + // Primitives - Marshal directly { TypeReference: ArrayTypeReference { Type: PrimitiveValueType s } } => s.Write(Target.Native, currentNamespace) + "[]", { TypeReference: { Type: PrimitiveValueType s } } => s.Write(Target.Native, currentNamespace), @@ -51,7 +59,7 @@ private static string WriteNativeType(AnyType anyType, Namespace currentNamespac // Enumerations - Marshal directly { TypeReference: ArrayTypeReference { Type: Enumeration } } => anyType.TypeReference.Type.Write(Target.Native, currentNamespace) + "[]", { TypeReference: { Type: Enumeration } } => anyType.TypeReference.Type.Write(Target.Native, currentNamespace), - + // Short path for strings as strings are pointers which should not be handled as pointers { TypeReference: { Type: String r } } => r.Name, @@ -68,7 +76,12 @@ private static string GetStructName(Record r, Namespace currentNamespace) { return AddNamespace(currentNamespace, r.Repository.Namespace, r.GetMetadataString("StructRefName"), Target.Native); } - + + private static string GetStructName(Union u, Namespace currentNamespace) + { + return AddNamespace(currentNamespace, u.Repository.Namespace, u.GetMetadataString("StructRefName"), Target.Native); + } + private static string GetSafeHandleName(Record r, Namespace currentNamespace, bool useSafeHandle) { if (useSafeHandle) diff --git a/Generator/Extensions/FieldsExtension.cs b/Generator/Extensions/FieldsExtension.cs index f566af727..18a63c7db 100644 --- a/Generator/Extensions/FieldsExtension.cs +++ b/Generator/Extensions/FieldsExtension.cs @@ -36,7 +36,7 @@ public static string WriteUnionStructFields(this IEnumerable fields, Name foreach (Field field in fields) { - builder.AppendLine("//[FieldOffset(0)] TODO Enable offset"); + builder.AppendLine("[FieldOffset(0)]"); builder.AppendLine(field.WriteNative(currentNamespace)); } diff --git a/Generator/Extensions/ParameterListExtension.cs b/Generator/Extensions/ParameterListExtension.cs index 0c917b949..4f843a9da 100644 --- a/Generator/Extensions/ParameterListExtension.cs +++ b/Generator/Extensions/ParameterListExtension.cs @@ -87,12 +87,19 @@ public static string WriteSignalArgsProperties(this ParameterList parameterList, var index = 0; foreach (var argument in parameterList.GetParameters()) { - index += 1; - var type = argument.WriteType(Target.Native, currentNamespace); - var name = new GirLoader.Helper.String(argument.Name).ToPascalCase(); - - builder.AppendLine($"//TODO: public {type} {name} => Args[{index}].Extract<{type}>();"); - builder.AppendLine($"public string {name} => \"\";"); + try + { + index += 1; + var type = argument.WriteType(Target.Managed, currentNamespace); + var name = new GirLoader.Helper.String(argument.Name).ToPascalCase(); + + builder.AppendLine($"public {type} {name} => Args[{index}].Extract<{type}>();"); + } + catch (Exception e) + { + Log.Error($"Could not write signal properties for {argument.Name}: {e.Message}"); + throw; + } } return builder.ToString(); diff --git a/Generator/Extensions/TypeExtension.cs b/Generator/Extensions/TypeExtension.cs index e7208e709..1a9f5d416 100644 --- a/Generator/Extensions/TypeExtension.cs +++ b/Generator/Extensions/TypeExtension.cs @@ -20,13 +20,18 @@ internal static string Write(this Type type, Target target, Namespace currentNam ComplexType c when !c.Repository.Namespace.IsForeignTo(currentNamespace) => c.Name, ComplexType c => $"{c.Repository.Namespace.GetName(target)}.{c.Name}", - _ => throw new Exception($"Unknown type {type}.") + _ => throw new Exception($"Unknown type: {type}") }; } - public static string WriteTypeRegistration(this Type type) + public static string WriteTypeRegistrationClass(this Type type) { return $"TypeDictionary.Add(typeof({type.Name}), new GObject.Type(Native.{type.Name}.Instance.Methods.GetGType()));\r\n"; } + + public static string WriteTypeRegistrationBoxed(this Type type) + { + return $"TypeDictionary.Add(typeof({type.Name}), new GObject.Type(Native.{type.Name}.Methods.GetGType()));\r\n"; + } } } diff --git a/Generator/Services/TypeRenamer.cs b/Generator/Services/TypeRenamer.cs index 10a8a2d26..91a1faa75 100644 --- a/Generator/Services/TypeRenamer.cs +++ b/Generator/Services/TypeRenamer.cs @@ -96,8 +96,9 @@ private void SetUnionMetadata(Union union) { union.Metadata["Name"] = union.Name; union.Metadata["StructName"] = "Struct"; + union.Metadata["StructRefName"] = $"{union.Name}.Struct"; - union.Name = new TypeName($"{union.Name}.Struct"); + union.Name = new TypeName($"{union.Name}"); } private void SetRecordMetadata(IEnumerable records) @@ -121,6 +122,7 @@ private void SetClassStructMetadata(Record record) record.Metadata["StructRefName"] = $"{className}.Class"; record.Metadata["SafeHandleName"] = "Handle"; record.Metadata["SafeHandleRefName"] = $"{className}.Handle"; + record.Metadata["SafeHandleRefManagedFunc"] = $"{className}.ManagedHandle.Create"; record.Name = new TypeName($"{className}.Class"); } @@ -132,6 +134,7 @@ private void SetRecordMetadata(Record record) record.Metadata["StructRefName"] = $"{record.Name}.Struct"; record.Metadata["SafeHandleName"] = "Handle"; record.Metadata["SafeHandleRefName"] = $"{record.Name}.Handle"; + record.Metadata["SafeHandleRefManagedFunc"] = $"{record.Name}.ManagedHandle.Create"; record.Name = new TypeName($"{record.Name}"); } diff --git a/Generator/Services/Writer/WriteModuleService.cs b/Generator/Services/Writer/WriteModuleService.cs index 1e9e67a85..2fe3518f5 100644 --- a/Generator/Services/Writer/WriteModuleService.cs +++ b/Generator/Services/Writer/WriteModuleService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Generator.Factories; @@ -37,17 +38,25 @@ public void Write(Namespace ns, string outputDir) private void WriteTypeDictionaryInitialization(Namespace ns, string outputDir) { - var classes = ns.Classes.Where(x => !x.IsFundamental); + IEnumerable classes = ns.Classes.Where(x => !x.IsFundamental); + IEnumerable records = ns.Records.Where(x => x.GetTypeFunction is not null); + IEnumerable unions = ns.Unions.Where(x => x.GetTypeFunction is not null); + + IEnumerable types = classes.Concat(records); - if (!classes.Any()) + if (!types.Any()) return; var scriptObject = new ScriptObject() { { "namespace", ns }, - { "classes", classes}, + { "classes", classes }, + { "records", records }, + { "unions", unions } }; - scriptObject.Import("write_type_registration", new Func(s => s.WriteTypeRegistration())); + scriptObject.Import("write_type_registration", new Func(s => s.WriteTypeRegistrationClass())); + scriptObject.Import("write_type_registration_record", new Func(s => s.WriteTypeRegistrationBoxed())); + scriptObject.Import("write_type_registration_union", new Func(s => s.WriteTypeRegistrationBoxed())); _writeHelperService.Write( projectName: ns.ToCanonicalName(), diff --git a/Generator/Templates/module_type_registration.sbntxt b/Generator/Templates/module_type_registration.sbntxt index 76be3fa8c..e78d00d61 100644 --- a/Generator/Templates/module_type_registration.sbntxt +++ b/Generator/Templates/module_type_registration.sbntxt @@ -1,4 +1,6 @@ +{{ if namespace.name != "GLib" # TODO: Temporary until we merge GLib + GObject }} using GObject.Native; +{{ end }} using System; namespace {{ namespace.name }} @@ -7,6 +9,7 @@ namespace {{ namespace.name }} { static partial void RegisterTypes() { + {{ if namespace.name != "GLib" # TODO: Temporary until we merge GLib + GObject }} {{ for $class in classes}} try { @@ -14,9 +17,32 @@ namespace {{ namespace.name }} } catch (Exception e) { - Console.WriteLine($"Could not register type '{{ $class.name }}': {e.Message}"); + Console.WriteLine($"Could not register class type '{{ $class.name }}': {e.Message}"); } {{ end }} + + {{ for $record in records }} + try + { + {{ $record | write_type_registration_record }} + } + catch (Exception e) + { + Console.WriteLine($"Could not register record type '{{ $record.name }}': {e.Message}"); + } + {{ end }} + + {{ for $union in unions }} + try + { + {{ $union | write_type_registration_union }} + } + catch (Exception e) + { + Console.WriteLine($"Could not register union type '{{ $union.name }}': {e.Message}"); + } + {{ end }} + {{ end }} } } } \ No newline at end of file diff --git a/Generator/Templates/record.sbntxt b/Generator/Templates/record.sbntxt index 4e1dd3965..f6bdc8527 100644 --- a/Generator/Templates/record.sbntxt +++ b/Generator/Templates/record.sbntxt @@ -21,6 +21,8 @@ namespace {{ namespace.name }} // Override this to perform additional steps in the constructor partial void Initialize(); + public {{ $record_name }}(IntPtr ptr) : this(new {{$safe_handle}}(ptr)){ } + public {{ $record_name }}({{ $safe_handle }} handle) { _handle = handle; diff --git a/Generator/Templates/union.native.struct.sbntxt b/Generator/Templates/union.native.struct.sbntxt index d2ae92cce..dbaf81c88 100644 --- a/Generator/Templates/union.native.struct.sbntxt +++ b/Generator/Templates/union.native.struct.sbntxt @@ -1,5 +1,4 @@ -//TODO: Enable explicit union generation if it does not break documentation generation anymore -//[StructLayout(LayoutKind.Explicit)] +[StructLayout(LayoutKind.Explicit)] public partial struct {{ get_metadata "StructName" }} { {{ include 'union.native.struct.fields.sbntxt' }} diff --git a/Generator/Templates/union.sbntxt b/Generator/Templates/union.sbntxt index 8e4765dc2..224b0d81e 100644 --- a/Generator/Templates/union.sbntxt +++ b/Generator/Templates/union.sbntxt @@ -6,7 +6,8 @@ using System.Runtime.InteropServices; namespace {{ namespace.name }} { // AUTOGENERATED FILE - DO NOT MODIFY - public partial record {{get_metadata "Name"}} + public partial class {{ get_metadata "Name" }} { + // TODO: Handle Unions } } \ No newline at end of file diff --git a/GirCore.sln b/GirCore.sln index cce42ed22..0aab041ac 100644 --- a/GirCore.sln +++ b/GirCore.sln @@ -51,12 +51,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{46D66262-F EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GObject-2.0.Tests", "Tests\Libs\GObject-2.0.Tests\GObject-2.0.Tests.csproj", "{53101A81-CB4A-4589-AEB1-0E229D17AE7A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CompositeTemplates", "CompositeTemplates", "{A8E40ED1-550F-4168-8299-64EFB875CD44}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSourceGenerator", "Samples\Gtk3\CompositeTemplates\NoSourceGenerator\NoSourceGenerator.csproj", "{BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UsingSourceGenerator", "Samples\Gtk3\CompositeTemplates\UsingSourceGenerator\UsingSourceGenerator.csproj", "{0231E616-62C8-4316-9355-326537C07651}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generator", "Generator\Generator.csproj", "{28F5A326-D1F9-42E7-985F-C69E01DB4C4E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GirLoader", "GirLoader\GirLoader.csproj", "{8385F95E-E778-44EF-96F2-8F357B1B6348}" @@ -73,10 +67,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestMemoryLeaks", "Samples\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Atk-1.0", "Libs\Atk-1.0\Atk-1.0.csproj", "{C2432595-F82E-4DF1-96FA-BD6B4D470010}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Builder", "Samples\Gtk3\Builder\Builder.csproj", "{537015CF-AE85-4DC2-AE5C-653B213C5BEA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GtkApp", "Samples\Gtk3\GtkApp\GtkApp.csproj", "{749EE7C7-D85E-496D-B127-948E0157AF3E}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Window", "Samples\Gtk3\Window\Window.csproj", "{F450E603-4DCA-473A-A9D6-EAD96421F338}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLoading", "Samples\GdkPixbuf\TestLoading\TestLoading.csproj", "{2BB1527F-D7A1-44BA-A297-4E69A3A4411C}" @@ -87,7 +77,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeclarativeUi", "Samples\Gt EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AboutDialog", "Samples\Gtk3\AboutDialog\AboutDialog.csproj", "{35D35175-A160-4557-BE3E-9BCB296C61A1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GirLoader.Tests", "Tests\GirLoader.Tests\GirLoader.Tests.csproj", "{F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GirLoader.Tests", "Tests\GirLoader.Tests\GirLoader.Tests.csproj", "{189A1440-3BFE-432E-8F43-931D1B571DCA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawingArea", "Samples\Gtk3\DrawingArea\DrawingArea.csproj", "{F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextEditor", "Samples\Gtk3\TextEditor\TextEditor.csproj", "{2510B0C1-793D-4EA7-A296-F54F881C94C8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GdkPixbuf-2.0.Tests", "Tests\Libs\GdkPixbuf-2.0.Tests\GdkPixbuf-2.0.Tests.csproj", "{61016ABA-608B-47FA-9FBD-CA17D24BAB89}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -330,30 +326,6 @@ Global {53101A81-CB4A-4589-AEB1-0E229D17AE7A}.Release|x64.Build.0 = Release|Any CPU {53101A81-CB4A-4589-AEB1-0E229D17AE7A}.Release|x86.ActiveCfg = Release|Any CPU {53101A81-CB4A-4589-AEB1-0E229D17AE7A}.Release|x86.Build.0 = Release|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Debug|x64.ActiveCfg = Debug|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Debug|x64.Build.0 = Debug|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Debug|x86.ActiveCfg = Debug|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Debug|x86.Build.0 = Debug|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Release|Any CPU.Build.0 = Release|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Release|x64.ActiveCfg = Release|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Release|x64.Build.0 = Release|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Release|x86.ActiveCfg = Release|Any CPU - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6}.Release|x86.Build.0 = Release|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Debug|x64.ActiveCfg = Debug|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Debug|x64.Build.0 = Debug|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Debug|x86.ActiveCfg = Debug|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Debug|x86.Build.0 = Debug|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Release|Any CPU.Build.0 = Release|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Release|x64.ActiveCfg = Release|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Release|x64.Build.0 = Release|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Release|x86.ActiveCfg = Release|Any CPU - {0231E616-62C8-4316-9355-326537C07651}.Release|x86.Build.0 = Release|Any CPU {28F5A326-D1F9-42E7-985F-C69E01DB4C4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {28F5A326-D1F9-42E7-985F-C69E01DB4C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU {28F5A326-D1F9-42E7-985F-C69E01DB4C4E}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -438,30 +410,6 @@ Global {C2432595-F82E-4DF1-96FA-BD6B4D470010}.Release|x64.Build.0 = Release|Any CPU {C2432595-F82E-4DF1-96FA-BD6B4D470010}.Release|x86.ActiveCfg = Release|Any CPU {C2432595-F82E-4DF1-96FA-BD6B4D470010}.Release|x86.Build.0 = Release|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Debug|x64.ActiveCfg = Debug|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Debug|x64.Build.0 = Debug|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Debug|x86.ActiveCfg = Debug|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Debug|x86.Build.0 = Debug|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Release|Any CPU.Build.0 = Release|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Release|x64.ActiveCfg = Release|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Release|x64.Build.0 = Release|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Release|x86.ActiveCfg = Release|Any CPU - {537015CF-AE85-4DC2-AE5C-653B213C5BEA}.Release|x86.Build.0 = Release|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Debug|x64.ActiveCfg = Debug|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Debug|x64.Build.0 = Debug|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Debug|x86.ActiveCfg = Debug|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Debug|x86.Build.0 = Debug|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Release|Any CPU.Build.0 = Release|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Release|x64.ActiveCfg = Release|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Release|x64.Build.0 = Release|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Release|x86.ActiveCfg = Release|Any CPU - {749EE7C7-D85E-496D-B127-948E0157AF3E}.Release|x86.Build.0 = Release|Any CPU {F450E603-4DCA-473A-A9D6-EAD96421F338}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F450E603-4DCA-473A-A9D6-EAD96421F338}.Debug|Any CPU.Build.0 = Debug|Any CPU {F450E603-4DCA-473A-A9D6-EAD96421F338}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -522,18 +470,54 @@ Global {35D35175-A160-4557-BE3E-9BCB296C61A1}.Release|x64.Build.0 = Release|Any CPU {35D35175-A160-4557-BE3E-9BCB296C61A1}.Release|x86.ActiveCfg = Release|Any CPU {35D35175-A160-4557-BE3E-9BCB296C61A1}.Release|x86.Build.0 = Release|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Debug|x64.ActiveCfg = Debug|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Debug|x64.Build.0 = Debug|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Debug|x86.ActiveCfg = Debug|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Debug|x86.Build.0 = Debug|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Release|Any CPU.Build.0 = Release|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Release|x64.ActiveCfg = Release|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Release|x64.Build.0 = Release|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Release|x86.ActiveCfg = Release|Any CPU - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770}.Release|x86.Build.0 = Release|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Debug|x64.ActiveCfg = Debug|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Debug|x64.Build.0 = Debug|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Debug|x86.ActiveCfg = Debug|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Debug|x86.Build.0 = Debug|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Release|Any CPU.Build.0 = Release|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Release|x64.ActiveCfg = Release|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Release|x64.Build.0 = Release|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Release|x86.ActiveCfg = Release|Any CPU + {189A1440-3BFE-432E-8F43-931D1B571DCA}.Release|x86.Build.0 = Release|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Debug|x64.ActiveCfg = Debug|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Debug|x64.Build.0 = Debug|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Debug|x86.ActiveCfg = Debug|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Debug|x86.Build.0 = Debug|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Release|Any CPU.Build.0 = Release|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Release|x64.ActiveCfg = Release|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Release|x64.Build.0 = Release|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Release|x86.ActiveCfg = Release|Any CPU + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F}.Release|x86.Build.0 = Release|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Debug|x64.ActiveCfg = Debug|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Debug|x64.Build.0 = Debug|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Debug|x86.ActiveCfg = Debug|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Debug|x86.Build.0 = Debug|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Release|Any CPU.Build.0 = Release|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Release|x64.ActiveCfg = Release|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Release|x64.Build.0 = Release|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Release|x86.ActiveCfg = Release|Any CPU + {2510B0C1-793D-4EA7-A296-F54F881C94C8}.Release|x86.Build.0 = Release|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Debug|x64.ActiveCfg = Debug|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Debug|x64.Build.0 = Debug|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Debug|x86.ActiveCfg = Debug|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Debug|x86.Build.0 = Debug|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Release|Any CPU.Build.0 = Release|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Release|x64.ActiveCfg = Release|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Release|x64.Build.0 = Release|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Release|x86.ActiveCfg = Release|Any CPU + {61016ABA-608B-47FA-9FBD-CA17D24BAB89}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {BF7F9B0B-CB43-4161-BFAD-C6EE479FC86B} = {386AE10F-B7AC-4C97-AC5C-202D3662A868} @@ -555,22 +539,20 @@ Global {EAC7D6FF-4BEF-4A24-89A0-600FD686C537} = {8BC11A63-D52B-40CB-9DDD-CD7C6DC21059} {46D66262-FC61-43B9-8E76-A361FA3D6C81} = {8BC11A63-D52B-40CB-9DDD-CD7C6DC21059} {53101A81-CB4A-4589-AEB1-0E229D17AE7A} = {46D66262-FC61-43B9-8E76-A361FA3D6C81} - {A8E40ED1-550F-4168-8299-64EFB875CD44} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} - {BC44EB45-DFA6-44B8-9B19-0C0AB2B856E6} = {A8E40ED1-550F-4168-8299-64EFB875CD44} - {0231E616-62C8-4316-9355-326537C07651} = {A8E40ED1-550F-4168-8299-64EFB875CD44} {B4C179CA-89E5-4638-BAEC-8E37B5BBED12} = {386AE10F-B7AC-4C97-AC5C-202D3662A868} {8E6A242B-B0E6-4DA2-ABA3-6389D65AED5E} = {46D66262-FC61-43B9-8E76-A361FA3D6C81} {76DD0496-67BC-4B86-BBE1-5648CAF0C719} = {46D66262-FC61-43B9-8E76-A361FA3D6C81} {7A71B07F-B28B-4DDA-B1EA-565194056951} = {1F2E4087-585C-4B48-8E3D-700D949A15DB} {46E769E2-FEC7-43EA-99B8-E7A7294D68B2} = {7A71B07F-B28B-4DDA-B1EA-565194056951} {C2432595-F82E-4DF1-96FA-BD6B4D470010} = {386AE10F-B7AC-4C97-AC5C-202D3662A868} - {537015CF-AE85-4DC2-AE5C-653B213C5BEA} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} - {749EE7C7-D85E-496D-B127-948E0157AF3E} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} {F450E603-4DCA-473A-A9D6-EAD96421F338} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} {2BB1527F-D7A1-44BA-A297-4E69A3A4411C} = {7A71B07F-B28B-4DDA-B1EA-565194056951} {F86D983A-9881-4BE7-AF92-FA0CE41FB319} = {46D66262-FC61-43B9-8E76-A361FA3D6C81} {59E6AF5C-5F8A-4735-9F95-6457CC17C075} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} {35D35175-A160-4557-BE3E-9BCB296C61A1} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} - {F0DEDEEB-7370-47AB-A5CD-56ECF50EF770} = {8BC11A63-D52B-40CB-9DDD-CD7C6DC21059} + {189A1440-3BFE-432E-8F43-931D1B571DCA} = {8BC11A63-D52B-40CB-9DDD-CD7C6DC21059} + {F1A41389-B4AD-4D0F-8C44-918BF3A6A57F} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} + {2510B0C1-793D-4EA7-A296-F54F881C94C8} = {79FE88D9-9545-4AE8-80AF-8E2E2E55E8A3} + {61016ABA-608B-47FA-9FBD-CA17D24BAB89} = {46D66262-FC61-43B9-8E76-A361FA3D6C81} EndGlobalSection EndGlobal diff --git a/Libs/Champlain/Core/Champlain.Core.csproj b/Libs/Champlain/Core/Champlain.Core.csproj deleted file mode 100644 index e3e28f2cc..000000000 --- a/Libs/Champlain/Core/Champlain.Core.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Gir.Core.CS.Champlain - - diff --git a/Libs/Champlain/Wrapper/Champlain.Wrapper.csproj b/Libs/Champlain/Wrapper/Champlain.Wrapper.csproj deleted file mode 100644 index 2fdcea9cd..000000000 --- a/Libs/Champlain/Wrapper/Champlain.Wrapper.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Gir.Wrapper.CS.Champlain - - diff --git a/Libs/Clutter/Clutter.csproj b/Libs/Clutter/Clutter.csproj deleted file mode 100644 index 8eb3a1bf6..000000000 --- a/Libs/Clutter/Clutter.csproj +++ /dev/null @@ -1,5 +0,0 @@ - - - Gir.Clutter - - diff --git a/Libs/GObject-2.0/Classes/ConstructAttribute.cs b/Libs/GObject-2.0/Classes/ConstructAttribute.cs new file mode 100644 index 000000000..d6dd65c56 --- /dev/null +++ b/Libs/GObject-2.0/Classes/ConstructAttribute.cs @@ -0,0 +1,16 @@ +using System; + +namespace GObject +{ + /// + /// This attribute can be used to give the runtime + /// an alternative constructor method. This is + /// usefull if a constructor should return a + /// more derived type than the constructor itself. + /// + [AttributeUsage(AttributeTargets.Method)] + public class ConstructAttribute : Attribute + { + + } +} diff --git a/Libs/GObject-2.0/Classes/Object.ClosureHelper.cs b/Libs/GObject-2.0/Classes/Object.ClosureHelper.cs index 1d87852c8..dba93dad1 100644 --- a/Libs/GObject-2.0/Classes/Object.ClosureHelper.cs +++ b/Libs/GObject-2.0/Classes/Object.ClosureHelper.cs @@ -5,10 +5,11 @@ namespace GObject { public partial class Object { - protected internal delegate void ActionRefValues(ref Native.Value.Struct[] items); + protected internal delegate void ActionRefValues(ref Value[] items); private class ClosureHelper : IDisposable { + private readonly ClosureMarshal? _marshalCallback; private readonly ActionRefValues _callback; private readonly Closure _closure; @@ -16,30 +17,19 @@ private class ClosureHelper : IDisposable public ClosureHelper(ActionRefValues action) { - //TODO Use MarshalCallback - _closure = new Closure(Workaround); + _marshalCallback = MarshalCallback; + _closure = new Closure(_marshalCallback); _callback = action; } - - //TODO: Delete this method - private void Workaround() - { - var data = Array.Empty(); - _callback(ref data); - } - - public void MarshalCallback(Closure closure, Value? returnValue, uint nParamValues, Value[] paramValues, IntPtr? invocationHint, IntPtr? marshalData) + private void MarshalCallback(Closure closure, Value? returnValue, uint nParamValues, Value[] paramValues, IntPtr? invocationHint, IntPtr? marshalData) { Debug.Assert( condition: paramValues.Length == nParamValues, message: "Values were not marshalled correctly. Breakage may occur" ); - //TODO forward values - - var data = Array.Empty(); - _callback(ref data); + _callback(ref paramValues); } public void Dispose() diff --git a/Libs/GObject-2.0/Classes/Object.ClosureRegistry.cs b/Libs/GObject-2.0/Classes/Object.ClosureRegistry.cs index 860f06f86..1578479b3 100644 --- a/Libs/GObject-2.0/Classes/Object.ClosureRegistry.cs +++ b/Libs/GObject-2.0/Classes/Object.ClosureRegistry.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; namespace GObject { @@ -19,6 +20,8 @@ internal sealed class ClosureRegistry : IDisposable public ClosureRegistry(Object obj, string name) { + Debug.WriteLine($"Created ClosureRegistry: Object {obj.GetType()} Name {name}."); + _name = name; _object = obj; } @@ -62,6 +65,8 @@ public void Disconnect(object callback) public void Dispose() { + Debug.WriteLine($"Disposing ClosureRegistry: Object {_object.GetType()} Name {_name}."); + foreach (var (_, closureHelper) in _connectedHandlers.Values) closureHelper.Dispose(); } diff --git a/Libs/GObject-2.0/Classes/Object.cs b/Libs/GObject-2.0/Classes/Object.cs index 73bb06753..97808f022 100644 --- a/Libs/GObject-2.0/Classes/Object.cs +++ b/Libs/GObject-2.0/Classes/Object.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; @@ -77,6 +78,7 @@ private Native.Value.Struct[] GetValues(ConstructArgument[] constructParameters) [MemberNotNull(nameof(_signalRegistry))] protected virtual void Initialize() { + Debug.WriteLine($"Initialising Object: Address {_handle.Handle}, Type {GetType()}."); _signalRegistry = new SignalRegistry(this); } @@ -97,6 +99,7 @@ protected internal void OnPropertyChanged([CallerMemberName] string? propertyNam public virtual void Dispose() { + Debug.WriteLine($"Disposing Object: Address {_handle.Handle}, Type {GetType()}."); _signalRegistry.Dispose(); _handle.Dispose(); } diff --git a/Libs/GObject-2.0/Classes/Property.cs b/Libs/GObject-2.0/Classes/Property.cs index ccd650441..bc9743128 100644 --- a/Libs/GObject-2.0/Classes/Property.cs +++ b/Libs/GObject-2.0/Classes/Property.cs @@ -141,7 +141,7 @@ internal void RegisterNotifyEvent(Object o) closureRegistry.Connect>( action: o.OnPropertyChanged, after: false, - mapping: arg => ((ref Native.Value.Struct[] _) => arg(PropertyName)) + mapping: arg => ((ref Value[] _) => arg(PropertyName)) ); } diff --git a/Libs/GObject-2.0/Classes/Signal.cs b/Libs/GObject-2.0/Classes/Signal.cs index acfba2736..46433bd70 100644 --- a/Libs/GObject-2.0/Classes/Signal.cs +++ b/Libs/GObject-2.0/Classes/Signal.cs @@ -127,12 +127,12 @@ public void Connect(TSender o, SignalHandler action, bool closureRegistry.Connect( action: action, after: after, - mapping: callback => ((ref Native.Value.Struct[] items) => + mapping: callback => (ref Value[] items) => { var args = new TSignalArgs(); - //TODO: args.SetArgs(items); + args.SetArgs(items); callback(o, args); - }) + } ); } @@ -183,7 +183,7 @@ public void Connect(TSender o, SignalHandler action, bool after = false closureRegistry.Connect( action: action, after: after, - mapping: callback => (ref Native.Value.Struct[] _) => callback(o, EventArgs.Empty) + mapping: callback => (ref Value[] _) => callback(o, EventArgs.Empty) ); } diff --git a/Libs/GObject-2.0/Delegates/ClosureMarshalCallbackWorkaround.cs b/Libs/GObject-2.0/Delegates/ClosureMarshalCallbackWorkaround.cs deleted file mode 100644 index 67d03f6b7..000000000 --- a/Libs/GObject-2.0/Delegates/ClosureMarshalCallbackWorkaround.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace GObject -{ - /// - /// Call Handler for ClosureMarshal with a simplified interface as long as delegates are not working out. - /// TOOD: Remove this class - /// - public class ClosureMarshalCallHandlerWorkaround : IDisposable - { - public Native.ClosureMarshalCallback NativeCallback; - - private readonly System.Action _managedCallback; - - public ClosureMarshalCallHandlerWorkaround(System.Action managed) - { - NativeCallback = NativeCallbackMarshaller; - _managedCallback = managed; - } - - private void NativeCallbackMarshaller(IntPtr closure, IntPtr returnValue, uint nParamValues, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Native.Value.Struct[] paramValues, IntPtr invocationHint, IntPtr marshalData) - { - _managedCallback(); - } - - public void Dispose() - { - // This implements IDisposable just to signal to the caller that this class contains - // disposable state. Actually there is no state which needs to be freed. But if an instance - // of this object is freed to early the NativeCallback can not be invoked from C anymore - // which breaks any native code relying on the availability of the NativeCallback. - } - } -} diff --git a/Libs/GObject-2.0/Native/Classes/BoxedWrapper.cs b/Libs/GObject-2.0/Native/Classes/BoxedWrapper.cs new file mode 100644 index 000000000..cc1ade124 --- /dev/null +++ b/Libs/GObject-2.0/Native/Classes/BoxedWrapper.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace GObject.Native +{ + public class BoxedWrapper + { + public static object WrapHandle(IntPtr handle, Type gtype) + { + System.Type trueType = TypeDictionary.GetSystemType(gtype); + + if (handle == IntPtr.Zero) + throw new NullReferenceException($"Failed to wrap handle as type <{trueType}>. Null handle passed to WrapHandle."); + + // Get constructor for the true type + var ctr = GetBoxedConstructor(trueType); + + object? result; + + if (ctr == null) + { + //If we do not find an constructor we try to find our secret factory method. + //TODO: This is a workaround for Gdk.Event Should get obsolete with GTK4 + var methodInfo = GetSecretFactoryMethod(trueType); + + if(methodInfo is null) + throw new Exception($"Type {trueType} does not define an IntPtr constructor. This could mean improperly defined bindings"); + + result = methodInfo.Invoke(null, new object[] { handle }); + } + else + { + result = ctr.Invoke(new object[] { handle }); + } + + if (result == null) + throw new Exception($"Type {trueType}'s factory method returned a null object. This could mean improperly defined bindings"); + + return result; + } + + private static MethodInfo? GetSecretFactoryMethod(System.Type type) + { + return type.GetMethods( + System.Reflection.BindingFlags.Static + | System.Reflection.BindingFlags.DeclaredOnly + | System.Reflection.BindingFlags.NonPublic + ).FirstOrDefault(x => x.GetCustomAttribute() is { }); + } + + private static ConstructorInfo? GetBoxedConstructor(System.Type type) + { + // Create using 'IntPtr' constructor + ConstructorInfo? ctor = type.GetConstructor( + System.Reflection.BindingFlags.NonPublic + | System.Reflection.BindingFlags.Public + | System.Reflection.BindingFlags.Instance, + null, new[] { typeof(IntPtr), }, null + ); + return ctor; + } + } +} diff --git a/Libs/GObject-2.0/Native/Classes/ObjectMapper.ToggleRef.cs b/Libs/GObject-2.0/Native/Classes/ObjectMapper.ToggleRef.cs index 23969b983..79a3165bf 100644 --- a/Libs/GObject-2.0/Native/Classes/ObjectMapper.ToggleRef.cs +++ b/Libs/GObject-2.0/Native/Classes/ObjectMapper.ToggleRef.cs @@ -80,7 +80,6 @@ private void ToggleReference(IntPtr data, IntPtr @object, bool isLastRef) _reference = weakObj; else throw new Exception("Could not toggle reference to strong. It is garbage collected."); - } else if (isLastRef && _reference is not WeakReference) { diff --git a/Libs/GObject-2.0/Native/Classes/ObjectMapper.cs b/Libs/GObject-2.0/Native/Classes/ObjectMapper.cs index 66004041e..65ed52c84 100644 --- a/Libs/GObject-2.0/Native/Classes/ObjectMapper.cs +++ b/Libs/GObject-2.0/Native/Classes/ObjectMapper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using GLib; @@ -9,6 +10,8 @@ public static partial class ObjectMapper { private static readonly Dictionary WrapperObjects = new(); + public static int ObjectCount => WrapperObjects.Count; + public static bool TryGetObject(IntPtr handle, [NotNullWhen(true)] out T? obj) where T : class, IHandle { if (WrapperObjects.TryGetValue(handle, out ToggleRef? weakRef)) @@ -30,6 +33,8 @@ public static void Map(IntPtr handle, object obj, bool ownedRef) { WrapperObjects[handle] = new ToggleRef(handle, obj, ownedRef); } + + Debug.WriteLine($"Mapped Object: Handle '{handle}' Object '{obj.GetType()}' OwnedRef '{ownedRef}'."); } public static void Unmap(IntPtr handle) @@ -39,6 +44,8 @@ public static void Unmap(IntPtr handle) if (WrapperObjects.Remove(handle, out var toggleRef)) toggleRef.Dispose(); } + + Debug.WriteLine($"Unmapped Object: Handle '{handle}'."); } } } diff --git a/Libs/GObject-2.0/Records/Closure.cs b/Libs/GObject-2.0/Records/Closure.cs index bc346145f..3371f26f4 100644 --- a/Libs/GObject-2.0/Records/Closure.cs +++ b/Libs/GObject-2.0/Records/Closure.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Runtime.InteropServices; namespace GObject @@ -6,12 +7,17 @@ namespace GObject //TODO: This should be in the native namespace. It does not belong into the managed api. We have events to handle this. public partial class Closure : IDisposable { - private readonly ClosureMarshalCallHandlerWorkaround _closureMarshalCallHandler; + // A call handler keeps the delegate alive for the + // lifetime of the call handler. As we save it as a + // field here, the delegate will match this class' lifetime. + private readonly ClosureMarshalCallHandler _closureMarshalCallHandler; - internal Closure(Action action) //TODO: Restore: ClosureMarshal action) + internal Closure(ClosureMarshal action) { - _closureMarshalCallHandler = new ClosureMarshalCallHandlerWorkaround(action); + _closureMarshalCallHandler = new ClosureMarshalCallHandler(action); _handle = Native.Closure.Methods.NewSimple((uint) Marshal.SizeOf(typeof(GObject.Native.Closure.Struct)), IntPtr.Zero); + + Debug.WriteLine($"Instantiating Closure: Address {_handle.DangerousGetHandle()}."); Native.Closure.Methods.Ref(_handle); Native.Closure.Methods.Sink(_handle); @@ -20,6 +26,8 @@ internal Closure(Action action) //TODO: Restore: ClosureMarshal action) public void Dispose() { + Debug.WriteLine($"Disposing Closure: Address {_handle.DangerousGetHandle()}."); + _closureMarshalCallHandler.Dispose(); _handle.Dispose(); } diff --git a/Libs/GObject-2.0/Records/Value.cs b/Libs/GObject-2.0/Records/Value.cs index 7e4360555..173396547 100644 --- a/Libs/GObject-2.0/Records/Value.cs +++ b/Libs/GObject-2.0/Records/Value.cs @@ -14,8 +14,8 @@ public partial class Value : IDisposable public Value(Type type) { - var h = Native.Value.ManagedHandle.Create(); - _handle = Native.Value.Methods.Init(h, type.Value); + _handle = Native.Value.ManagedHandle.Create(); + _handle = Native.Value.Methods.Init(_handle, type.Value); } public Value(Object value) : this(Type.Object) => SetObject(value); @@ -145,21 +145,30 @@ public void Set(object? value) if (Functions.TypeIsA(gtype, (nuint) BasicType.Flags)) return GetFlags(); - throw new NotSupportedException($"Unable to extract the value to the given type. The type {gtype} is unknown."); + var name = StringHelper.ToStringUtf8(Native.Functions.TypeName(gtype)); + + throw new NotSupportedException($"Unable to extract the value for type '{name}'. The type (id: {gtype}) is unknown."); } public T Extract() => (T) Extract()!; public IntPtr GetPtr() => Native.Value.Methods.GetPointer(Handle); - public object? GetBoxed(ulong type) + public object? GetBoxed(nuint type) { IntPtr ptr = Native.Value.Methods.GetBoxed(Handle); if (type == Functions.StrvGetType()) return StringHelper.ToStringArrayUtf8(ptr); - - throw new NotSupportedException($"Can't get boxed value. Type {type} is not supported."); + + // TODO: It would be nice to support boxing arbitrary managed types + // One idea for how to achieve this is creating our own 'OpaqueBoxed' type + // which wraps a GCHandle or similar. We can then retrieve this at runtime + // from a static dictionary, etc. Alternatively, perhaps we want to find a + // method which plays nice with AOT compilation. + + // TODO: Should this be GetBoxed/TakeBoxed/DupBoxed? + return BoxedWrapper.WrapHandle(Native.Value.Methods.GetBoxed(Handle), new Type(type)); } public Object? GetObject() diff --git a/Libs/Gdk-3.0/Records/Event.cs b/Libs/Gdk-3.0/Records/Event.cs new file mode 100644 index 000000000..5099a9479 --- /dev/null +++ b/Libs/Gdk-3.0/Records/Event.cs @@ -0,0 +1,87 @@ +using System; +using System.Runtime.InteropServices; + +namespace Gdk +{ + public partial class Event + { + // TODO: Workaround as long as we need GDK3 or + // do not create instances from safe handles + [GObject.Construct] + private static Event __FactoryNew(IntPtr ptr) + { + var ev = Marshal.PtrToStructure(ptr); + switch (ev.Type) + { + case EventType.Expose: + return new EventExpose(ptr); + case EventType.VisibilityNotify: + return new EventVisibility(ptr); + case EventType.MotionNotify: + return new EventMotion(ptr); + case EventType.ButtonPress: + case EventType.TwoButtonPress: + case EventType.ThreeButtonPress: + case EventType.ButtonRelease: + return new EventButton(ptr); + case EventType.TouchBegin: + return new EventTouch(ptr); + case EventType.Scroll: + return new EventScroll(ptr); + case EventType.KeyPress: + case EventType.KeyRelease: + return new EventKey(ptr); + case EventType.EnterNotify: + case EventType.LeaveNotify: + return new EventCrossing(ptr); + case EventType.FocusChange: + return new EventFocus(ptr); + case EventType.Configure: + return new EventConfigure(ptr); + case EventType.PropertyNotify: + return new EventProperty(ptr); + case EventType.SelectionClear: + case EventType.SelectionNotify: + case EventType.SelectionRequest: + return new EventSelection(ptr); + case EventType.OwnerChange: + return new EventOwnerChange(ptr); + case EventType.ProximityIn: + case EventType.ProximityOut: + return new EventProximity(ptr); + case EventType.DragEnter: + case EventType.DragLeave: + case EventType.DragMotion: + case EventType.DragStatus: + case EventType.DropStart: + case EventType.DropFinished: + return new EventDND(ptr); + case EventType.WindowState: + return new EventWindowState(ptr); + case EventType.Setting: + return new EventSetting(ptr); + case EventType.GrabBroken: + return new EventGrabBroken(ptr); + case EventType.TouchpadSwipe: + return new EventTouchpadSwipe(ptr); + case EventType.TouchpadPinch: + return new EventTouchpadPinch(ptr); + case EventType.PadButtonPress: + case EventType.PadButtonRelease: + return new EventPadButton(ptr); + case EventType.PadRing: + case EventType.PadStrip: + return new EventPadAxis(ptr); + case EventType.PadGroupMode: + return new EventPadGroupMode(ptr); + // Default/Not Implemented + case EventType.Map: + case EventType.Unmap: + case EventType.Delete: + case EventType.Destroy: + default: + throw new NotImplementedException("Event Type not yet supported"); + } + } + } +} diff --git a/Libs/Gdk-3.0/Records/EventButton.cs b/Libs/Gdk-3.0/Records/EventButton.cs new file mode 100644 index 000000000..5451c3700 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventButton.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventButton : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventConfigure.cs b/Libs/Gdk-3.0/Records/EventConfigure.cs new file mode 100644 index 000000000..ba84674bc --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventConfigure.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventConfigure : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventCrossing.cs b/Libs/Gdk-3.0/Records/EventCrossing.cs new file mode 100644 index 000000000..741450e7c --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventCrossing.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventCrossing : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventDND.cs b/Libs/Gdk-3.0/Records/EventDND.cs new file mode 100644 index 000000000..3f527d59f --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventDND.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventDND : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventExpose.cs b/Libs/Gdk-3.0/Records/EventExpose.cs new file mode 100644 index 000000000..aee1799d1 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventExpose.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventExpose : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventFocus.cs b/Libs/Gdk-3.0/Records/EventFocus.cs new file mode 100644 index 000000000..ed5ab4cbf --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventFocus.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventFocus : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventGrabBroken.cs b/Libs/Gdk-3.0/Records/EventGrabBroken.cs new file mode 100644 index 000000000..9f9fa97e4 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventGrabBroken.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventGrabBroken : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventKey.cs b/Libs/Gdk-3.0/Records/EventKey.cs new file mode 100644 index 000000000..d01cebcf7 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventKey.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; + +namespace Gdk +{ + public partial class EventKey : Event + { + // TODO: Proof-of-concept for accessing record fields. We'll want to generate this eventually + + public Gdk.EventType Type + { + get => Marshal.PtrToStructure(Handle.DangerousGetHandle()).Type; + } + + public uint Keyval + { + get => Marshal.PtrToStructure(Handle.DangerousGetHandle()).Keyval; + } + + public ushort HardwareKeycode + { + get => Marshal.PtrToStructure(Handle.DangerousGetHandle()).HardwareKeycode; + } + } +} diff --git a/Libs/Gdk-3.0/Records/EventMotion.cs b/Libs/Gdk-3.0/Records/EventMotion.cs new file mode 100644 index 000000000..4d3babb00 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventMotion.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventMotion : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventOwnerChange.cs b/Libs/Gdk-3.0/Records/EventOwnerChange.cs new file mode 100644 index 000000000..d7638d8d8 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventOwnerChange.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventOwnerChange : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventPadAxis.cs b/Libs/Gdk-3.0/Records/EventPadAxis.cs new file mode 100644 index 000000000..140ab1349 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventPadAxis.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventPadAxis : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventPadButton.cs b/Libs/Gdk-3.0/Records/EventPadButton.cs new file mode 100644 index 000000000..5a7dc4fe1 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventPadButton.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventPadButton : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventPadGroupMode.cs b/Libs/Gdk-3.0/Records/EventPadGroupMode.cs new file mode 100644 index 000000000..c28792171 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventPadGroupMode.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventPadGroupMode : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventProperty.cs b/Libs/Gdk-3.0/Records/EventProperty.cs new file mode 100644 index 000000000..07a89ba58 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventProperty.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventProperty : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventProximity.cs b/Libs/Gdk-3.0/Records/EventProximity.cs new file mode 100644 index 000000000..02e60525b --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventProximity.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventProximity : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventScroll.cs b/Libs/Gdk-3.0/Records/EventScroll.cs new file mode 100644 index 000000000..22cda9193 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventScroll.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventScroll : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventSelection.cs b/Libs/Gdk-3.0/Records/EventSelection.cs new file mode 100644 index 000000000..ad36c9a0d --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventSelection.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventSelection : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventSequence.cs b/Libs/Gdk-3.0/Records/EventSequence.cs new file mode 100644 index 000000000..a0a939963 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventSequence.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventSequence : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventSetting.cs b/Libs/Gdk-3.0/Records/EventSetting.cs new file mode 100644 index 000000000..c74feca62 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventSetting.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventSetting : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventTouch.cs b/Libs/Gdk-3.0/Records/EventTouch.cs new file mode 100644 index 000000000..1f2a20a85 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventTouch.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventTouch : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventTouchpadPinch.cs b/Libs/Gdk-3.0/Records/EventTouchpadPinch.cs new file mode 100644 index 000000000..a3bbcc852 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventTouchpadPinch.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventTouchpadPinch : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventTouchpadSwipe.cs b/Libs/Gdk-3.0/Records/EventTouchpadSwipe.cs new file mode 100644 index 000000000..767ebd560 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventTouchpadSwipe.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventTouchpadSwipe : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventVisibility.cs b/Libs/Gdk-3.0/Records/EventVisibility.cs new file mode 100644 index 000000000..1ee5b9877 --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventVisibility.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventVisibility : Event + { + + } +} diff --git a/Libs/Gdk-3.0/Records/EventWindowState.cs b/Libs/Gdk-3.0/Records/EventWindowState.cs new file mode 100644 index 000000000..2e1fa715a --- /dev/null +++ b/Libs/Gdk-3.0/Records/EventWindowState.cs @@ -0,0 +1,7 @@ +namespace Gdk +{ + public partial class EventWindowState : Event + { + + } +} diff --git a/Libs/Gdk4/Core/Classes/Snapshot.cs b/Libs/Gdk4/Core/Classes/Snapshot.cs deleted file mode 100644 index 787663c93..000000000 --- a/Libs/Gdk4/Core/Classes/Snapshot.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using GObject; - -namespace Gdk -{ - public class Snapshot : GObject.Object - { - protected internal Snapshot(IntPtr ptr) : base(ptr) { } - protected internal Snapshot(ConstructParam[] properties) : base(properties) { } - } -} diff --git a/Libs/Gdk4/Core/Gdk4.Core.csproj b/Libs/Gdk4/Core/Gdk4.Core.csproj deleted file mode 100644 index 295e1dcc8..000000000 --- a/Libs/Gdk4/Core/Gdk4.Core.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Gir.Core.CS.Gdk4 - - diff --git a/Libs/Gdk4/Wrapper/Gdk4.Wrapper.csproj b/Libs/Gdk4/Wrapper/Gdk4.Wrapper.csproj deleted file mode 100644 index e6ef95acd..000000000 --- a/Libs/Gdk4/Wrapper/Gdk4.Wrapper.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - Gir.Wrapper.CS.Gdk4 - - diff --git a/Libs/Gsk4/Wrapper/Gsk4.Wrapper.csproj b/Libs/Gsk4/Wrapper/Gsk4.Wrapper.csproj deleted file mode 100644 index 08dec2e4d..000000000 --- a/Libs/Gsk4/Wrapper/Gsk4.Wrapper.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Gir.Wrapper.CS.Gsk4 - - diff --git a/Libs/Gtk-3.0/Classes/EventBox.cs b/Libs/Gtk-3.0/Classes/EventBox.cs new file mode 100644 index 000000000..4dea4e3e3 --- /dev/null +++ b/Libs/Gtk-3.0/Classes/EventBox.cs @@ -0,0 +1,8 @@ +namespace Gtk +{ + public partial class EventBox + { + public static EventBox New() + => new EventBox(Native.EventBox.Instance.Methods.New(), false); + } +} diff --git a/Libs/Gtk-3.0/Classes/IMContextSimple.cs b/Libs/Gtk-3.0/Classes/IMContextSimple.cs new file mode 100644 index 000000000..16901d2c6 --- /dev/null +++ b/Libs/Gtk-3.0/Classes/IMContextSimple.cs @@ -0,0 +1,8 @@ +namespace Gtk +{ + public partial class IMContextSimple + { + public static IMContextSimple New() + => new IMContextSimple(Native.IMContextSimple.Instance.Methods.New(), true); + } +} diff --git a/Libs/Gtk-3.0/Classes/Notebook.cs b/Libs/Gtk-3.0/Classes/Notebook.cs new file mode 100644 index 000000000..a25002c9c --- /dev/null +++ b/Libs/Gtk-3.0/Classes/Notebook.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Gtk +{ + public partial class Notebook + { + public Notebook() { } + + public Widget this[string label] + { + set => AppendPage(value, Label.New(label)); + } + } +} diff --git a/Libs/Gtk-3.0/Classes/Paned.cs b/Libs/Gtk-3.0/Classes/Paned.cs new file mode 100644 index 000000000..c75da5351 --- /dev/null +++ b/Libs/Gtk-3.0/Classes/Paned.cs @@ -0,0 +1,8 @@ +namespace Gtk +{ + public partial class Paned + { + public static Paned New(Orientation orientation) + => new Paned(Native.Paned.Instance.Methods.New(orientation), false); + } +} diff --git a/Libs/Gtk-3.0/Classes/Window.cs b/Libs/Gtk-3.0/Classes/Window.cs index 59ffe8dd1..8c8704b5d 100644 --- a/Libs/Gtk-3.0/Classes/Window.cs +++ b/Libs/Gtk-3.0/Classes/Window.cs @@ -12,5 +12,10 @@ public Window(string title) : this(ConstructArgument.With("title", title)) { } + + public void SetInteractiveDebugging(bool enable) + { + Native.Window.Instance.Methods.SetInteractiveDebugging(enable); + } } } diff --git a/Libs/Gtk4/Core/Classes/Application.cs b/Libs/Gtk4/Core/Classes/Application.cs deleted file mode 100644 index 198fef12a..000000000 --- a/Libs/Gtk4/Core/Classes/Application.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Gtk -{ - public partial class Application - { - public Application(string applicationId) : base(Sys.Application.@new(applicationId, Gio.Sys.ApplicationFlags.flags_none)) {} - } -} \ No newline at end of file diff --git a/Libs/Gtk4/Core/Classes/ApplicationWindow.cs b/Libs/Gtk4/Core/Classes/ApplicationWindow.cs deleted file mode 100644 index a811a2b40..000000000 --- a/Libs/Gtk4/Core/Classes/ApplicationWindow.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Reflection; - -namespace Gtk -{ - public partial class ApplicationWindow - { - //public ApplicationWindow(Application application) : this(Sys.ApplicationWindow.@new(application)) {} - } -} \ No newline at end of file diff --git a/Libs/Gtk4/Core/Classes/Box.cs b/Libs/Gtk4/Core/Classes/Box.cs deleted file mode 100644 index c0e43f111..000000000 --- a/Libs/Gtk4/Core/Classes/Box.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Gtk -{ - public partial class Box - { - public Box() : this(Sys.Box.@new(Sys.Orientation.horizontal, 0)) {} - - public void Append(Widget widget) => Sys.Box.append(Handle, widget.Handle); - } -} diff --git a/Libs/Gtk4/Core/Classes/Button.cs b/Libs/Gtk4/Core/Classes/Button.cs deleted file mode 100644 index 0785f06c0..000000000 --- a/Libs/Gtk4/Core/Classes/Button.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using GObject; - -namespace Gtk -{ - public partial class Button - { - public Button() : this(Sys.Button.@new()) { } - public Button(string text) : this(Sys.Button.new_with_label(text)) { } - } -} diff --git a/Libs/Gtk4/Core/Classes/Widget.cs b/Libs/Gtk4/Core/Classes/Widget.cs deleted file mode 100644 index e80da947b..000000000 --- a/Libs/Gtk4/Core/Classes/Widget.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using GObject; - -namespace Gtk -{ - public partial class Widget - { - public void Show() => Sys.Widget.show(Handle); - } -} diff --git a/Libs/Gtk4/Core/Classes/Window.cs b/Libs/Gtk4/Core/Classes/Window.cs deleted file mode 100644 index 51d200c8f..000000000 --- a/Libs/Gtk4/Core/Classes/Window.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using GObject; - -namespace Gtk -{ - public partial class Window - { - public Window() : this(Sys.Window.@new()) { } - - public void SetDefaultSize(int width, int height) => Sys.Window.set_default_size(Handle, width, height); - public void SetTitlebar(Widget widget) => Sys.Window.set_titlebar(Handle, widget.Handle); - public void SetChild(Widget child) => Sys.Window.set_child(Handle, child.Handle); - } -} diff --git a/Libs/Gtk4/Core/Gtk4.Core.csproj b/Libs/Gtk4/Core/Gtk4.Core.csproj deleted file mode 100644 index 47eff4a5c..000000000 --- a/Libs/Gtk4/Core/Gtk4.Core.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - Gir.Core.CS.Gtk4 - - diff --git a/Libs/Gtk4/Wrapper/Gtk4.Wrapper.csproj b/Libs/Gtk4/Wrapper/Gtk4.Wrapper.csproj deleted file mode 100644 index 64bd5a991..000000000 --- a/Libs/Gtk4/Wrapper/Gtk4.Wrapper.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - Gir.Wrapper.CS.Gtk4 - - diff --git a/Libs/GtkChamplain/Core/Classes/Embed.cs b/Libs/GtkChamplain/Core/Classes/Embed.cs deleted file mode 100644 index a71d936ae..000000000 --- a/Libs/GtkChamplain/Core/Classes/Embed.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace GtkChamplain -{ - public class Embed : Gtk.Bin - { - public Embed() : base(Sys.Embed.@new()) { } - } -} diff --git a/Libs/GtkChamplain/Core/GtkChamplain.Core.csproj b/Libs/GtkChamplain/Core/GtkChamplain.Core.csproj deleted file mode 100644 index 44229add0..000000000 --- a/Libs/GtkChamplain/Core/GtkChamplain.Core.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - Gir.Core.CS.GtkChamplain - - diff --git a/Libs/GtkChamplain/Wrapper/GtkChamplain.Wrapper.csproj b/Libs/GtkChamplain/Wrapper/GtkChamplain.Wrapper.csproj deleted file mode 100644 index 9a603ba1e..000000000 --- a/Libs/GtkChamplain/Wrapper/GtkChamplain.Wrapper.csproj +++ /dev/null @@ -1,5 +0,0 @@ - - - Gir.Wrapper.CS.GtkChamplain - - diff --git a/Libs/GtkClutter/Core/Extensions/GtkApplicationExtensions.cs b/Libs/GtkClutter/Core/Extensions/GtkApplicationExtensions.cs deleted file mode 100644 index 8f2e131d8..000000000 --- a/Libs/GtkClutter/Core/Extensions/GtkApplicationExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace GtkClutter -{ - public static class GtkApplicationExtensions - { - public static void InitClutter(this Gtk.Application application) - { - var ptr = IntPtr.Zero; - var i = 0; - Sys.Methods.init(ref i, ref ptr); - } - } -} diff --git a/Libs/GtkClutter/Core/GtkClutter.Core.csproj b/Libs/GtkClutter/Core/GtkClutter.Core.csproj deleted file mode 100644 index bc225d61f..000000000 --- a/Libs/GtkClutter/Core/GtkClutter.Core.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Gir.Core.CS.GtkClutter - - diff --git a/Libs/GtkClutter/Wrapper/GtkClutter.Wrapper.csproj b/Libs/GtkClutter/Wrapper/GtkClutter.Wrapper.csproj deleted file mode 100644 index ce3b46ac1..000000000 --- a/Libs/GtkClutter/Wrapper/GtkClutter.Wrapper.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Gir.Wrapper.CS.GtkClutter - - diff --git a/Libs/Handy/Core/Classes/PageChangedEventArgs.cs b/Libs/Handy/Core/Classes/PageChangedEventArgs.cs deleted file mode 100644 index 8dc98abd0..000000000 --- a/Libs/Handy/Core/Classes/PageChangedEventArgs.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Handy -{ - public class PageChangedEventArgs : EventArgs - { - public uint Index { get; } - public PageChangedEventArgs(uint index) - { - Index = index; - } - } -} diff --git a/Libs/Handy/Core/Classes/Paginator.cs b/Libs/Handy/Core/Classes/Paginator.cs deleted file mode 100644 index a4be4626c..000000000 --- a/Libs/Handy/Core/Classes/Paginator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using GObject; -using Gtk; - -namespace Handy -{ - public partial class Paginator - { - public Paginator() : this(Sys.Paginator.@new()) { } - - public void Prepend(Widget widget) => Sys.Paginator.prepend(Handle, widget.Handle); - public void Append(Widget widget) => Sys.Paginator.insert(Handle, widget.Handle, -1); - public void ScrollTo(Widget widget) => Sys.Paginator.scroll_to(Handle, widget.Handle); - } -} diff --git a/Libs/Handy/Core/Enums/PaginatorIndicatorStyle.cs b/Libs/Handy/Core/Enums/PaginatorIndicatorStyle.cs deleted file mode 100644 index 90f037b2e..000000000 --- a/Libs/Handy/Core/Enums/PaginatorIndicatorStyle.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Handy -{ - /// - /// In sync with Handy.PaginatorIndicatorStyle - /// - public enum PaginatorIndicatorStyle : long - { - None = 0, - Dots = 1, - Lines = 2, - } -} diff --git a/Libs/Handy/Core/Handy.Core.csproj b/Libs/Handy/Core/Handy.Core.csproj deleted file mode 100644 index 5c26d0ec6..000000000 --- a/Libs/Handy/Core/Handy.Core.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - Gir.Core.CS.Handy - - diff --git a/Libs/Handy/Wrapper/Handy.Wrapper.csproj b/Libs/Handy/Wrapper/Handy.Wrapper.csproj deleted file mode 100644 index 36a60742e..000000000 --- a/Libs/Handy/Wrapper/Handy.Wrapper.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Gir.Wrapper.CS.Handy - - diff --git a/Libs/JavascriptCore/Core/Classes/Context.cs b/Libs/JavascriptCore/Core/Classes/Context.cs deleted file mode 100644 index e1c263072..000000000 --- a/Libs/JavascriptCore/Core/Classes/Context.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace JavaScriptCore -{ - public partial class Context - { - public void Throw(string errorMessage) => Sys.Context.@throw(Handle, errorMessage); - public void SetValue(string name, Value value) => Sys.Context.set_value(Handle, name, value.Handle); - public Value GetValue(string name) => new Value(Sys.Context.get_value(Handle, name)); - public Value GetGlobalObject() => new Value(Sys.Context.get_global_object(Handle)); - } -} diff --git a/Libs/JavascriptCore/Core/Classes/Value.cs b/Libs/JavascriptCore/Core/Classes/Value.cs deleted file mode 100644 index 0287c031d..000000000 --- a/Libs/JavascriptCore/Core/Classes/Value.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using GObject; - -namespace JavaScriptCore -{ - public partial class Value - { - #region Methods - public double GetDouble() => Sys.Value.to_double(Handle); - public int GetInt() => Sys.Value.to_int32(Handle); - public string GetString() => Marshal.PtrToStringAuto(Sys.Value.to_string(Handle)); - public bool GetBool() => Sys.Value.to_boolean(Handle); - - public bool IsNumber() => Sys.Value.is_number(Handle); - public bool IsString() => Sys.Value.is_string(Handle); - public bool IsNull() => Sys.Value.is_null(Handle); - public bool IsUndefined() => Sys.Value.is_undefined(Handle); - public bool IsBool() => Sys.Value.is_boolean(Handle); - public bool IsObject() => Sys.Value.is_object(Handle); - public bool IsFunction() => Sys.Value.is_function(Handle); - public bool IsArray() => Sys.Value.is_array(Handle); - - public bool HasProperty(string name) => Sys.Value.object_has_property(Handle, name); - public Value InvokeMethod(string name) - { - var ptr = IntPtr.Zero; - var ret = Sys.Value.object_invoke_methodv(Handle, name, 0, ref ptr); - - return new Value(ret); - } - - public Value GetProperty(string name) => GetProperty(Sys.Value.object_get_property(Handle, name)); - - public Value GetPropertyAtIndex(uint index) => GetProperty(Sys.Value.object_get_property_at_index(Handle, index)); - - private static Value GetProperty(IntPtr ptr) - { - return WrapPointerAs(ptr); - } - #endregion - - public static Value Create(IntPtr ptr) => new Value(ptr); - } -} diff --git a/Libs/JavascriptCore/Core/JavascriptCore.Core.csproj b/Libs/JavascriptCore/Core/JavascriptCore.Core.csproj deleted file mode 100644 index f76464437..000000000 --- a/Libs/JavascriptCore/Core/JavascriptCore.Core.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Gir.Core.CS.JavascriptCore - - diff --git a/Libs/JavascriptCore/Wrapper/JavascriptCore.Wrapper.csproj b/Libs/JavascriptCore/Wrapper/JavascriptCore.Wrapper.csproj deleted file mode 100644 index 403443cb8..000000000 --- a/Libs/JavascriptCore/Wrapper/JavascriptCore.Wrapper.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Gir.Wrapper.CS.JavascriptCore - - diff --git a/Libs/WebKit2WebExtension/Core/Classes/WebExtension.cs b/Libs/WebKit2WebExtension/Core/Classes/WebExtension.cs deleted file mode 100644 index 19e8df159..000000000 --- a/Libs/WebKit2WebExtension/Core/Classes/WebExtension.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace WebKit2WebExtension -{ - public class PageCreatedEventArgs : EventArgs - { - public WebPage WebPage { get; } - - public PageCreatedEventArgs(WebPage webPage) - { - WebPage = webPage ?? throw new ArgumentNullException(nameof(webPage)); - } - } - public partial class WebExtension : GObject.Object - { - private WebPage GetPage(ref GObject.Sys.Value[] values) => null!;//TODO - } -} diff --git a/Libs/WebKit2WebExtension/Core/Classes/WebPage.cs b/Libs/WebKit2WebExtension/Core/Classes/WebPage.cs deleted file mode 100644 index d87cb815b..000000000 --- a/Libs/WebKit2WebExtension/Core/Classes/WebPage.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace WebKit2WebExtension -{ - public partial class WebPage - { - } -} diff --git a/Libs/WebKit2WebExtension/Core/WebKit2WebExtension.Core.csproj b/Libs/WebKit2WebExtension/Core/WebKit2WebExtension.Core.csproj deleted file mode 100644 index cd805ed4a..000000000 --- a/Libs/WebKit2WebExtension/Core/WebKit2WebExtension.Core.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - Gir.Core.CS.WebKit2WebExtension - - diff --git a/Libs/WebKit2WebExtension/Wrapper/WebKit2WebExtension.Wrapper.csproj b/Libs/WebKit2WebExtension/Wrapper/WebKit2WebExtension.Wrapper.csproj deleted file mode 100644 index 08316db75..000000000 --- a/Libs/WebKit2WebExtension/Wrapper/WebKit2WebExtension.Wrapper.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Gir.Wrapper.CS.WebKit2WebExtension - - diff --git a/Libs/WebKitGTK/Core/Classes/Settings.cs b/Libs/WebKitGTK/Core/Classes/Settings.cs deleted file mode 100644 index 6bc0ce595..000000000 --- a/Libs/WebKitGTK/Core/Classes/Settings.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using GObject; - -namespace WebKit2 -{ - public partial class Settings - { - } -} diff --git a/Libs/WebKitGTK/Core/Classes/StringUserScript.cs b/Libs/WebKitGTK/Core/Classes/StringUserScript.cs deleted file mode 100644 index af1cce48f..000000000 --- a/Libs/WebKitGTK/Core/Classes/StringUserScript.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace WebKit2 -{ - public class StringUserScript : UserScript - { - public string Script { get; } - - public StringUserScript(string script) - { - Script = script ?? throw new ArgumentNullException(nameof(script)); - } - } -} diff --git a/Libs/WebKitGTK/Core/Classes/UserContentManager.cs b/Libs/WebKitGTK/Core/Classes/UserContentManager.cs deleted file mode 100644 index 146b58c3b..000000000 --- a/Libs/WebKitGTK/Core/Classes/UserContentManager.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using GObject; - -namespace WebKit2 -{ - public partial class UserContentManager - { - public bool RegisterScriptMessageHandler(string name, Action callback) - { - if (!Sys.UserContentManager.register_script_message_handler(Handle, name)) - return false; - - void OnMessageReceived(ref GObject.Sys.Value[] values) - { - var result = values[1].GetBoxed(); - result = Sys.JavascriptResult.@ref(result); - var jsValue = Sys.JavascriptResult.get_js_value(result); - var value = JavaScriptCore.Value.Create(jsValue); - callback(value); - } - - RegisterEvent($"script-message-received::{name}", (ActionRefValues) OnMessageReceived); - return true; - } - - public void AddScript(UserScript script) - { - var zero = IntPtr.Zero; - var webkitScript = Sys.UserScript.@new(script.Script, Sys.UserContentInjectedFrames.all_frames, Sys.UserScriptInjectionTime.end, zero, zero); - Sys.UserContentManager.add_script(Handle, webkitScript); - } - } -} diff --git a/Libs/WebKitGTK/Core/Classes/WebContext.cs b/Libs/WebKitGTK/Core/Classes/WebContext.cs deleted file mode 100644 index 4bb5791c9..000000000 --- a/Libs/WebKitGTK/Core/Classes/WebContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace WebKit2 -{ - public partial class WebContext - { - public WebContext() : this(Sys.WebContext.@new()) { } - - public void ClearCache() => Sys.WebContext.clear_cache(Handle); - public void SetWebExtensionsDirectory(string directory) => Sys.WebContext.set_web_extensions_directory(Handle, directory); - } -} diff --git a/Libs/WebKitGTK/Core/Classes/WebInspector.cs b/Libs/WebKitGTK/Core/Classes/WebInspector.cs deleted file mode 100644 index 7c7b656fc..000000000 --- a/Libs/WebKitGTK/Core/Classes/WebInspector.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace WebKit2 -{ - public partial class WebInspector - { - public void Show() => Sys.WebInspector.show(Handle); - } -} diff --git a/Libs/WebKitGTK/Core/Classes/WebView.cs b/Libs/WebKitGTK/Core/Classes/WebView.cs deleted file mode 100644 index e6a7b1140..000000000 --- a/Libs/WebKitGTK/Core/Classes/WebView.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Threading.Tasks; -using GObject; -using Gtk; -using JavaScriptCore; - -namespace WebKit2 -{ - public partial class WebView - { - public WebView(WebContext context) : this(Sys.WebView.new_with_context(context.Handle)) { } - - public void LoadUri(string uri) => Sys.WebView.load_uri(Handle, uri); - public Settings GetSettings() => WrapPointerAs(Sys.WebView.get_settings(Handle)); - public UserContentManager GetUserContentManager() => WrapPointerAs(Sys.WebView.get_user_content_manager(Handle)); - public WebInspector GetInspector() => WrapPointerAs(Sys.WebView.get_inspector(Handle)); - - public Task RunJavascriptAsync(string script) - { - var tcs = new TaskCompletionSource(); - - void Callback(IntPtr sourceObject, IntPtr res, IntPtr userData) - { - var jsResult = Sys.WebView.run_javascript_finish(sourceObject, res, out var error); - HandleError(error); - - var jsValue = Sys.JavascriptResult.get_js_value(jsResult); - var value = WrapPointerAs(jsValue); - tcs.SetResult(value); - } - - Sys.WebView.run_javascript(Handle, script, IntPtr.Zero, Callback, IntPtr.Zero); - - return tcs.Task; - } - } -} diff --git a/Libs/WebKitGTK/Core/Interfaces/UserScript.cs b/Libs/WebKitGTK/Core/Interfaces/UserScript.cs deleted file mode 100644 index d699c6140..000000000 --- a/Libs/WebKitGTK/Core/Interfaces/UserScript.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WebKit2 -{ - public interface UserScript - { - string Script { get; } - } -} diff --git a/Libs/WebKitGTK/Core/WebKitGTK.Core.csproj b/Libs/WebKitGTK/Core/WebKitGTK.Core.csproj deleted file mode 100644 index 697e4cf93..000000000 --- a/Libs/WebKitGTK/Core/WebKitGTK.Core.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - Gir.Core.CS.WebKitGTK - - diff --git a/Libs/WebKitGTK/Wrapper/WebKitGTK.Wrapper.csproj b/Libs/WebKitGTK/Wrapper/WebKitGTK.Wrapper.csproj deleted file mode 100644 index 9ff534b2c..000000000 --- a/Libs/WebKitGTK/Wrapper/WebKitGTK.Wrapper.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - Gir.Wrapper.CS.WebKitGTK - - diff --git a/Libs/cairo-1.0/Classes/DllImportOverride.cs b/Libs/cairo-1.0/Classes/DllImportOverride.cs new file mode 100644 index 000000000..81ca13db5 --- /dev/null +++ b/Libs/cairo-1.0/Classes/DllImportOverride.cs @@ -0,0 +1,107 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +#nullable enable + +namespace cairo.Native +{ + // Manual override of the DllImport class so we can handle + // cairo being in multiple shared libraries/dlls. See the + // method 'TryGetOsDependentLibraryName' for an explanation + // of what is happening. + internal static class DllImportOverride + { + #region Fields + + // libcairo (for manually written code) + private const string _windowsDllName = "libcairo-2.dll"; + private const string _linuxDllName = "libcairo.so.2"; + private const string _osxDllName = "libcairo.2.dylib"; + + // libcairo-gobject (for autogenerated/introspection code) + private const string _cgoWindowsDllName = "libcairo-gobject-2.dll"; + private const string _cgoLinuxDllName = "libcairo-gobject.so.2"; + private const string _cgoOsxDllName = "libcairo-gobject.2.dylib"; + + private static readonly Dictionary _cache = new (); + + #endregion + + #region Methods + + public static void Initialize() + { + NativeLibrary.SetDllImportResolver(typeof(DllImportOverride).Assembly, ImportResolver); + } + + private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) + { + if (_cache.TryGetValue(libraryName, out var cachedLibHandle)) + return cachedLibHandle; + + if (!TryGetOsDependentLibraryName(libraryName, out var osDependentLibraryName)) + return IntPtr.Zero; + + if (NativeLibrary.TryLoad(osDependentLibraryName, assembly, searchPath, out IntPtr libHandle)) + { + _cache[libraryName] = libHandle; + return libHandle; + } + + // Fall back to default dll search mechanic + return IntPtr.Zero; + } + + private static bool TryGetOsDependentLibraryName(string libraryName, [NotNullWhen(true)] out string? osDependentLibraryName) + { + // Cairo, as used by GTK, is spread across two (maybe more?) + // shared libraries. These are 'cairo' - the library itself, + // and 'cairo-gobject' - interop code for using with GDK. + + // We map the string 'libraryName' to the correct shared library: + // * "cairo" -> "libcairo-gobject" + // * "cairo-graphics" -> "libcairo" + + // Confusingly, "cairo" refers to "cairo-gobject" as this is + // the library specified in "cairo-1.0.gir". + if (libraryName == "cairo") + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + osDependentLibraryName = _cgoWindowsDllName; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + osDependentLibraryName = _cgoOsxDllName; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + osDependentLibraryName = _cgoLinuxDllName; + else + throw new Exception("Unknown platform"); + + return true; + } + + // This is the actual "libcairo" which defines the + // functions, structs, etc that we want. + if (libraryName == "cairo-graphics") + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + osDependentLibraryName = _windowsDllName; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + osDependentLibraryName = _osxDllName; + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + osDependentLibraryName = _linuxDllName; + else + throw new Exception("Unknown platform"); + + return true; + } + + // Library name not recognised, return + osDependentLibraryName = null; + return false; + } + + #endregion + } +} diff --git a/Libs/cairo-1.0/Classes/Module.cs b/Libs/cairo-1.0/Classes/Module.cs index 64c3ef03d..b717740c8 100644 --- a/Libs/cairo-1.0/Classes/Module.cs +++ b/Libs/cairo-1.0/Classes/Module.cs @@ -7,7 +7,12 @@ internal partial class Module [ModuleInitializer] internal static void Initialize() { - InitializeDllImport(); + // InitializeDllImport(); + + // We override the normal DllImporter generated for us + // as we need to take into account cairo being spread + // across multiple shared libraries. + Native.DllImportOverride.Initialize(); RegisterTypes(); } diff --git a/Libs/cairo-1.0/Records/Context.cs b/Libs/cairo-1.0/Records/Context.cs new file mode 100644 index 000000000..cc9113749 --- /dev/null +++ b/Libs/cairo-1.0/Records/Context.cs @@ -0,0 +1,62 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace cairo +{ + public partial class Context + { + // IMPORTANT: We should follow cairo's guidelines on memory management + // for language bindings. This is a quick attempt at implementing something + // workable. + + [DllImport ("cairo-graphics", EntryPoint = "cairo_set_source_rgba")] + private static extern void NativeSetSourceRgba (Native.Context.Handle cr, double red, double green, double blue, double alpha); + + public void SetSourceRgba(double red, double green, double blue, double alpha) + => NativeSetSourceRgba(Handle, red, green, blue, alpha); + + [DllImport ("cairo-graphics", EntryPoint = "cairo_show_text")] + private static extern void NativeShowText (Native.Context.Handle cr, [MarshalAs(UnmanagedType.LPUTF8Str)] string utf8); + + public void ShowText(string text) + => NativeShowText(Handle, text); + + [DllImport ("cairo-graphics", EntryPoint = "cairo_move_to")] + private static extern void NativeMoveTo (Native.Context.Handle cr, double x, double y); + + public void MoveTo(double x, double y) + => NativeMoveTo(Handle, x, y); + + [DllImport ("cairo-graphics", EntryPoint = "cairo_text_extents")] + private static extern void NativeTextExtents (Native.Context.Handle cr, [MarshalAs (UnmanagedType.LPUTF8Str)] string utf8, out TextExtents extents); + + public void TextExtents(string text, out TextExtents extents) + => NativeTextExtents(Handle, text, out extents); + + [DllImport ("cairo-graphics", EntryPoint = "cairo_font_extents")] + private static extern void NativeFontExtents (Native.Context.Handle cr, out FontExtents extents); + + public void FontExtents(out FontExtents extents) + => NativeFontExtents(Handle, out extents); + + [DllImport ("cairo-graphics", EntryPoint = "cairo_fill")] + private static extern void NativeFill (Native.Context.Handle cr); + + public void Fill() + => NativeFill(Handle); + + [DllImport ("cairo-graphics", EntryPoint = "cairo_rectangle")] + private static extern void NativeRectangle (Native.Context.Handle cr, double x, double y, double width, double height); + + public void Rectangle(double x, double y, double width, double height) + => NativeRectangle(Handle, x, y, width, height); + + + [DllImport("cairo-graphics", EntryPoint = "cairo_set_font_size")] + private static extern void NativeSetFontSize (Native.Context.Handle cr, double size); + + public void SetFontSize(double size) + => NativeSetFontSize(Handle, size); + } +} diff --git a/Libs/cairo-1.0/Records/FontExtents.cs b/Libs/cairo-1.0/Records/FontExtents.cs new file mode 100644 index 000000000..303de6b8c --- /dev/null +++ b/Libs/cairo-1.0/Records/FontExtents.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace cairo +{ + [StructLayout(LayoutKind.Sequential)] + public struct FontExtents + { + public double Ascent; + public double Descent; + public double Height; + public double MaxXAdvance; + public double MaxYAdvance; + } +} diff --git a/Libs/cairo-1.0/Records/TextExtents.cs b/Libs/cairo-1.0/Records/TextExtents.cs new file mode 100644 index 000000000..853036118 --- /dev/null +++ b/Libs/cairo-1.0/Records/TextExtents.cs @@ -0,0 +1,15 @@ +using System.Runtime.InteropServices; + +namespace cairo +{ + [StructLayout(LayoutKind.Sequential)] + public struct TextExtents + { + public double xBearing; + public double yBearing; + public double width; + public double height; + public double xAdvance; + public double yAdvance; + } +} diff --git a/Libs/cairo-1.0/cairo-1.0.csproj b/Libs/cairo-1.0/cairo-1.0.csproj index ac8dac527..6286c7ad2 100644 --- a/Libs/cairo-1.0/cairo-1.0.csproj +++ b/Libs/cairo-1.0/cairo-1.0.csproj @@ -5,5 +5,6 @@ + diff --git a/Samples/GObject/CreateCustomGObject.cs b/Samples/GObject/CreateCustomGObject.cs deleted file mode 100644 index 1dbf4bf9e..000000000 --- a/Samples/GObject/CreateCustomGObject.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using GObject; -using Object = GObject.Object; - -namespace Sample -{ - - public class Bar : Foo - { - } - public class Foo : Object - { - public string Text { get; set; } - } - - public class GObject - { - public static void CreateCustomGObject() - { - var myObject = new Bar(); - - var b = new Binding(null, "", null, ""); - - //Console.WriteLine(myObject.Text); - } - } -} \ No newline at end of file diff --git a/Samples/GObject/Program.cs b/Samples/GObject/Program.cs deleted file mode 100644 index 01ca2091a..000000000 --- a/Samples/GObject/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Samples -{ - class Program - { - static void Main(string[] args) - { - Sample.GObject.CreateCustomGObject(); - } - } -} diff --git a/Samples/Gtk3/Builder/Builder.csproj b/Samples/Gtk3/Builder/Builder.csproj deleted file mode 100644 index 465d793a7..000000000 --- a/Samples/Gtk3/Builder/Builder.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - Exe - net5.0 - enable - - - - - - %(Filename)%(Extension) - - - - diff --git a/Samples/Gtk3/Builder/DemoWindow.cs b/Samples/Gtk3/Builder/DemoWindow.cs deleted file mode 100644 index 13038281c..000000000 --- a/Samples/Gtk3/Builder/DemoWindow.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using Gtk; - -namespace GtkDemo -{ - public class DemoWindow : ApplicationWindow - { - [Connect] - private Button Button = default!; - - [Connect] - private Box Box = default!; - - private Notebook notebook; - - public DemoWindow(Application application) : this(application, new Builder("demo_window.glade")) { } - private DemoWindow(Application application, Builder builder) : base(builder.GetObject("root"), false) - { - Application = application; - builder.Connect(this); - - // Connect Button - Button.OnClicked += Button_Clicked; - - // Create Notebook - notebook = new Notebook(); - Box.PackStart(notebook, true, true, 0); - - var image = Image.NewFromFile("data/gtk.png"); - notebook.InsertPage("Image", image, 0); - - var label = new Label("Gtk and C# - Very exciting isn't it?"); - notebook.InsertPage("Label", label, 1); - } - - private void Button_Clicked(Button sender, EventArgs args) - { - Console.WriteLine("Hello World!"); - Resizable = !Resizable; - } - } -} diff --git a/Samples/Gtk3/Builder/Program.cs b/Samples/Gtk3/Builder/Program.cs deleted file mode 100644 index d715a0e0e..000000000 --- a/Samples/Gtk3/Builder/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Diagnostics; -using Gtk; -using Application = Gtk.Application; - -namespace GtkDemo -{ - public class Program - { - public static void Main(string[] args) - { - var app = new Program(); - } - - public Program() - { - var app = new Application("org.gircore.builder"); - app.OnActivate += OnActivate; - app.Run(); - } - - private void OnActivate(Gio.Application sender, EventArgs args) - { - if (sender is Application app) - { - var w = new DemoWindow(app) - { - DefaultHeight = 600, - DefaultWidth = 800, - }; - - w.ShowAll(); - } - } - } -} diff --git a/Samples/Gtk3/Builder/data/demo_window.glade b/Samples/Gtk3/Builder/data/demo_window.glade deleted file mode 100644 index ae45aa56c..000000000 --- a/Samples/Gtk3/Builder/data/demo_window.glade +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - False - Gtk C# builder api example - - - True - False - vertical - - - Click Me! - True - True - True - 10 - 10 - 10 - 10 - - - False - True - end - 0 - - - - - - - - - diff --git a/Samples/Gtk3/Builder/data/gtk.png b/Samples/Gtk3/Builder/data/gtk.png deleted file mode 100644 index b622179b5..000000000 Binary files a/Samples/Gtk3/Builder/data/gtk.png and /dev/null differ diff --git a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/CompositeWidget.cs b/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/CompositeWidget.cs deleted file mode 100644 index 0e8272efa..000000000 --- a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/CompositeWidget.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Reflection; -using GLib; -using GObject; -using Gtk; -using Type = GObject.Type; - -namespace GtkDemo -{ - public class CompositeWidget : Bin - { - private Button Button = default!; - - private static void ClassInit(Type gClass, System.Type type, IntPtr classData) - { - var templateData = Assembly.GetExecutingAssembly().ReadResourceAsByteArray("CompositeWidget.ui"); - SetTemplate( - gtype: gClass, - template: Bytes.From(templateData) - ); - BindTemplateChild(gClass, nameof(Button)); - BindTemplateSignals(gClass, type); - } - - protected override void Initialize() - { - InitTemplate(); - ConnectTemplateChildToField(nameof(Button), ref Button); - } - - private void button_clicked(Button sender, System.EventArgs args) - { - sender.Label = "Clicked!"; - } - } -} diff --git a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/CompositeWidget.ui b/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/CompositeWidget.ui deleted file mode 100644 index 34dcb1804..000000000 --- a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/CompositeWidget.ui +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/NoSourceGenerator.csproj b/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/NoSourceGenerator.csproj deleted file mode 100644 index 05d301fc2..000000000 --- a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/NoSourceGenerator.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - Exe - net5.0 - enable - - - - - - - - - - %(Filename)%(Extension) - - - - \ No newline at end of file diff --git a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/Program.cs b/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/Program.cs deleted file mode 100644 index ac817c768..000000000 --- a/Samples/Gtk3/CompositeTemplates/NoSourceGenerator/Program.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Gtk; -using Global = Gtk.Global; -using Object = GObject.Object; - -namespace GtkDemo -{ - /// - /// Minimalist demo program demonstrating the GTK templating system - /// - public static class Program - { - #region Methods - - public static void Main(string[] args) - { - Global.Init(); - - var mainWindow = new Window("MyWindow") - { - DefaultWidth = 300, - DefaultHeight = 200, - Child = new CompositeWidget(), - [Window.DestroySignal] = (o, e) => Global.MainQuit() - }; - - mainWindow.ShowAll(); - Global.Main(); - } - #endregion - } -} diff --git a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/CompositeWidget.cs b/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/CompositeWidget.cs deleted file mode 100644 index af7ab9bc2..000000000 --- a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/CompositeWidget.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Gtk; - -namespace GtkDemo -{ - [Template("CompositeWidget.ui")] - public partial class CompositeWidget : Bin - { - [Connect] - private Button Button = default!; - - private void button_clicked(Button sender, System.EventArgs args) - { - sender.Label = "Clicked!"; - } - } -} diff --git a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/CompositeWidget.ui b/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/CompositeWidget.ui deleted file mode 100644 index 34dcb1804..000000000 --- a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/CompositeWidget.ui +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/Program.cs b/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/Program.cs deleted file mode 100644 index ac817c768..000000000 --- a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/Program.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using Gtk; -using Global = Gtk.Global; -using Object = GObject.Object; - -namespace GtkDemo -{ - /// - /// Minimalist demo program demonstrating the GTK templating system - /// - public static class Program - { - #region Methods - - public static void Main(string[] args) - { - Global.Init(); - - var mainWindow = new Window("MyWindow") - { - DefaultWidth = 300, - DefaultHeight = 200, - Child = new CompositeWidget(), - [Window.DestroySignal] = (o, e) => Global.MainQuit() - }; - - mainWindow.ShowAll(); - Global.Main(); - } - #endregion - } -} diff --git a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/UsingSourceGenerator.csproj b/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/UsingSourceGenerator.csproj deleted file mode 100644 index a48bf9017..000000000 --- a/Samples/Gtk3/CompositeTemplates/UsingSourceGenerator/UsingSourceGenerator.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - Exe - net5.0 - enable - - - - - - - - - - - %(Filename)%(Extension) - - - - \ No newline at end of file diff --git a/Samples/Gtk3/DrawingArea/DrawingArea.cs b/Samples/Gtk3/DrawingArea/DrawingArea.cs new file mode 100644 index 000000000..fee91abbd --- /dev/null +++ b/Samples/Gtk3/DrawingArea/DrawingArea.cs @@ -0,0 +1,24 @@ +using System; +using Gtk; + +Functions.Init(); + +var window = new Window("DrawingArea Demo"); +var drawingArea = DrawingArea.New(); +window.Child = drawingArea; + +drawingArea.OnDraw += (d, a) => +{ + cairo.Context cr = a.Cr; + cr.SetSourceRgba(0.1, 0.1, 0.1, 1.0); + cr.MoveTo(20, 30); + cr.ShowText("This is some text, drawn with cairo"); + + cr.MoveTo(40, 60); + cr.ShowText("Powered by gir.core - GObject bindings for .NET"); +}; +window.ShowAll(); + +window.OnDestroy += (o,e) => Functions.MainQuit(); + +Functions.Main(); diff --git a/Samples/GObject/GObject.csproj b/Samples/Gtk3/DrawingArea/DrawingArea.csproj similarity index 71% rename from Samples/GObject/GObject.csproj rename to Samples/Gtk3/DrawingArea/DrawingArea.csproj index da1ae88a0..ed9e529af 100644 --- a/Samples/GObject/GObject.csproj +++ b/Samples/Gtk3/DrawingArea/DrawingArea.csproj @@ -1,12 +1,12 @@ - Exe net5.0 + Exe - + diff --git a/Samples/Gtk3/GtkApp/GtkApp.csproj b/Samples/Gtk3/GtkApp/GtkApp.csproj deleted file mode 100644 index fec70c721..000000000 --- a/Samples/Gtk3/GtkApp/GtkApp.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - Exe - net5.0 - - - - - - %(Filename)%(Extension) - - - - - enable - - - diff --git a/Samples/Gtk3/GtkApp/MyBox.cs b/Samples/Gtk3/GtkApp/MyBox.cs deleted file mode 100644 index 2eef7e879..000000000 --- a/Samples/Gtk3/GtkApp/MyBox.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Gtk; - -namespace GtkApp -{ - public class MyBox : Box - { - [Connect] - private Label Label1 = default!; - - [Connect] - private Label Label2 = default!; - - [Connect] - private Label Label3 = default!; - - public MyBox() : base("box.glade") - { - } - } -} diff --git a/Samples/Gtk3/GtkApp/MyWindow.cs b/Samples/Gtk3/GtkApp/MyWindow.cs deleted file mode 100644 index f36cee4c0..000000000 --- a/Samples/Gtk3/GtkApp/MyWindow.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System; -using Gtk; -using Handy; -using WebKit2; - -namespace GtkApp -{ - public class MyWindow : ApplicationWindow - { - [Connect] - private Button Button = default!; - - [Connect] - private Box Box = default!; - - private Box innerBox = new MyBox(); - private Button button; - - private Image image; - private TextLabelExpander r; - private Revealer revealer; - - private SimpleCommand action; - private TextCombobox textCombobox; - private CheckButton checkButton; - private Notebook notebook; - private WebView webView; - private WebContext context; - private Paginator paginator; - private Label b; - - private GtkChamplain.Embed map; - - public MyWindow(Application application) : base(application, "ui.glade") - { - notebook = new Notebook(); - - button = new Button("Test"); - - button.Text.Value = "NEW TEXT"; - button.Clicked += (obj, args) => image.Clear(); - - image = new StockImage("folder", IconSize.Button); - - notebook.InsertPage("Image", image, 0); - notebook.InsertPage("Box", innerBox, 1); - - context = new WebContext(); - context.InitializeWebExtensions += OnInitializeWebExtension; - webView = new WebView(context); - - var settings = webView.GetSettings(); - settings.AllowModalDialogs.Value = true; - settings.EnableDeveloperExtras.Value = true; - - var ucm = webView.GetUserContentManager(); - var ret = ucm.RegisterScriptMessageHandler("foobar", JsCallback); - - if (ret) - { - const string code = @" - (function(globalContext) { - globalContext.document.getElementById(""clickMe"").onclick = function () - { - var message = { - myProp : ""5"", - }; - window.webkit.messageHandlers[""foobar""].postMessage(message); - }; - })(this) - - function test() { return 'test' } - "; - ucm.AddScript(new StringUserScript(code)); - } - - Console.WriteLine(System.IO.Directory.GetCurrentDirectory()); - webView.LoadUri("file:///home/marcel/Programmieren/csharp/gircore/gir.core/GtkApp/test.html"); - webView.HeightRequest.Value = 500; - webView.WidthRequest.Value = 500; - - paginator = new Paginator(); - paginator.AllowMouseDrag.Value = true; - paginator.Append(webView); - paginator.IndicatorStyle.Value = PaginatorIndicatorStyle.Lines; - - b = new Label("label"); - paginator.Append(b); - - map = new GtkChamplain.Embed(); - map.WidthRequest.Value = 500; - map.HeightRequest.Value = 500; - paginator.Append(map); - - notebook.InsertPage("Paginator", paginator, 2); - Box.Add(notebook); - - checkButton = new CheckButton("Check"); - checkButton.Toggled += (s, o) => Console.WriteLine("Toggled"); - Box.Add(checkButton); - - r = new TextLabelExpander("Te_st"); - r.UseMarkup.Value = true; - r.UseUnderline.Value = true; - - textCombobox = new TextCombobox("combobox.glade"); - textCombobox.AppendText("t3", "Test 3"); - textCombobox.AppendText("t4", "Test 4"); - - revealer = new Revealer(); - revealer.TransitionType.Value = RevealerTransitionType.Crossfade; - revealer.Add(textCombobox); - Box.Add(revealer); - - r.Add(new Label("test")); - Box.Add(r); - - action = new SimpleCommand((o) => Console.WriteLine("Do it!")); - application.AddAction("do", action); - } - - private void JsCallback(JavaScriptCore.Value value) - { - if (value.IsString()) - Console.WriteLine(value.GetString()); - - if (!value.IsObject()) - return; - - var p = value.GetProperty("myProp"); - Console.WriteLine(p.GetString()); - } - - private void OnInitializeWebExtension(object? sender, EventArgs args) - { - Console.WriteLine("INIT"); - Console.WriteLine(System.IO.Directory.GetCurrentDirectory()); - } - - private async void button_clicked(object obj, EventArgs args) - { - revealer.Reveal.Value = !revealer.Reveal.Value; - action.SetCanExecute(!action.CanExecute(default)); - - var inspector = webView.GetInspector(); - inspector.Show(); - - var value = await webView.RunJavascriptAsync("test()"); - Console.WriteLine(value.GetString()); - } - } -} diff --git a/Samples/Gtk3/GtkApp/Program.cs b/Samples/Gtk3/GtkApp/Program.cs deleted file mode 100644 index cebac7853..000000000 --- a/Samples/Gtk3/GtkApp/Program.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using Gtk; -using GtkClutter; - -namespace GtkApp -{ - public class Program - { - - public static void Main(string[] args) - { - var app = new Program(); - } - - public Program() - { - var app = new Application("org.GtkApp"); - app.InitClutter(); - app.Activate += OnActivate; - app.Startup += OnStartup; - app.Run(); - } - - private void OnStartup(object? sender, EventArgs args) - { - if (!(sender is Application app)) - return; - - var menu = new Menu("menu.glade"); - app.SetAppMenu(menu); - } - - private void OnActivate(object? sender, EventArgs args) - { - if (!(sender is Application app)) - return; - - var headerBar = new HeaderBar(); - headerBar.Title.Value = "Title"; - headerBar.Subtitle.Value = "Subtitle"; - headerBar.ShowCloseButton.Value = true; - - var w = new MyWindow(app); - w.DefaultHeight.Value = 800; - w.DefaultWidth.Value = 400; - w.SetTitlebar(headerBar); - w.ShowAll(); - } - } -} diff --git a/Samples/Gtk3/GtkApp/SimpleCommand.cs b/Samples/Gtk3/GtkApp/SimpleCommand.cs deleted file mode 100644 index b492a2550..000000000 --- a/Samples/Gtk3/GtkApp/SimpleCommand.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Windows.Input; - -namespace GtkApp -{ - public class SimpleCommand : ICommand - { - public event EventHandler? CanExecuteChanged; - - private bool canExecute; - private readonly Action callback; - - public SimpleCommand(Action callback) - { - this.callback = callback ?? throw new ArgumentNullException(nameof(callback)); - } - - public bool CanExecute(object? parameter) => canExecute; - public void SetCanExecute(bool canExecute) - { - this.canExecute = canExecute; - OnCanExecuteChanged(); - } - - protected void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty); - public void Execute(object parameter) => callback(parameter); - } -} diff --git a/Samples/Gtk3/GtkApp/box.glade b/Samples/Gtk3/GtkApp/box.glade deleted file mode 100644 index b4e10d0a9..000000000 --- a/Samples/Gtk3/GtkApp/box.glade +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - True - False - vertical - - - True - False - Label 1 - - - False - True - 0 - - - - - True - False - Label 2 - - - False - True - 1 - - - - - True - False - Label 3 - - - False - True - 2 - - - - diff --git a/Samples/Gtk3/GtkApp/combobox.glade b/Samples/Gtk3/GtkApp/combobox.glade deleted file mode 100644 index ec6772425..000000000 --- a/Samples/Gtk3/GtkApp/combobox.glade +++ /dev/null @@ -1,9 +0,0 @@ - - - - - Test 1 - Test 2 - - - \ No newline at end of file diff --git a/Samples/Gtk3/GtkApp/menu.glade b/Samples/Gtk3/GtkApp/menu.glade deleted file mode 100644 index bb36ba20d..000000000 --- a/Samples/Gtk3/GtkApp/menu.glade +++ /dev/null @@ -1,18 +0,0 @@ - - - -
- - Do - app.do - -
-
- My section - - Do even more - app.domore - -
-
-
\ No newline at end of file diff --git a/Samples/Gtk3/GtkApp/test.html b/Samples/Gtk3/GtkApp/test.html deleted file mode 100644 index c9285038d..000000000 --- a/Samples/Gtk3/GtkApp/test.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - abc - - - - Halloaa - - - - - \ No newline at end of file diff --git a/Samples/Gtk3/GtkApp/ui.glade b/Samples/Gtk3/GtkApp/ui.glade deleted file mode 100644 index 3b69b0a57..000000000 --- a/Samples/Gtk3/GtkApp/ui.glade +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - False - My pretty window - - - - - - True - False - vertical - - - Button - True - True - True - - - - False - True - 0 - - - - - - - - - diff --git a/Samples/Gtk3/QuickStart/Program.cs b/Samples/Gtk3/QuickStart/Program.cs index 8db813358..33dff7a9a 100644 --- a/Samples/Gtk3/QuickStart/Program.cs +++ b/Samples/Gtk3/QuickStart/Program.cs @@ -1,5 +1,4 @@ using Gtk; -using Global = Gtk.Global; namespace GtkDemo { @@ -22,10 +21,10 @@ public static class Program // Entry Point public static void Main(string[] args) { - // We need to call Gtk.Global.Init() before using + // We need to call Gtk.Functions.Init() before using // any Gtk widgets or functions. If you use Gtk.Application, // this is done for you. - Global.Init(); + Functions.Init(); // Gir.Core supports Object Initialiser Syntax for every widget, // allowing for entire widget trees to be created using a nice, @@ -45,8 +44,8 @@ public static void Main(string[] args) [Notebook.SwitchPageSignal] = OnPageSwitched, // Add some widgets to the notebook - ["Page1"] = new Label("Hello C#"), - ["Page2"] = new Button("Open") + ["Page 0"] = Label.New("Hello C#"), + ["Page 1"] = new Button("Open") { // Register a callback for the button [Button.ClickedSignal] = OnOpenButtonClick, @@ -56,7 +55,7 @@ public static void Main(string[] args) // Setup our application to quit when the main // window is closed. We can use delegates as well as // ordinary methods for signal callbacks. - [Window.DestroySignal] = (o, e) => Global.MainQuit() + [Window.DestroySignal] = (o, e) => Functions.MainQuit() }; // Show our window. In Gtk3, widgets are hidden by default. @@ -67,7 +66,7 @@ public static void Main(string[] args) // Call Gtk.Global.Main() to start our application // main loop. The program will keep on running until // Gtk.Global.MainQuit() is called. - Global.Main(); + Functions.Main(); // Finally, clean up after ourselves and dispose of the // window widget. This is not required, but it is good diff --git a/Samples/Gtk3/TextEditor/Application/AppWindow.cs b/Samples/Gtk3/TextEditor/Application/AppWindow.cs new file mode 100644 index 000000000..a6914dc0e --- /dev/null +++ b/Samples/Gtk3/TextEditor/Application/AppWindow.cs @@ -0,0 +1,99 @@ +using System; +using Gtk; + +namespace TextEditor.Application +{ + using Document; + + public class AppWindow : Gtk.ApplicationWindow + { + const string WindowTitle = "Editor"; + + private Paned contentPaned; + private Entry insertEntry; + private SpinButton spinButton; + private DocumentView documentView; + + public Document Document { get; set; } + + public AppWindow() + { + this.DefaultWidth = 800; + this.DefaultHeight = 600; + + // Create UI + var headerBar = HeaderBar.New(); + headerBar.ShowCloseButton = true; + headerBar.Title = WindowTitle; + this.SetTitlebar(headerBar); + this.SetDecorated(true); + + // About Dialog Button + var aboutButton = new Button("About"); + aboutButton.Image = Image.NewFromIconName("dialog-information-symbolic", IconSize.Button); + aboutButton.AlwaysShowImage = true; + aboutButton.OnClicked += (_, _) => + { + // This is implemented in the 'AboutDialog' sample. You can + // safely substitute it for the built-in GTK AboutDialog. + var dlg = new AboutDialog.SampleDialog("Text Editor"); + + dlg.SetTransientFor(this); + dlg.SetModal(true); + dlg.Present(); + }; + headerBar.PackEnd(aboutButton); + + // Inspector Button + var inspectButton = new Button("Inspector"); + inspectButton.Image = Image.NewFromIconName("edit-find-symbolic", IconSize.Button); + inspectButton.AlwaysShowImage = true; + inspectButton.OnClicked += (_, _) => + { + SetInteractiveDebugging(true); + }; + headerBar.PackEnd(inspectButton); + + // Main Content Pane + contentPaned = Paned.New(Orientation.Vertical); + this.Child = contentPaned; + + // Start by creating a document + Document = Document.NewFromString("The quick brown fox jumps over the lazy dog."); + documentView = new DocumentView(Document); + + var display = new PieceTableDisplay(Document); + + // Paned + contentPaned.Add1(documentView); + contentPaned.Add2(display); + contentPaned.Position = 400; + + // Set visible + headerBar.ShowAll(); + contentPaned.ShowAll(); + } + + void UpdateCursor() + { + var value = Math.Clamp((int)spinButton.GetValue(), 0, Int32.MaxValue-1); + documentView.SetCursorIndex(value); + } + + void Insert(Button button, EventArgs args) + { + var index = spinButton.GetValue(); + var text = insertEntry.GetText(); + Document.Insert((int)index, text); + + // Move cursor to end of insertion + spinButton.Value += text.Length; + } + + void Delete(Button button, EventArgs args) + { + var index = (int)spinButton.GetValue(); + Document.Delete(index, 1); + } + } +} diff --git a/Samples/Gtk3/TextEditor/Application/DocumentView.cs b/Samples/Gtk3/TextEditor/Application/DocumentView.cs new file mode 100644 index 000000000..10af35fbf --- /dev/null +++ b/Samples/Gtk3/TextEditor/Application/DocumentView.cs @@ -0,0 +1,171 @@ +using System; +using System.Text; +using System.Diagnostics; +using Gtk; + +using cairo; +using Gdk; +using Pango; + +namespace TextEditor.Application +{ + using Document; + + public class DocumentView : Gtk.Bin + { + private Document doc; + private int cursorIndex; + + private string cachedText; + + private EventBox eventBox; + + private DrawingArea area; + + private IMContext context; + + public DocumentView(Document document) + { + // Setup IMContext + context = IMContextSimple.New(); + context.OnCommit += OnEnterText; + + // Add event box to catch keyboard input + eventBox = EventBox.New(); + eventBox.OnKeyPressEvent += OnKeydown; + eventBox.CanFocus = true; + eventBox.OnRealize += (o, e) => context.SetClientWindow(eventBox.GetWindow()); + Child = eventBox; + + // Drawing area to display rich text + area = DrawingArea.New(); + area.OnDraw += Render; + eventBox.Child = area; + + // Load data + SetDocument(document); + + ShowAll(); + } + + public void SetDocument(Document document) + { + doc = document; + doc.DocumentChanged += OnDocumentChanged; + + UpdateCache(); + Redraw(); + + cursorIndex = 0; + } + + public void SetCursorIndex(int index) + { + cursorIndex = Math.Clamp(index, 0, cachedText.Length); + Redraw(); + } + + public void CloseDocument() + { + doc = null; + cursorIndex = 0; + cachedText = null; + } + + private void OnDocumentChanged(object sender, EventArgs e) + { + // The document has been modified - redraw + // TODO: Redraw the currently on-screen section only + Debug.Assert(sender == doc); + UpdateCache(); + Redraw(); + } + + private void OnKeydown(object sender, KeyPressEventSignalArgs e) + { + Console.WriteLine("Keydown " + e.@event.Keyval); + + var keyVal = e.@event.Keyval; + + if (keyVal == Gdk.Constants.KEY_Left) + { + cursorIndex = Math.Clamp(cursorIndex - 1, 0, cachedText.Length); + Redraw(); + } + else if (keyVal == Gdk.Constants.KEY_Right) + { + cursorIndex = Math.Clamp(cursorIndex + 1, 0, cachedText.Length); + Redraw(); + } + else if (keyVal == Gdk.Constants.KEY_BackSpace) + doc.Delete(Math.Clamp(cursorIndex - 1, 0, cachedText.Length), 1); + else + context.FilterKeypress(e.@event); // Check result? + } + + private void OnEnterText(object sender, IMContext.CommitSignalArgs e) + { + doc.Insert(cursorIndex, e.Str); + cursorIndex += e.Str.Length; + } + + private void UpdateCache() + { + var builder = new StringBuilder(); + + // Assemble the document + foreach (Node textSpan in doc.Contents) + builder.Append(doc.RenderNode(textSpan)); + + cachedText = builder.ToString(); + } + + private void Redraw() + { + // textLayout.LabelProp = cachedText.Insert(cursorIndex, "|"); + area.QueueDraw(); + } + + private void Render(object sender, DrawingArea.DrawSignalArgs e) + { + Debug.Assert(area == sender); + + int xDist = 30; + int yDist = 100; + + cairo.Context cr = e.Cr; + + // Fill background + cr.SetSourceRgba(1,1,1,1); + cr.Rectangle(0, 0, GetAllocatedWidth(), GetAllocatedHeight()); + cr.Fill(); + + // Write Info Text + cr.SetSourceRgba(0,0,0,1.0); + cr.MoveTo(xDist, 30); + cr.ShowText("This sample uses Cairo and a Gtk.DrawingArea to create a simple 'TextView' clone."); + cr.MoveTo(xDist, 50); + cr.ShowText("Use the LEFT and RIGHT arrow keys to navigate."); //"Press BACKSPACE to delete."); + + // Draw Cursor + cr.SetFontSize(16); + + cr.TextExtents(cachedText, out TextExtents lineExtents); + var height = lineExtents.height; + + cr.TextExtents(cachedText.Substring(0, cursorIndex), out TextExtents cursorExtents); + var xPos = cursorExtents.width; + + cr.FontExtents(out FontExtents fontExtents); + + cr.SetSourceRgba(1.0, 0, 0, 1.0); + cr.Rectangle(xDist + cursorExtents.xAdvance - 0.5, yDist + fontExtents.Descent, 1, -(fontExtents.Descent + fontExtents.Ascent)); + cr.Fill(); + + // Draw Text from Buffer + cr.MoveTo(xDist, yDist); + cr.SetSourceRgba(0, 0, 0, 1.0); + cr.ShowText(cachedText); + } + } +} diff --git a/Samples/Gtk3/TextEditor/Application/PieceTableDisplay.cs b/Samples/Gtk3/TextEditor/Application/PieceTableDisplay.cs new file mode 100644 index 000000000..b412b7dcc --- /dev/null +++ b/Samples/Gtk3/TextEditor/Application/PieceTableDisplay.cs @@ -0,0 +1,95 @@ +using cairo; +using Gtk; + +namespace TextEditor.Application +{ + using Document; + + public class PieceTableDisplay : Bin + { + private Document doc; + private DrawingArea drawingArea; + public PieceTableDisplay(Document document) + { + doc = document; + doc.DocumentChanged += (_,_) => QueueDraw(); + + drawingArea = DrawingArea.New(); + drawingArea.OnDraw += Render; + Child = drawingArea; + ShowAll(); + } + + private void Render(object sender, DrawSignalArgs args) + { + Context cr = args.Cr; + + double xPos = 40; + double yPos = 120; + int padding = 5; + + RenderHeading(cr, xPos); + + cr.FontExtents(out FontExtents fontExtents); + cr.SetFontSize(14); + + double position = xPos; + foreach (Node node in doc.Contents) + { + // Get text for node + string text = doc.RenderNode(node); + + // DRAW: Buffer Rectangle + cr.MoveTo(position, yPos); + + cr.TextExtents(text, out TextExtents lineExtents); + var length = lineExtents.xAdvance; + var height = fontExtents.Height; + + // Set colour + if (node.location == BufferType.File) + cr.SetSourceRgba(1, 0, 0, 1); + else + cr.SetSourceRgba(0, 0, 1, 1); + + cr.Rectangle(position, yPos + fontExtents.Descent, length, height); + cr.Fill(); + + // DRAW: Buffer Text + cr.MoveTo(position, yPos); + cr.SetSourceRgba(0,0,0,1); + cr.ShowText(text); + + // Move to next position - TODO: line wrap? + position += length + padding; + } + } + + private void RenderHeading(Context cr, double xPos) + { + cr.MoveTo(xPos, 30); + cr.SetFontSize(16); + cr.ShowText("Piece Table Visualisation"); + + // Red Square + cr.SetSourceRgba(1,0,0,1); + cr.Rectangle(xPos, 50, 10, -10); + cr.Fill(); + + // Blue Square + cr.SetSourceRgba(0,0,1,1); + cr.Rectangle(xPos, 70, 10, -10); + cr.Fill(); + + // Labels + cr.SetFontSize(10); + cr.SetSourceRgba(0,0,0,1); + + cr.MoveTo(xPos + 12, 50); + cr.ShowText("File Buffer"); + + cr.MoveTo(xPos + 12, 70); + cr.ShowText("Add Buffer"); + } + } +} diff --git a/Samples/Gtk3/TextEditor/Document/Buffer.cs b/Samples/Gtk3/TextEditor/Document/Buffer.cs new file mode 100644 index 000000000..56cbf7c16 --- /dev/null +++ b/Samples/Gtk3/TextEditor/Document/Buffer.cs @@ -0,0 +1,34 @@ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace TextEditor.Document +{ + public abstract class Buffer + { + protected string _data = string.Empty; + + public string GetString(int index, int length) + => _data.Substring(index, length); + } + + public class ReadOnlyBuffer : Buffer + { + public ReadOnlyBuffer(string initData) + => _data = initData; + } + + public class AppendBuffer : Buffer + { + public AppendBuffer() {} + + public int Append(string text) + { + var index = _data.Length; + _data += text; + + return index; + } + } +} diff --git a/Samples/Gtk3/TextEditor/Document/Document.cs b/Samples/Gtk3/TextEditor/Document/Document.cs new file mode 100644 index 000000000..c89e5726b --- /dev/null +++ b/Samples/Gtk3/TextEditor/Document/Document.cs @@ -0,0 +1,196 @@ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace TextEditor.Document +{ + /// + /// A document is a representation of one single text buffer. It + /// may be up to 2GB in size (approximately 1 billion characters), + /// which is the maximum limit of the C# String data type. + /// + public class Document + { + // See: https://web.archive.org/web/20180223071931/https://www.cs.unm.edu/~crowley/papers/sds.pdf + // This paper demonstrates the piece-table based data structure used to store the + // document's text and subsequent modifications. + + public IEnumerable Contents => pieceTable; + + public event EventHandler DocumentChanged = default!; + + + private PieceTable pieceTable; + private ReadOnlyBuffer fileBuffer; + private AppendBuffer addBuffer; + + private (Node desc, int baseIndex) FromIndex(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(); + + var curIndex = 0; + + foreach (Node span in pieceTable) + { + curIndex += span.length; + + if (curIndex > index) + return (span, curIndex - span.length); + } + + // We might be the final element -> in which case, create a new descriptor? + + return (null, -1); // throw new IndexOutOfRangeException(); + } + + private Buffer GetBufferForNode(Node span) + => span.location == BufferType.Add + ? addBuffer + : fileBuffer; + + public string RenderNode(Node span) + => GetBufferForNode(span).GetString(span.offset, span.length); + + public string GetContents() + { + var builder = new StringBuilder(); + + foreach (Node piece in pieceTable) + builder.Append(RenderNode(piece)); + + return builder.ToString(); + } + + private Node CreateSpan(string text) + { + var index = addBuffer.Append(text); + return new Node(BufferType.Add, index, text.Length); + } + + public void Insert(int index, string text) + { + if (string.IsNullOrEmpty(text)) + return; + + if (index < 0) + throw new IndexOutOfRangeException(); + + // Create a new entry into the add buffer + var insertSpan = CreateSpan(text); + + // Find the piece which contains the cursor index + var (currentSpan, baseIndex) = FromIndex(index); + + + // Case 1: If the current span is null, append to the end + // of the document and return. + if (currentSpan == null) + { + pieceTable.AddLast(insertSpan); + DocumentChanged(this, EventArgs.Empty); + return; + } + + // Case 2: If we are at the start boundary, we can simply + // insert at the beginning and return. // TODO: Multiple insertions + if (index - baseIndex == 0) + { + pieceTable.AddBefore(currentSpan, insertSpan); + DocumentChanged(this, EventArgs.Empty); + return; + } + + // Case 3: We split the current span into three. The contents of the + // span up to the insertion point, the insertion itself, and + // the remainder of the span after the insertion. + + // Find the index at which to split, relative to the + // start of the current piece. + var insertionOffset = index - baseIndex; + + // We have one piece |current| + var startLength = insertionOffset; + var endLength = currentSpan.length - startLength; + + // Split into |start| |end| + var startSpan = new Node(currentSpan.location, currentSpan.offset, startLength); + var endSpan = new Node(currentSpan.location, currentSpan.offset + insertionOffset, endLength); + + // Insert so we have three pieces: |start| |insertion| |end| + pieceTable.AddAfter(currentSpan, endSpan); + pieceTable.AddAfter(currentSpan, insertSpan); + pieceTable.Replace(currentSpan, startSpan); + + DocumentChanged(this, EventArgs.Empty); + } + + public void Delete(int index, int length) + { + // NOTE: Deletion is disabled as it cannot delete across piece + // boundaries. This should be implemented so the text editor is + // fully functional. + + /*var (deleteStartDesc, deleteStartNodeBaseIndex) = FromIndex(index); + + // Cannot delete from the end of the sequence + if (deleteStartDesc == null) + return; + + if (length < deleteStartDesc.length) + { + var internalOffset = index - deleteStartNodeBaseIndex; + if (internalOffset == 0) + { + // Simple case + var newLength = (deleteStartDesc.length - length); + var newOffset = deleteStartDesc.offset + length; + pieceTable.Replace(deleteStartDesc, new Node(deleteStartDesc.location, newOffset, newLength)); + } + else + { + // Split into two + + // Create new + var newLength = deleteStartDesc.length - length - internalOffset; + var addOffset = addBuffer.Append(GetBufferForNode(deleteStartDesc).GetString(internalOffset + length, newLength)); + var newDesc = new Node(BufferType.Add, addOffset, newLength); + pieceTable.AddAfter(deleteStartDesc, newDesc); + + // Resize original + var resizeLength = internalOffset; + pieceTable.Replace(deleteStartDesc, new Node(deleteStartDesc.location, deleteStartDesc.offset, resizeLength)); + } + } + else + { + // Complex case - not supported yet + throw new NotImplementedException("Cannot delete across piece boundaries yet"); + } + + // Emit document-changed event + DocumentChanged(this, EventArgs.Empty);*/ + } + + private Document(string data) + { + // Initialise + fileBuffer = new ReadOnlyBuffer(data); + addBuffer = new AppendBuffer(); + pieceTable = new(); + + pieceTable.AddFirst(new Node(BufferType.File, 0, data.Length)); + } + + public static Document New() => new Document(string.Empty); + public static Document NewFromString(string data) => new Document(data); + + public static Document NewFromFile(FileInfo fileInfo) + { + var contents = fileInfo.OpenRead().ToString(); + + return new Document(contents); + } + } +} diff --git a/Samples/Gtk3/TextEditor/Document/Node.cs b/Samples/Gtk3/TextEditor/Document/Node.cs new file mode 100644 index 000000000..0ffa7954c --- /dev/null +++ b/Samples/Gtk3/TextEditor/Document/Node.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace TextEditor.Document +{ + public enum BufferType : byte + { + // For guard nodes + None, + + // Original file buffer + File, + + // Append-only add buffer + Add + }; + + // Also called: Span, Piece, Descriptor, etc + public class Node + { + internal Node? Next { get; set; } + + internal Node? Prev { get; set; } + + internal BufferType location { get; init; } + internal int offset { get; init; } + internal int length { get; init; } + + public Node(BufferType location, int offset, int length) + { + this.location = location; + this.offset = offset; + this.length = length; + } + + internal static Node CreateGuardNode() + => new Node(BufferType.None, 0, 0); + } +} diff --git a/Samples/Gtk3/TextEditor/Document/PieceTable.cs b/Samples/Gtk3/TextEditor/Document/PieceTable.cs new file mode 100644 index 000000000..5f898ce61 --- /dev/null +++ b/Samples/Gtk3/TextEditor/Document/PieceTable.cs @@ -0,0 +1,159 @@ +using System; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; + +namespace TextEditor.Document +{ + internal class PieceTable : IEnumerable + { + // See: https://www.catch22.net/tuts/piece-chains + // Also: https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation + + // These two are "sentinel" nodes which + // do not store or point to data + private readonly Node head; + private readonly Node tail; + + internal class BoundaryException : Exception {} + + public PieceTable() + { + head = Node.CreateGuardNode(); + tail = Node.CreateGuardNode(); + + head.Next = tail; + tail.Prev = head; + } + + private void CheckGuardNode(Node node) + { + if (node == head || node == tail) + throw new BoundaryException(); + } + + public void AddAfter(Node current, Node insert) + { + CheckGuardNode(current); + CheckGuardNode(insert); + + // [Current] [After] -> [Current] [Insert] [After] + + Node after = current.Next; + + insert.Next = after; + insert.Prev = current; + + current.Next = insert; + after!.Prev = insert; + } + + public void AddBefore(Node current, Node insert) + { + CheckGuardNode(current); + CheckGuardNode(insert); + + // [Before] [Current] -> [Before] [Insert] [Current] + + Node before = current.Prev; + + insert.Prev = before; + insert.Next = current; + + before!.Next = insert; + current.Prev = insert; + } + + public void AddFirst(Node insert) + { + CheckGuardNode(insert); + + // [Head Sentinel] [After] -> [Head Sentinel] [Insert] [After] + + Node after = head.Next; + + insert.Next = after; + insert.Prev = head; + + head.Next = insert; + after!.Prev = insert; + } + + public void AddLast(Node insert) + { + CheckGuardNode(insert); + + // [Before] [Tail Sentinel] -> [Before] [Insert] [Tail Sentinel] + + Node before = tail.Prev; + + insert.Next = tail; + insert.Prev = before; + + tail.Prev = insert; + before!.Next = insert; + } + + public void Replace(Node old, Node replace) + { + CheckGuardNode(old); + CheckGuardNode(replace); + + // [Before] [Old] [After] -> [Before] [Replace] [After] + + Node before = old.Prev; + Node after = old.Next; + + replace.Prev = before; + replace.Next = after; + + before!.Next = replace; + after!.Prev = replace; + } + + public void Remove(Node remove) + { + CheckGuardNode(remove); + + // [Before] [Remove] [After] -> [Before] [After] + + Node before = remove.Prev; + Node after = remove.Next; + + before!.Next = after; + after!.Prev = before; + } + + // Implement IEnumerable + public IEnumerator GetEnumerator() + { + var nodes = new List(); + var cur = head; + while (cur != null) + { + nodes.Add(cur); + cur = cur.Next; + + // We have traversed the entire list + if (cur == null) + break; + + // Check for broken linked list -> Abort + Debug.Assert( + condition: cur.Prev != null, + message: "Linked list has missing previous element. It may be broken" + ); + } + + nodes.Remove(head); + nodes.Remove(tail); + + return nodes.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + } +} diff --git a/Samples/Gtk3/TextEditor/Program.cs b/Samples/Gtk3/TextEditor/Program.cs new file mode 100644 index 000000000..4899281eb --- /dev/null +++ b/Samples/Gtk3/TextEditor/Program.cs @@ -0,0 +1,29 @@ +using System; +using GObject; +using Gtk; + +namespace TextEditor +{ + using Application; + + public class App : Gtk.Application + { + const string AppName = "org.gircore.TextEditor"; + + public App() + { + this.ApplicationId = AppName; + this.OnActivate += Activate; + } + + private void Activate(object app, EventArgs args) + { + var window = new AppWindow(); + window.Application = this; + window.Present(); + } + + static int Main(string[] args) + => new App().Run(); + } +} diff --git a/Samples/Gtk3/TextEditor/README.md b/Samples/Gtk3/TextEditor/README.md new file mode 100644 index 000000000..4f55d2787 --- /dev/null +++ b/Samples/Gtk3/TextEditor/README.md @@ -0,0 +1,4 @@ +# TextEditor Demo +A more complex sample demonstrating how GTK and Cairo can be used +together to create a simple re-implementation of GtkTextView from +scratch. \ No newline at end of file diff --git a/Samples/Gtk3/TextEditor/TextEditor.csproj b/Samples/Gtk3/TextEditor/TextEditor.csproj new file mode 100644 index 000000000..c3b483e45 --- /dev/null +++ b/Samples/Gtk3/TextEditor/TextEditor.csproj @@ -0,0 +1,13 @@ + + + + Exe + net5.0 + + + + + + + + diff --git a/Samples/Gtk4/SimpleWindow/Program.cs b/Samples/Gtk4/SimpleWindow/Program.cs deleted file mode 100644 index 2842b9901..000000000 --- a/Samples/Gtk4/SimpleWindow/Program.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using Gtk; - -namespace Gtk4Demo -{ - public class Program - { - public static void Main(string[] args) - { - var app = new Program(); - } - - public Program() - { - var app = new Application("org.gircore.minimal"); - app.Activate += OnActivate; - app.Run(); - } - - private void OnActivate(object? sender, EventArgs args) - { - if(sender is Application app) - { - var w = new ApplicationWindow(app); - w.DefaultHeight.Value = 600; - w.DefaultWidth.Value = 800; - - var box = new Box(); - w.SetChild(box); - - var button = new Button("Hello Gtk4"); - button.Clicked += (sender, args) => Console.WriteLine("Hello dear user"); - - box.Append(button); - w.Show(); - } - } - } -} diff --git a/Samples/Gtk4/SimpleWindow/SimpleWindow.csproj b/Samples/Gtk4/SimpleWindow/SimpleWindow.csproj deleted file mode 100644 index 94a20c9b6..000000000 --- a/Samples/Gtk4/SimpleWindow/SimpleWindow.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - Exe - net5.0 - enable - - - diff --git a/Tests/Libs/GObject-2.0.Tests/Records/ValueTest.cs b/Tests/Libs/GObject-2.0.Tests/Records/ValueTest.cs index 3fa9caf5b..105bf9d5d 100644 --- a/Tests/Libs/GObject-2.0.Tests/Records/ValueTest.cs +++ b/Tests/Libs/GObject-2.0.Tests/Records/ValueTest.cs @@ -1,4 +1,6 @@ -using FluentAssertions; +using System; +using System.Runtime.InteropServices; +using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace GObject.Tests @@ -15,5 +17,19 @@ public void ValueFromDataShouldContainGivenData(object data) var v = Value.From(data); v.Extract().Should().Be(data); } + + [TestMethod] + public void ValueReturnsExpectedType() + { + // Check that we have a value + var v = Value.From("Hello"); + Native.Functions.TypeCheckValue(v.Handle).Should().Be(true); + + // Check we can marshal as a struct + Native.Value.Struct str = Marshal.PtrToStructure(v.Handle.DangerousGetHandle()); + Native.Functions.TypeCheckValueHolds(v.Handle, str.GType); + Native.Functions.TypeCheckValueHolds(v.Handle, (nuint)Native.BasicType.String); + str.GType.Should().Be((nuint) Native.BasicType.String); + } } } diff --git a/Tests/Libs/GdkPixbuf-2.0.Tests/GdkPixbuf-2.0.Tests.csproj b/Tests/Libs/GdkPixbuf-2.0.Tests/GdkPixbuf-2.0.Tests.csproj new file mode 100644 index 000000000..ba457085c --- /dev/null +++ b/Tests/Libs/GdkPixbuf-2.0.Tests/GdkPixbuf-2.0.Tests.csproj @@ -0,0 +1,15 @@ + + + GdkPixbuf.Tests + + + + + + + + + PreserveNewest + + + diff --git a/Tests/Libs/GdkPixbuf-2.0.Tests/MemoryManagementTest.cs b/Tests/Libs/GdkPixbuf-2.0.Tests/MemoryManagementTest.cs new file mode 100644 index 000000000..62c67b0ed --- /dev/null +++ b/Tests/Libs/GdkPixbuf-2.0.Tests/MemoryManagementTest.cs @@ -0,0 +1,63 @@ +using System; +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace GdkPixbuf.Tests +{ + [TestClass, TestCategory("IntegrationTest")] + public class MemoryManagementTest + { + [TestMethod] + public void TestAutomaticGObjectDisposal() + { + WeakReference weakReference = new(null); + IDisposable? strongReference = null; + + void CreateInstance(bool keepInstance) + { + var obj = Pixbuf.NewFromFile("test.bmp"); + + GObject.Native.ObjectMapper.ObjectCount.Should().Be(1); + + if(keepInstance) + strongReference = obj; + + weakReference.Target = obj; + } + + CreateInstance(keepInstance: false); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + GObject.Native.ObjectMapper.ObjectCount.Should().Be(0); + weakReference.IsAlive.Should().BeFalse(); + strongReference.Should().BeNull(); + + CreateInstance(keepInstance: true); + GC.Collect(); + GC.WaitForPendingFinalizers(); + GObject.Native.ObjectMapper.ObjectCount.Should().Be(1); + weakReference.IsAlive.Should().BeTrue(); + strongReference.Should().NotBeNull(); + + // Cleanup: Dispose for other tests to work properly + // It looks like the GC is not collecting the ObjectMapper data + // if the GC.Collect() call is happening in the method which + // contains the reference to be freed. There must be a context + // switch before disposal happens. + // This is the reason why we need to use the "CreateInstance" + // method to create the instances which should be freed. + // This behaviour is verified on Linux. + strongReference.Dispose(); + } + + [TestMethod] + public void TestManualGObjectDisposal() + { + var obj = Pixbuf.NewFromFile("test.bmp"); + GObject.Native.ObjectMapper.ObjectCount.Should().Be(1); + obj.Dispose(); + GObject.Native.ObjectMapper.ObjectCount.Should().Be(0); + } + } +} diff --git a/Tests/Libs/GdkPixbuf-2.0.Tests/PropertyTest.cs b/Tests/Libs/GdkPixbuf-2.0.Tests/PropertyTest.cs new file mode 100644 index 000000000..9e815842f --- /dev/null +++ b/Tests/Libs/GdkPixbuf-2.0.Tests/PropertyTest.cs @@ -0,0 +1,19 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace GdkPixbuf.Tests +{ + [TestClass, TestCategory("IntegrationTest")] + public class PropertyTests + { + [TestMethod] + public void ReadPropertyTest() + { + var pixbuf = Pixbuf.NewFromFile("test.bmp"); + pixbuf.GetWidth().Should().Be(500); + pixbuf.GetHeight().Should().Be(500); + pixbuf.GetHasAlpha().Should().Be(false); + pixbuf.GetNChannels().Should().Be(3); + } + } +} diff --git a/Tests/Libs/GdkPixbuf-2.0.Tests/test.bmp b/Tests/Libs/GdkPixbuf-2.0.Tests/test.bmp new file mode 100644 index 000000000..c599257f5 Binary files /dev/null and b/Tests/Libs/GdkPixbuf-2.0.Tests/test.bmp differ