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
data/src/rbgobj_strv.c ADDED
@@ -0,0 +1,61 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobj_gstrv.c -
5
+
6
+ $Author: sakai $
7
+ $Date: 2007/07/07 08:46:50 $
8
+
9
+ Copyright (C) 2005 Masao Mutoh
10
+ **********************************************************************/
11
+
12
+ #include "rbgprivate.h"
13
+
14
+ #if GLIB_CHECK_VERSION(2,6,0)
15
+
16
+ static VALUE
17
+ strv_to_ruby(const GValue* from)
18
+ {
19
+ VALUE ary;
20
+ const gchar** boxed = (const gchar**)g_value_get_boxed(from);
21
+ if (!boxed)
22
+ return Qnil;
23
+
24
+ ary = rb_ary_new();
25
+ while (*boxed){
26
+ rb_ary_push(ary, CSTR2RVAL(*boxed));
27
+ boxed++;
28
+ }
29
+ return ary;
30
+ }
31
+
32
+ static void
33
+ strv_from_ruby(VALUE from, GValue* to)
34
+ {
35
+ int i;
36
+ gchar** gstrv;
37
+
38
+ if (NIL_P(from)) {
39
+ g_value_set_boxed(to, NULL);
40
+ return;
41
+ }
42
+
43
+ Check_Type(from, T_ARRAY);
44
+ gstrv = g_new(gchar*, RARRAY_LEN(from) + 1);
45
+
46
+ for (i = 0; i < RARRAY_LEN(from); i++) {
47
+ VALUE v = RARRAY_PTR(from)[i];
48
+ gstrv[i] = g_strdup(StringValuePtr(v));
49
+ }
50
+ gstrv[RARRAY_LEN(from)] = NULL;
51
+
52
+ g_value_set_boxed(to, gstrv);
53
+ }
54
+
55
+ void Init_gobject_gstrv()
56
+ {
57
+ /* GStrv is treated as Array */
58
+ rbgobj_register_g2r_func(G_TYPE_STRV, strv_to_ruby);
59
+ rbgobj_register_r2g_func(G_TYPE_STRV, strv_from_ruby);
60
+ }
61
+ #endif
data/src/rbgobj_type.c ADDED
@@ -0,0 +1,851 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /**********************************************************************
3
+
4
+ rbgobj_type.c -
5
+
6
+ $Author: sakai $
7
+ $Date: 2007/07/16 03:35:53 $
8
+ created at: Sun Jun 9 20:31:47 JST 2002
9
+
10
+ Copyright (C) 2002-2009 Ruby-GNOME2 Project Team
11
+ Copyright (C) 2002,2003 Masahiro Sakai
12
+
13
+ **********************************************************************/
14
+
15
+ #include "rbgprivate.h"
16
+
17
+ /**********************************************************************/
18
+ /* Type Mapping */
19
+
20
+ #ifdef RBGOBJ_USE_DLPTR
21
+ #include "dl.h"
22
+ #endif
23
+
24
+ static VALUE rb_cMutex;
25
+ static VALUE lookup_class_mutex;
26
+
27
+ static ID id_new;
28
+ static ID id_superclass;
29
+ static ID id_lock;
30
+ static ID id_unlock;
31
+ static GHashTable *gtype_to_cinfo;
32
+ static VALUE klass_to_cinfo;
33
+
34
+ static GHashTable* dynamic_gtype_list;
35
+ typedef struct {
36
+ const gchar* name;
37
+ VALUE module;
38
+ void (*mark)(gpointer);
39
+ void (*free)(gpointer);
40
+ int flags; /* RGObjClassFlag */
41
+ } RGObjClassInfoDynamic;
42
+
43
+ typedef struct {
44
+ VALUE parent;
45
+ GType gtype;
46
+ gboolean create_class;
47
+ } RGObjClassByGtypeData;
48
+
49
+ static void
50
+ cinfo_mark(RGObjClassInfo* cinfo)
51
+ {
52
+ rb_gc_mark(cinfo->klass);
53
+ }
54
+
55
+
56
+ const RGObjClassInfo *
57
+ rbgobj_lookup_class(klass)
58
+ VALUE klass;
59
+ {
60
+ VALUE data = rb_hash_aref(klass_to_cinfo, klass);
61
+ if (!NIL_P(data)){
62
+ RGObjClassInfo* cinfo;
63
+ Data_Get_Struct(data, RGObjClassInfo, cinfo);
64
+ return cinfo;
65
+ }
66
+
67
+ if (TYPE(klass) == T_CLASS) {
68
+ VALUE super;
69
+ if (FL_TEST(klass, FL_SINGLETON)) {
70
+ super = rb_class_real(klass);
71
+ } else {
72
+ super = rb_funcall(klass, id_superclass, 0);
73
+ }
74
+ return rbgobj_lookup_class(super);
75
+ }
76
+
77
+ rb_raise(rb_eRuntimeError, "can't get gobject class information");
78
+ }
79
+
80
+ static const RGObjClassInfo *rbgobj_lookup_class_by_gtype_without_lock(GType gtype,
81
+ VALUE parent,
82
+ gboolean create_class);
83
+
84
+ static VALUE
85
+ get_superclass(GType gtype)
86
+ {
87
+ VALUE super_class;
88
+
89
+ if (rbgobj_convert_get_superclass(gtype, &super_class))
90
+ return super_class;
91
+
92
+ switch (gtype) {
93
+ case G_TYPE_PARAM:
94
+ case G_TYPE_OBJECT:
95
+ return cInstantiatable;
96
+ case G_TYPE_BOXED:
97
+ return rb_cObject;
98
+ case G_TYPE_POINTER:
99
+ #ifdef RBGOBJ_USE_DLPTR
100
+ return rb_cDLPtrData;
101
+ #else
102
+ return rb_cData;
103
+ #endif
104
+ case G_TYPE_ENUM:
105
+ case G_TYPE_FLAGS:
106
+ return rb_cObject;
107
+ default:
108
+ {
109
+ const RGObjClassInfo *cinfo_super;
110
+ GType parent_type;
111
+
112
+ parent_type = g_type_parent(gtype);
113
+ cinfo_super = rbgobj_lookup_class_by_gtype_without_lock(parent_type,
114
+ Qnil,
115
+ TRUE);
116
+ return cinfo_super->klass;
117
+ }
118
+ }
119
+ }
120
+
121
+ static const RGObjClassInfo *
122
+ rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent,
123
+ gboolean create_class)
124
+ {
125
+ GType fundamental_type;
126
+ RGObjClassInfo* cinfo;
127
+ RGObjClassInfoDynamic* cinfod;
128
+ void* gclass = NULL;
129
+ VALUE c;
130
+
131
+ if (gtype == G_TYPE_INVALID)
132
+ return NULL;
133
+
134
+ cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype));
135
+ if (cinfo)
136
+ return cinfo;
137
+
138
+ if (!create_class)
139
+ return NULL;
140
+
141
+ c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
142
+ cinfo->gtype = gtype;
143
+ cinfo->mark = NULL;
144
+ cinfo->free = NULL;
145
+ cinfo->flags = 0;
146
+
147
+ fundamental_type = G_TYPE_FUNDAMENTAL(gtype);
148
+ switch (fundamental_type){
149
+ case G_TYPE_POINTER:
150
+ case G_TYPE_BOXED:
151
+ case G_TYPE_PARAM:
152
+ case G_TYPE_OBJECT:
153
+ case G_TYPE_ENUM:
154
+ case G_TYPE_FLAGS:
155
+ if (NIL_P(parent)) parent = get_superclass(gtype);
156
+ cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
157
+ break;
158
+
159
+ case G_TYPE_INTERFACE:
160
+ cinfo->klass = rb_module_new();
161
+ break;
162
+
163
+ default:
164
+ if (NIL_P(parent)) parent = get_superclass(gtype);
165
+ if (NIL_P(parent)) {
166
+ fprintf(stderr,
167
+ "%s: %s's fundamental type %s isn't supported\n",
168
+ "rbgobj_lookup_class_by_gtype",
169
+ g_type_name(gtype),
170
+ g_type_name(fundamental_type));
171
+ return NULL;
172
+ }
173
+ cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
174
+ }
175
+
176
+ cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list,
177
+ g_type_name(gtype));
178
+ if (cinfod){
179
+ cinfo->mark = cinfod->mark;
180
+ cinfo->free = cinfod->free;
181
+ rb_define_const(cinfod->module, cinfod->name, cinfo->klass);
182
+ }
183
+
184
+ rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
185
+ g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);
186
+
187
+ if (G_TYPE_IS_CLASSED(gtype))
188
+ gclass = g_type_class_ref(gtype);
189
+
190
+ if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype))
191
+ rbgobj_define_action_methods(cinfo->klass);
192
+
193
+ if (G_TYPE_IS_INSTANTIATABLE(gtype)){
194
+ GType* interfaces = NULL;
195
+ guint n_interfaces = 0;
196
+ int i;
197
+
198
+ interfaces = g_type_interfaces(gtype, &n_interfaces);
199
+ for (i = 0; i < n_interfaces; i++){
200
+ const RGObjClassInfo *iface_cinfo;
201
+ iface_cinfo =
202
+ rbgobj_lookup_class_by_gtype_without_lock(interfaces[i],
203
+ Qnil,
204
+ TRUE);
205
+ rb_include_module(cinfo->klass, iface_cinfo->klass);
206
+ }
207
+ g_free(interfaces);
208
+ }
209
+
210
+ if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) {
211
+ switch (fundamental_type) {
212
+ case G_TYPE_OBJECT:
213
+ rbgobj_init_object_class(cinfo->klass);
214
+ break;
215
+ case G_TYPE_ENUM:
216
+ rbgobj_init_enum_class(cinfo->klass);
217
+ break;
218
+ case G_TYPE_FLAGS:
219
+ rbgobj_init_flags_class(cinfo->klass);
220
+ break;
221
+ case G_TYPE_INTERFACE:
222
+ rbgobj_init_interface(cinfo->klass);
223
+ break;
224
+ default:
225
+ rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass);
226
+ break;
227
+ }
228
+ }
229
+
230
+ if (gclass)
231
+ g_type_class_unref(gclass);
232
+
233
+ return cinfo;
234
+ }
235
+
236
+ static VALUE
237
+ rbgobj_lookup_class_by_gtype_body(VALUE data)
238
+ {
239
+ RGObjClassByGtypeData *cdata = (RGObjClassByGtypeData *)data;
240
+ const RGObjClassInfo *cinfo;
241
+
242
+ cinfo = rbgobj_lookup_class_by_gtype_without_lock(cdata->gtype,
243
+ cdata->parent,
244
+ cdata->create_class);
245
+ return (VALUE)cinfo;
246
+ }
247
+
248
+ static VALUE
249
+ rbgobj_lookup_class_by_gtype_ensure(VALUE data)
250
+ {
251
+ rb_funcall(lookup_class_mutex, id_unlock, 0);
252
+ return Qundef;
253
+ }
254
+
255
+ const RGObjClassInfo *
256
+ rbgobj_lookup_class_by_gtype(GType gtype, VALUE parent)
257
+ {
258
+ return rbgobj_lookup_class_by_gtype_full(gtype, parent, TRUE);
259
+ }
260
+
261
+ const RGObjClassInfo *
262
+ rbgobj_lookup_class_by_gtype_full(GType gtype, VALUE parent,
263
+ gboolean create_class)
264
+ {
265
+ RGObjClassByGtypeData data;
266
+
267
+ data.gtype = gtype;
268
+ data.parent = parent;
269
+ data.create_class = create_class;
270
+
271
+ if (create_class) {
272
+ rb_funcall(lookup_class_mutex, id_lock, 0);
273
+ return (RGObjClassInfo *)rb_ensure(rbgobj_lookup_class_by_gtype_body,
274
+ (VALUE)&data,
275
+ rbgobj_lookup_class_by_gtype_ensure,
276
+ (VALUE)&data);
277
+ } else {
278
+ return rbgobj_lookup_class_by_gtype_without_lock(gtype, parent,
279
+ create_class);
280
+ }
281
+ }
282
+
283
+ VALUE
284
+ rbgobj_gtype_to_ruby_class(GType gtype)
285
+ {
286
+ const RGObjClassInfo *cinfo;
287
+
288
+ cinfo = GTYPE2CINFO(gtype);
289
+ return cinfo ? cinfo->klass : Qnil;
290
+ }
291
+
292
+ VALUE
293
+ rbgobj_define_class(gtype, name, module, mark, free, parent)
294
+ GType gtype;
295
+ const gchar* name;
296
+ VALUE module;
297
+ void* mark;
298
+ void* free;
299
+ VALUE parent;
300
+ {
301
+ RGObjClassInfo* cinfo;
302
+ if (gtype == 0)
303
+ rb_bug("rbgobj_define_class: Invalid gtype [%s]\n", name);
304
+
305
+ cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(gtype, parent);
306
+ cinfo->mark = mark;
307
+ cinfo->free = free;
308
+ rb_define_const(module, name, cinfo->klass);
309
+ return cinfo->klass;
310
+ }
311
+
312
+ VALUE
313
+ rbgobj_define_class_dynamic(gtype_name, name, module, mark, free)
314
+ const gchar* gtype_name;
315
+ const gchar* name;
316
+ VALUE module;
317
+ void* mark;
318
+ void* free;
319
+ {
320
+ RGObjClassInfoDynamic* cinfo;
321
+ cinfo = (RGObjClassInfoDynamic*)g_new(RGObjClassInfoDynamic, 1);
322
+ cinfo->name = name;
323
+ cinfo->module = module;
324
+ cinfo->mark = mark;
325
+ cinfo->free = free;
326
+ g_hash_table_insert(dynamic_gtype_list, (void*)gtype_name, (void*)cinfo);
327
+ return Qnil;
328
+ }
329
+
330
+ void
331
+ rbgobj_register_class(VALUE klass,
332
+ GType gtype,
333
+ gboolean klass2gtype,
334
+ gboolean gtype2klass)
335
+ {
336
+ RGObjClassInfo* cinfo = NULL;
337
+ VALUE c = Qnil;
338
+
339
+ if (klass2gtype)
340
+ c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
341
+ if (gtype2klass && !cinfo)
342
+ cinfo = g_new(RGObjClassInfo, 1);
343
+
344
+ if (cinfo) {
345
+ cinfo->klass = klass;
346
+ cinfo->gtype = gtype;
347
+ cinfo->mark = NULL;
348
+ cinfo->free = NULL;
349
+ cinfo->flags = 0;
350
+ }
351
+
352
+ if (klass2gtype)
353
+ rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
354
+
355
+ if (gtype2klass)
356
+ g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);
357
+ }
358
+
359
+ #define _register_fundamental_klass_to_gtype(klass, gtype) \
360
+ rbgobj_register_class(klass, gtype, TRUE, FALSE)
361
+
362
+ #define _register_fundamental_gtype_to_klass(gtype,klass) \
363
+ rbgobj_register_class(klass, gtype, FALSE, TRUE)
364
+
365
+ static void
366
+ Init_typemap()
367
+ {
368
+ id_new = rb_intern("new");
369
+ id_superclass = rb_intern("superclass");
370
+
371
+ gtype_to_cinfo = g_hash_table_new(g_direct_hash, g_direct_equal);
372
+ rb_global_variable(&klass_to_cinfo);
373
+ klass_to_cinfo = rb_hash_new();
374
+
375
+ _register_fundamental_klass_to_gtype(rb_cFixnum, G_TYPE_LONG);
376
+ _register_fundamental_klass_to_gtype(rb_cFloat, G_TYPE_DOUBLE);
377
+ _register_fundamental_klass_to_gtype(rb_cInteger, G_TYPE_LONG);
378
+ _register_fundamental_klass_to_gtype(rb_cString, G_TYPE_STRING);
379
+ _register_fundamental_klass_to_gtype(rb_cSymbol, G_TYPE_STRING);
380
+ _register_fundamental_klass_to_gtype(Qnil, G_TYPE_NONE);
381
+ _register_fundamental_klass_to_gtype(rb_cNilClass, G_TYPE_NONE);
382
+ _register_fundamental_klass_to_gtype(rb_cTrueClass, G_TYPE_BOOLEAN);
383
+ _register_fundamental_klass_to_gtype(rb_cFalseClass, G_TYPE_BOOLEAN);
384
+ _register_fundamental_klass_to_gtype(Qtrue, G_TYPE_BOOLEAN);
385
+ _register_fundamental_klass_to_gtype(Qfalse, G_TYPE_BOOLEAN);
386
+ _register_fundamental_klass_to_gtype(rb_cObject, RBGOBJ_TYPE_RUBY_VALUE);
387
+
388
+ _register_fundamental_gtype_to_klass(G_TYPE_UINT, rb_cInteger);
389
+ _register_fundamental_gtype_to_klass(G_TYPE_FLOAT, rb_cFloat);
390
+ _register_fundamental_gtype_to_klass(G_TYPE_DOUBLE, rb_cFloat);
391
+ _register_fundamental_gtype_to_klass(G_TYPE_INT64, rb_cInteger);
392
+ _register_fundamental_gtype_to_klass(G_TYPE_UINT64, rb_cInteger);
393
+ _register_fundamental_gtype_to_klass(G_TYPE_INT, rb_cInteger);
394
+ _register_fundamental_gtype_to_klass(G_TYPE_LONG, rb_cInteger);
395
+ _register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cFixnum);
396
+ _register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cFixnum);
397
+ _register_fundamental_gtype_to_klass(G_TYPE_STRING, rb_cString);
398
+ _register_fundamental_gtype_to_klass(G_TYPE_ULONG, rb_cInteger);
399
+ _register_fundamental_gtype_to_klass(G_TYPE_NONE, rb_cNilClass);
400
+ _register_fundamental_gtype_to_klass(G_TYPE_BOOLEAN, rb_cTrueClass);
401
+ }
402
+
403
+ /**********************************************************************/
404
+ /* GLib::Type */
405
+
406
+ VALUE rbgobj_cType;
407
+ static ID id_gtype;
408
+
409
+ VALUE
410
+ rbgobj_gtype_new(gtype)
411
+ GType gtype;
412
+ {
413
+ VALUE result = rb_obj_alloc(rbgobj_cType);
414
+ VALUE arg = UINT2NUM(gtype);
415
+ rb_obj_call_init(result, 1, &arg);
416
+ return result;
417
+ }
418
+
419
+ GType
420
+ rbgobj_gtype_get(self)
421
+ VALUE self;
422
+ {
423
+ if (RVAL2CBOOL(rb_obj_is_kind_of(self, rbgobj_cType))) {
424
+ return NUM2ULONG(rb_ivar_get(self, id_gtype));
425
+ } else {
426
+ return CLASS2GTYPE(self);
427
+ }
428
+ rb_raise(rb_eTypeError, "Not a GLib::Type");
429
+ }
430
+
431
+ static VALUE
432
+ type_initialize(self, type)
433
+ VALUE self, type;
434
+ {
435
+ GType gtype;
436
+
437
+ if (RVAL2CBOOL(rb_obj_is_kind_of(type, rb_cInteger))) {
438
+ gtype = NUM2UINT(type);
439
+ // XXX
440
+ if (!g_type_name(gtype))
441
+ gtype = G_TYPE_INVALID;
442
+ } else {
443
+ gtype = g_type_from_name(StringValuePtr(type));
444
+ }
445
+
446
+ if (G_TYPE_INVALID == gtype)
447
+ rb_raise(rb_eArgError, "invalid type");
448
+
449
+ rb_ivar_set(self, id_gtype, UINT2NUM(gtype));
450
+
451
+ return Qnil;
452
+ }
453
+
454
+ static VALUE
455
+ type_inspect(self)
456
+ VALUE self;
457
+ {
458
+ GType gtype = rbgobj_gtype_get(self);
459
+ gchar* str;
460
+ VALUE result;
461
+
462
+ str = g_strdup_printf("GLib::Type[\"%s\"]", g_type_name(gtype));
463
+ result = rb_str_new2(str);
464
+ g_free(str);
465
+
466
+ return result;
467
+ }
468
+
469
+ static VALUE
470
+ type_compare(self, other)
471
+ VALUE self, other;
472
+ {
473
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
474
+ return Qnil;
475
+ else {
476
+ GType a = rbgobj_gtype_get(self);
477
+ GType b = rbgobj_gtype_get(other);
478
+
479
+ if (a==b)
480
+ return INT2FIX(0);
481
+ else if (g_type_is_a(a,b))
482
+ return INT2FIX(-1);
483
+ else if (g_type_is_a(b,a))
484
+ return INT2FIX(1);
485
+ else
486
+ return Qnil;
487
+ }
488
+ }
489
+
490
+ static VALUE
491
+ type_eq(self, other)
492
+ VALUE self, other;
493
+ {
494
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
495
+ return Qnil;
496
+ else {
497
+ GType a = rbgobj_gtype_get(self);
498
+ GType b = rbgobj_gtype_get(other);
499
+ return CBOOL2RVAL(a == b);
500
+ }
501
+ }
502
+
503
+ static VALUE
504
+ type_lt_eq(self, other)
505
+ VALUE self, other;
506
+ {
507
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
508
+ return Qnil;
509
+ else {
510
+ GType a = rbgobj_gtype_get(self);
511
+ GType b = rbgobj_gtype_get(other);
512
+ return CBOOL2RVAL(g_type_is_a(a, b));
513
+ }
514
+ }
515
+
516
+ static VALUE
517
+ type_gt_eq(self, other)
518
+ VALUE self, other;
519
+ {
520
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
521
+ return Qnil;
522
+ else {
523
+ GType a = rbgobj_gtype_get(self);
524
+ GType b = rbgobj_gtype_get(other);
525
+ return CBOOL2RVAL(g_type_is_a(b, a));
526
+ }
527
+ }
528
+
529
+ static VALUE
530
+ type_lt(self, other)
531
+ VALUE self, other;
532
+ {
533
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
534
+ return Qnil;
535
+ else {
536
+ GType a = rbgobj_gtype_get(self);
537
+ GType b = rbgobj_gtype_get(other);
538
+ return CBOOL2RVAL(g_type_is_a(a, b) && a != b);
539
+ }
540
+ }
541
+
542
+ static VALUE
543
+ type_gt(self, other)
544
+ VALUE self, other;
545
+ {
546
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(other, rbgobj_cType)))
547
+ return Qnil;
548
+ else {
549
+ GType a = rbgobj_gtype_get(self);
550
+ GType b = rbgobj_gtype_get(other);
551
+ return CBOOL2RVAL(g_type_is_a(b, a) && a != b);
552
+ }
553
+ }
554
+
555
+ static VALUE
556
+ type_to_int(self)
557
+ VALUE self;
558
+ {
559
+ return rb_ivar_get(self, id_gtype);
560
+ }
561
+
562
+ static VALUE
563
+ type_to_class(self)
564
+ VALUE self;
565
+ {
566
+ return GTYPE2CLASS(rbgobj_gtype_get(self));
567
+ }
568
+
569
+ static VALUE
570
+ type_fundamental(self)
571
+ VALUE self;
572
+ {
573
+ return rbgobj_gtype_new(G_TYPE_FUNDAMENTAL(rbgobj_gtype_get(self)));
574
+ }
575
+
576
+ static VALUE
577
+ type_is_fundamental(self)
578
+ VALUE self;
579
+ {
580
+ return CBOOL2RVAL(G_TYPE_IS_FUNDAMENTAL(rbgobj_gtype_get(self)));
581
+ }
582
+
583
+ static VALUE
584
+ type_is_derived(self)
585
+ VALUE self;
586
+ {
587
+ return CBOOL2RVAL(G_TYPE_IS_DERIVED(rbgobj_gtype_get(self)));
588
+ }
589
+
590
+ static VALUE
591
+ type_is_interface(self)
592
+ VALUE self;
593
+ {
594
+ return CBOOL2RVAL(G_TYPE_IS_INTERFACE(rbgobj_gtype_get(self)));
595
+ }
596
+
597
+ static VALUE
598
+ type_is_classed(self)
599
+ VALUE self;
600
+ {
601
+ return CBOOL2RVAL(G_TYPE_IS_CLASSED(rbgobj_gtype_get(self)));
602
+ }
603
+
604
+ static VALUE
605
+ type_is_instantiatable(self)
606
+ VALUE self;
607
+ {
608
+ return CBOOL2RVAL(G_TYPE_IS_INSTANTIATABLE(rbgobj_gtype_get(self)));
609
+ }
610
+
611
+ static VALUE
612
+ type_is_derivable(self)
613
+ VALUE self;
614
+ {
615
+ return CBOOL2RVAL(G_TYPE_IS_DERIVABLE(rbgobj_gtype_get(self)));
616
+ }
617
+
618
+ static VALUE
619
+ type_is_deep_derivable(self)
620
+ VALUE self;
621
+ {
622
+ return CBOOL2RVAL(G_TYPE_IS_DEEP_DERIVABLE(rbgobj_gtype_get(self)));
623
+ }
624
+
625
+ static VALUE
626
+ type_is_abstract(self)
627
+ VALUE self;
628
+ {
629
+ return CBOOL2RVAL(G_TYPE_IS_ABSTRACT(rbgobj_gtype_get(self)));
630
+ }
631
+
632
+ static VALUE
633
+ type_is_value_abstract(self)
634
+ VALUE self;
635
+ {
636
+ return CBOOL2RVAL(G_TYPE_IS_VALUE_ABSTRACT(rbgobj_gtype_get(self)));
637
+ }
638
+
639
+ static VALUE
640
+ type_is_value_type(self)
641
+ VALUE self;
642
+ {
643
+ return CBOOL2RVAL(G_TYPE_IS_VALUE_TYPE(rbgobj_gtype_get(self)));
644
+ }
645
+
646
+ static VALUE
647
+ type_has_value_table(self)
648
+ VALUE self;
649
+ {
650
+ return CBOOL2RVAL(G_TYPE_HAS_VALUE_TABLE(rbgobj_gtype_get(self)));
651
+ }
652
+
653
+ static VALUE
654
+ type_name(self)
655
+ VALUE self;
656
+ {
657
+ return rb_str_new2(g_type_name(rbgobj_gtype_get(self)));
658
+ }
659
+
660
+ static VALUE
661
+ type_parent(self)
662
+ VALUE self;
663
+ {
664
+ GType parent = g_type_parent(rbgobj_gtype_get(self));
665
+ return parent ? rbgobj_gtype_new(parent) : Qnil;
666
+ }
667
+
668
+ static VALUE
669
+ type_depth(self)
670
+ VALUE self;
671
+ {
672
+ return UINT2NUM(g_type_depth(rbgobj_gtype_get(self)));
673
+ }
674
+
675
+ static VALUE
676
+ type_next_base(leaf_type, root_type)
677
+ VALUE leaf_type, root_type;
678
+ {
679
+ GType ret = g_type_next_base(rbgobj_gtype_get(leaf_type),
680
+ rbgobj_gtype_get(root_type));
681
+ return ret ? rbgobj_gtype_new(ret) : Qnil;
682
+ }
683
+
684
+ static VALUE
685
+ type_is_a(self, is_a_type)
686
+ VALUE self, is_a_type;
687
+ {
688
+ return CBOOL2RVAL(g_type_is_a(rbgobj_gtype_get(self), rbgobj_gtype_get(is_a_type)));
689
+ }
690
+
691
+ #if 0
692
+ gpointer g_type_class_ref (GType type);
693
+ gpointer g_type_class_peek (GType type);
694
+ void g_type_class_unref (gpointer g_class);
695
+ gpointer g_type_class_peek_parent (gpointer g_class);
696
+ gpointer g_type_interface_peek (gpointer instance_class,
697
+ GType iface_type);
698
+ gpointer g_type_interface_peek_parent (gpointer g_iface);
699
+ #endif
700
+
701
+ static VALUE
702
+ type_children(self)
703
+ VALUE self;
704
+ {
705
+ guint n_children;
706
+ GType* types;
707
+ VALUE result;
708
+ int i;
709
+
710
+ types = g_type_children(rbgobj_gtype_get(self), &n_children);
711
+ result = rb_ary_new2(n_children);
712
+ for (i = 0; i < n_children; i++)
713
+ rb_ary_store(result, i, rbgobj_gtype_new(types[i]));
714
+ g_free(types);
715
+
716
+ return result;
717
+ }
718
+
719
+ static VALUE
720
+ type_interfaces(self)
721
+ VALUE self;
722
+ {
723
+ guint n_interfaces;
724
+ GType* types;
725
+ VALUE result;
726
+ int i;
727
+
728
+ types = g_type_interfaces(rbgobj_gtype_get(self), &n_interfaces);
729
+ result = rb_ary_new2(n_interfaces);
730
+ for (i = 0; i < n_interfaces; i++)
731
+ rb_ary_store(result, i, rbgobj_gtype_new(types[i]));
732
+ g_free(types);
733
+
734
+ return result;
735
+ }
736
+
737
+ static VALUE
738
+ type_class_size(self)
739
+ VALUE self;
740
+ {
741
+ GTypeQuery query;
742
+ g_type_query(rbgobj_gtype_get(self), &query);
743
+ return UINT2NUM(query.class_size);
744
+ }
745
+
746
+ static VALUE
747
+ type_instance_size(self)
748
+ VALUE self;
749
+ {
750
+ GTypeQuery query;
751
+ g_type_query(rbgobj_gtype_get(self), &query);
752
+ return UINT2NUM(query.instance_size);
753
+ }
754
+
755
+
756
+ static inline
757
+ void _def_fundamental_type(VALUE ary, GType gtype, const char* name)
758
+ {
759
+ VALUE c = rbgobj_gtype_new(gtype);
760
+ rb_define_const(rbgobj_cType, name, c);
761
+ rb_ary_push(ary, c);
762
+ }
763
+
764
+ static void
765
+ Init_type()
766
+ {
767
+ rb_cMutex = rb_const_get(rb_cObject, rb_intern("Mutex"));
768
+ id_lock = rb_intern("lock");
769
+ id_unlock = rb_intern("unlock");
770
+ lookup_class_mutex = rb_funcall(rb_cMutex, id_new, 0);
771
+ rb_iv_set(mGLib, "lookup_class_mutex", lookup_class_mutex);
772
+
773
+ dynamic_gtype_list = g_hash_table_new(g_str_hash, g_str_equal);
774
+ id_gtype = rb_intern("__gobject_gtype__");
775
+
776
+ rbgobj_cType = rb_define_class_under(mGLib, "Type", rb_cObject);
777
+
778
+ rb_define_alias(CLASS_OF(rbgobj_cType), "[]", "new");
779
+ rb_define_method(rbgobj_cType, "initialize", type_initialize, 1);
780
+ rb_define_method(rbgobj_cType, "inspect", type_inspect, 0);
781
+ rb_define_method(rbgobj_cType, "<=>", type_compare, 1);
782
+ rb_define_method(rbgobj_cType, "==", type_eq, 1);
783
+ rb_define_method(rbgobj_cType, "<=", type_lt_eq, 1);
784
+ rb_define_method(rbgobj_cType, ">=", type_gt_eq, 1);
785
+ rb_define_method(rbgobj_cType, "<", type_lt, 1);
786
+ rb_define_method(rbgobj_cType, ">", type_gt, 1);
787
+ rb_define_method(rbgobj_cType, "eql?", type_eq, 1);
788
+ rb_define_method(rbgobj_cType, "hash", type_to_int, 0);
789
+ rb_define_method(rbgobj_cType, "to_i", type_to_int, 0);
790
+ rb_define_method(rbgobj_cType, "to_int", type_to_int, 0);
791
+ rb_define_method(rbgobj_cType, "to_class", type_to_class, 0);
792
+
793
+ rb_define_method(rbgobj_cType, "fundamental", type_fundamental, 0);
794
+ rb_define_method(rbgobj_cType, "fundamental?", type_is_fundamental, 0);
795
+ rb_define_method(rbgobj_cType, "derived?", type_is_derived, 0);
796
+ rb_define_method(rbgobj_cType, "interface?", type_is_interface, 0);
797
+ rb_define_method(rbgobj_cType, "classed?", type_is_classed, 0);
798
+ rb_define_method(rbgobj_cType, "instantiatable?", type_is_instantiatable, 0);
799
+ rb_define_method(rbgobj_cType, "derivable?", type_is_derivable, 0);
800
+ rb_define_method(rbgobj_cType, "deep_derivable?", type_is_deep_derivable, 0);
801
+ rb_define_method(rbgobj_cType, "abstract?", type_is_abstract, 0);
802
+ rb_define_method(rbgobj_cType, "value_abstract?", type_is_value_abstract, 0);
803
+ rb_define_method(rbgobj_cType, "value_type?", type_is_value_type, 0);
804
+ rb_define_method(rbgobj_cType, "has_value_table", type_has_value_table, 0);
805
+
806
+ rb_define_method(rbgobj_cType, "name", type_name, 0);
807
+ rb_define_method(rbgobj_cType, "to_s", type_name, 0);
808
+ rb_define_method(rbgobj_cType, "parent", type_parent, 0);
809
+ rb_define_method(rbgobj_cType, "depth", type_depth, 0);
810
+ rb_define_method(rbgobj_cType, "next_base", type_next_base, 1);
811
+ rb_define_method(rbgobj_cType, "type_is_a?", type_is_a, 1);
812
+ rb_define_method(rbgobj_cType, "children", type_children, 0);
813
+ rb_define_method(rbgobj_cType, "interfaces", type_interfaces, 0);
814
+ rb_define_method(rbgobj_cType, "class_size", type_class_size, 0);
815
+ rb_define_method(rbgobj_cType, "instance_size", type_instance_size, 0);
816
+
817
+ {
818
+ VALUE ary = rb_ary_new();
819
+ rb_define_const(rbgobj_cType, "FUNDAMENTAL_MAX", INT2FIX(G_TYPE_FUNDAMENTAL_MAX));
820
+ _def_fundamental_type(ary, G_TYPE_NONE, "NONE");
821
+ _def_fundamental_type(ary, G_TYPE_INTERFACE, "INTERFACE");
822
+ _def_fundamental_type(ary, G_TYPE_CHAR, "CHAR");
823
+ _def_fundamental_type(ary, G_TYPE_UCHAR, "UCHAR");
824
+ _def_fundamental_type(ary, G_TYPE_BOOLEAN, "BOOLEAN");
825
+ _def_fundamental_type(ary, G_TYPE_INT, "INT");
826
+ _def_fundamental_type(ary, G_TYPE_UINT, "UINT");
827
+ _def_fundamental_type(ary, G_TYPE_LONG, "LONG");
828
+ _def_fundamental_type(ary, G_TYPE_ULONG, "ULONG");
829
+ _def_fundamental_type(ary, G_TYPE_INT64, "INT64");
830
+ _def_fundamental_type(ary, G_TYPE_UINT64, "UINT64");
831
+ _def_fundamental_type(ary, G_TYPE_ENUM, "ENUM");
832
+ _def_fundamental_type(ary, G_TYPE_FLAGS, "FLAGS");
833
+ _def_fundamental_type(ary, G_TYPE_FLOAT, "FLOAT");
834
+ _def_fundamental_type(ary, G_TYPE_DOUBLE, "DOUBLE");
835
+ _def_fundamental_type(ary, G_TYPE_STRING, "STRING");
836
+ _def_fundamental_type(ary, G_TYPE_POINTER, "POINTER");
837
+ _def_fundamental_type(ary, G_TYPE_BOXED, "BOXED");
838
+ _def_fundamental_type(ary, G_TYPE_PARAM, "PARAM");
839
+ _def_fundamental_type(ary, G_TYPE_OBJECT, "OBJECT");
840
+ rb_define_const(rbgobj_cType, "FUNDAMENTAL_TYPES", ary); /* FIXME: better name */
841
+ }
842
+ }
843
+
844
+ /**********************************************************************/
845
+
846
+ void Init_gobject_gtype()
847
+ {
848
+ g_type_init();
849
+ Init_typemap();
850
+ Init_type();
851
+ }