static IntPtr ConstructorCallback(IntPtr gtypeval, uint n_construct_properties, IntPtr construct_properties) { GType gtype = new GLib.GType(gtypeval); GObjectClass threshold_class = (GObjectClass)Marshal.PtrToStructure(gtype.GetThresholdType().GetClassPtr(), typeof(GObjectClass)); IntPtr raw = threshold_class.constructor_cb(gtypeval, n_construct_properties, construct_properties); bool construct_needed = true; for (int i = 0; i < n_construct_properties; i++) { IntPtr p = new IntPtr(construct_properties.ToInt64() + i * 2 * IntPtr.Size); string prop_name = Marshaller.Utf8PtrToString(g_param_spec_get_name(Marshal.ReadIntPtr(p))); if (prop_name != "gtk-sharp-managed-instance") { continue; } Value val = (Value)Marshal.PtrToStructure(Marshal.ReadIntPtr(p, IntPtr.Size), typeof(Value)); if ((IntPtr)val.Val != IntPtr.Zero) { GCHandle gch = (GCHandle)(IntPtr)val.Val; Object o = (GLib.Object)gch.Target; o.Raw = raw; construct_needed = false; break; } } if (construct_needed) { GetObject(raw, false); } return(raw); }
static void AddInterfaces(GType gtype, Type t, ref bool handlers_overridden) { foreach (Type iface in t.GetInterfaces()) { if (!iface.IsDefined(typeof(GInterfaceAttribute), true)) { continue; } GInterfaceAttribute attr = iface.GetCustomAttributes(typeof(GInterfaceAttribute), false) [0] as GInterfaceAttribute; GInterfaceAdapter adapter = Activator.CreateInstance(attr.AdapterType, null) as GInterfaceAdapter; if (!handlers_overridden) { IntPtr class_ptr = gtype.GetClassPtr(); GObjectClass gobject_class = (GObjectClass)Marshal.PtrToStructure(class_ptr, typeof(GObjectClass)); gobject_class.get_prop_cb = GetPropertyHandler; gobject_class.set_prop_cb = SetPropertyHandler; Marshal.StructureToPtr(gobject_class, class_ptr, false); handlers_overridden = true; } if (!iface.IsAssignableFrom(t.BaseType)) { GInterfaceInfo info = adapter.Info; info.Data = gtype.GetClassPtr(); //FIXME: overiding prop is done inside the init of interface adapter // not sure that it is the good solution but // it is the only one I found without exception or loop g_type_add_interface_static(gtype.Val, adapter.GType.Val, ref info); } foreach (PropertyInfo p in iface.GetProperties()) { PropertyAttribute[] attrs = p.GetCustomAttributes(typeof(PropertyAttribute), true) as PropertyAttribute []; if (attrs.Length == 0) { continue; } PropertyAttribute property_attr = attrs [0]; PropertyInfo declared_prop = t.GetProperty(p.Name, BindingFlags.Public | BindingFlags.Instance); if (declared_prop == null) { continue; } IntPtr param_spec = FindInterfaceProperty(adapter.GType, property_attr.Name); Dictionary <IntPtr, PropertyInfo> props; if (!Properties.TryGetValue(t, out props)) { props = new Dictionary <IntPtr, PropertyInfo> (); Properties [t] = props; } props [param_spec] = declared_prop; } } }
static void AddProperties(GType gtype, System.Type t, bool register_instance_prop, ref bool handlers_overridden) { if (register_instance_prop) { IntPtr declaring_class = gtype.GetClassPtr(); ParamSpec pspec = new ParamSpec("gtk-sharp-managed-instance", "", "", GType.Pointer, ParamFlags.Writable | ParamFlags.ConstructOnly); g_object_class_install_property(declaring_class, idx, pspec.Handle); idx++; } foreach (PropertyInfo pinfo in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) { foreach (object attr in pinfo.GetCustomAttributes(typeof(PropertyAttribute), false)) { if (pinfo.GetIndexParameters().Length > 0) { throw(new InvalidOperationException(String.Format("GLib.RegisterPropertyAttribute cannot be applied to property {0} of type {1} because the property expects one or more indexed parameters", pinfo.Name, t.FullName))); } if (!handlers_overridden) { IntPtr class_ptr = gtype.GetClassPtr(); GObjectClass gobject_class = (GObjectClass)Marshal.PtrToStructure(class_ptr, typeof(GObjectClass)); gobject_class.get_prop_cb = GetPropertyHandler; gobject_class.set_prop_cb = SetPropertyHandler; Marshal.StructureToPtr(gobject_class, class_ptr, false); handlers_overridden = true; } PropertyAttribute property_attr = attr as PropertyAttribute; try { IntPtr param_spec = RegisterProperty(gtype, property_attr.Name, property_attr.Nickname, property_attr.Blurb, idx, (GType)pinfo.PropertyType, pinfo.CanRead, pinfo.CanWrite); Type type = (Type)gtype; Dictionary <IntPtr, PropertyInfo> gtype_properties; if (!Properties.TryGetValue(type, out gtype_properties)) { gtype_properties = new Dictionary <IntPtr, PropertyInfo> (); Properties [type] = gtype_properties; } gtype_properties.Add(param_spec, pinfo); idx++; } catch (ArgumentException) { throw new InvalidOperationException(String.Format("GLib.PropertyAttribute cannot be applied to property {0} of type {1} because the return type of the property is not supported", pinfo.Name, t.FullName)); } } } }
static IntPtr ConstructorCallback(IntPtr gtypeval, uint n_construct_properties, IntPtr construct_properties) { GType gtype = new GLib.GType(gtypeval); GObjectClass threshold_class = (GObjectClass)Marshal.PtrToStructure(gtype.GetThresholdType().GetClassPtr(), typeof(GObjectClass)); IntPtr raw = threshold_class.constructor_cb(gtypeval, n_construct_properties, construct_properties); Dictionary <IntPtr, GLib.Value> deferred; GLib.Object obj = null; for (int i = 0; i < n_construct_properties; i++) { IntPtr p = new IntPtr(construct_properties.ToInt64() + i * 2 * IntPtr.Size); string prop_name = Marshaller.Utf8PtrToString(g_param_spec_get_name(Marshal.ReadIntPtr(p))); if (prop_name != "gtk-sharp-managed-instance") { continue; } Value val = (Value)Marshal.PtrToStructure(Marshal.ReadIntPtr(p, IntPtr.Size), typeof(Value)); if ((IntPtr)val.Val != IntPtr.Zero) { GCHandle gch = (GCHandle)(IntPtr)val.Val; obj = (GLib.Object)gch.Target; obj.Raw = raw; break; } } if (obj == null) { obj = GetObject(raw, false); } if (PropertiesToSet.TryGetValue(raw, out deferred)) { foreach (var item in deferred) { SetDeferredProperty(obj, item.Value, item.Key); } PropertiesToSet.Remove(raw); } return(raw); }
protected internal static GType RegisterGType(System.Type t) { GType gtype = GType.RegisterGObjectType(t); bool is_first_subclass = gtype.GetBaseType() == gtype.GetThresholdType(); if (is_first_subclass) { IntPtr class_ptr = gtype.GetClassPtr(); GObjectClass gobject_class = (GObjectClass)Marshal.PtrToStructure(class_ptr, typeof(GObjectClass)); gobject_class.constructor_cb = ConstructorHandler; gobject_class.get_prop_cb = GetPropertyHandler; gobject_class.set_prop_cb = SetPropertyHandler; Marshal.StructureToPtr(gobject_class, class_ptr, false); } AddProperties(gtype, t, is_first_subclass); ConnectDefaultHandlers(gtype, t); InvokeTypeInitializers(gtype, t); AddInterfaces(gtype, t); return(gtype); }
private void OverrideHandlers(IntPtr gobject_class_handle, bool ctor, bool properties) { if (HandlersOverriden || (ctor == false && properties == false)) { return; } GObjectClass gobject_class = (GObjectClass)Marshal.PtrToStructure(gobject_class_handle, typeof(GObjectClass)); if (ctor) { gobject_class.constructor_cb = GLib.Object.ConstructorHandler; } if (properties) { gobject_class.get_prop_cb = GLib.Object.GetPropertyHandler; gobject_class.set_prop_cb = GLib.Object.SetPropertyHandler; } Marshal.StructureToPtr(gobject_class, gobject_class_handle, false); HandlersOverriden = true; }