diff --git a/ChangeLog b/ChangeLog index 6103bb1be..2eb8f3522 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-05-14 Andres G. Aragoneses + + * atk/Object.custom: Track API changes in GLib.Signal. + * glib/Signal.cs: AddEmissionHook binding (for closing #386950), and + change API of Emit to mimic the detailed_signal pattern. + * glib/GType.cs: GType.FromName: new wrapper for native call. + * glib/ObjectManager.cs: Use the new FromName managed method. + 2008-05-08 Mike Kestner * atk/atk-api-2.12.raw: reparsed. diff --git a/atk/Object.custom b/atk/Object.custom index 10e4a17a3..3989c20c3 100644 --- a/atk/Object.custom +++ b/atk/Object.custom @@ -94,7 +94,9 @@ protected void EmitChildrenChanged (ChildrenChangedDetail detail, uint child_index, Atk.Object child) { - GLib.Signal.Emit (this, "children-changed", detail.ToString().ToLower(), child_index, child); + GLib.Signal.Emit (this, + "children-changed::" + detail.ToString ().ToLower (), + child_index, child); } protected enum ChildrenChangedDetail diff --git a/glib/GType.cs b/glib/GType.cs index 71d882143..4787f7e86 100755 --- a/glib/GType.cs +++ b/glib/GType.cs @@ -37,6 +37,11 @@ namespace GLib { this.val = val; } + public static GType FromName (string native_name) + { + return new GType (g_type_from_name (native_name)); + } + public static readonly GType Invalid = new GType ((IntPtr) TypeFundamentals.TypeInvalid); public static readonly GType None = new GType ((IntPtr) TypeFundamentals.TypeNone); public static readonly GType Interface = new GType ((IntPtr) TypeFundamentals.TypeInterface); @@ -195,6 +200,9 @@ namespace GLib { [DllImport("libgobject-2.0-0.dll")] static extern IntPtr g_type_name (IntPtr raw); + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_type_from_name (string name); public override string ToString () { diff --git a/glib/ObjectManager.cs b/glib/ObjectManager.cs index 8cb91582f..b7592910e 100644 --- a/glib/ObjectManager.cs +++ b/glib/ObjectManager.cs @@ -58,7 +58,7 @@ namespace GLib { [Obsolete ("Replaced by GType.Register (GType, Type)")] public static void RegisterType (string native_name, string mangled) { - RegisterType (new GType (g_type_from_name (native_name)), Type.GetType (mangled)); + RegisterType (GType.FromName (native_name), Type.GetType (mangled)); } [Obsolete ("Replaced by GType.Register (GType, Type)")] @@ -86,8 +86,5 @@ namespace GLib { [DllImport("libgobject-2.0-0.dll")] static extern IntPtr g_type_parent (IntPtr typ); - - [DllImport("libgobject-2.0-0.dll")] - static extern IntPtr g_type_from_name (string name); } } diff --git a/glib/Signal.cs b/glib/Signal.cs index d1b3a3fa8..8f91e647a 100644 --- a/glib/Signal.cs +++ b/glib/Signal.cs @@ -1,8 +1,9 @@ // GLib.Signal.cs - signal marshaling class // // Authors: Mike Kestner +// Andrés G. Aragoneses // -// Copyright (c) 2005 Novell, Inc. +// Copyright (c) 2005,2008 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 @@ -278,10 +279,28 @@ namespace GLib { } } - public static object Emit (GLib.Object instance, string signal_name, string detail, params object[] args) + // format: children-changed::add + private static void ParseSignalDetail (string signal_detail, out string signal_name, out uint gquark) { - uint signal_id = GetSignalId (signal_name, instance); - uint gquark = GetGQuarkFromString (detail); + //can't use String.Split because it doesn't accept a string arg (only char) in the 1.x profile + int link_pos = signal_detail.IndexOf ("::"); + if (link_pos < 0) { + gquark = 0; + signal_name = signal_detail; + } else if (link_pos == 0) { + throw new FormatException ("Invalid detailed_signal: " + signal_detail); + } else { + signal_name = signal_detail.Substring (0, link_pos); + gquark = GetGQuarkFromString (signal_detail.Substring (link_pos + 2)); + } + } + + public static object Emit (GLib.Object instance, string detailed_signal, params object[] args) + { + uint gquark, signal_id; + string signal_name; + ParseSignalDetail (detailed_signal, out signal_name, out gquark); + signal_id = GetSignalId (signal_name, instance); GLib.Value[] vals = new GLib.Value [args.Length + 1]; GLib.ValueArray inst_and_params = new GLib.ValueArray ((uint) args.Length + 1); @@ -314,12 +333,28 @@ namespace GLib { private static uint GetSignalId (string signal_name, GLib.Object obj) { IntPtr typeid = gtksharp_get_type_id (obj.Handle); + return GetSignalId (signal_name, typeid); + } + + private static uint GetSignalId (string signal_name, IntPtr typeid) + { IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (signal_name); uint signal_id = g_signal_lookup (native_name, typeid); GLib.Marshaller.Free (native_name); return signal_id; } + public static ulong AddEmissionHook (string detailed_signal, GLib.GType type, EmissionHook handler_func) + { + uint gquark; + string signal_name; + ParseSignalDetail (detailed_signal, out signal_name, out gquark); + uint signal_id = GetSignalId (signal_name, type.Val); + if (signal_id == 0) + throw new Exception ("Invalid signal name: " + signal_name); + return g_signal_add_emission_hook (signal_id, gquark, new EmissionHookMarshaler (handler_func).Callback, IntPtr.Zero, IntPtr.Zero); + } + [DllImport("libgobject-2.0-0.dll")] static extern IntPtr g_signal_get_invocation_hint (IntPtr instance); @@ -335,6 +370,10 @@ namespace GLib { [DllImport("glibsharpglue-2")] static extern IntPtr gtksharp_get_type_id (IntPtr raw); + + [DllImport("libgobject-2.0-0.dll")] + static extern ulong g_signal_add_emission_hook (uint signal_id, uint gquark_detail, EmissionHookNative hook_func, IntPtr hook_data, IntPtr data_destroy); + } }