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