1 /* object.c : Glue to clean up GtkObject references.
2  *
3  * Author: Mike Kestner <mkestner@speakeasy.net>
4  *
5  * Copyright (c) 2002 Mike Kestner
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2 of the Lesser GNU General
9  * Public License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
22 #include <glib-object.h>
23 
24 /* Forward declarations */
25 int      gtksharp_object_get_ref_count (GObject *obj);
26 GObject *gtksharp_object_newv (GType type, gint cnt, gchar **names, GValue *vals);
27 void gtksharp_override_property_handlers(GType type, gpointer get_property_cb, gpointer set_property_cb);
28 GParamSpec *gtksharp_register_property(GType declaring_type, const gchar *name, const gchar *nick, const gchar *blurb, guint id, GType return_type, gboolean can_read, gboolean can_write);
29 /* */
30 
31 int
gtksharp_object_get_ref_count(GObject * obj)32 gtksharp_object_get_ref_count (GObject *obj)
33 {
34 	return obj->ref_count;
35 }
36 
37 GObject *
gtksharp_object_newv(GType type,gint cnt,gchar ** names,GValue * vals)38 gtksharp_object_newv (GType type, gint cnt, gchar **names, GValue *vals)
39 {
40 	int i;
41 	GParameter *parms = NULL;
42 	GObject *result;
43 
44 	if (cnt > 0)
45 		parms = g_new0 (GParameter, cnt);
46 
47 	for (i = 0; i < cnt; i++) {
48 		parms[i].name = names[i];
49 		parms[i].value = vals[i];
50 	}
51 
52 	result = g_object_newv (type, cnt, parms);
53 
54 	g_free (parms);
55 	return result;
56 }
57 
58 void
gtksharp_override_property_handlers(GType type,gpointer get_property_cb,gpointer set_property_cb)59 gtksharp_override_property_handlers(GType type, gpointer get_property_cb, gpointer set_property_cb)
60 {
61 	GObjectClass *type_class = g_type_class_peek (type);
62 	if(!type_class)
63 		type_class = g_type_class_ref (type);
64 
65 	type_class->get_property = get_property_cb;
66 	type_class->set_property = set_property_cb;
67 }
68 
69 GParamSpec *
gtksharp_register_property(GType declaring_type,const gchar * name,const gchar * nick,const gchar * blurb,guint id,GType return_type,gboolean can_read,gboolean can_write)70 gtksharp_register_property(GType declaring_type, const gchar *name, const gchar *nick, const gchar *blurb, guint id, GType return_type, gboolean can_read, gboolean can_write)
71 {
72 	GParamSpec *param_spec;
73 	GParamFlags flags = 0;
74 	GObjectClass *declaring_class = g_type_class_peek (declaring_type);
75 	if (!declaring_class)
76 		declaring_class = g_type_class_ref (declaring_type);
77 	if (can_read)
78 		flags |= G_PARAM_READABLE;
79 	if (can_write)
80 		flags |= G_PARAM_WRITABLE;
81 
82 	/* Create the ParamSpec for the property
83 	*  These are used to hold default values and to validate values
84 	*  Both is not needed since the check for invalid values takes place in the managed set accessor of the property and properties do not
85 	*  contain default values. Therefore the ParamSpecs must allow every value that can be assigned to the property type.
86 	*  Furthermore the default value that is specified in the constructors will never be used and assigned to the property;
87 	*  they are not relevant, but have to be passed
88 	*/
89 
90 	switch (return_type) {
91 	case G_TYPE_CHAR:
92 		param_spec = g_param_spec_char (name, nick, blurb, G_MININT8, G_MAXINT8, 0, flags);
93 		break;
94 	case G_TYPE_UCHAR:
95 		param_spec = g_param_spec_uchar (name, nick, blurb, 0, G_MAXUINT8, 0, flags);
96 		break;
97 	case G_TYPE_BOOLEAN:
98 		param_spec = g_param_spec_boolean (name, nick, blurb, FALSE, flags);
99 		break;
100 	case G_TYPE_INT:
101 		param_spec = g_param_spec_int (name, nick, blurb, G_MININT, G_MAXINT, 0, flags);
102 		break;
103 	case G_TYPE_UINT:
104 		param_spec = g_param_spec_uint (name, nick, blurb, 0, G_MAXUINT, 0, flags);
105 		break;
106 	case G_TYPE_LONG:
107 		param_spec = g_param_spec_long (name, nick, blurb, G_MINLONG, G_MAXLONG, 0, flags);
108 		break;
109 	case G_TYPE_ULONG:
110 		param_spec = g_param_spec_ulong (name, nick, blurb, 0, G_MAXULONG, 0, flags);
111 		break;
112 	case G_TYPE_INT64:
113 		param_spec = g_param_spec_int64 (name, nick, blurb, G_MININT64, G_MAXINT64, 0, flags);
114 		break;
115 	case G_TYPE_UINT64:
116 		param_spec = g_param_spec_uint64 (name, nick, blurb, 0, G_MAXUINT64, 0, flags);
117 		break;
118 	/* case G_TYPE_ENUM:
119 	* case G_TYPE_FLAGS:
120 	* TODO: Implement both G_TYPE_ENUM and G_TYPE_FLAGS
121 	* My problem: Both g_param_spec_enum and g_param_spec_flags expect default property values and the members of the enum seemingly cannot be enumerated
122 	*/
123 	case G_TYPE_FLOAT:
124 		param_spec = g_param_spec_float (name, nick, blurb, -G_MINFLOAT, G_MAXFLOAT, 0, flags);
125 		break;
126 	case G_TYPE_DOUBLE:
127 		param_spec = g_param_spec_double (name, nick, blurb, -G_MINDOUBLE, G_MAXDOUBLE, 0, flags);
128 		break;
129 	case G_TYPE_STRING:
130 		param_spec = g_param_spec_string (name, nick, blurb, NULL, flags);
131 		break;
132 	case G_TYPE_POINTER:
133 		param_spec = g_param_spec_pointer (name, nick, blurb, flags);
134 		break;
135 	default:
136 		if(return_type == G_TYPE_GTYPE)
137 			param_spec = g_param_spec_gtype (name, nick, blurb, G_TYPE_NONE, flags);
138 		else if(g_type_is_a (return_type, G_TYPE_BOXED))
139 			param_spec = g_param_spec_boxed (name, nick, blurb, return_type, flags);
140 		else if(g_type_is_a (return_type, G_TYPE_OBJECT))
141 			param_spec = g_param_spec_object (name, nick, blurb, return_type, flags);
142 		else
143 			// The property's return type is not supported
144 			return NULL;
145 	}
146 
147 	g_object_class_install_property (declaring_class, id, param_spec);
148 	return param_spec;
149 }
150