2001-09-19 04:04:57 +02:00
// Object.cs - GObject class wrapper implementation
//
2003-07-23 19:19:21 +02:00
// Authors: Mike Kestner <mkestner@speakeasy.net>
2013-04-07 08:51:30 +02:00
// Andres G. Aragoneses <knocte@gmail.com>
2001-09-19 04:04:57 +02:00
//
2004-05-27 18:35:21 +02:00
// Copyright (c) 2001-2003 Mike Kestner
2005-08-15 17:56:16 +02:00
// Copyright (c) 2004-2005 Novell, Inc.
2013-04-07 08:51:30 +02:00
// Copyright (c) 2013 Andres G. Aragoneses
2004-06-25 20:42:19 +02:00
//
// 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.
2004-03-16 20:43:04 +01:00
2001-09-19 13:37:15 +02:00
namespace GLib {
2001-09-19 04:04:57 +02:00
using System ;
2011-03-25 00:11:10 +01:00
using System.Collections.Generic ;
2002-12-25 01:36:00 +01:00
using System.Reflection ;
2001-09-19 04:04:57 +02:00
using System.Runtime.InteropServices ;
2002-09-04 07:25:58 +02:00
public class Object : IWrapper , IDisposable {
2001-09-27 20:39:53 +02:00
2007-11-16 19:35:38 +01:00
IntPtr handle ;
2008-01-22 17:54:44 +01:00
ToggleRef tref ;
2002-09-04 07:25:58 +02:00
bool disposed = false ;
2011-11-20 19:41:56 +01:00
static uint idx = 1 ;
2011-03-25 00:11:10 +01:00
static Dictionary < IntPtr , ToggleRef > Objects = new Dictionary < IntPtr , ToggleRef > ( ) ;
2015-09-01 17:54:14 +02:00
static Dictionary < IntPtr , Dictionary < IntPtr , GLib . Value > > PropertiesToSet = new Dictionary < IntPtr , Dictionary < IntPtr , GLib . Value > > ( ) ;
2001-09-27 20:39:53 +02:00
2002-09-04 07:25:58 +02:00
~ Object ( )
{
2011-03-25 18:22:04 +01:00
if ( WarnOnFinalize )
Console . Error . WriteLine ( "Unexpected finalization of " + GetType ( ) + " instance. Consider calling Dispose." ) ;
2003-03-15 21:49:37 +01:00
2011-03-25 18:22:04 +01:00
Dispose ( false ) ;
2003-03-15 21:49:37 +01:00
}
2011-03-25 18:22:04 +01:00
public void Dispose ( )
2002-09-04 07:25:58 +02:00
{
if ( disposed )
return ;
2011-03-25 18:22:04 +01:00
Dispose ( true ) ;
2002-09-04 07:25:58 +02:00
disposed = true ;
2011-03-25 18:22:04 +01:00
GC . SuppressFinalize ( this ) ;
}
protected virtual void Dispose ( bool disposing )
{
ToggleRef tref ;
lock ( Objects ) {
if ( Objects . TryGetValue ( Handle , out tref ) ) {
Objects . Remove ( Handle ) ;
}
2003-03-15 21:49:37 +01:00
}
2011-03-25 18:22:04 +01:00
2007-11-16 19:35:38 +01:00
handle = IntPtr . Zero ;
2011-03-25 18:22:04 +01:00
if ( tref = = null )
return ;
if ( disposing )
2011-07-29 20:33:02 +02:00
tref . Dispose ( ) ;
2011-03-25 18:22:04 +01:00
else
tref . QueueUnref ( ) ;
2002-09-04 07:25:58 +02:00
}
2011-03-25 18:22:04 +01:00
public static bool WarnOnFinalize { get ; set ; }
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2008-04-04 18:10:08 +02:00
static extern IntPtr g_object_ref ( IntPtr raw ) ;
2002-09-12 07:21:16 +02:00
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2011-03-25 18:22:04 +01:00
static extern void g_object_unref ( IntPtr raw ) ;
2012-09-20 01:41:04 +02:00
public static Object TryGetObject ( IntPtr o )
{
if ( o = = IntPtr . Zero )
return null ;
2012-05-09 23:21:50 +02:00
ToggleRef toggle_ref ;
lock ( Objects ) {
2015-09-01 17:54:14 +02:00
if ( ! Objects . TryGetValue ( o , out toggle_ref ) ) {
return null ;
}
2012-05-09 23:21:50 +02:00
}
if ( toggle_ref ! = null ) {
return toggle_ref . Target ;
2012-09-20 01:41:04 +02:00
}
return null ;
}
2003-07-23 19:19:21 +02:00
public static Object GetObject ( IntPtr o , bool owned_ref )
2001-09-19 06:47:48 +02:00
{
2005-03-03 21:50:46 +01:00
if ( o = = IntPtr . Zero )
return null ;
2005-08-15 17:56:16 +02:00
Object obj = null ;
2007-11-16 19:35:38 +01:00
2011-03-25 00:11:10 +01:00
ToggleRef toggle_ref ;
2012-05-09 23:21:50 +02:00
lock ( Objects ) {
if ( Objects . TryGetValue ( o , out toggle_ref ) ) {
if ( toggle_ref ! = null )
obj = toggle_ref . Target ;
}
2007-02-16 17:18:59 +01:00
}
2005-05-31 21:22:58 +02:00
2007-11-16 19:35:38 +01:00
if ( obj ! = null & & obj . Handle = = o ) {
2003-07-23 19:19:21 +02:00
if ( owned_ref )
2007-11-16 19:35:38 +01:00
g_object_unref ( obj . Handle ) ;
2003-07-23 19:19:21 +02:00
return obj ;
2003-04-09 19:50:51 +02:00
}
2007-11-16 19:35:38 +01:00
if ( ! owned_ref )
2007-11-29 03:02:24 +01:00
g_object_ref ( o ) ;
2007-11-16 19:35:38 +01:00
2004-05-28 18:59:21 +02:00
obj = GLib . ObjectManager . CreateObject ( o ) ;
2007-11-16 19:35:38 +01:00
if ( obj = = null ) {
g_object_unref ( o ) ;
2003-07-23 19:19:21 +02:00
return null ;
2007-11-16 19:35:38 +01:00
}
2003-07-23 19:19:21 +02:00
return obj ;
2001-09-19 04:04:57 +02:00
}
2001-09-20 06:03:27 +02:00
2003-12-10 23:56:49 +01:00
public static Object GetObject ( IntPtr o )
{
return GetObject ( o , false ) ;
}
2011-12-01 17:49:50 +01:00
// Key: The Type for the set of properties
// Value->SubKey: The pointer to the ParamSpec of the property
// Value->SubValue: The corresponding PropertyInfo object
static Dictionary < Type , Dictionary < IntPtr , PropertyInfo > > properties ;
static Dictionary < Type , Dictionary < IntPtr , PropertyInfo > > Properties {
2008-06-06 18:55:00 +02:00
get {
if ( properties = = null )
2011-12-01 17:49:50 +01:00
properties = new Dictionary < Type , Dictionary < IntPtr , PropertyInfo > > ( ) ;
2008-06-06 18:55:00 +02:00
return properties ;
}
}
2011-11-20 19:41:56 +01:00
static Dictionary < IntPtr , Dictionary < Type , PropertyInfo > > interface_properties ;
static Dictionary < IntPtr , Dictionary < Type , PropertyInfo > > IProperties {
get {
if ( interface_properties = = null )
interface_properties = new Dictionary < IntPtr , Dictionary < Type , PropertyInfo > > ( ) ;
return interface_properties ;
}
}
2008-12-19 19:57:42 +01:00
struct GTypeClass {
2009-05-01 20:40:44 +02:00
public IntPtr gtype ;
2008-12-19 19:57:42 +01:00
}
struct GObjectClass {
2011-03-23 20:05:01 +01:00
public GTypeClass type_class ;
public IntPtr construct_props ;
2009-09-12 03:01:12 +02:00
public ConstructorDelegate constructor_cb ;
2008-12-19 19:57:42 +01:00
public SetPropertyDelegate set_prop_cb ;
public GetPropertyDelegate get_prop_cb ;
2011-03-23 20:05:01 +01:00
public IntPtr dispose ;
public IntPtr finalize ;
public IntPtr dispatch_properties_changed ;
public IntPtr notify ;
public IntPtr constructed ;
public IntPtr dummy1 ;
public IntPtr dummy2 ;
public IntPtr dummy3 ;
public IntPtr dummy4 ;
public IntPtr dummy5 ;
public IntPtr dummy6 ;
public IntPtr dummy7 ;
2008-12-19 19:57:42 +01:00
}
2013-04-07 08:51:30 +02:00
internal class ClassInitializer {
internal Type Type { get ; private set ; }
internal bool HandlersOverriden { get ; private set ; }
2013-07-17 14:24:02 +02:00
internal GType . ClassInitDelegate ClassInitManagedDelegate { get ; private set ; }
2013-04-07 08:51:30 +02:00
2013-04-07 09:17:44 +02:00
uint idx = 1 ;
2013-04-07 08:51:30 +02:00
bool is_first_subclass ;
private GType gtype ;
private List < GInterfaceAdapter > adapters = new List < GInterfaceAdapter > ( ) ;
internal ClassInitializer ( Type type )
{
2013-07-17 14:24:02 +02:00
ClassInitManagedDelegate = this . ClassInit ;
2013-04-07 08:51:30 +02:00
Type = type ;
gtype = GType . RegisterGObjectType ( this ) ;
is_first_subclass = gtype . GetBaseType ( ) = = gtype . GetThresholdType ( ) ;
}
internal GType Init ( )
{
AddGInterfaces ( ) ;
gtype . EnsureClass ( ) ; //calls class_init
2013-04-07 09:17:44 +02:00
ConnectDefaultHandlers ( ) ;
InvokeTypeInitializers ( ) ;
AddInterfaceProperties ( ) ;
2013-04-07 08:51:30 +02:00
return gtype ;
}
private void AddGInterfaces ( )
{
foreach ( Type iface in Type . 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 ( ! iface . IsAssignableFrom ( Type . BaseType ) ) {
GInterfaceInfo info = adapter . Info ;
info . Data = gtype . Val ;
2013-10-12 14:09:23 +02:00
g_type_add_interface_static ( gtype . Val , adapter . GInterfaceGType . Val , ref info ) ;
2013-04-07 08:51:30 +02:00
adapters . Add ( adapter ) ;
}
}
}
2013-07-17 14:24:02 +02:00
private void ClassInit ( IntPtr gobject_class_handle )
2013-04-07 08:51:30 +02:00
{
bool override_ctor = is_first_subclass ;
bool override_props = is_first_subclass | | adapters . Count > 0 ;
OverrideHandlers ( gobject_class_handle , override_ctor , override_props ) ;
foreach ( GInterfaceAdapter adapter in adapters ) {
InitializeProperties ( adapter , gobject_class_handle ) ;
}
2013-10-21 00:37:29 +02:00
AddProperties ( gobject_class_handle ) ;
2013-04-07 08:51:30 +02:00
}
private void InitializeProperties ( GInterfaceAdapter adapter , IntPtr gobject_class_handle )
{
foreach ( PropertyInfo pinfo in adapter . GetType ( ) . 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 ( "Property {0} of type {1} cannot be overriden because its GLib.PropertyAttribute is expected to have one or more indexed parameters" ,
pinfo . Name , adapter . GetType ( ) . FullName ) ) ;
PropertyAttribute property_attr = attr as PropertyAttribute ;
if ( property_attr ! = null ) {
OverrideProperty ( gobject_class_handle , property_attr . Name ) ;
}
}
}
}
void OverrideProperty ( IntPtr declaring_class , string name )
{
2013-04-07 09:17:44 +02:00
Object . OverrideProperty ( declaring_class , idx + + , name ) ;
idx + + ;
2013-04-07 08:51:30 +02:00
}
2013-04-07 09:17:44 +02:00
private void OverrideHandlers ( bool ctor , bool properties )
2013-04-07 08:51:30 +02:00
{
OverrideHandlers ( gtype . GetClassPtr ( ) , ctor , properties ) ;
}
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 ;
}
2013-04-07 09:17:44 +02:00
2013-10-21 00:37:29 +02:00
void AddProperties ( IntPtr gobject_class_handle )
2013-04-07 09:17:44 +02:00
{
if ( is_first_subclass ) {
ParamSpec pspec = new ParamSpec ( "gtk-sharp-managed-instance" , "" , "" , GType . Pointer , ParamFlags . Writable | ParamFlags . ConstructOnly ) ;
2013-10-21 00:37:29 +02:00
g_object_class_install_property ( gobject_class_handle , idx , pspec . Handle ) ;
2013-04-07 09:17:44 +02:00
idx + + ;
}
foreach ( PropertyInfo pinfo in Type . 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 , Type . FullName ) ) ;
OverrideHandlers ( false , 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 , Type . FullName ) ) ;
}
}
}
}
void AddInterfaceProperties ( )
{
foreach ( Type iface in Type . 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 ;
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 = Type . GetProperty ( p . Name , BindingFlags . Public | BindingFlags . Instance ) ;
if ( declared_prop = = null )
continue ;
2013-10-12 14:09:23 +02:00
IntPtr param_spec = FindInterfaceProperty ( adapter . GInterfaceGType , property_attr . Name ) ;
2013-04-07 09:17:44 +02:00
Dictionary < IntPtr , PropertyInfo > props ;
if ( ! Properties . TryGetValue ( Type , out props ) ) {
props = new Dictionary < IntPtr , PropertyInfo > ( ) ;
Properties [ Type ] = props ;
}
props [ param_spec ] = declared_prop ;
}
}
}
void ConnectDefaultHandlers ( )
{
foreach ( MethodInfo minfo in Type . GetMethods ( BindingFlags . Instance | BindingFlags . NonPublic | BindingFlags . Public | BindingFlags . DeclaredOnly ) ) {
MethodInfo baseinfo = minfo . GetBaseDefinition ( ) ;
if ( baseinfo = = minfo )
continue ;
foreach ( object attr in baseinfo . GetCustomAttributes ( typeof ( DefaultSignalHandlerAttribute ) , false ) ) {
DefaultSignalHandlerAttribute sigattr = attr as DefaultSignalHandlerAttribute ;
MethodInfo connector = sigattr . Type . GetMethod ( sigattr . ConnectionMethod , BindingFlags . Static | BindingFlags . NonPublic , null , new Type [ ] { typeof ( GType ) } , new ParameterModifier [ 0 ] ) ;
object [ ] parms = new object [ 1 ] ;
parms [ 0 ] = gtype ;
connector . Invoke ( null , parms ) ;
break ;
}
}
}
void InvokeTypeInitializers ( )
{
object [ ] parms = { gtype , Type } ;
BindingFlags flags = BindingFlags . Static | BindingFlags . NonPublic ;
foreach ( TypeInitializerAttribute tia in Type . GetCustomAttributes ( typeof ( TypeInitializerAttribute ) , true ) ) {
MethodInfo m = tia . Type . GetMethod ( tia . MethodName , flags ) ;
if ( m ! = null )
m . Invoke ( null , parms ) ;
}
}
2013-04-07 08:51:30 +02:00
}
2009-09-12 03:01:12 +02:00
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate IntPtr ConstructorDelegate ( IntPtr gtype , uint n_construct_properties , IntPtr construct_properties ) ;
static ConstructorDelegate constructor_handler ;
static ConstructorDelegate ConstructorHandler {
get {
if ( constructor_handler = = null )
constructor_handler = new ConstructorDelegate ( ConstructorCallback ) ;
return constructor_handler ;
}
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2009-09-12 03:01:12 +02:00
static extern IntPtr g_param_spec_get_name ( IntPtr pspec ) ;
static IntPtr ConstructorCallback ( IntPtr gtypeval , uint n_construct_properties , IntPtr construct_properties )
2008-12-19 19:57:42 +01:00
{
2009-09-12 03:01:12 +02:00
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 ) ;
2015-09-01 17:54:14 +02:00
Dictionary < IntPtr , GLib . Value > deferred ;
GLib . Object obj = null ;
2009-09-12 03:01:12 +02:00
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 ;
2015-09-01 17:54:14 +02:00
obj = ( GLib . Object ) gch . Target ;
obj . Raw = raw ;
2009-09-12 03:01:12 +02:00
break ;
}
}
2015-09-01 17:54:14 +02:00
if ( obj = = null )
obj = GetObject ( raw , false ) ;
2009-09-12 03:01:12 +02:00
2015-09-01 17:54:14 +02:00
if ( PropertiesToSet . TryGetValue ( raw , out deferred ) ) {
foreach ( var item in deferred ) {
SetDeferredProperty ( obj , item . Value , item . Key ) ;
}
PropertiesToSet . Remove ( raw ) ;
}
2009-09-12 03:01:12 +02:00
return raw ;
2008-12-19 19:57:42 +01:00
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2011-11-20 19:41:56 +01:00
static extern void g_object_class_override_property ( IntPtr klass , uint prop_id , IntPtr name ) ;
2013-04-07 08:51:30 +02:00
public static void OverrideProperty ( IntPtr oclass , uint property_id , string name )
2011-11-20 19:41:56 +01:00
{
IntPtr native_name = GLib . Marshaller . StringToPtrGStrdup ( name ) ;
2013-04-07 08:51:30 +02:00
g_object_class_override_property ( oclass , property_id , native_name ) ;
}
[Obsolete ("Use OverrideProperty(oclass,property_id,name)")]
public static void OverrideProperty ( IntPtr declaring_class , string name )
{
OverrideProperty ( declaring_class , idx , name ) ;
2011-11-20 19:41:56 +01:00
idx + + ;
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2011-11-20 19:41:56 +01:00
static extern IntPtr g_object_class_find_property ( IntPtr klass , IntPtr name ) ;
2013-10-11 11:13:08 +02:00
static IntPtr FindClassProperty ( GLib . Object o , string name )
2011-11-20 19:41:56 +01:00
{
2013-10-11 11:13:08 +02:00
IntPtr gobjectclass = Marshal . ReadIntPtr ( o . Handle ) ;
2011-11-20 19:41:56 +01:00
IntPtr native_name = GLib . Marshaller . StringToPtrGStrdup ( name ) ;
2013-10-11 11:13:08 +02:00
return g_object_class_find_property ( gobjectclass , native_name ) ;
2011-11-20 19:41:56 +01:00
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2011-11-20 19:41:56 +01:00
static extern IntPtr g_object_interface_find_property ( IntPtr klass , IntPtr name ) ;
static IntPtr FindInterfaceProperty ( GType type , string name )
{
IntPtr g_iface = type . GetDefaultInterfacePtr ( ) ;
IntPtr native_name = GLib . Marshaller . StringToPtrGStrdup ( name ) ;
return g_object_interface_find_property ( g_iface , native_name ) ;
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2008-12-19 19:57:42 +01:00
static extern void g_object_class_install_property ( IntPtr klass , uint prop_id , IntPtr param_spec ) ;
static IntPtr RegisterProperty ( GType type , string name , string nick , string blurb , uint property_id , GType property_type , bool can_read , bool can_write )
{
2009-08-09 01:42:15 +02:00
IntPtr declaring_class = type . GetClassPtr ( ) ;
2008-12-19 19:57:42 +01:00
ParamSpec pspec = new ParamSpec ( name , nick , blurb , property_type , can_read , can_write ) ;
g_object_class_install_property ( declaring_class , property_id , pspec . Handle ) ;
return pspec . Handle ;
}
2008-06-06 18:55:00 +02:00
2009-09-03 21:50:53 +02:00
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
2008-06-06 18:55:00 +02:00
delegate void GetPropertyDelegate ( IntPtr GObject , uint property_id , ref GLib . Value value , IntPtr pspec ) ;
static void GetPropertyCallback ( IntPtr handle , uint property_id , ref GLib . Value value , IntPtr param_spec )
{
2011-12-01 17:49:50 +01:00
GLib . Object obj = GLib . Object . GetObject ( handle , false ) ;
var type = ( Type ) obj . LookupGType ( ) ;
Dictionary < IntPtr , PropertyInfo > props ;
if ( ! Properties . TryGetValue ( type , out props ) )
2009-09-12 03:01:12 +02:00
return ;
2011-12-03 16:24:23 +01:00
PropertyInfo prop ;
2011-12-01 17:49:50 +01:00
if ( ! props . TryGetValue ( param_spec , out prop ) )
return ;
value . Val = prop . GetValue ( obj , new object [ 0 ] ) ;
2008-06-06 18:55:00 +02:00
}
static GetPropertyDelegate get_property_handler ;
static GetPropertyDelegate GetPropertyHandler {
get {
if ( get_property_handler = = null )
get_property_handler = new GetPropertyDelegate ( GetPropertyCallback ) ;
return get_property_handler ;
}
}
2009-09-03 21:50:53 +02:00
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
2008-06-06 18:55:00 +02:00
delegate void SetPropertyDelegate ( IntPtr GObject , uint property_id , ref GLib . Value value , IntPtr pspec ) ;
static void SetPropertyCallback ( IntPtr handle , uint property_id , ref GLib . Value value , IntPtr param_spec )
{
2015-09-01 17:54:14 +02:00
// There are multiple issues in this place.
// We cannot construct an object here as it can be in construction
// from ConstructorCallback thus managed object already created.
//
// We cannot use the "gtk-sharp-managed-instance" property as when
// constructed by Gtk.Builder it is set to null.
//
// We defer setting the properties to later time when
// we have unmanaged and managed objects paired.
GLib . Object obj = TryGetObject ( handle ) ;
if ( obj ! = null ) {
SetDeferredProperty ( obj , value , param_spec ) ;
return ;
2011-11-20 19:41:56 +01:00
}
2015-09-01 17:54:14 +02:00
Dictionary < IntPtr , GLib . Value > deferred ;
if ( ! PropertiesToSet . TryGetValue ( handle , out deferred ) ) {
deferred = new Dictionary < IntPtr , GLib . Value > ( ) ;
PropertiesToSet . Add ( handle , deferred ) ;
}
deferred [ param_spec ] = value ;
}
static void SetDeferredProperty ( GLib . Object obj , GLib . Value value , IntPtr param_spec )
{
2011-12-01 17:49:50 +01:00
var type = ( Type ) obj . LookupGType ( ) ;
Dictionary < IntPtr , PropertyInfo > props ;
if ( ! Properties . TryGetValue ( type , out props ) )
2009-09-12 03:01:12 +02:00
return ;
2011-12-03 16:24:23 +01:00
PropertyInfo prop ;
2011-12-01 17:49:50 +01:00
if ( ! props . TryGetValue ( param_spec , out prop ) )
return ;
prop . SetValue ( obj , value . Val , new object [ 0 ] ) ;
2008-06-06 18:55:00 +02:00
}
static SetPropertyDelegate set_property_handler ;
static SetPropertyDelegate SetPropertyHandler {
get {
if ( set_property_handler = = null )
set_property_handler = new SetPropertyDelegate ( SetPropertyCallback ) ;
return set_property_handler ;
}
}
2004-12-23 23:59:59 +01:00
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2007-09-11 22:34:24 +02:00
static extern void g_type_add_interface_static ( IntPtr gtype , IntPtr iface_type , ref GInterfaceInfo info ) ;
2008-12-19 19:57:42 +01:00
protected internal static GType RegisterGType ( System . Type t )
2002-12-25 01:36:00 +01:00
{
2013-04-07 08:51:30 +02:00
//this is a deprecated way of tracking a property counter,
//but we may still need it for backwards compatibility
2011-11-20 19:41:56 +01:00
idx = 1 ;
2013-04-07 08:51:30 +02:00
return new ClassInitializer ( t ) . Init ( ) ;
2002-12-25 01:36:00 +01:00
}
2004-05-17 19:52:00 +02:00
protected GType LookupGType ( )
2004-05-07 15:42:59 +02:00
{
2009-05-04 00:49:12 +02:00
if ( Handle ! = IntPtr . Zero ) {
GTypeInstance obj = ( GTypeInstance ) Marshal . PtrToStructure ( Handle , typeof ( GTypeInstance ) ) ;
GTypeClass klass = ( GTypeClass ) Marshal . PtrToStructure ( obj . g_class , typeof ( GTypeClass ) ) ;
return new GLib . GType ( klass . gtype ) ;
} else {
return LookupGType ( GetType ( ) ) ;
}
2004-05-07 15:42:59 +02:00
}
2005-05-04 18:54:24 +02:00
protected internal static GType LookupGType ( System . Type t )
2004-04-07 21:15:01 +02:00
{
2008-12-19 19:57:42 +01:00
return GType . LookupGObjectType ( t ) ;
2004-04-07 21:15:01 +02:00
}
2002-02-03 04:44:10 +01:00
2004-05-17 19:52:00 +02:00
protected Object ( IntPtr raw )
2002-02-03 04:44:10 +01:00
{
2002-02-19 20:46:44 +01:00
Raw = raw ;
2002-02-03 04:44:10 +01:00
}
2001-09-19 04:04:57 +02:00
2007-10-02 05:02:43 +02:00
protected Object ( )
{
CreateNativeObject ( new string [ 0 ] , new GLib . Value [ 0 ] ) ;
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2003-12-15 17:59:25 +01:00
static extern IntPtr g_object_new ( IntPtr gtype , IntPtr dummy ) ;
2002-12-25 01:36:00 +01:00
2008-12-19 19:57:42 +01:00
struct GParameter {
public IntPtr name ;
public GLib . Value val ;
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2008-12-19 19:57:42 +01:00
static extern IntPtr g_object_newv ( IntPtr gtype , int n_params , GParameter [ ] parms ) ;
2004-05-07 15:42:59 +02:00
2004-11-09 15:22:39 +01:00
protected virtual void CreateNativeObject ( string [ ] names , GLib . Value [ ] vals )
2004-05-07 15:42:59 +02:00
{
2009-09-12 03:01:12 +02:00
GType gtype = LookupGType ( ) ;
2015-09-01 23:55:41 +02:00
bool is_managed_subclass = GType . IsManaged ( gtype ) ;
2009-09-12 03:01:12 +02:00
GParameter [ ] parms = new GParameter [ is_managed_subclass ? names . Length + 1 : names . Length ] ;
2008-12-19 19:57:42 +01:00
for ( int i = 0 ; i < names . Length ; i + + ) {
parms [ i ] . name = GLib . Marshaller . StringToPtrGStrdup ( names [ i ] ) ;
parms [ i ] . val = vals [ i ] ;
}
2009-09-12 03:01:12 +02:00
if ( is_managed_subclass ) {
GCHandle gch = GCHandle . Alloc ( this ) ;
parms [ names . Length ] . name = GLib . Marshaller . StringToPtrGStrdup ( "gtk-sharp-managed-instance" ) ;
parms [ names . Length ] . val = new GLib . Value ( ( IntPtr ) gch ) ;
Raw = g_object_newv ( gtype . Val , parms . Length , parms ) ;
gch . Free ( ) ;
} else {
Raw = g_object_newv ( gtype . Val , parms . Length , parms ) ;
}
2008-12-19 19:57:42 +01:00
foreach ( GParameter p in parms )
GLib . Marshaller . Free ( p . name ) ;
2004-05-07 15:42:59 +02:00
}
2002-11-10 11:09:05 +01:00
protected virtual IntPtr Raw {
2001-09-19 13:37:15 +02:00
get {
2007-11-16 19:35:38 +01:00
return handle ;
2001-09-19 04:04:57 +02:00
}
2001-09-19 13:37:15 +02:00
set {
2007-11-16 19:35:38 +01:00
if ( handle = = value )
2004-06-09 19:53:05 +02:00
return ;
2007-11-16 19:35:38 +01:00
2012-05-09 23:21:50 +02:00
lock ( Objects ) {
if ( handle ! = IntPtr . Zero ) {
Objects . Remove ( handle ) ;
if ( tref ! = null ) {
tref . Dispose ( ) ;
tref = null ;
}
}
handle = value ;
if ( value ! = IntPtr . Zero ) {
tref = new ToggleRef ( this ) ;
Objects [ value ] = tref ;
2008-01-22 17:54:44 +01:00
}
}
2001-09-19 04:04:57 +02:00
}
2002-11-10 11:09:05 +01:00
}
2001-09-19 04:04:57 +02:00
2004-05-27 18:35:21 +02:00
public static GLib . GType GType {
2011-03-25 00:11:10 +01:00
get { return GType . Object ; }
2002-08-09 05:56:27 +02:00
}
2004-05-17 19:52:00 +02:00
protected string TypeName {
2011-03-25 00:11:10 +01:00
get { return NativeType . ToString ( ) ; }
2003-12-03 21:23:25 +01:00
}
2004-05-17 19:52:00 +02:00
internal GLib . GType NativeType {
2011-03-25 00:11:10 +01:00
get { return LookupGType ( ) ; }
2002-11-18 19:55:39 +01:00
}
2008-01-22 17:54:44 +01:00
internal ToggleRef ToggleRef {
2011-03-25 00:11:10 +01:00
get { return tref ; }
2007-11-16 19:35:38 +01:00
}
2008-01-22 17:54:44 +01:00
public IntPtr Handle {
2011-03-25 00:11:10 +01:00
get { return handle ; }
2001-10-07 02:41:52 +02:00
}
2008-04-04 18:10:08 +02:00
public IntPtr OwnedHandle {
2011-03-25 00:11:10 +01:00
get { return g_object_ref ( handle ) ; }
2005-01-28 17:44:30 +01:00
}
public void AddNotification ( string property , NotifyHandler handler )
{
2011-03-25 00:11:10 +01:00
AddSignalHandler ( "notify::" + property , handler , typeof ( NotifyArgs ) ) ;
2005-01-28 17:44:30 +01:00
}
public void AddNotification ( NotifyHandler handler )
{
2011-03-25 00:11:10 +01:00
AddSignalHandler ( "notify" , handler , typeof ( NotifyArgs ) ) ;
2005-01-28 17:44:30 +01:00
}
public void RemoveNotification ( string property , NotifyHandler handler )
{
2011-03-25 00:11:10 +01:00
RemoveSignalHandler ( "notify::" + property , handler ) ;
2005-01-28 17:44:30 +01:00
}
public void RemoveNotification ( NotifyHandler handler )
{
2011-03-25 00:11:10 +01:00
RemoveSignalHandler ( "notify" , handler ) ;
2005-01-28 17:44:30 +01:00
}
2001-10-31 02:31:05 +01:00
public override int GetHashCode ( )
{
return Handle . GetHashCode ( ) ;
}
2011-03-25 00:11:10 +01:00
System . Collections . Hashtable data ;
public System . Collections . Hashtable Data {
2003-07-04 09:13:19 +02:00
get {
if ( data = = null )
2011-03-25 00:11:10 +01:00
data = new System . Collections . Hashtable ( ) ;
2003-07-04 09:13:19 +02:00
return data ;
}
2001-09-19 04:04:57 +02:00
}
2001-09-20 06:03:27 +02:00
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2005-03-08 22:28:08 +01:00
static extern void g_object_get_property ( IntPtr obj , IntPtr name , ref GLib . Value val ) ;
2004-03-16 20:43:04 +01:00
2016-12-18 23:17:12 +01:00
public GLib . Value GetProperty ( string name )
2001-09-28 20:23:14 +02:00
{
2004-04-12 17:54:57 +02:00
Value val = new Value ( this , name ) ;
2005-03-08 22:28:08 +01:00
IntPtr native_name = GLib . Marshaller . StringToPtrGStrdup ( name ) ;
g_object_get_property ( Raw , native_name , ref val ) ;
GLib . Marshaller . Free ( native_name ) ;
2004-04-12 17:54:57 +02:00
return val ;
2001-09-28 20:23:14 +02:00
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2005-03-08 22:28:08 +01:00
static extern void g_object_set_property ( IntPtr obj , IntPtr name , ref GLib . Value val ) ;
2004-03-16 20:43:04 +01:00
2016-12-18 23:17:12 +01:00
public void SetProperty ( string name , GLib . Value val )
2002-01-12 03:08:16 +01:00
{
2005-03-08 22:28:08 +01:00
IntPtr native_name = GLib . Marshaller . StringToPtrGStrdup ( name ) ;
g_object_set_property ( Raw , native_name , ref val ) ;
GLib . Marshaller . Free ( native_name ) ;
2002-01-12 03:08:16 +01:00
}
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2008-11-14 17:21:16 +01:00
static extern void g_object_notify ( IntPtr obj , IntPtr property_name ) ;
protected void Notify ( string property_name )
{
IntPtr native_name = GLib . Marshaller . StringToPtrGStrdup ( property_name ) ;
g_object_notify ( Handle , native_name ) ;
GLib . Marshaller . Free ( native_name ) ;
}
2011-03-25 00:11:10 +01:00
Dictionary < string , Signal > signals ;
Dictionary < string , Signal > Signals {
get {
if ( signals = = null )
signals = new Dictionary < string , Signal > ( ) ;
return signals ;
}
}
public void AddSignalHandler ( string name , Delegate handler )
{
AddSignalHandler ( name , handler , typeof ( EventArgs ) ) ;
}
public void AddSignalHandler ( string name , Delegate handler , Delegate marshaler )
{
Signal sig ;
if ( ! Signals . TryGetValue ( name , out sig ) ) {
sig = new Signal ( this , name , marshaler ) ;
Signals [ name ] = sig ;
}
sig . AddDelegate ( handler ) ;
}
public void AddSignalHandler ( string name , Delegate handler , Type args_type )
{
if ( args_type = = null )
args_type = handler . Method . GetParameters ( ) [ 1 ] . ParameterType ;
Signal sig ;
if ( ! Signals . TryGetValue ( name , out sig ) ) {
sig = new Signal ( this , name , args_type ) ;
Signals [ name ] = sig ;
}
sig . AddDelegate ( handler ) ;
}
public void RemoveSignalHandler ( string name , Delegate handler )
{
Signal sig ;
if ( Signals . TryGetValue ( name , out sig ) )
sig . RemoveDelegate ( handler ) ;
}
2003-12-15 17:59:25 +01:00
protected static void OverrideVirtualMethod ( GType gtype , string name , Delegate cb )
{
2008-12-19 19:57:42 +01:00
Signal . OverrideDefaultHandler ( gtype , name , cb ) ;
2003-12-15 17:59:25 +01:00
}
2003-12-10 23:56:49 +01:00
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2004-04-12 17:54:57 +02:00
protected static extern void g_signal_chain_from_overridden ( IntPtr args , ref GLib . Value retval ) ;
2003-12-09 06:01:22 +01:00
2013-11-05 11:12:27 +01:00
[DllImport (Global.GObjectNativeDll, CallingConvention = CallingConvention.Cdecl)]
2008-12-19 19:57:42 +01:00
static extern bool g_type_check_instance_is_a ( IntPtr obj , IntPtr gtype ) ;
2002-09-01 06:46:38 +02:00
internal static bool IsObject ( IntPtr obj )
{
2008-12-19 19:57:42 +01:00
return g_type_check_instance_is_a ( obj , GType . Object . Val ) ;
}
2017-08-31 13:42:08 +02:00
public struct GTypeInstance {
2008-12-19 19:57:42 +01:00
public IntPtr g_class ;
2002-09-01 06:46:38 +02:00
}
2002-11-10 11:09:05 +01:00
2017-08-31 13:42:08 +02:00
public struct GObject {
2008-12-19 19:57:42 +01:00
public GTypeInstance type_instance ;
public uint ref_count ;
public IntPtr qdata ;
}
2002-11-10 11:09:05 +01:00
2004-05-17 19:52:00 +02:00
protected int RefCount {
2002-11-10 11:09:05 +01:00
get {
2008-12-19 19:57:42 +01:00
GObject native = ( GObject ) Marshal . PtrToStructure ( Handle , typeof ( GObject ) ) ;
return ( int ) native . ref_count ;
2002-11-10 11:09:05 +01:00
}
}
2008-04-17 18:32:44 +02:00
internal void Harden ( )
{
tref . Harden ( ) ;
}
2008-04-30 22:15:45 +02:00
static Object ( )
{
2008-05-02 18:58:46 +02:00
if ( Environment . GetEnvironmentVariable ( "GTK_SHARP_DEBUG" ) ! = null )
2008-08-25 22:43:09 +02:00
GLib . Log . SetLogHandler ( "GLib-GObject" , GLib . LogLevelFlags . All , new GLib . LogFunc ( GLib . Log . PrintTraceLogFunction ) ) ;
2008-04-30 22:15:45 +02:00
}
2001-09-19 04:04:57 +02:00
}
}