From 7648593a6718b128b8a79352028be533cedd64b7 Mon Sep 17 00:00:00 2001 From: Rachel Hestilow Date: Fri, 2 Aug 2002 22:35:23 +0000 Subject: [PATCH] 2002-08-02 Rachel Hestilow [ Mike, this is everything I wanted in for the release. ] * generator/StructBase.cs: Generate field accessors for wrapped types (opaque, object, and structs/boxed). Bitfields, unions, and arrays are still unsupported for accessors, and are probably marshalling incorrectly. But this is enough to get events working (see example in sample/GnomeHelloWorld.cs). * parser/Metadata.pm: Support a "delete" directive, and set metadata on structs and boxed (previously was only checking objects and interfaces). * parser/Gdk.metadata: Delete bogus entries GdkWindowObject and GdkPixmapObject (more evil drawable stuff.) * sample/GnomeHelloWorld.cs: Show an example of how to use marshalled events, in our selection callback. svn path=/trunk/gtk-sharp/; revision=6370 --- ChangeLog | 19 +++++++++++++++++++ generator/StructBase.cs | 33 +++++++++++++++++++++++++++++---- generator/gtkapi.xml | 37 ++----------------------------------- parser/GAPI/Metadata.pm | 13 ++++++++++--- parser/Gdk.metadata | 9 +++++++++ parser/Metadata.pm | 13 ++++++++++--- sample/GnomeHelloWorld.cs | 10 ++++++++-- sources/Gdk.metadata | 9 +++++++++ 8 files changed, 96 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 962e4781f..2973786df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2002-08-02 Rachel Hestilow + + [ Mike, this is everything I wanted in for the release. ] + + * generator/StructBase.cs: Generate field accessors for wrapped + types (opaque, object, and structs/boxed). Bitfields, unions, and + arrays are still unsupported for accessors, and are probably marshalling + incorrectly. But this is enough to get events working (see example + in sample/GnomeHelloWorld.cs). + + * parser/Metadata.pm: Support a "delete" directive, and set metadata + on structs and boxed (previously was only checking objects and interfaces). + + * parser/Gdk.metadata: Delete bogus entries GdkWindowObject and + GdkPixmapObject (more evil drawable stuff.) + + * sample/GnomeHelloWorld.cs: Show an example of how to use marshalled + events, in our selection callback. + 2002-07-31 Rachel Hestilow * generator/StructBase.cs (GetFieldInfo): Generate strings correctly. diff --git a/generator/StructBase.cs b/generator/StructBase.cs index 1e714be30..92002e356 100644 --- a/generator/StructBase.cs +++ b/generator/StructBase.cs @@ -108,10 +108,10 @@ namespace GtkSharp.Generation { } } - protected bool GetFieldInfo (XmlElement field, out string type, out string name) + protected bool GetFieldInfo (XmlElement field, out string c_type, out string type, out string name) { name = ""; - string c_type = field.GetAttribute ("type"); + c_type = field.GetAttribute ("type"); type = SymbolTable.GetCSType (c_type); if (IsBit (field)) { type = "uint"; @@ -141,10 +141,35 @@ namespace GtkSharp.Generation { protected bool GenField (XmlElement field, StreamWriter sw) { - string type, name; - if (!GetFieldInfo (field, out type, out name)) + string c_type, type, name; + if (!GetFieldInfo (field, out c_type, out type, out name)) return false; sw.WriteLine ("\t\tpublic {0} {1};", type, name); + + if (field.HasAttribute("array_len")) + Console.WriteLine ("warning: array field {0}.{1} probably incorrectly generated", QualifiedName, name); + + string wrapped = SymbolTable.GetCSType (c_type); + string wrapped_name = MangleName (field.GetAttribute ("cname")); + if (SymbolTable.IsObject (c_type) || SymbolTable.IsOpaque (c_type)) { + // FIXME: cut n paste code, remove after introspection completed + sw.WriteLine (); + sw.WriteLine ("\t\tpublic " + wrapped + " " + wrapped_name + " {"); + sw.WriteLine ("\t\t\tget { "); + sw.WriteLine ("\t\t\t\t" + wrapped + " ret = " + SymbolTable.FromNativeReturn(c_type, name) + ";"); + sw.WriteLine ("\t\t\t\tif (ret == null) ret = new " + wrapped + "(" + name + ");"); + sw.WriteLine ("\t\t\t\treturn ret;"); + sw.WriteLine ("\t\t\t}"); + + sw.WriteLine ("\t\t\tset { " + name + " = " + SymbolTable.CallByName (c_type, "value") + "; }"); + sw.WriteLine ("\t\t}"); + } else if (IsPointer (field) && (SymbolTable.IsStruct (c_type) || SymbolTable.IsBoxed (c_type))) { + sw.WriteLine (); + sw.WriteLine ("\t\tpublic " + wrapped + " " + wrapped_name + " {"); + sw.WriteLine ("\t\t\tget { return " + SymbolTable.FromNativeReturn (c_type, name) + "; }"); + sw.WriteLine ("\t\t}"); + } + return true; } diff --git a/generator/gtkapi.xml b/generator/gtkapi.xml index 8ceff75d2..1bfed827a 100644 --- a/generator/gtkapi.xml +++ b/generator/gtkapi.xml @@ -3565,11 +3565,6 @@ - - - - - @@ -3788,34 +3783,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -14556,7 +14523,7 @@ - + @@ -14679,7 +14646,7 @@ - + diff --git a/parser/GAPI/Metadata.pm b/parser/GAPI/Metadata.pm index 0e2c21695..973ebb259 100644 --- a/parser/GAPI/Metadata.pm +++ b/parser/GAPI/Metadata.pm @@ -46,6 +46,7 @@ sub parseData { my @attrs = $data_node->attributes; my $target = $attrs[0]->value; my ($filter_level, $filter_value, $attr_name, $attr_value); + my $directives = ""; for ($attr_node = $data_node->firstChild; $attr_node != undef; $attr_node = $attr_node->nextSibling ()) { if ($attr_node->nodeName eq "filter") { my @filter_attrs = $attr_node->attributes; @@ -55,9 +56,11 @@ sub parseData { $attr_name = $attr_node->firstChild->nodeValue; } elsif ($attr_node->nodeName eq "value") { $attr_value = $attr_node->firstChild->nodeValue; + } elsif ($attr_node->nodeName eq "delete") { + $directives = "delete"; } } - my @data_attr = ("attribute", $target, "filter", $filter_level, $filter_value, $attr_name, $attr_value); + my @data_attr = ("attribute", $target, "filter", $filter_level, $filter_value, $attr_name, $attr_value, $directives); push @data, \@data_attr; } @@ -144,12 +147,16 @@ sub addClassData { foreach $data (@$data_list_ref) { if ($$data[1] eq "class") { + if ($$data[7] eq "delete") { + my $parent = $node->parentNode; + $parent->removeChild ($node); + return; + } # my copy of XML::LibXML doesn't have this method. #my @nodes = $node->getChildrenByTagName ($$data[5]); my @nodes = myGetChildrenByTagName ($node, $$data[5]); if (0 == scalar @nodes) { - print STDERR "DEBUG> $class $$data[0] $$data[1] $$data[2] $$data[3] $$data[4] $$data[5] $$data[6]\n"; $node->setAttribute ($$data[5], $$data[6]); } next; @@ -163,7 +170,7 @@ sub fixupNamespace { foreach $rule (@{$self->{rules}}) { my ($classes_ref, $data_list_ref) = @$rule; for ($node = $ns_node->firstChild; $node; $node = $node->nextSibling ()) { - next if not ($node->nodeName eq "object" or $node->nodeName eq "interface"); + next if not ($node->nodeName eq "object" or $node->nodeName eq "interface" or $node->nodeName eq "struct" or $node->nodeName eq "boxed"); my $class, $methods_ref, $attr; foreach $attr ($node->attributes) { if ($attr->name eq "cname") { diff --git a/parser/Gdk.metadata b/parser/Gdk.metadata index 1d4b52cf0..a6f6aba27 100644 --- a/parser/Gdk.metadata +++ b/parser/Gdk.metadata @@ -54,5 +54,14 @@ + + + + + + + + + diff --git a/parser/Metadata.pm b/parser/Metadata.pm index 0e2c21695..973ebb259 100644 --- a/parser/Metadata.pm +++ b/parser/Metadata.pm @@ -46,6 +46,7 @@ sub parseData { my @attrs = $data_node->attributes; my $target = $attrs[0]->value; my ($filter_level, $filter_value, $attr_name, $attr_value); + my $directives = ""; for ($attr_node = $data_node->firstChild; $attr_node != undef; $attr_node = $attr_node->nextSibling ()) { if ($attr_node->nodeName eq "filter") { my @filter_attrs = $attr_node->attributes; @@ -55,9 +56,11 @@ sub parseData { $attr_name = $attr_node->firstChild->nodeValue; } elsif ($attr_node->nodeName eq "value") { $attr_value = $attr_node->firstChild->nodeValue; + } elsif ($attr_node->nodeName eq "delete") { + $directives = "delete"; } } - my @data_attr = ("attribute", $target, "filter", $filter_level, $filter_value, $attr_name, $attr_value); + my @data_attr = ("attribute", $target, "filter", $filter_level, $filter_value, $attr_name, $attr_value, $directives); push @data, \@data_attr; } @@ -144,12 +147,16 @@ sub addClassData { foreach $data (@$data_list_ref) { if ($$data[1] eq "class") { + if ($$data[7] eq "delete") { + my $parent = $node->parentNode; + $parent->removeChild ($node); + return; + } # my copy of XML::LibXML doesn't have this method. #my @nodes = $node->getChildrenByTagName ($$data[5]); my @nodes = myGetChildrenByTagName ($node, $$data[5]); if (0 == scalar @nodes) { - print STDERR "DEBUG> $class $$data[0] $$data[1] $$data[2] $$data[3] $$data[4] $$data[5] $$data[6]\n"; $node->setAttribute ($$data[5], $$data[6]); } next; @@ -163,7 +170,7 @@ sub fixupNamespace { foreach $rule (@{$self->{rules}}) { my ($classes_ref, $data_list_ref) = @$rule; for ($node = $ns_node->firstChild; $node; $node = $node->nextSibling ()) { - next if not ($node->nodeName eq "object" or $node->nodeName eq "interface"); + next if not ($node->nodeName eq "object" or $node->nodeName eq "interface" or $node->nodeName eq "struct" or $node->nodeName eq "boxed"); my $class, $methods_ref, $attr; foreach $attr ($node->attributes) { if ($attr->name eq "cname") { diff --git a/sample/GnomeHelloWorld.cs b/sample/GnomeHelloWorld.cs index 3a9a2915f..848e8f6a8 100644 --- a/sample/GnomeHelloWorld.cs +++ b/sample/GnomeHelloWorld.cs @@ -153,9 +153,15 @@ namespace GtkSamples { void icon_selected_cb (object obj, IconSelectedArgs args) { int idx = args.Num; - Event ev = args.Event; + Event ev_any = args.Event; + EventButton ev = EventButton.New (ev_any.Handle); - if (ev.IsValid && ev.Type == EventType.TwoButtonPress) { + // test the accessor, this is unnecessary in real code + Gdk.WindowType type = ev.window.WindowType; + if (type != Gdk.WindowType.Child) + Console.WriteLine ("Struct field accessors appear to be broken."); + + if (!ev.IsNull && ev.type == EventType.TwoButtonPress && ev.button == 1) { g_spawn_command_line_async ("mono " + entries[idx].program, IntPtr.Zero); } } diff --git a/sources/Gdk.metadata b/sources/Gdk.metadata index 1d4b52cf0..a6f6aba27 100644 --- a/sources/Gdk.metadata +++ b/sources/Gdk.metadata @@ -54,5 +54,14 @@ + + + + + + + + +