glib2 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }