diff --git a/ChangeLog b/ChangeLog index a3d9d835d..d0d164dd9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-08-07 Mike Kestner + + * configure.in.in: add new dir and autofu for it. + * Makefile.am: add new dir + * gapi/*: a small extension method library to add generation-related + api to GType in 2.0. Access it with -pkg:gapi-2.0-compat to pick up + the needed refs. + * generator/GObjectVM.cs: generate new GType getter methods. + * generator/ObjectGen.cs: generate new GType getter methods. + * glib/GType.cs: change a few props to methods to make them extension + method friendly for 2.0 compat. + * glib/Object.cs: use new GType getter methods. + * glib/Value.cs: use new GType getter methods. + * gtk/Widget.custom: use new GetClassPtr method. + 2009-08-07 Mike Kestner * generator/ObjectGen.cs: kill GType ctor generation. diff --git a/Makefile.am b/Makefile.am index 3af68cce7..c4efb6d74 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = sources generator parser glib gio cairo pango atk gdk gtk glade gtkdotnet sample doc +SUBDIRS = sources generator parser gapi glib gio cairo pango atk gdk gtk glade gtkdotnet sample doc EXTRA_DIST = \ mono.snk \ diff --git a/configure.in.in b/configure.in.in index 8eb3f57b5..52b51edf8 100644 --- a/configure.in.in +++ b/configure.in.in @@ -167,6 +167,9 @@ AC_SUBST(GENERATED_SOURCES) PKG_CHECK_MODULES(MONO_CAIRO, mono-cairo >= $MONO_REQUIRED_VERSION, enable_mono_cairo=no, enable_mono_cairo=yes) AC_SUBST(MONO_CAIRO_LIBS) +PKG_CHECK_MODULES(GLIBSHARP2, glib-sharp-2.0, enable_glib2_compat=yes, enable_glib2_compat=no) +AC_SUBST(GLIBSHARP2_LIBS) + GTK_REQUIRED_VERSION=@GTK_REQUIRED_VERSION@ GLIB_REQUIRED_VERSION=@GLIB_REQUIRED_VERSION@ @@ -214,6 +217,7 @@ AM_CONDITIONAL(ENABLE_GLADE, test "x$enable_glade" = "xyes") AM_CONDITIONAL(ENABLE_DOTNET, test "x$enable_dotnet" = "xyes") AM_CONDITIONAL(ENABLE_MONODOC, test "x$enable_monodoc" = "xyes") AM_CONDITIONAL(ENABLE_MONOGETOPTIONS, test "x$has_mono" = "xtrue") +AM_CONDITIONAL(ENABLE_GLIBSHARP2_COMPAT, test "x$enable_glib2_compat" = "xyes") AC_SUBST(CFLAGS) @@ -228,6 +232,8 @@ parser/Makefile parser/gapi-3.0.pc parser/gapi3-fixup parser/gapi3-parser +gapi/Makefile +gapi/gapi-2.0-compat.pc generator/Makefile generator/gapi3-codegen glib/Makefile diff --git a/gapi/AssemblyInfo.cs b/gapi/AssemblyInfo.cs new file mode 100644 index 000000000..c24cc0ff0 --- /dev/null +++ b/gapi/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly:AssemblyVersion("3.0.0.0")] +[assembly:AssemblyDelaySign(false)] +[assembly:AssemblyKeyFile("gtk-sharp.snk")] diff --git a/gapi/GTypeExtensions.cs b/gapi/GTypeExtensions.cs new file mode 100644 index 000000000..dc3825b63 --- /dev/null +++ b/gapi/GTypeExtensions.cs @@ -0,0 +1,94 @@ +// Author: Mike Kestner +// +// Copyright (c) 2009 Novell, Inc. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the Lesser GNU General +// Public License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + + +using System; +using System.Runtime.InteropServices; + +namespace Gapi { + + public static class GTypeExtensions { + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_type_class_peek (IntPtr gtype); + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_type_class_ref (IntPtr gtype); + + public static IntPtr GetClassPtr (this GLib.GType gtype) + { + IntPtr klass = g_type_class_peek (gtype.Val); + if (klass == IntPtr.Zero) + klass = g_type_class_ref (gtype.Val); + return klass; + } + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_type_parent (IntPtr type); + + public static GLib.GType GetBaseType (this GLib.GType gtype) + { + IntPtr parent = g_type_parent (gtype.Val); + return parent == IntPtr.Zero ? GLib.GType.None : new GLib.GType (parent); + } + + public static GLib.GType GetThresholdType (this GLib.GType gtype) + { + GLib.GType curr = gtype; + while (curr.ToString ().StartsWith ("__gtksharp_")) + curr = GetBaseType (curr); + return curr; + } + + struct GTypeQuery { + public IntPtr type; + public IntPtr type_name; + public uint class_size; + public uint instance_size; + } + + [DllImport("libgobject-2.0-0.dll")] + static extern void g_type_query (IntPtr type, out GTypeQuery query); + + public static uint GetClassSize (this GLib.GType gtype) + { + GTypeQuery query; + g_type_query (gtype.Val, out query); + return query.class_size; + } + + static IntPtr ValFromInstancePtr (IntPtr handle) + { + if (handle == IntPtr.Zero) + return IntPtr.Zero; + + // First field of instance is a GTypeClass*. + IntPtr klass = Marshal.ReadIntPtr (handle); + // First field of GTypeClass is a GType. + return Marshal.ReadIntPtr (klass); + } + + [DllImport("libgobject-2.0-0.dll")] + static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type); + + public static bool IsInstance (this GLib.GType gtype, IntPtr raw) + { + return g_type_is_a (ValFromInstancePtr (raw), gtype.Val); + } + } +} diff --git a/gapi/Makefile.am b/gapi/Makefile.am new file mode 100644 index 000000000..d1e043d02 --- /dev/null +++ b/gapi/Makefile.am @@ -0,0 +1,44 @@ +if ENABLE_GLIBSHARP2_COMPAT +TARGET = $(ASSEMBLY) +else +TARGET = +endif + +ASSEMBLY = $(ASSEMBLY_NAME).dll +ASSEMBLY_NAME = gapi-2.0-compat +noinst_DATA = $(TARGET) + +CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb gtk-sharp.snk + +references = $(GLIBSHARP2_LIBS) + +sources = \ + AssemblyInfo.cs \ + GTypeExtensions.cs + +build_sources = $(addprefix $(srcdir)/, $(sources)) +dist_sources = $(sources) + +EXTRA_DIST = \ + $(dist_sources) \ + $(ASSEMBLY).config + +gtk-sharp.snk: $(top_srcdir)/gtk-sharp.snk + cp $(top_srcdir)/gtk-sharp.snk . + +$(ASSEMBLY): $(build_sources) gtk-sharp.snk + @rm -f $(ASSEMBLY).mdb + $(CSC) $(CSFLAGS) -unsafe -nowarn:0169,0612,0618 -out:$(ASSEMBLY) -target:library $(references) $(build_sources) + +install-data-local: + @if test -n '$(TARGET)'; then \ + echo "$(GACUTIL) /i $(ASSEMBLY) /f $(GACUTIL_FLAGS)"; \ + $(GACUTIL) /i $(ASSEMBLY) /f $(GACUTIL_FLAGS) || exit 1; \ + fi + +uninstall-local: + @if test -n '$(TARGET)'; then \ + echo "$(GACUTIL) /u $(ASSEMBLY_NAME) $(GACUTIL_FLAGS)"; \ + $(GACUTIL) /u $(ASSEMBLY_NAME) $(GACUTIL_FLAGS) || exit 1; \ + fi + diff --git a/gapi/gapi-2.0-compat.dll.config b/gapi/gapi-2.0-compat.dll.config new file mode 100644 index 000000000..bc5271299 --- /dev/null +++ b/gapi/gapi-2.0-compat.dll.config @@ -0,0 +1,4 @@ + + + + diff --git a/gapi/gapi-2.0-compat.pc.in b/gapi/gapi-2.0-compat.pc.in new file mode 100644 index 000000000..b7bd9d2c9 --- /dev/null +++ b/gapi/gapi-2.0-compat.pc.in @@ -0,0 +1,10 @@ +prefix=${pcfiledir}/../.. +exec_prefix=${prefix} +libdir=${exec_prefix}/lib + +Name: GAPI 2.0 Compatibility library +Description: Provides extensions necessary for using gapi 3.0 with glib 2.0. +Version: @VERSION@ +Libs: -r:${libdir}/mono/@PACKAGE_VERSION@/gapi-2.0-compat.dll +Requires: glib-sharp-2.0 + diff --git a/generator/GObjectVM.cs b/generator/GObjectVM.cs index da89fb315..6e03c8d27 100644 --- a/generator/GObjectVM.cs +++ b/generator/GObjectVM.cs @@ -204,7 +204,7 @@ namespace GtkSharp.Generation { this.GenerateMethodBody (sw, null); // Find the first unmanaged ancestor - sw.WriteLine ("\t\t\t{0}NativeDelegate unmanaged = GetClassStruct (this.LookupGType ().ThresholdType, true).{0};", this.Name); + sw.WriteLine ("\t\t\t{0}NativeDelegate unmanaged = GetClassStruct (this.LookupGType ().GetThresholdType (), true).{0};", this.Name); sw.Write ("\t\t\tif (unmanaged == null) "); if (parms.HasOutParam) sw.WriteLine ("throw new InvalidOperationException (\"No base method to invoke\");"); @@ -286,7 +286,7 @@ namespace GtkSharp.Generation { glue.WriteLine (); GenerateOverrideBody (sw); - sw.WriteLine ("\t\t\t{0} (gtype.ClassPtr, callback);", glue_name); + sw.WriteLine ("\t\t\t{0} (gtype.GetClassPtr (), callback);", glue_name); sw.WriteLine ("\t\t}"); sw.WriteLine (); } @@ -325,7 +325,7 @@ namespace GtkSharp.Generation { GenerateMethodBody (sw, null); Body.Initialize (gen_info, false, false, String.Empty); - string glue_call_string = "this.LookupGType ().ThresholdType.ClassPtr"; + string glue_call_string = "this.LookupGType ().GetThresholdType ().GetClassPtr ()"; if (!IsStatic) glue_call_string += ", Handle"; if (parms.Count > 0) diff --git a/generator/ObjectGen.cs b/generator/ObjectGen.cs index 753afc8a6..e70b94bb5 100644 --- a/generator/ObjectGen.cs +++ b/generator/ObjectGen.cs @@ -302,7 +302,7 @@ namespace GtkSharp.Generation { if (cs_parent == "") sw.WriteLine ("\t\tstatic uint class_offset = 0;"); else - sw.WriteLine ("\t\tstatic uint class_offset = ((GLib.GType) typeof ({0})).ClassSize;", cs_parent); + sw.WriteLine ("\t\tstatic uint class_offset = ((GLib.GType) typeof ({0})).GetClassSize ();", cs_parent); sw.WriteLine ("\t\tstatic Hashtable class_structs;"); sw.WriteLine (); sw.WriteLine ("\t\tstatic {0} GetClassStruct (GLib.GType gtype, bool use_cache)", class_struct_name); @@ -313,7 +313,7 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\tif (use_cache && class_structs.Contains (gtype))"); sw.WriteLine ("\t\t\t\treturn ({0}) class_structs [gtype];", class_struct_name); sw.WriteLine ("\t\t\telse {"); - sw.WriteLine ("\t\t\t\tIntPtr class_ptr = new IntPtr (gtype.ClassPtr.ToInt64 () + class_offset);"); + sw.WriteLine ("\t\t\t\tIntPtr class_ptr = new IntPtr (gtype.GetClassPtr ().ToInt64 () + class_offset);"); sw.WriteLine ("\t\t\t\t{0} class_struct = ({0}) Marshal.PtrToStructure (class_ptr, typeof ({0}));", class_struct_name); sw.WriteLine ("\t\t\t\tif (use_cache)"); sw.WriteLine ("\t\t\t\t\tclass_structs.Add (gtype, class_struct);"); @@ -323,7 +323,7 @@ namespace GtkSharp.Generation { sw.WriteLine (); sw.WriteLine ("\t\tstatic void OverrideClassStruct (GLib.GType gtype, {0} class_struct)", class_struct_name); sw.WriteLine ("\t\t{"); - sw.WriteLine ("\t\t\tIntPtr class_ptr = new IntPtr (gtype.ClassPtr.ToInt64 () + class_offset);"); + sw.WriteLine ("\t\t\tIntPtr class_ptr = new IntPtr (gtype.GetClassPtr ().ToInt64 () + class_offset);"); sw.WriteLine ("\t\t\tMarshal.StructureToPtr (class_struct, class_ptr, false);"); sw.WriteLine ("\t\t}"); sw.WriteLine (); diff --git a/glib/GType.cs b/glib/GType.cs index 027535f44..75cde5999 100755 --- a/glib/GType.cs +++ b/glib/GType.cs @@ -285,41 +285,33 @@ namespace GLib { return Marshaller.Utf8PtrToString (g_type_name (val)); } - public IntPtr ClassPtr { - get { - IntPtr klass = g_type_class_peek (val); - if (klass == IntPtr.Zero) - klass = g_type_class_ref (val); - return klass; - } + public IntPtr GetClassPtr () + { + IntPtr klass = g_type_class_peek (val); + if (klass == IntPtr.Zero) + klass = g_type_class_ref (val); + return klass; } - public GType BaseType { - get { - IntPtr parent = g_type_parent (this.Val); - if (parent == IntPtr.Zero) - return GType.None; - else - return new GType (parent); - } + public GType GetBaseType () + { + IntPtr parent = g_type_parent (this.Val); + return parent == IntPtr.Zero ? GType.None : new GType (parent); } - public GType ThresholdType { - get { - GLib.GType curr_type = this; - while (curr_type.ToString ().StartsWith ("__gtksharp_")) { - curr_type = curr_type.BaseType; - } - return curr_type; - } + public GType GetThresholdType () + { + GType curr_type = this; + while (curr_type.ToString ().StartsWith ("__gtksharp_")) + curr_type = curr_type.GetBaseType (); + return curr_type; } - public uint ClassSize { - get { - GTypeQuery query; - g_type_query (this.Val, out query); - return query.class_size; - } + public uint GetClassSize () + { + GTypeQuery query; + g_type_query (this.Val, out query); + return query.class_size; } internal void EnsureClass () diff --git a/glib/Object.cs b/glib/Object.cs index 4df05e382..1b4340ae0 100644 --- a/glib/Object.cs +++ b/glib/Object.cs @@ -211,7 +211,7 @@ namespace GLib { static void OverridePropertyHandlers (GType gtype, GetPropertyDelegate get_cb, SetPropertyDelegate set_cb) { - IntPtr class_ptr = gtype.ClassPtr; + IntPtr class_ptr = gtype.GetClassPtr (); GObjectClass klass = (GObjectClass) Marshal.PtrToStructure (class_ptr, typeof (GObjectClass)); klass.get_prop_cb = get_cb; klass.set_prop_cb = set_cb; @@ -223,7 +223,7 @@ namespace GLib { static IntPtr RegisterProperty (GType type, string name, string nick, string blurb, uint property_id, GType property_type, bool can_read, bool can_write) { - IntPtr declaring_class = type.ClassPtr; + IntPtr declaring_class = type.GetClassPtr (); ParamSpec pspec = new ParamSpec (name, nick, blurb, property_type, can_read, can_write); g_object_class_install_property (declaring_class, property_id, pspec.Handle); diff --git a/glib/Value.cs b/glib/Value.cs index 290d96ae7..e8b573a42 100755 --- a/glib/Value.cs +++ b/glib/Value.cs @@ -553,7 +553,7 @@ namespace GLib { void InitForProperty (GType gtype, string name) { IntPtr p_name = Marshaller.StringToPtrGStrdup (name); - IntPtr spec_ptr = g_object_class_find_property (gtype.ClassPtr, p_name); + IntPtr spec_ptr = g_object_class_find_property (gtype.GetClassPtr (), p_name); Marshaller.Free (p_name); if (spec_ptr == IntPtr.Zero) diff --git a/gtk/Widget.custom b/gtk/Widget.custom index 9ea136f26..27292bd91 100644 --- a/gtk/Widget.custom +++ b/gtk/Widget.custom @@ -251,7 +251,7 @@ static void ConnectSetScrollAdjustments (GLib.GType gtype) SetScrollAdjustmentsMarshalCallback = new ClosureMarshal (SetScrollAdjustmentsMarshal_cb); uint signal_id = RegisterSignal ("set_scroll_adjustments", gtype, GLib.Signal.Flags.RunLast, GLib.GType.None, new GLib.GType [] {Adjustment.GType, Adjustment.GType}, SetScrollAdjustmentsMarshalCallback); - gtksharp_widget_class_set_set_scroll_adjustments_signal (gtype.ClassPtr, signal_id); + gtksharp_widget_class_set_set_scroll_adjustments_signal (gtype.GetClassPtr (), signal_id); } [GLib.DefaultSignalHandler (Type=typeof (Gtk.Widget), ConnectionMethod="ConnectSetScrollAdjustments")] @@ -286,7 +286,7 @@ static void ConnectActivate (GLib.GType gtype) ActivateMarshalCallback = new ClosureMarshal (ActivateMarshal_cb); uint signal_id = RegisterSignal ("activate_signal", gtype, GLib.Signal.Flags.RunLast, GLib.GType.None, new GLib.GType [0], ActivateMarshalCallback); - gtksharp_widget_class_set_activate_signal (gtype.ClassPtr, signal_id); + gtksharp_widget_class_set_activate_signal (gtype.GetClassPtr (), signal_id); } [GLib.DefaultSignalHandler (Type=typeof (Gtk.Widget), ConnectionMethod="ConnectActivate")] @@ -393,7 +393,7 @@ static void ClassInit (GLib.GType gtype, Type t) #endif GLib.SList binding_args = new GLib.SList (new object[] {arg}, typeof (GtkBindingArg), false, false); - gtk_binding_entry_add_signall (gtk_binding_set_by_class (gtype.ClassPtr), (uint) attr.Key, attr.Mod, native_signame, binding_args.Handle); + gtk_binding_entry_add_signall (gtk_binding_set_by_class (gtype.GetClassPtr ()), (uint) attr.Key, attr.Mod, native_signame, binding_args.Handle); binding_args.Dispose (); } GLib.Marshaller.Free (native_signame); @@ -422,7 +422,7 @@ internal GLib.Value StyleGetPropertyValue (string property_name) { IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (property_name); try { - IntPtr pspec_ptr = gtk_widget_class_find_style_property (this.LookupGType ().ClassPtr, native_name); + IntPtr pspec_ptr = gtk_widget_class_find_style_property (this.LookupGType ().GetClassPtr (), native_name); if (pspec_ptr == IntPtr.Zero) throw new ArgumentException (String.Format ("Cannot find style property \"{0}\"", property_name));