glib2 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/ChangeLog +3023 -0
  2. data/README +28 -0
  3. data/Rakefile +87 -0
  4. data/extconf.rb +61 -0
  5. data/sample/bookmarkfile.rb +66 -0
  6. data/sample/completion.rb +45 -0
  7. data/sample/idle.rb +41 -0
  8. data/sample/iochannel.rb +44 -0
  9. data/sample/keyfile.rb +62 -0
  10. data/sample/shell.rb +36 -0
  11. data/sample/spawn.rb +25 -0
  12. data/sample/timeout.rb +28 -0
  13. data/sample/timeout2.rb +35 -0
  14. data/sample/timer.rb +40 -0
  15. data/sample/type-register.rb +103 -0
  16. data/sample/type-register2.rb +104 -0
  17. data/sample/utils.rb +54 -0
  18. data/src/glib-enum-types.c +1032 -0
  19. data/src/glib-enum-types.h +140 -0
  20. data/src/lib/glib-mkenums.rb +199 -0
  21. data/src/lib/glib2.rb +220 -0
  22. data/src/lib/mkmf-gnome2.rb +390 -0
  23. data/src/lib/pkg-config.rb +137 -0
  24. data/src/rbgcompat.h +30 -0
  25. data/src/rbglib.c +320 -0
  26. data/src/rbglib.h +96 -0
  27. data/src/rbglib_bookmarkfile.c +595 -0
  28. data/src/rbglib_completion.c +192 -0
  29. data/src/rbglib_convert.c +195 -0
  30. data/src/rbglib_error.c +95 -0
  31. data/src/rbglib_fileutils.c +83 -0
  32. data/src/rbglib_i18n.c +44 -0
  33. data/src/rbglib_int64.c +157 -0
  34. data/src/rbglib_iochannel.c +883 -0
  35. data/src/rbglib_keyfile.c +846 -0
  36. data/src/rbglib_maincontext.c +917 -0
  37. data/src/rbglib_mainloop.c +87 -0
  38. data/src/rbglib_messages.c +150 -0
  39. data/src/rbglib_pollfd.c +111 -0
  40. data/src/rbglib_shell.c +68 -0
  41. data/src/rbglib_source.c +190 -0
  42. data/src/rbglib_spawn.c +345 -0
  43. data/src/rbglib_threads.c +51 -0
  44. data/src/rbglib_timer.c +127 -0
  45. data/src/rbglib_unicode.c +611 -0
  46. data/src/rbglib_utils.c +386 -0
  47. data/src/rbglib_win32.c +136 -0
  48. data/src/rbgobj_boxed.c +251 -0
  49. data/src/rbgobj_closure.c +337 -0
  50. data/src/rbgobj_convert.c +167 -0
  51. data/src/rbgobj_enums.c +961 -0
  52. data/src/rbgobj_fundamental.c +30 -0
  53. data/src/rbgobj_object.c +892 -0
  54. data/src/rbgobj_param.c +390 -0
  55. data/src/rbgobj_paramspecs.c +305 -0
  56. data/src/rbgobj_signal.c +963 -0
  57. data/src/rbgobj_strv.c +61 -0
  58. data/src/rbgobj_type.c +851 -0
  59. data/src/rbgobj_typeinstance.c +121 -0
  60. data/src/rbgobj_typeinterface.c +148 -0
  61. data/src/rbgobj_typemodule.c +66 -0
  62. data/src/rbgobj_typeplugin.c +49 -0
  63. data/src/rbgobj_value.c +313 -0
  64. data/src/rbgobj_valuearray.c +59 -0
  65. data/src/rbgobj_valuetypes.c +298 -0
  66. data/src/rbgobject.c +406 -0
  67. data/src/rbgobject.h +265 -0
  68. data/src/rbgprivate.h +88 -0
  69. data/src/rbgutil.c +222 -0
  70. data/src/rbgutil.h +82 -0
  71. data/src/rbgutil_callback.c +231 -0
  72. data/test/glib-test-init.rb +6 -0
  73. data/test/glib-test-utils.rb +12 -0
  74. data/test/run-test.rb +25 -0
  75. data/test/test_enum.rb +99 -0
  76. data/test/test_file_utils.rb +15 -0
  77. data/test/test_glib2.rb +120 -0
  78. data/test/test_iochannel.rb +275 -0
  79. data/test/test_key_file.rb +38 -0
  80. data/test/test_mkenums.rb +25 -0
  81. data/test/test_signal.rb +20 -0
  82. data/test/test_timeout.rb +28 -0
  83. data/test/test_unicode.rb +369 -0
  84. data/test/test_utils.rb +37 -0
  85. data/test/test_win32.rb +13 -0
  86. metadata +165 -0
@@ -0,0 +1,59 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobj_valuearray.c -
5
+
6
+ $Author: mutoh $
7
+ $Date: 2006/05/17 14:00:24 $
8
+
9
+ Copyright (C) 2006 Sjoerd Simons
10
+ **********************************************************************/
11
+
12
+ #include "rbgprivate.h"
13
+
14
+ static VALUE
15
+ value_array_to_ruby(const GValue* from)
16
+ {
17
+ VALUE ary;
18
+ int i;
19
+ GValueArray *val_array = (GValueArray*)g_value_get_boxed(from);
20
+ if (!val_array)
21
+ return Qnil;
22
+
23
+ ary = rb_ary_new();
24
+ for (i = 0 ; i < val_array->n_values ; i++) {
25
+ rb_ary_push(ary, GVAL2RVAL(g_value_array_get_nth(val_array, i)));
26
+ }
27
+ return ary;
28
+ }
29
+
30
+ static void
31
+ value_array_from_ruby(VALUE from, GValue* to)
32
+ {
33
+ int i;
34
+ GValueArray * array;
35
+
36
+ if (NIL_P(from)) {
37
+ g_value_set_boxed(to, NULL);
38
+ return;
39
+ }
40
+
41
+ Check_Type(from, T_ARRAY);
42
+
43
+ array = g_value_array_new(0);
44
+
45
+ for (i = 0; i < RARRAY_LEN(from); i++) {
46
+ GValue v = { 0, };
47
+ g_value_init(&v, RVAL2GTYPE(RARRAY_PTR(from)[i]));
48
+ rbgobj_rvalue_to_gvalue(RARRAY_PTR(from)[i], &v);
49
+ g_value_array_append(array, &v);
50
+ }
51
+ g_value_set_boxed(to, array);
52
+ }
53
+
54
+ void Init_gobject_value_array()
55
+ {
56
+ /* ValueArray is treated as Array */
57
+ rbgobj_register_g2r_func(G_TYPE_VALUE_ARRAY, value_array_to_ruby);
58
+ rbgobj_register_r2g_func(G_TYPE_VALUE_ARRAY, value_array_from_ruby);
59
+ }
@@ -0,0 +1,298 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobj_valuetypes.c -
5
+
6
+ $Author: ggc $
7
+ $Date: 2007/07/13 14:27:07 $
8
+
9
+ Copyright (C) 2002,2003 Masahiro Sakai
10
+
11
+ **********************************************************************/
12
+
13
+ #include "rbgprivate.h"
14
+ #ifdef RBGOBJ_USE_DLPTR
15
+ #include "dl.h"
16
+ #endif
17
+
18
+
19
+ VALUE
20
+ rbgobj_ptr_new(type, ptr)
21
+ GType type;
22
+ gpointer ptr;
23
+ {
24
+ #ifdef RBGOBJ_USE_DLPTR
25
+ return rb_dlptr_new2(GTYPE2CLASS(type), 0, NULL);
26
+ #else
27
+ return Data_Wrap_Struct(GTYPE2CLASS(type), NULL, NULL, ptr);
28
+ #endif
29
+ }
30
+
31
+ gpointer
32
+ rbgobj_ptr2cptr(ptr)
33
+ VALUE ptr;
34
+ {
35
+ #ifdef RBGOBJ_USE_DLPTR
36
+ return rb_dlptr2cptr(ptr);
37
+ #else
38
+ gpointer dest;
39
+ if (rb_obj_is_kind_of(ptr, GTYPE2CLASS(G_TYPE_POINTER))){
40
+ Data_Get_Struct(ptr, void, dest);
41
+ } else if (rb_obj_is_kind_of(ptr, rb_cObject)){
42
+ dest = (gpointer)ptr;
43
+ } else{
44
+ rb_raise(rb_eTypeError, "not a pointer object");
45
+ }
46
+ return dest;
47
+ #endif
48
+ }
49
+
50
+ static VALUE
51
+ ptr_s_gtype(klass)
52
+ VALUE klass;
53
+ {
54
+ return rbgobj_gtype_new(rbgobj_lookup_class(klass)->gtype);
55
+ }
56
+
57
+ static VALUE
58
+ ptr_gtype(self)
59
+ VALUE self;
60
+ {
61
+ return ptr_s_gtype(CLASS_OF(self));
62
+ }
63
+
64
+ #ifndef RBGOBJ_USE_DLPTR
65
+ static VALUE
66
+ ptr_inspect(self)
67
+ VALUE self;
68
+ {
69
+ gpointer ptr;
70
+ gchar* s;
71
+ VALUE result;
72
+
73
+ Data_Get_Struct(self, void, ptr);
74
+
75
+ s = g_strdup_printf("#<%s:%p ptr=%p>",
76
+ rb_class2name(CLASS_OF(self)),
77
+ (void *)self,
78
+ ptr);
79
+
80
+ result = rb_str_new2(s);
81
+ g_free(s);
82
+
83
+ return result;
84
+ }
85
+
86
+ static VALUE
87
+ ptr_eql(self, other)
88
+ VALUE self, other;
89
+ {
90
+ gpointer ptr1, ptr2;
91
+ if (!rb_obj_is_kind_of(other, GTYPE2CLASS(G_TYPE_POINTER)))
92
+ return Qnil;
93
+ Data_Get_Struct(self, void, ptr1);
94
+ Data_Get_Struct(other, void, ptr2);
95
+ return CBOOL2RVAL(ptr1 == ptr2);
96
+ }
97
+
98
+ static VALUE
99
+ ptr_hash(self)
100
+ VALUE self;
101
+ {
102
+ gpointer ptr;
103
+ Data_Get_Struct(self, void, ptr);
104
+ return INT2FIX((long)ptr);
105
+ }
106
+ #endif
107
+
108
+ static void
109
+ Init_gtype_pointer()
110
+ {
111
+ VALUE cPtr = G_DEF_CLASS(G_TYPE_POINTER, "Pointer", mGLib);
112
+ rb_define_singleton_method(cPtr, "gtype", ptr_s_gtype, 1);
113
+ rb_define_method(cPtr, "gtype", ptr_gtype, 1);
114
+ #ifndef RBGOBJ_USE_DLPTR
115
+ rb_define_method(cPtr, "inspect", ptr_inspect, 0);
116
+ rb_define_method(cPtr, "==", ptr_eql, 1);
117
+ rb_define_method(cPtr, "eql?", ptr_eql, 1);
118
+ rb_define_method(cPtr, "hash", ptr_hash, 0);
119
+ #endif
120
+ }
121
+
122
+ /**********************************************************************/
123
+
124
+ static GHashTable* boxed_ruby_value_table;
125
+ static VALUE boxed_ruby_value_table_wrapper;
126
+
127
+ typedef struct {
128
+ VALUE obj;
129
+ guint ref_count;
130
+ } boxed_ruby_value_counter;
131
+
132
+ static void
133
+ boxed_ruby_value_counter_mark(gpointer key,
134
+ gpointer value,
135
+ gpointer user_data)
136
+ {
137
+ boxed_ruby_value_counter* counter = value;
138
+ if (counter->ref_count)
139
+ rb_gc_mark(counter->obj);
140
+ }
141
+
142
+ static void
143
+ boxed_ruby_value_table_mark(GHashTable* table)
144
+ {
145
+ g_hash_table_foreach(table, boxed_ruby_value_counter_mark, NULL);
146
+ }
147
+
148
+ static VALUE
149
+ boxed_ruby_value_ref(VALUE val)
150
+ {
151
+ if (!SPECIAL_CONST_P(val)){
152
+ boxed_ruby_value_counter* counter;
153
+
154
+ counter = g_hash_table_lookup(boxed_ruby_value_table, (gpointer)val);
155
+
156
+ if (!counter){
157
+ counter = g_new(boxed_ruby_value_counter, 1);
158
+ counter->obj = val;
159
+ counter->ref_count = 1;
160
+ g_hash_table_insert(boxed_ruby_value_table, (gpointer)val,
161
+ counter);
162
+ } else {
163
+ counter->ref_count += 1;
164
+ }
165
+ }
166
+ return val;
167
+ }
168
+
169
+ static void
170
+ boxed_ruby_value_unref(VALUE val)
171
+ {
172
+ if (!SPECIAL_CONST_P(val)){
173
+ boxed_ruby_value_counter* counter;
174
+
175
+ counter = g_hash_table_lookup(boxed_ruby_value_table, (gpointer)val);
176
+ counter->ref_count -= 1;
177
+
178
+ if (!counter->ref_count)
179
+ g_hash_table_remove(boxed_ruby_value_table, (gpointer)val);
180
+ }
181
+ }
182
+
183
+ struct transform_arg {
184
+ const GValue *src_value;
185
+ GValue *dest_value;
186
+ };
187
+
188
+ static VALUE
189
+ value_transform_ruby_any_impl(VALUE arg_)
190
+ {
191
+ struct transform_arg* arg = (struct transform_arg*)arg_;
192
+ rbgobj_rvalue_to_gvalue(g_value_get_ruby_value(arg->src_value),
193
+ arg->dest_value);
194
+ return Qnil;
195
+ }
196
+
197
+ static void
198
+ value_transform_ruby_any(const GValue *src_value,
199
+ GValue *dest_value)
200
+ {
201
+ int state;
202
+ struct transform_arg arg;
203
+ arg.src_value = src_value;
204
+ arg.dest_value = dest_value;
205
+ rb_protect(&value_transform_ruby_any_impl, (VALUE)&arg, &state);
206
+ }
207
+
208
+ static void
209
+ value_transform_any_ruby(const GValue *src_value,
210
+ GValue *dest_value)
211
+ {
212
+ g_value_set_ruby_value(dest_value, GVAL2RVAL(src_value));
213
+ }
214
+
215
+ GType rbgobj_ruby_value_get_type()
216
+ {
217
+ static GType our_type = 0;
218
+
219
+ if (!our_type){
220
+ const GType table[] = {
221
+ G_TYPE_CHAR,
222
+ G_TYPE_UCHAR,
223
+ G_TYPE_BOOLEAN,
224
+ G_TYPE_INT,
225
+ G_TYPE_UINT,
226
+ G_TYPE_LONG,
227
+ G_TYPE_ULONG,
228
+ G_TYPE_INT64,
229
+ G_TYPE_UINT64,
230
+ G_TYPE_ENUM,
231
+ G_TYPE_FLAGS,
232
+ G_TYPE_FLOAT,
233
+ G_TYPE_DOUBLE,
234
+ G_TYPE_STRING,
235
+ G_TYPE_POINTER,
236
+ //G_TYPE_BOXED,
237
+ G_TYPE_PARAM,
238
+ G_TYPE_OBJECT,
239
+ };
240
+ int i;
241
+
242
+ our_type = g_boxed_type_register_static(
243
+ "VALUE",
244
+ (GBoxedCopyFunc)boxed_ruby_value_ref,
245
+ (GBoxedFreeFunc)boxed_ruby_value_unref);
246
+
247
+ for (i = 0; i < sizeof(table)/sizeof(table[0]); i++){
248
+ g_value_register_transform_func(table[i], our_type,
249
+ value_transform_any_ruby);
250
+ }
251
+
252
+ g_value_register_transform_func(our_type, G_TYPE_BOOLEAN,
253
+ value_transform_ruby_any);
254
+ }
255
+ return our_type;
256
+ }
257
+
258
+ VALUE
259
+ g_value_get_ruby_value(const GValue* value)
260
+ {
261
+ return (VALUE)g_value_get_boxed(value);
262
+ }
263
+
264
+ void
265
+ g_value_set_ruby_value(GValue* value, VALUE ruby)
266
+ {
267
+ g_value_set_boxed(value, (gconstpointer)ruby);
268
+ }
269
+
270
+ static void
271
+ ruby_value_r2g(VALUE from, GValue* to)
272
+ {
273
+ g_value_set_ruby_value(to, from);
274
+ }
275
+
276
+ static void
277
+ Init_boxed_ruby_value()
278
+ {
279
+ boxed_ruby_value_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
280
+
281
+ boxed_ruby_value_table_wrapper =
282
+ Data_Wrap_Struct(rb_cData,
283
+ boxed_ruby_value_table_mark, NULL,
284
+ boxed_ruby_value_table);
285
+ rb_global_variable(&boxed_ruby_value_table_wrapper);
286
+
287
+ rbgobj_register_g2r_func(RBGOBJ_TYPE_RUBY_VALUE, g_value_get_ruby_value);
288
+ rbgobj_register_r2g_func(RBGOBJ_TYPE_RUBY_VALUE, ruby_value_r2g);
289
+ }
290
+
291
+ /**********************************************************************/
292
+
293
+ void
294
+ Init_gobject_gvaluetypes()
295
+ {
296
+ Init_gtype_pointer();
297
+ Init_boxed_ruby_value();
298
+ }
data/src/rbgobject.c ADDED
@@ -0,0 +1,406 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobject.c -
5
+
6
+ $Author: ktou $
7
+ $Date: 2007/10/03 12:48:55 $
8
+
9
+ Copyright (C) 2003-2006 Ruby-GNOME2 Project Team
10
+ Copyright (C) 2002,2003 Masahiro Sakai
11
+
12
+ This file is derived from rbgtkobject.c in Ruby/Gtk distribution.
13
+ rbgtkobject.c -
14
+ Copyright (C) 1998-2000 Yukihiro Matsumoto,
15
+ Daisuke Kanda,
16
+ Hiroshi Igarashi
17
+
18
+ **********************************************************************/
19
+
20
+ #include "ruby.h"
21
+ #include "rbgprivate.h"
22
+ #include <ctype.h>
23
+
24
+ #include "rbgprivate.h"
25
+
26
+ static ID id_relatives;
27
+ static ID id_delete;
28
+ static ID id_module_eval;
29
+
30
+ ID rbgobj_id_children;
31
+
32
+ /**********************************************************************/
33
+
34
+ void
35
+ rbgobj_initialize_object(VALUE obj, gpointer cobj)
36
+ {
37
+ GType type;
38
+ GType parent_type;
39
+
40
+ if (!cobj)
41
+ rb_raise(rb_eRuntimeError, "failed to initialize");
42
+
43
+ type = RVAL2GTYPE(obj);
44
+
45
+ for (parent_type = type;
46
+ parent_type != G_TYPE_INVALID;
47
+ parent_type = g_type_parent(parent_type)) {
48
+
49
+ if (rbgobj_convert_initialize(parent_type, obj, cobj))
50
+ return;
51
+ }
52
+
53
+ type = G_TYPE_FUNDAMENTAL(type);
54
+ switch (type){
55
+ case G_TYPE_OBJECT:
56
+ rbgobj_gobject_initialize(obj, cobj);
57
+ break;
58
+ case G_TYPE_PARAM:
59
+ rbgobj_param_spec_initialize(obj, cobj);
60
+ break;
61
+ case G_TYPE_BOXED:
62
+ rbgobj_boxed_initialize(obj, cobj);
63
+ break;
64
+ default:
65
+ rbgobj_convert_initialize(type, obj, cobj);
66
+ }
67
+ }
68
+
69
+ gpointer
70
+ rbgobj_instance_from_ruby_object(VALUE obj)
71
+ {
72
+ GType type;
73
+
74
+ if (NIL_P(obj))
75
+ return NULL;
76
+
77
+ type = RVAL2GTYPE(obj);
78
+ if (rbgobj_convert_has_type(type)) {
79
+ gpointer instance;
80
+ if (rbgobj_convert_robj2instance(type, obj, &instance))
81
+ return instance;
82
+ }
83
+
84
+ type = G_TYPE_FUNDAMENTAL(type);
85
+ switch (type){
86
+ case G_TYPE_OBJECT:
87
+ return rbgobj_get_gobject(obj);
88
+ case G_TYPE_PARAM:
89
+ return rbgobj_get_param_spec(obj);
90
+ default:
91
+ {
92
+ gpointer instance;
93
+ if (!rbgobj_convert_robj2instance(type, obj, &instance)) {
94
+ rb_raise(rb_eTypeError, "%s isn't supported",
95
+ rb_class2name(CLASS_OF(obj)));
96
+ }
97
+ return instance;
98
+ }
99
+ }
100
+ }
101
+
102
+ VALUE
103
+ rbgobj_ruby_object_from_instance(gpointer instance)
104
+ {
105
+ return rbgobj_ruby_object_from_instance2(instance, TRUE);
106
+ }
107
+
108
+ VALUE
109
+ rbgobj_ruby_object_from_instance2(gpointer instance, gboolean alloc)
110
+ {
111
+ VALUE object;
112
+ GType type;
113
+
114
+ if (!instance)
115
+ return Qnil;
116
+
117
+ type = G_TYPE_FROM_INSTANCE(instance);
118
+ if (alloc) {
119
+ GType parent_type;
120
+ for (parent_type = type;
121
+ parent_type != G_TYPE_INVALID;
122
+ parent_type = g_type_parent(parent_type)) {
123
+ if (rbgobj_convert_instance2robj(parent_type, instance, &object))
124
+ return object;
125
+ }
126
+ }
127
+
128
+ switch (G_TYPE_FUNDAMENTAL(type)) {
129
+ case G_TYPE_OBJECT:
130
+ return rbgobj_get_ruby_object_from_gobject(instance, alloc);
131
+ case G_TYPE_PARAM:
132
+ return rbgobj_get_ruby_object_from_param_spec(instance, alloc);
133
+ default:
134
+ if (alloc) {
135
+ rb_raise(rb_eTypeError, "%s isn't supported", g_type_name(type));
136
+ } else {
137
+ return Qnil;
138
+ }
139
+ }
140
+ }
141
+
142
+ VALUE
143
+ rbgobj_ruby_object_from_instance_with_unref(gpointer instance)
144
+ {
145
+ VALUE result = rbgobj_ruby_object_from_instance(instance);
146
+ if (!NIL_P(result)) {
147
+ GType type;
148
+
149
+ type = G_TYPE_FROM_INSTANCE(instance);
150
+ if (!rbgobj_convert_unref(type, instance)) {
151
+ type = G_TYPE_FUNDAMENTAL(type);
152
+ switch (type) {
153
+ case G_TYPE_OBJECT:
154
+ g_object_unref(instance);
155
+ break;
156
+ default:
157
+ rbgobj_convert_unref(type, instance);
158
+ break;
159
+ }
160
+ }
161
+ }
162
+ return result;
163
+ }
164
+
165
+ /**********************************************************************/
166
+
167
+ void
168
+ rbgobj_add_relative(obj, relative)
169
+ VALUE obj, relative;
170
+ {
171
+ VALUE hash = Qnil;
172
+
173
+ if (RVAL2CBOOL(rb_ivar_defined(obj, id_relatives)))
174
+ hash = rb_ivar_get(obj, id_relatives);
175
+
176
+ if (NIL_P(hash) || TYPE(hash) != T_HASH) {
177
+ hash = rb_hash_new();
178
+ rb_ivar_set(obj, id_relatives, hash);
179
+ }
180
+ rb_hash_aset(hash, relative, Qnil);
181
+ }
182
+
183
+ void
184
+ rbgobj_invalidate_relatives(obj)
185
+ VALUE obj;
186
+ {
187
+ if (RVAL2CBOOL(rb_ivar_defined(obj, id_relatives)))
188
+ rb_ivar_set(obj, id_relatives, Qnil);
189
+ if (RVAL2CBOOL(rb_ivar_defined(obj, rbgobj_id_children)))
190
+ rb_ivar_set(obj, rbgobj_id_children, Qnil);
191
+ }
192
+
193
+ void
194
+ rbgobj_add_relative_removable(obj, relative, obj_ivar_id, hash_key)
195
+ VALUE obj, relative, hash_key;
196
+ ID obj_ivar_id;
197
+ {
198
+ VALUE hash = Qnil;
199
+
200
+ if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id)))
201
+ hash = rb_ivar_get(obj, obj_ivar_id);
202
+
203
+ if (NIL_P(hash) || TYPE(hash) != T_HASH) {
204
+ hash = rb_hash_new();
205
+ rb_ivar_set(obj, obj_ivar_id, hash);
206
+ }
207
+ rb_hash_aset(hash, hash_key, relative);
208
+ }
209
+
210
+ VALUE
211
+ rbgobj_get_relative_removable(obj, obj_ivar_id, hash_key)
212
+ VALUE obj, hash_key;
213
+ ID obj_ivar_id;
214
+ {
215
+ VALUE hash = Qnil;
216
+
217
+ if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id)))
218
+ hash = rb_ivar_get(obj, obj_ivar_id);
219
+
220
+ if (NIL_P(hash) || TYPE(hash) != T_HASH) {
221
+ return Qnil;
222
+ }
223
+ return rb_hash_aref(hash, hash_key);
224
+ }
225
+
226
+ void
227
+ rbgobj_remove_relative(obj, obj_ivar_id, hash_key)
228
+ VALUE obj, hash_key;
229
+ ID obj_ivar_id;
230
+ {
231
+ VALUE hash = Qnil;
232
+
233
+ if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id)))
234
+ hash = rb_ivar_get(obj, obj_ivar_id);
235
+
236
+ if (NIL_P(hash) || TYPE(hash) != T_HASH) {
237
+ /* should not happen. */
238
+ } else {
239
+ rb_funcall(hash, id_delete, 1, hash_key);
240
+ }
241
+ }
242
+
243
+ void
244
+ rbgobj_remove_relative_all(obj, obj_ivar_id)
245
+ VALUE obj;
246
+ ID obj_ivar_id;
247
+ {
248
+ rb_ivar_set(obj, obj_ivar_id, Qnil);
249
+ }
250
+
251
+ /**********************************************************************/
252
+
253
+ static GHashTable* prop_exclude_list;
254
+
255
+ #define IS_FLAG(bitmask, flag) (((bitmask) & (flag)) == (flag))
256
+
257
+ void
258
+ rbgobj_define_property_accessors(klass)
259
+ VALUE klass;
260
+ {
261
+ GType gtype;
262
+ GParamSpec** pspecs = NULL;
263
+ int i;
264
+ GString* source;
265
+ guint n_properties = 0;
266
+ gtype = CLASS2GTYPE(klass);
267
+
268
+ if (G_TYPE_IS_INTERFACE(gtype)){
269
+ #if GLIB_CHECK_VERSION(2,4,0)
270
+ gpointer iface = g_type_default_interface_ref(gtype);
271
+ pspecs = g_object_interface_list_properties(iface, &n_properties);
272
+ g_type_default_interface_unref(iface);
273
+ #endif
274
+ } else {
275
+ GObjectClass* oclass = G_OBJECT_CLASS(g_type_class_ref(gtype));
276
+ pspecs = g_object_class_list_properties(oclass, &n_properties);
277
+ g_type_class_unref(oclass);
278
+ }
279
+
280
+ if (n_properties == 0)
281
+ return;
282
+
283
+ source = g_string_new(NULL);
284
+ for (i = 0; i < n_properties; i++){
285
+ GParamSpec* pspec = pspecs[i];
286
+ char* buf;
287
+ char* prop_name;
288
+ char* p;
289
+
290
+ if (pspec->owner_type != gtype)
291
+ continue;
292
+
293
+ buf = g_strdup(pspec->name);
294
+ for (p = buf; *p; p++)
295
+ if (*p == '-')
296
+ *p = '_';
297
+
298
+ if (!strncmp(buf, "is_", 3))
299
+ prop_name = buf + 3;
300
+ else
301
+ prop_name = buf;
302
+
303
+ if (g_hash_table_lookup(prop_exclude_list, prop_name)){
304
+ g_free(buf);
305
+ continue;
306
+ }
307
+
308
+ if (pspec->flags & G_PARAM_READABLE){
309
+ g_string_append_printf(
310
+ source,
311
+ "def %s%s; get_property('%s'); end\n",
312
+ prop_name,
313
+ (G_PARAM_SPEC_VALUE_TYPE(pspec) == G_TYPE_BOOLEAN) ? "?" : "",
314
+ pspec->name);
315
+ }
316
+
317
+ if (IS_FLAG(pspec->flags, G_PARAM_WRITABLE) && !IS_FLAG(pspec->flags, G_PARAM_CONSTRUCT_ONLY)){
318
+ g_string_append_printf(source,
319
+ "def set_%s(val); set_property('%s', val); end\n",
320
+ prop_name, pspec->name);
321
+ #ifdef HAVE_NODE_ATTRASGN
322
+ g_string_append_printf(source, "alias %s= set_%s\n",
323
+ prop_name, prop_name);
324
+ #else
325
+ g_string_append_printf(source,
326
+ "def %s=(val); set_property('%s', val); val; end\n",
327
+ prop_name, pspec->name);
328
+ #endif
329
+ }
330
+
331
+ g_free(buf);
332
+ }
333
+
334
+ if (source->len > 0)
335
+ rb_funcall(klass, id_module_eval, 1, rb_str_new2(source->str));
336
+ g_string_free(source, TRUE);
337
+ }
338
+
339
+ /**********************************************************************/
340
+
341
+ void
342
+ Init_gobject()
343
+ {
344
+ extern void Init_gobject_convert();
345
+ extern void Init_gobject_gtype();
346
+ extern void Init_gobject_typeinterface();
347
+ extern void Init_gobject_typeinstance();
348
+ extern void Init_gobject_gvalue();
349
+ extern void Init_gobject_gvaluetypes();
350
+ extern void Init_gobject_gboxed();
351
+ #if GLIB_CHECK_VERSION(2,6,0)
352
+ extern void Init_gobject_gstrv();
353
+ #endif
354
+ extern void Init_gobject_value_array();
355
+ extern void Init_gobject_genums();
356
+ extern void Init_gobject_gparam();
357
+ extern void Init_gobject_gparamspecs();
358
+ extern void Init_gobject_gclosure();
359
+ extern void Init_gobject_gobject();
360
+ extern void Init_gobject_gsignal();
361
+ extern void Init_gobject_gtypeplugin();
362
+ extern void Init_gobject_gtypemodule();
363
+
364
+ /* Not defined properties. They are already used as methods of Object */
365
+ prop_exclude_list = g_hash_table_new(g_str_hash, g_str_equal);
366
+ g_hash_table_insert(prop_exclude_list, "class", "class");
367
+ g_hash_table_insert(prop_exclude_list, "clone", "clone");
368
+ g_hash_table_insert(prop_exclude_list, "dup", "dup");
369
+ g_hash_table_insert(prop_exclude_list, "extend", "extend");
370
+ g_hash_table_insert(prop_exclude_list, "freeze", "freeze");
371
+ g_hash_table_insert(prop_exclude_list, "hash", "hash");
372
+ g_hash_table_insert(prop_exclude_list, "method", "method");
373
+ g_hash_table_insert(prop_exclude_list, "methods", "methods");
374
+ g_hash_table_insert(prop_exclude_list, "object_id", "object_id");
375
+ g_hash_table_insert(prop_exclude_list, "taint", "taint");
376
+ g_hash_table_insert(prop_exclude_list, "untaint", "untaint");
377
+
378
+ /* IDs */
379
+ id_relatives = rb_intern("__relatives__");
380
+ id_delete = rb_intern("delete");
381
+ id_module_eval = rb_intern("module_eval");
382
+
383
+ rbgobj_id_children = rb_intern("__stored_children__");
384
+
385
+ Init_gobject_convert();
386
+
387
+ Init_gobject_gtype();
388
+ Init_gobject_typeinterface();
389
+ Init_gobject_typeinstance();
390
+ Init_gobject_gvalue();
391
+ Init_gobject_gvaluetypes();
392
+ Init_gobject_gboxed();
393
+ #if GLIB_CHECK_VERSION(2,6,0)
394
+ Init_gobject_gstrv();
395
+ #endif
396
+ Init_gobject_value_array();
397
+ Init_gobject_genums();
398
+ Init_gobject_gparam();
399
+ Init_gobject_gparamspecs();
400
+ Init_gobject_gclosure();
401
+ Init_gobject_gobject();
402
+ Init_gobject_gsignal();
403
+
404
+ Init_gobject_gtypeplugin();
405
+ Init_gobject_gtypemodule();
406
+ }